PWE_PRC8/_module/nss/bdm_include.nss
Jaysyn904 ee1dc35889 Initial Commit
Initial Commit
2025-04-03 10:29:41 -04:00

1147 lines
38 KiB
Plaintext

//::///////////////////////////////////////////////
//:: Name: Bedlamson's Dynamic Merchant System
//:: FileName: bdm_include
//:: Copyright (c) 2003 Stephen Spann
//::///////////////////////////////////////////////
//:: Created By: Bedlamson
//:: Created On: 1/23/2003
//::///////////////////////////////////////////////
//:: Time Functions: from CS Event Scheduler
//:: by Craig Smith (Galap)
//:: Token Functions: from NWNSS by Palor
//::///////////////////////////////////////////////
#include "prc_inc_racial"
int nDebug = 0;
int CheckAlignment(string sAlignment, object oPC);
int CheckClass (string sClass, object oPC);
int CheckRace (string sRace, object oPC);
int CheckGender (string sGender, object oPC);
int CheckSubrace(string sSubrace, object oPC);
void BDM_SetNPCStores();
void BDM_ModuleItemAcquired();
void BDM_ModuleItemUnacquired();
// Time Functions by
int cs_time_GetSecondsSinceEpoch(struct cs_time time);
struct cs_time cs_time_GetEpochTime();
struct cs_time cs_time_GetCurrentTime();
string cs_time_TimeToString(struct cs_time time);
struct cs_time cs_time_StringToTime(string strtime);
// If you are using the ALFA subrace system, and you want a
// merchant to restrict a cache to a subrace, discriminate
// against a subrace, or favor a subrace, delete the first
// CheckSubrace() code (lines 44-47), and uncomment the
// second one by deleting lines 51 and 99. You will also
// need to uncomment the following line so it turns red:
//
// #include "subraces"
//
// If you have custom ALFA subraces in your module, you need
// to create additional case statements to account for them.
// The case number becomes the 'xx' value in the parameters
// listed in the 'bdm__readme' script.
//
// Delete this function to enable ALFA subraces, it is only
// here so that scripts will compile correctly without the
// ALFA scripts.
int CheckSubrace(string sSubrace, object oPC)
{
return FALSE;
}
/* DELETE THIS LINE TO ENABLE THE ALFA SUBRACES
int CheckSubrace(string sSubrace, object oPC)
{
int nSubrace = StringToInt(sSubrace);
int nPlayerSubrace = GetLocalInt(oPC, SUBRACE_FIELD);
switch (nSubrace)
{
case 0:
break;
case 1:
break;
case 2:
if (nPlayerSubrace == SUBRACE_DWARF_GOLD) return TRUE;
break;
case 3:
if (nPlayerSubrace == SUBRACE_DWARF_GRAY) return TRUE;
break;
case 4:
if (nPlayerSubrace == SUBRACE_DWARF_SHIELD) return TRUE;
break;
case 5:
if (nPlayerSubrace == SUBRACE_ELF_DARK) return TRUE;
break;
case 6:
if (nPlayerSubrace == SUBRACE_ELF_MOON) return TRUE;
break;
case 7:
if (nPlayerSubrace == SUBRACE_ELF_SUN) return TRUE;
break;
case 8:
if (nPlayerSubrace == SUBRACE_ELF_WILD) return TRUE;
break;
case 9:
if (nPlayerSubrace == SUBRACE_ELF_WOOD) return TRUE;
break;
case 10:
if (nPlayerSubrace == SUBRACE_GNOME_DEEP) return TRUE;
break;
case 11:
if (nPlayerSubrace == SUBRACE_GNOME_ROCK) return TRUE;
break;
case 12:
if (nPlayerSubrace == SUBRACE_HALFELF) return TRUE;
break;
case 13:
if (nPlayerSubrace == SUBRACE_HALFORC) return TRUE;
break;
case 14:
if (nPlayerSubrace == SUBRACE_HALFLING_GHOSTWISE) return TRUE;
break;
case 15:
if (nPlayerSubrace == SUBRACE_HALFLING_LIGHTFOOT) return TRUE;
break;
case 16:
if (nPlayerSubrace == SUBRACE_HALFLING_STRONGHEART) return TRUE;
break;
case 17:
if (nPlayerSubrace == SUBRACE_HUMAN) return TRUE;
break;
case 18:
if (nPlayerSubrace == SUBRACE_HALFDROW) return TRUE;
break;
}
}
*///DELETE THIS LINE TOO, IF YOU WANT.
// If you are not using the ALFA subrace system, and you want
// a merchant to restrict a cache to a subrace, discriminate
// against a subrace, or favor a subrace, you need to set up
// additional case statements to the function below, with
// the conditional for sPlayerSubrace is changed to exactly
// what the player enters in the Subrace field during character
// creation, and the conditional for nPlayer race is set to the
// appropriate base race of the subrace. Case 8 is an example
// of how to enable discrimination, favoritism, and restriction
// of moon elves. The case number becomes the 'xx' value in the
// parameters listed in the 'bdm__readme' script.
int CheckRace(string sRace, object oPC)
{
int nRace = StringToInt(sRace);
int nPlayerRace = MyPRCGetRacialType(oPC);
string sPlayerSubrace = GetSubRace(oPC);
switch (nRace)
{
case 1:
if (nPlayerRace == RACIAL_TYPE_DWARF) return TRUE;
break;
case 2:
if (nPlayerRace == RACIAL_TYPE_ELF) return TRUE;
break;
case 3:
if (nPlayerRace == RACIAL_TYPE_GNOME) return TRUE;
break;
case 4:
if (nPlayerRace == RACIAL_TYPE_HALFELF) return TRUE;
break;
case 5:
if (nPlayerRace == RACIAL_TYPE_HALFLING) return TRUE;
break;
case 6:
if (nPlayerRace == RACIAL_TYPE_HALFORC) return TRUE;
break;
case 7:
if (nPlayerRace == RACIAL_TYPE_HUMAN) return TRUE;
break;
case 8:
if (sPlayerSubrace == "Moon Elf" && nPlayerRace == RACIAL_TYPE_ELF) return TRUE;
break;
}
return FALSE;
}
int CheckAlignment(string sAlignment, object oPC)
{
int nAlign = StringToInt(sAlignment);
//if (nDebug) SendMessageToPC(oPC, "Alignment Case = " + IntToString(nAlign));
int nGoodEvil = GetAlignmentGoodEvil(oPC);
int nLawChaos = GetAlignmentLawChaos(oPC);
//if (nDebug) SendMessageToPC(oPC, "Good/Evil: " + IntToString(nGoodEvil) + " Law/Chaos: " + IntToString(nLawChaos));
switch (nAlign)
{
case 1:
if (nLawChaos == ALIGNMENT_CHAOTIC) return TRUE;
break;
case 2:
if (nGoodEvil == ALIGNMENT_EVIL) return TRUE;
break;
case 3:
if (nGoodEvil == ALIGNMENT_GOOD) return TRUE;
break;
case 4:
if (nLawChaos == ALIGNMENT_LAWFUL) return TRUE;
break;
case 5:
if (nGoodEvil == ALIGNMENT_NEUTRAL) return TRUE;
break;
case 6:
if (nLawChaos == ALIGNMENT_NEUTRAL) return TRUE;
break;
case 7:
if (nLawChaos == ALIGNMENT_CHAOTIC && nGoodEvil == ALIGNMENT_EVIL) return TRUE;
break;
case 8:
if (nLawChaos == ALIGNMENT_CHAOTIC && nGoodEvil == ALIGNMENT_GOOD) return TRUE;
break;
case 9:
if (nLawChaos == ALIGNMENT_CHAOTIC && nGoodEvil == ALIGNMENT_NEUTRAL) return TRUE;
break;
case 10:
if (nLawChaos == ALIGNMENT_LAWFUL && nGoodEvil == ALIGNMENT_EVIL) return TRUE;
break;
case 11:
if (nLawChaos == ALIGNMENT_LAWFUL && nGoodEvil == ALIGNMENT_GOOD) return TRUE;
break;
case 12:
if (nLawChaos == ALIGNMENT_LAWFUL && nGoodEvil == ALIGNMENT_NEUTRAL) return TRUE;
break;
case 13:
if (nLawChaos == ALIGNMENT_NEUTRAL && nGoodEvil == ALIGNMENT_EVIL) return TRUE;
break;
case 14:
if (nLawChaos == ALIGNMENT_NEUTRAL && nGoodEvil == ALIGNMENT_GOOD) return TRUE;
break;
case 15:
if (nLawChaos == ALIGNMENT_NEUTRAL && nGoodEvil == ALIGNMENT_NEUTRAL) return TRUE;
break;
}
return FALSE;
}
int CheckClass(string sClass, object oPC)
{
int nClass = StringToInt(sClass);
int nPlayerClass;
int nNth;
for (nNth = 1; nNth <= 8; nNth++)
{
nPlayerClass = GetClassByPosition(nNth, oPC);
switch (nClass)
{
case 1:
if (nPlayerClass == CLASS_TYPE_BARBARIAN) return TRUE; else break;
case 2:
if (nPlayerClass == CLASS_TYPE_BARD) return TRUE; else break;
case 3:
if (nPlayerClass == CLASS_TYPE_CLERIC) return TRUE; else break;
case 4:
if (nPlayerClass == CLASS_TYPE_DRUID) return TRUE; else break;
case 5:
if (nPlayerClass == CLASS_TYPE_FIGHTER) return TRUE; else break;
case 6:
if (nPlayerClass == CLASS_TYPE_MONK) return TRUE; else break;
case 7:
if (nPlayerClass == CLASS_TYPE_PALADIN) return TRUE; else break;
case 8:
if (nPlayerClass == CLASS_TYPE_RANGER) return TRUE; else break;
case 9:
if (nPlayerClass == CLASS_TYPE_ROGUE) return TRUE; else break;
case 10:
if (nPlayerClass == CLASS_TYPE_SORCERER) return TRUE; else break;
case 11:
if (nPlayerClass == CLASS_TYPE_WIZARD) return TRUE; else break;
default:
return TRUE;
}
}
return FALSE;
}
int CheckGender(string sGender, object oPC)
{
int nPlayerGender = GetGender(oPC);
if (sGender == "M" && nPlayerGender == GENDER_MALE) return TRUE;
if (sGender == "F" && nPlayerGender == GENDER_FEMALE) return TRUE;
return FALSE;
}
int GetItemTime(object oItem)
{
string sTime = GetLocalString(oItem, "TIME");
struct cs_time ItemTime = cs_time_StringToTime(sTime);
struct cs_time CurrentTime = cs_time_GetCurrentTime();
int nItemTime = cs_time_GetSecondsSinceEpoch(ItemTime);
int nCurrentTime = cs_time_GetSecondsSinceEpoch(CurrentTime);
int nTimeElapsed = nCurrentTime - nItemTime;
return nTimeElapsed;
}
void BDM_SetNPCStores()
{
// Find the nearest store and set it as the
// main store for the NPC
object oMainStore = GetNearestObject(OBJECT_TYPE_STORE);
SetLocalObject(OBJECT_SELF, "STORE", oMainStore);
// Find and set the parameters to the NPC
// If the store's tag doesn't begin with 'M_'
// then look for a waypoint.
string sParams = GetStringUpperCase(GetTag(oMainStore));
if (GetStringLeft(sParams, 2) != "M_")
{
object oWaypoint = GetNearestObject(OBJECT_TYPE_WAYPOINT, oMainStore);
int nNth = 1;
while (oWaypoint != OBJECT_INVALID)
{
sParams = GetStringUpperCase(GetName(oWaypoint));
if (GetStringLeft(sParams, 2) == "M_") break;
nNth++;
oWaypoint = GetNearestObject(OBJECT_TYPE_WAYPOINT, oMainStore, nNth);
}
}
SetLocalString(OBJECT_SELF, "PARAMS", sParams);
SetLocalString(oMainStore, "PARAMS", sParams);
// Find if there are any caches for dynamic
// inventories, then set them to the NPC merchant.
int nPosition = FindSubString(sParams, "NC");
int nValidCaches = StringToInt(GetSubString(sParams, nPosition + 2, 2));
int nNth;
for (nNth = 1; nNth <= nValidCaches; nNth++)
{
object oCache = GetNearestObject(OBJECT_TYPE_STORE, oMainStore, nNth);
if (GetStringLeft(GetTag(oCache), 2) == "C_")
{
SetLocalObject(oMainStore, "CACHE_" + IntToString(nNth), oCache);
}
}
}
void BDM_ModuleItemAcquired()
{
// Get the item that was acquired.
object oItemAcquired = GetModuleItemAcquired();
// If the item is being stolen, destroy the temporary
// store it was stolen from to avoid a PC being able
// to steal a store's entire inventory.
if (GetLocalInt(oItemAcquired, "STOLEN"))
{
object oAcquiredFrom = GetLocalObject(oItemAcquired, "STEALSTORE");
DestroyObject(oAcquiredFrom);
DeleteLocalInt(oItemAcquired, "STOLEN");
DeleteLocalObject(oItemAcquired, "STEALSTORE");
}
}
void BDM_ModuleItemUnacquired()
{
// Get the item that was lost.
object oItemLost = GetModuleItemLost();
// Delete the dynamic item variable in case the item
// is being sold back to a store with a dynamic
// inventory.
DeleteLocalInt(oItemLost, "DYNAMIC");
// Set the time that the item was lost. This will
// be used to determine how long it has been in a
// store's inventory.
struct cs_time CurrentTime = cs_time_GetCurrentTime();
string sCurrentTime = cs_time_TimeToString(CurrentTime);
SetLocalString(oItemLost, "TIME", sCurrentTime);
}
/*##
# NWN Spawn System v2.4.4c
# Author: Palor <palor@truefear.net>
# Description:
# Complete Spawn System, one script.
#
##*/
int GetValue(object oObject, string sParam, string sName);
void GetDiceValue(object oObject, string sName, string sNumDice, string sDice);
int GetValue(object oObject, string sParam, string sName)
{
int iSwitchValue = 0;
int iIsMinutes = 0;
int iIsHours = 0;
if (FindSubString(sName, sParam) > 0)
{
if (sParam == "HA" || // Haggle All
sParam == "HD" || // Haggle Down
sParam == "HU" || // Haggle Up
sParam == "HB" || // Haggle Buy
sParam == "HS" || // Haggle Sell
sParam == "HC" || // Haggle Cumulative
sParam == "FG" || // Favors Gender
sParam == "FL" || // Favoritism Linked
sParam == "FB" || // Favors Buy
sParam == "FE" || // Favors Sell
sParam == "FU" || // Favoritism Unlimited
sParam == "PG" || // Prejudice Gender
sParam == "PL" || // Prejudice Linked
sParam == "PB" || // Prejudice Buy
sParam == "PE" || // Prejudice Sell
sParam == "PU" || // Prejudice Unlimited
sParam == "ST" || // Stealing
sParam == "SA" || // Steal All
sParam == "RH" || // Reaction Hostile
sParam == "UQ" || // Unique Items
sParam == "IR" || // Items Remain
sParam == "LG" || // Limit to Gender
sParam == "LL" || // Limits Linked
sParam == "TL") // Timer Linked
{
iSwitchValue = 1;
}
else
{
int iNumberPos = FindSubString(sName, sParam);
if (sParam == "TM" || sParam == "CL")
{
if (GetSubString(sName, (iNumberPos + 4), 1) == "M")
{
iIsMinutes = 1;
}
else if (GetSubString(sName, (iNumberPos + 4), 1) == "H")
{
iIsHours = 1;
}
}
int iNumberLength = GetStringLength(sName) - iNumberPos;
string sParamValue = GetSubString(sName, (iNumberPos + 2), 2);
iSwitchValue = StringToInt(sParamValue);
if (iIsMinutes == 1)
{
iSwitchValue = iSwitchValue * 60;
}
else if (iIsHours == 1)
{
iSwitchValue = (iSwitchValue * 60) * 60;
}
if (GetSubString(sName, (iNumberPos + 4), 1) == "R")
{
int iMaxRand = StringToInt(GetSubString(
sName, (iNumberPos + 5), 2));
if (GetSubString(sName, (iNumberPos + 7), 1) == "M")
{
iIsMinutes = 1;
iMaxRand = iMaxRand * 60;
}
else if (GetSubString(sName, (iNumberPos + 7), 1) == "H")
{
iMaxRand = (iMaxRand * 60) * 60;
}
iSwitchValue = iSwitchValue + Random(iMaxRand - iSwitchValue);
}
}
}
return iSwitchValue;
}
//============================================================================
//
// Name: General utility functions
// File: cs_utility
// Author: Craig Smith (Galap) <craig@smith.dropbear.id.au>
//
//----------------------------------------------------------------------------
// This software is distributed in the hope that it will be useful. It is
// provided "as is" WITHOUT WARRANTY OF ANY KIND, either expressed or implied,
// including, but not limited to, the implied warranties of merchantability
// and fitness for a particular purpose. You may redistribute or modify this
// software for your own purposes so long as all original credit information
// remains intact.
//----------------------------------------------------------------------------
//
// Introduction
// ------------
// A collection of generally useful functions that don't belong to any
// particular cs_* subsystem or script.
//
// This script contains the following sets of functions:
//
// * cs_time_XXXX Functions for manipulating times
// * cs_util_XXXX Other general functions
//
//============================================================================
// Uncomment this directive to compile without errors for testing.
//# include "cs_dbg"
//============================================================================
//
// Function Prototypes
//
//============================================================================
// Return the number of seconds that have elapsed since the calendar epoch,
// accounting for wildcards on any time or date field.
//
// time The cs_time struct to be converted
//
// returns The number of seconds since the epoch
int cs_time_GetSecondsSinceEpoch(struct cs_time time);
// Return the time of the epoch, i.e. 0, as a struct cs_time.
//
// returns The epoch time
//
struct cs_time cs_time_GetEpochTime();
// Return the current time formatted into a struct cs_time.
//
// returns The current time
struct cs_time cs_time_GetCurrentTime();
// Convert a struct cs_time into a string. The string will comprise the
// fields in the struct separated by colons, with "cs_time" prefixed.
//
// time The cs_time struct to be converted
//
// returns A string representation of the time
string cs_time_TimeToString(struct cs_time time);
// Convert a properly formatted string into a cs_time struct. Use the
// cs_IsValidTime() function to determine whether the string has been
// correctly converted.
//
// strtime The string to be converted
//
// returns A cs_time struct of the time represented by the string
struct cs_time cs_time_StringToTime(string strtime);
// Determine whether a specific time structure is valid.
//
// time The time structure to test for validity
//
// returns TRUE if the time structure is valid, FALSE otherwise
int cs_time_GetIsValidTime(struct cs_time time);
// Compare the specified time with the start time to determine if the
// specified time falls after.
//
// time The time to be compared
// start The time to be compared against
//
// returns TRUE if the time is greater than the start time
int cs_time_GetIsTimeAfter(struct cs_time time, struct cs_time start);
// Compare the specified time with the start time to determine if the
// specified time falls before.
//
// time The time to be compared
// start The time to be compared against
//
// returns TRUE if the time is less than or equal to the start time
int cs_time_GetIsTimeBefore(struct cs_time time, struct cs_time start);
// Compare the specified time with the start time and the end time to
// determine if the specified time falls between.
//
// time The time to be compared
// start The time at which the compare period begins
// end The time at which the compare period ends
//
// returns TRUE if the time is greater than or equal to the start
// time and less than the end time, otherwise FALSE
int cs_time_GetIsTimeBetween(struct cs_time time, struct cs_time start, struct cs_time end);
// Determine whether the specified value exists in a set. A set in this case
// is a formatted string containing distinct elements separated by colons.
// Values to be added to the set may not contain colons or bad things will
// happen.
//
// set The current set of values
// value The value for which to search
//
// returns TRUE if the value is in the set, otherwise FALSE
int cs_util_GetIsInSet(string set, string value);
// Add a value to a set if it is not already in the set. A set in this case
// is a formatted string containing distinct elements separated by colons.
// Values to be added to the set may not contain colons or bad things will
// happen.
//
// set The current set of values
// value The value to add to the set
//
// returns The new value of the set
string cs_util_AddToSet(string set, string value);
// Remove a value from a set if it exists within the set. A set in this case
// is a formatted string containing distinct elements separated by colons.
// Values to be remove from the set may not contain colons or bad things will
// happen.
//
// set The current set of values
// value The value to remove from the set
//
// returns The new value of the set
string cs_util_RemoveFromSet(string set, string value);
// Retrieve a string from a set. A set in this case is a formatted string
// containing distinct elements separated by colons. The value indices
// start at 1 for the first value in the set.
//
// set The current set of values
// value The index of the value to retrieve from the set
//
// returns The value from the set, or "" if the specified index does
// not correspond to a value in the set
string cs_util_GetValueFromSet(string set, int index);
// Invoke a specific user-defined event on every object that matches a
// specified tag.
//
// tag The tag that identifies target objects
// eventNum The event number with which to signal target objects
void cs_util_InvokeEventByTag(string tag, int eventNum);
// When invoked by a creature, displays the current action being performed
// by the creature.
void cs_util_PrintCurrentAction();
//============================================================================
//
// Data Types and Constants
//
//============================================================================
// A structure that represents a single point in time. The valid field is
// necessary since there does not appear to be an equivalent to a null
// value for structs so a valid struct must always be returned from
// functions, even if the data in the struct is not valid.
//
struct cs_time
{
// The valid field is used for error checking returned structs. It is
// not part of the data for a time.
int valid;
// Self explantary fields
int second;
int minute;
int hour;
int day;
int month;
int year;
};
// When this value is specified instead of a specific time field, the field
// is treated as a wildcard that matches every possible value for that field.
int CS_TIME_ANY = -1;
// The prefix string for time conversions.
string cs_time_conversionPrefix = "cs_time";
// Constants for manipulating dates as a number of seconds since the
// beginning of the calendar epoch, i.e. year 0. Given the standard start
// date in NWN of 1372DR, game-time dates since 0DR all fit into a single
// 32bit signed int, which is very convenient for comparisons. The DR
// suffix is short for Dale Reckoning, the name of the calendar defined
// for the Forgotten Realms and used by NWN.
//
// The number of minutes per game hour may be changed in the Module Properties
// dialog in the Aurora Toolset. Be aware that if you change the number of
// minutes per hour to anything higher than 4, the date functions in this
// file will cease to function for the default calendar (i.e. 1372DR).
// Earlier dates may work if you wish to run a module set in an earlier
// time, or if you are building your own world history and can use any
// calendar settings you please. If you set the minutes per hour property
// to 4, the date functions will still work, but you don't have a lot of
// leeway for the default calendar. Advance by a few years from 1372DR
// and the total seconds since 0DR will overflow a signed 32bit int and
// you will be sad. Set the minutes per hour property to a value of 5 or
// more and you will certainly be sad anyway.
//
int cs_time_secondsPerMinute = 60;
int cs_time_hoursPerDay = 24;
int cs_time_daysPerMonth = 28;
int cs_time_monthsPerYear = 12;
int cs_time_secondsPerHour = FloatToInt(HoursToSeconds(1));
int cs_time_secondsPerDay = cs_time_hoursPerDay * cs_time_secondsPerHour;
int cs_time_secondsPerMonth = cs_time_daysPerMonth * cs_time_secondsPerDay;
int cs_time_secondsPerYear = cs_time_monthsPerYear * cs_time_secondsPerMonth;
//----------------------------------------------------------------------------
int cs_time_GetSecondsSinceEpoch(struct cs_time time)
{
// Deal with wildcard fields by setting the time field to the corresponding
// current time/date value to force a match.
if (time.year < 0)
{
time.year = GetCalendarYear();
}
if (time.month < 0)
{
time.month = GetCalendarMonth();
}
if (time.day < 0)
{
time.day = GetCalendarDay();
}
if (time.hour < 0)
{
time.hour = GetTimeHour();
}
if (time.minute < 0)
{
time.minute = GetTimeMinute();
}
if (time.second < 0)
{
time.second = GetTimeSecond();
}
int seconds = (time.year * cs_time_secondsPerYear) +
(time.month * cs_time_secondsPerMonth) +
(time.day * cs_time_secondsPerDay) +
(time.hour * cs_time_secondsPerHour) +
(time.minute * cs_time_secondsPerMinute) +
time.second;
//cs_dbg_PrintString(
// CS_DBG_INFO,
// "cs_time_SecondsSinceEpoch: " +
// IntToString(seconds)
//);
return seconds;
}
//----------------------------------------------------------------------------
struct cs_time cs_time_GetEpochTime()
{
struct cs_time time;
time.valid = TRUE;
// Populate the time fields. I know this is a bit silly but I'm a
// completist.
time.second = 0;
time.minute = 0;
time.hour = 0;
time.day = 0;
time.month = 0;
time.year = 0;
//cs_dbg_PrintString(
// CS_DBG_INFO,
// "cs_time_GetEpochTime: " +
// cs_time_TimeToString(time)
//);
return time;
}
//----------------------------------------------------------------------------
struct cs_time cs_time_GetCurrentTime()
{
struct cs_time time;
time.valid = TRUE;
// Populate the time fields
time.second = GetTimeSecond();
time.minute = GetTimeMinute();
time.hour = GetTimeHour();
time.day = GetCalendarDay();
time.month = GetCalendarMonth();
time.year = GetCalendarYear();
//cs_dbg_PrintString(
// CS_DBG_INFO,
// "cs_time_GetCurrentTime: " +
// cs_time_TimeToString(time)
//);
return time;
}
//----------------------------------------------------------------------------
string cs_time_TimeToString(struct cs_time time)
{
string strtime = cs_time_conversionPrefix + ":" +
IntToString(time.year) + ":" +
IntToString(time.month) + ":" +
IntToString(time.day) + ":" +
IntToString(time.hour) + ":" +
IntToString(time.minute) + ":" +
IntToString(time.second);
return strtime;
}
//----------------------------------------------------------------------------
struct cs_time cs_time_StringToTime(string strtime)
{
//cs_dbg_Enter("cs_time_StringToTime: " + strtime);
struct cs_time time;
time.valid = FALSE;
// Make sure that we have a formatted cs_time as a string
int pos = FindSubString(strtime, ":");
if (GetStringLeft(strtime, pos) == cs_time_conversionPrefix)
{
time.valid = TRUE;
// Remove the "cs_time" prefix from the string
strtime = GetStringRight(strtime, GetStringLength(strtime) - pos - 1);
// Extract the year and then remove it from the string
pos = FindSubString(strtime, ":");
time.year = StringToInt(GetStringLeft(strtime, pos));
strtime = GetStringRight(strtime, GetStringLength(strtime) - pos - 1);
// Extract the month and then remove it from the string
pos = FindSubString(strtime, ":");
time.month = StringToInt(GetStringLeft(strtime, pos));
strtime = GetStringRight(strtime, GetStringLength(strtime) - pos - 1);
// Extract the day and then remove it from the string
pos = FindSubString(strtime, ":");
time.day = StringToInt(GetStringLeft(strtime, pos));
strtime = GetStringRight(strtime, GetStringLength(strtime) - pos - 1);
// Extract the hour and then remove it from the string
pos = FindSubString(strtime, ":");
time.hour = StringToInt(GetStringLeft(strtime, pos));
strtime = GetStringRight(strtime, GetStringLength(strtime) - pos - 1);
// Extract the minute and then remove it from the string
pos = FindSubString(strtime, ":");
time.minute = StringToInt(GetStringLeft(strtime, pos));
// Whatever we have left must be the seconds
time.second = StringToInt(
GetStringRight(strtime, GetStringLength(strtime) - pos - 1)
);
}
//cs_dbg_Exit("cs_time_StringToTime: " + IntToString(time.valid));
return time;
}
//----------------------------------------------------------------------------
int cs_time_GetIsValidTime(struct cs_time time)
{
int valid = time.valid == TRUE;
//cs_dbg_PrintString(
// CS_DBG_INFO,
// "cs_time_IsValidTime: " +
// IntToString(valid)
//);
return valid;
}
//----------------------------------------------------------------------------
int cs_time_GetIsTimeAfter(struct cs_time time, struct cs_time start)
{
int timeElapsed = cs_time_GetSecondsSinceEpoch(time);
int startElapsed = cs_time_GetSecondsSinceEpoch(start);
int value = timeElapsed > startElapsed;
//cs_dbg_PrintString(
// CS_DBG_INFO,
// "cs_time_IsTimeAfter: " + IntToString(value) + " (" +
// IntToString(timeElapsed) + ">" + IntToString(startElapsed) + ")"
//);
return value;
}
//----------------------------------------------------------------------------
int cs_time_GetIsTimeBefore(struct cs_time time, struct cs_time start)
{
int timeElapsed = cs_time_GetSecondsSinceEpoch(time);
int startElapsed = cs_time_GetSecondsSinceEpoch(start);
int value = timeElapsed <= startElapsed;
//cs_dbg_PrintString(
// CS_DBG_INFO,
// "cs_time_IsTimeBefore: " + IntToString(value) + " (" +
// IntToString(timeElapsed) + "<=" + IntToString(startElapsed) + ")"
//);
return value;
}
//----------------------------------------------------------------------------
int cs_time_GetIsTimeBetween(
struct cs_time time,
struct cs_time start,
struct cs_time end)
{
int timeElapsed = cs_time_GetSecondsSinceEpoch(time);
int startElapsed = cs_time_GetSecondsSinceEpoch(start);
int endElapsed = cs_time_GetSecondsSinceEpoch(end);
int value = (timeElapsed == endElapsed) ||
((timeElapsed > startElapsed) && (timeElapsed <= endElapsed));
//cs_dbg_PrintString(
// CS_DBG_INFO,
// "cs_time_IsTimeBetween: " + IntToString(value) +
// " (" + IntToString(timeElapsed) + "==" + IntToString(endElapsed) + " || (" +
// IntToString(timeElapsed) + ">" + IntToString(startElapsed) + " && " +
// IntToString(timeElapsed) + "<=" + IntToString(endElapsed) + "))"
//);
return value;
}
//----------------------------------------------------------------------------
int cs_util_GetIsInSet(string set, string value)
{
int result = FALSE;
// Append the value to the set, but only if it is not already in the
// set. The set is either "", or always begins and ends with colons.
// This allows a search for the value bounded by colons, ensuring that
// values that are substrings of longer values don't cause false positives
// in the search. Of course, should a value have a colon in it all bets
// are off.
if (FindSubString(set, ":" + value + ":") >= 0)
{
// The value is in the set
result = TRUE;;
}
//cs_dbg_PrintString(
// CS_DBG_INFO,
// "cs_util_IsInSet: " +
// IntToString(result)
//);
return result;
}
//----------------------------------------------------------------------------
string cs_util_AddToSet(string set, string value)
{
//cs_dbg_Enter("cs_util_AddToSet: " + value);
// Append the value to the set, but only if it is not already in the
// set. The set is either "", or always begins and ends with colons.
// This allows a search for the value bounded by colons, ensuring that
// values that are substrings of longer values don't cause false positives
// in the search. Of course, should a value have a colon in it all bets
// are off.
if (!cs_util_GetIsInSet(set, value))
{
// The value is not in the set so append it to the end
set = set + (set == "" ? ":" : "") + value + ":";
}
//cs_dbg_Exit("cs_util_AddToSet");
return set;
}
//----------------------------------------------------------------------------
string cs_util_RemoveFromSet(string set, string value)
{
//cs_dbg_Enter("cs_util_RemoveFromSet: " + value);
// Find the value if it exists in the set. The set is either "", or
// always begins and ends with colons. This allows a search for the
// value bounded by colons, ensuring that values that are substrings
// of longer values don't cause false positives in the search.
int pos = FindSubString(set, ":" + value + ":");
if (pos >= 0)
{
// Extract the portion of the set before the value to be
// removed, removing the trailing colon.
string before = GetStringLeft(set, pos);
// Extract the portion of the set after the value to be
// removed, removing the leading colon.
string after = GetStringRight(
set,
GetStringLength(set) - pos - GetStringLength(":" + value + ":")
);
// Concatenate the before and after portions to form the new set
if ((before == "") && (after == ""))
{
// There was only one value and we've now removed it so clear
// the set
set = "";
}
else
{
// Put the set back together
set = before + ":" + after;
}
}
//cs_dbg_Exit("cs_util_RemoveFromSet");
return set;
}
//----------------------------------------------------------------------------
string cs_util_GetValueFromSet(string set, int index)
{
//cs_dbg_Enter("cs_util_GetValueFromSet: " + IntToString(index));
// Only bother to check if there actually is something in the set
string value = "";
if (set != "")
{
int count = 0;
int pos = 0;
while ((pos >= 0) && (count < index))
{
// Chop the leftmost portion of the string up to the colon
// just found.
set = GetStringRight(set, GetStringLength(set) - pos - 1);
// Find the position of the next value in the set.
pos = FindSubString(set, ":");
count = count + 1;
}
// At this point, the set string should have been reduced to the value
// being searched for as the leftmost value, or an empty string if the
// specified index is too high, so we chop off the right of the set
// string after the first colon.
pos = FindSubString(set, ":");
value = GetStringLeft(set, pos);
}
//cs_dbg_Exit("cs_util_GetValueFromSet: " + value);
return value;
}
//----------------------------------------------------------------------------
void cs_util_InvokeEventByTag(string tag, int eventNum)
{
//cs_dbg_Enter(
// "cs_util_InvokeEventByTag: " +
// tag + ", " +
// IntToString(eventNum)
//);
// Start with the first object that matches the tag
int currentObj = 0;
object obj = GetObjectByTag(tag, currentObj);
while(GetIsObjectValid(obj))
{
//cs_dbg_PrintString(
// CS_DBG_INFO,
// "Signalling object " +
// IntToString(currentObj)
//);
// Fire the event at the object
SignalEvent(obj, EventUserDefined(eventNum));
// Get the next object that matches the tag
currentObj++;
obj = OBJECT_INVALID; // NWN Lexicon says to set OBJECT_INVALID
// before calling GetObjectByTag() to avoid
// a known bug when there are no more objects.
obj = GetObjectByTag(tag, currentObj);
}
//cs_dbg_Exit("cs_util_InvokeEventByTag");
}
//----------------------------------------------------------------------------
// A nifty function originally written by Padmewan and shamelessly stolen :)
void cs_util_PrintCurrentAction()
{
int act = GetCurrentAction();
string currentAction;
switch (act)
{
case ACTION_ANIMALEMPATHY:
currentAction = ": ACTION_ANIMALEMPATHY";
break;
case ACTION_ATTACKOBJECT:
currentAction = ": ACTION_ATTACKOBJECT";
break;
case ACTION_CASTSPELL:
currentAction = ": ACTION_CASTSPELL";
break;
case ACTION_CLOSEDOOR:
currentAction = ": ACTION_CLOSEDOOR";
break;
case ACTION_COUNTERSPELL:
currentAction = ": ACTION_COUNTERSPELL";
break;
case ACTION_DIALOGOBJECT:
currentAction = ": ACTION_DIALOGOBJECT";
break;
case ACTION_DISABLETRAP:
currentAction = ": ACTION_DISABLETRAP";
break;
case ACTION_DROPITEM:
currentAction = ": ACTION_DROPITEM";
break;
case ACTION_EXAMINETRAP:
currentAction = ": ACTION_EXAMINETRAP";
break;
case ACTION_FLAGTRAP:
currentAction = ": ACTION_FLAGTRAP";
break;
case ACTION_FOLLOW:
currentAction = ": ACTION_FOLLOW";
break;
case ACTION_HEAL:
currentAction = ": ACTION_HEAL";
break;
case ACTION_INVALID:
currentAction = ": ACTION_INVALID";
break;
case ACTION_ITEMCASTSPELL:
currentAction = ": ACTION_ITEMCASTSPELL";
break;
case ACTION_LOCK:
currentAction = ": ACTION_LOCK";
break;
case ACTION_MOVETOPOINT:
currentAction = ": ACTION_MOVETOPOINT";
break;
case ACTION_OPENDOOR:
currentAction = ": ACTION_OPENDOOR";
break;
case ACTION_OPENLOCK:
currentAction = ": ACTION_OPENLOCK";
break;
case ACTION_PICKPOCKET:
currentAction = ": ACTION_PICKPOCKET";
break;
case ACTION_PICKUPITEM:
currentAction = ": ACTION_PICKUPITEM";
break;
case ACTION_RECOVERTRAP:
currentAction = ": ACTION_RECOVERTRAP";
break;
case ACTION_REST:
currentAction = ": ACTION_REST";
break;
case ACTION_SETTRAP:
currentAction = ": ACTION_SETTRAP";
break;
case ACTION_SIT:
currentAction = ": ACTION_SIT";
break;
case ACTION_TAUNT:
currentAction = ": ACTION_TAUNT";
break;
case ACTION_USEOBJECT:
currentAction = ": ACTION_USEOBJECT";
break;
case ACTION_WAIT:
currentAction = ": ACTION_WAIT";
break;
default:
currentAction = ": is totally messed up";
break;
}
//cs_dbg_PrintString(CS_DBG_INFO, GetTag(OBJECT_SELF) + currentAction);
}