Files
HeroesStone_PRC8/_module/nss/dmfi_start_area.nss
Jaysyn904 1eefc84201 Initial Commit
Initial Commit.
2025-09-14 15:40:46 -04:00

1197 lines
49 KiB
Plaintext

#include "x3_inc_horse"
#include "prc_inc_racial"
// DMFI DM Start Area 0.01b
// by OldManWhistler
// *****************************************************************************
// ** CONFIGURATION (modify this section to suit your module)
// *****************************************************************************
// STARTING LEVEL/XP
// Specify the starting level. If this is set to zero, then it will give the
// specific amount of XP specified by DMSTART_GIVE_XP.
const int DMSTART_GIVE_LEVEL = 3;
// This is the amount of XP given if DMSTART_GIVE_LEVEL = 0;
const int DMSTART_GIVE_XP = 0;
// STARTING GOLD
// If this is set to -1 then it will give the amount of gold appropriate for
// level as per the DMG. Otherwise it will give the value specified. A value of
// will mean the player will get no starting gold.
const int DMSTART_GIVE_GP = 1300;
// If this is set to TRUE then it will give the average GP for level 1 characters
// by class instead of rolling for each character.
const int DMSTART_AVERAGE_GP_LEVEL_1 = TRUE;
// STARTING ITEMS
// Give DMs the items in the DM chest. The chest is in the DM Control Room.
const int DMSTART_GIVE_ITEMS_DM = TRUE;
// Give players the items in the player chests. The chest is in the DM Control Room.
const int DMSTART_GIVE_ITEMS_PC = TRUE;
// Give players the DMFI voice widgets appropriate for their race/class.
const int DMSTART_GIVE_ITEMS_LANGUAGE = TRUE;
// MERCHANT
// These settings will affect all merchants in the starting area.
// If set to TRUE, merchant prices will be modified by the Appraise skill.
const int DMSTART_MERCHANTS_USE_APPRAISE = TRUE;
// Mark up (-100 to 100) on items sold by merchants.
const int DMSTART_MERCHANTS_MARK_UP_SELL = 0;
// Mark down (-100 to 100) on items bought by merchants.
const int DMSTART_MERCHANTS_MARK_DOWN_BUY = 0;
// DOORS
// These settings control which doors will automatically be opened in the
// starting area. You can always control the doors in-game by right clicking on
// them and choosing DM Lock/DM Unlock, Open/Close.
// If TRUE then the newbie merchant area will start out unlocked and opened.
const int DMSTART_UNLOCK_MERCHANT = FALSE;
// If TRUE then the magic item merchant area will start out unlocked and opened.
// NOTE: it can only be accessed it DMSTART_UNLOCK_MERCHANT is true.
const int DMSTART_UNLOCK_MAGIC = FALSE;
// If TRUE then the west area will start out unlocked and opened.
const int DMSTART_UNLOCK_WEST = FALSE;
// If TRUE then the east area will start out unlocked and opened.
const int DMSTART_UNLOCK_EAST = FALSE;
// If TRUE then the north area will start out unlocked and opened.
const int DMSTART_UNLOCK_NORTH = FALSE;
// JOURNAL ENTRIES (CANNOT BE CHANGED IN GAME)
// You can automatically give up to 5 journal entries to DMs and up to 10 journal
// entries to players. Journal entries can be useful for documenting the specific
// rules of the game, as well as the background story so far.
// Setting the journal entry to a blank string ("") will prevent it from being given.
// A journal can have multiple entries, so you have to specify the entry ID of the
// entry you want to display.
const string DMSTART_JOURNAL_NAME_DM_1 = "";
const int DMSTART_JOURNAL_ENTRY_DM_1 = 1;
const string DMSTART_JOURNAL_NAME_DM_2 = "";
const int DMSTART_JOURNAL_ENTRY_DM_2 = 1;
const string DMSTART_JOURNAL_NAME_DM_3 = "";
const int DMSTART_JOURNAL_ENTRY_DM_3 = 1;
const string DMSTART_JOURNAL_NAME_DM_4 = "";
const int DMSTART_JOURNAL_ENTRY_DM_4 = 1;
const string DMSTART_JOURNAL_NAME_DM_5 = "";
const int DMSTART_JOURNAL_ENTRY_DM_5 = 1;
const string DMSTART_JOURNAL_NAME_PC_1 = "welcome";
const int DMSTART_JOURNAL_ENTRY_PC_1 = 1;
const string DMSTART_JOURNAL_NAME_PC_2 = "rules";
const int DMSTART_JOURNAL_ENTRY_PC_2 = 1;
const string DMSTART_JOURNAL_NAME_PC_3 = "class";
const int DMSTART_JOURNAL_ENTRY_PC_3 = 1;
const string DMSTART_JOURNAL_NAME_PC_4 = "skills";
const int DMSTART_JOURNAL_ENTRY_PC_4 = 1;
const string DMSTART_JOURNAL_NAME_PC_5 = "character";
const int DMSTART_JOURNAL_ENTRY_PC_5 = 1;
const string DMSTART_JOURNAL_NAME_PC_6 = "death";
const int DMSTART_JOURNAL_ENTRY_PC_6 = 1;
const string DMSTART_JOURNAL_NAME_PC_7 = "";
const int DMSTART_JOURNAL_ENTRY_PC_7 = 1;
const string DMSTART_JOURNAL_NAME_PC_8 = "pvp";
const int DMSTART_JOURNAL_ENTRY_PC_8 = 1;
const string DMSTART_JOURNAL_NAME_PC_9 = "horses";
const int DMSTART_JOURNAL_ENTRY_PC_9 = 1;
const string DMSTART_JOURNAL_NAME_PC_10 = "";
const int DMSTART_JOURNAL_ENTRY_PC_10 = 1;
// *****************************************************************************
// ** CONSTANTS (do not modify)
// *****************************************************************************
// LOCAL VARIABLES
const string DMSTART_INITIALIZED = "DMStartInit";
const string DMSTART_UNLOCK = "DMStartUnlock";
const string DMSTART_ITEMS_DM = "DMStartItemsDM";
const string DMSTART_ITEMS_PC = "DMStartItemsPC";
const string DMSTART_ITEMS_LANGUAGE= "DMStartItemsLanguage";
const string DMSTART_XP = "DMStartXP";
const string DMSTART_XP_BY_LEVEL = "DMStartXPByLevel";
const string DMSTART_GP = "DMStartGP";
const string DMSTART_GP_BY_LEVEL = "DMStartGPByLevel";
const string DMSTART_MERC_APPRAISE = "DMStartMercAppraise";
const string DMSTART_MERC_BUY = "DMStartMercBuy";
const string DMSTART_MERC_SELL = "DMStartMercSell";
const string DMSTART_SETTINGS_WP = "DMStartSettingsWP";
const string DMSTART_SETTINGS_NPC = "DMStartSettingsNPC";
const string DMSTART_SETTINGS_VAR = "DMStartSettingsVar";
const string DMSTART_SETTINGS_DESC = "DMStartSettingsDesc";
const string DMSTART_PROTECTION = "DMStartProtection";
// DOORS
const string DMSTART_DOOR_MERCHANT = "dmfi_start_door_merchants";
const string DMSTART_DOOR_MAGIC = "dmfi_start_door_magic";
const string DMSTART_DOOR_WEST = "dmfi_start_door_west";
const string DMSTART_DOOR_EAST = "dmfi_start_door_east";
const string DMSTART_DOOR_NORTH = "dmfi_start_door_north";
// CHESTS (STARTING ITEMS)
const string DMSTART_CHEST_DM_ONCE = "dmfi_start_chest_dm";
const string DMSTART_CHEST_PC_ONCE = "dmfi_start_chest_pc";
const string DMSTART_CHEST_PC_ALWAYS = "dmfi_start_chest_pc_always";
const string DMSTART_CHEST_PC_CLASS = "dmfi_start_chest_pc_class_";
// ITEM STRIPPING
const string DMSTART_STRIP_CHEST = "dmfi_start_stripped_items";
const string DMSTART_STRIP_TRIGGER = "dmfi_start_strip_player";
// SETTINGS
const string DMSTART_SETTINGS_NPC_TAG = "dmfi_start_area_setting_npc";
const string DMSTART_SETTINGS_WP_TAG = "dmfi_start_area_setting_wp";
// *****************************************************************************
// ** FUNCTIONS
// *****************************************************************************
// DMStartStrTok
// Returns the ith element in a , separated string. If the element
// does not exist it returns an empty string.
// sStr - the string.
// i - the ith element.
// bGetRest - if true, then get the rest of the string.
string DMStartStrTok(string sStr, int i, int bGetRest = FALSE);
string DMStartStrTok(string sStr, int i, int bGetRest = FALSE)
{
int iIndex = 1;
int iPos = GetStringLength(sStr);
int iDelimiter = FindSubString(sStr, ",");
string sMatch = "";
// Base case, list is one item long and will never enter the loop.
if (iDelimiter == -1) sMatch = sStr;
while (iDelimiter != -1)
{
// Quit the loop if we've found the item.
if (iIndex == i)
{
if (bGetRest) sMatch = GetStringRight(sStr, iPos);
else sMatch = GetStringLeft(GetStringRight(sStr, iPos), iDelimiter);
break;
}
iIndex++;
iPos = iPos - iDelimiter - 1;
iDelimiter = FindSubString(GetStringRight(sStr, iPos), ",");
// At the last item.
if (iDelimiter == -1) sMatch = GetStringRight(sStr, iPos);
}
// If we found the item we are looking for, then return it.
// Otherwise return an empty string.
if (iIndex == i) return sMatch;
else return "";
}
// *****************************************************************************
// Get the amount of XP required for a specific level.
// iLevel - the level to get the XP for.
// Returns the amount of XP.
int DMStartGetXPForLevel (int iLevel);
int DMStartGetXPForLevel (int iLevel)
{
int i = 0;
int iXP = 0;
for (i=1; i<=iLevel; i++)
{
iXP += 1000*(i-1);
}
return iXP;
}
// *****************************************************************************
// Get the level for a specific amount of XP.
// iXP - the XP to get the level for.
// Returns the level.
int DMStartGetLevelByXP (int iXP);
int DMStartGetLevelByXP (int iXP)
{
// L1
if ((iXP >= 0) && (iXP < 1000)) return 1;
// L2
else if ((iXP >= 1000) && (iXP < 3000)) return 2;
// L3
else if ((iXP >= 3000) && (iXP < 6000)) return 3;
// L4
else if ((iXP >= 6000) && (iXP < 10000)) return 4;
// L5
else if ((iXP >= 10000) && (iXP < 15000)) return 5;
// L6
else if ((iXP >= 15000) && (iXP < 21000)) return 6;
// L7
else if ((iXP >= 21000) && (iXP < 28000)) return 7;
// L8
else if ((iXP >= 28000) && (iXP < 36000)) return 8;
// L9
else if ((iXP >= 36000) && (iXP < 45000)) return 9;
// L10
else if ((iXP >= 45000) && (iXP < 55000)) return 10;
// L11
else if ((iXP >= 55000) && (iXP < 66000)) return 11;
// L12
else if ((iXP >= 66000) && (iXP < 78000)) return 12;
// L13
else if ((iXP >= 78000) && (iXP < 91000)) return 13;
// L14
else if ((iXP >= 91000) && (iXP < 105000)) return 14;
// L15
else if ((iXP >= 105000) && (iXP < 120000)) return 15;
// L16
else if ((iXP >= 120000) && (iXP < 136000)) return 16;
// L17
else if ((iXP >= 136000) && (iXP < 153000)) return 17;
// L18
else if ((iXP >= 153000) && (iXP < 171000)) return 18;
// L19
else if ((iXP >= 171000) && (iXP < 190000)) return 19;
// L20
else if (iXP >= 190000) return 20;
return 0;
}
// *****************************************************************************
// Get the starting GP for a level 1 character by class.
// oPC - the player to get the GP for.
// Returns the starting GP for oPC.
int DMStartGetStartingGPByClass(object oPC);
int DMStartGetStartingGPByClass(object oPC)
{
if (DMSTART_AVERAGE_GP_LEVEL_1)
{
switch(GetClassByPosition(1, oPC))
{
case CLASS_TYPE_BARBARIAN: return 100;
case CLASS_TYPE_BARD: return 100;
case CLASS_TYPE_CLERIC: return 125;
case CLASS_TYPE_DRUID: return 50;
case CLASS_TYPE_FIGHTER: return 150;
case CLASS_TYPE_MONK: return 13;
case CLASS_TYPE_PALADIN: return 150;
case CLASS_TYPE_RANGER: return 150;
case CLASS_TYPE_ROGUE: return 125;
case CLASS_TYPE_SORCERER: return 75;
case CLASS_TYPE_WIZARD: return 75;
}
} else {
switch(GetClassByPosition(1, oPC))
{
case CLASS_TYPE_BARBARIAN: return 10*d4(4);
case CLASS_TYPE_BARD: return 10*d4(4);
case CLASS_TYPE_CLERIC: return 10*d4(5);
case CLASS_TYPE_DRUID: return 10*d4(2);
case CLASS_TYPE_FIGHTER: return 10*d4(6);
case CLASS_TYPE_MONK: return d4(5);
case CLASS_TYPE_PALADIN: return 10*d4(6);
case CLASS_TYPE_RANGER: return 10*d4(6);
case CLASS_TYPE_ROGUE: return 10*d4(5);
case CLASS_TYPE_SORCERER: return 10*d4(3);
case CLASS_TYPE_WIZARD: return 10*d4(3);
}
}
return 0;
}
// *****************************************************************************
// Gets the amount of GP for a specific level.
// oPC - the player to get the starting GP for.
// iXP - the amount of XP (level) to get the GP for.
// The GP amount.
int DMStartGetGPForXP (object oPC, int iXP);
int DMStartGetGPForXP (object oPC, int iXP)
{
// Numbers taken from this thread:
// http://enworld.cyberstreet.com/showthread.php?t=49118
switch(DMStartGetLevelByXP(iXP))
{
case 1: return DMStartGetStartingGPByClass(oPC);
case 2: return 900;
case 3: return 2700;
case 4: return 5400;
case 5: return 9000;
case 6: return 13000;
case 7: return 19000;
case 8: return 27000;
case 9: return 36000;
case 10: return 49000;
case 11: return 66000;
case 12: return 88000;
case 13: return 110000;
case 14: return 150000;
case 15: return 200000;
case 16: return 260000;
case 17: return 340000;
case 18: return 440000;
case 19: return 580000;
case 20: return 760000;
}
return 0;
}
// *****************************************************************************
// Initialization routine.
void DMStartInitializeState();
void DMStartInitializeState()
{
// Set up local area variables based on the default settings.
if (DMSTART_GIVE_LEVEL > 0) SetLocalInt(OBJECT_SELF, DMSTART_XP, DMStartGetXPForLevel(DMSTART_GIVE_LEVEL));
else SetLocalInt(OBJECT_SELF, DMSTART_XP, DMSTART_GIVE_XP);
if (DMSTART_GIVE_GP == -1) SetLocalInt(OBJECT_SELF, DMSTART_GP_BY_LEVEL, 1);
else SetLocalInt(OBJECT_SELF, DMSTART_GP, DMSTART_GIVE_GP);
if (DMSTART_GIVE_ITEMS_DM) SetLocalInt(OBJECT_SELF, DMSTART_ITEMS_DM, 1);
if (DMSTART_GIVE_ITEMS_PC) SetLocalInt(OBJECT_SELF, DMSTART_ITEMS_PC, 1);
if (DMSTART_GIVE_ITEMS_LANGUAGE) SetLocalInt(OBJECT_SELF, DMSTART_ITEMS_LANGUAGE, 1);
if (DMSTART_MERCHANTS_USE_APPRAISE) SetLocalInt(OBJECT_SELF, DMSTART_MERC_APPRAISE, 1);
if (DMSTART_MERCHANTS_MARK_UP_SELL) SetLocalInt(OBJECT_SELF, DMSTART_MERC_SELL, DMSTART_MERCHANTS_MARK_UP_SELL);
if (DMSTART_MERCHANTS_MARK_DOWN_BUY) SetLocalInt(OBJECT_SELF, DMSTART_MERC_BUY, DMSTART_MERCHANTS_MARK_DOWN_BUY);
// This is just a quick way to set up a variable for the tag of each door.
if (DMSTART_UNLOCK_MERCHANT) SetLocalInt(OBJECT_SELF, DMSTART_UNLOCK+DMSTART_DOOR_MERCHANT, 1);
if (DMSTART_UNLOCK_MAGIC) SetLocalInt(OBJECT_SELF, DMSTART_UNLOCK+DMSTART_DOOR_MAGIC, 1);
if (DMSTART_UNLOCK_WEST) SetLocalInt(OBJECT_SELF, DMSTART_UNLOCK+DMSTART_DOOR_WEST, 1);
if (DMSTART_UNLOCK_EAST) SetLocalInt(OBJECT_SELF, DMSTART_UNLOCK+DMSTART_DOOR_EAST, 1);
if (DMSTART_UNLOCK_NORTH) SetLocalInt(OBJECT_SELF, DMSTART_UNLOCK+DMSTART_DOOR_NORTH, 1);
}
// *****************************************************************************
// Initialization routine.
// Initialize all of the objects in the game. This function is not called
// until a player logs in. That prevents the function from running before
// the objects it is supposed to initialize exist.
void DMStartInitializeObjects();
void DMStartInitializeObjects()
{
object oObject = GetFirstObjectInArea(OBJECT_SELF);
int iType;
while (GetIsObjectValid(oObject))
{
iType = GetObjectType(oObject);
if (iType == OBJECT_TYPE_CREATURE)
{
if (!GetIsPC(oObject))
{
if(GetTag(oObject) == DMSTART_SETTINGS_NPC_TAG)
{
// Store the settings NPC as a local object to speed up finding it.
SetLocalObject(OBJECT_SELF, DMSTART_SETTINGS_NPC, oObject);
SetListening(oObject, TRUE);
SetListenPattern(oObject, "**", 20600); //listen to all text
} else {
// Freeze all of the creatures (ie: store fronts) so that they do not
// perform ambient animations. Need a slight delay so that they do not
// get stuck equipping items.
//AssignCommand(oObject, DelayCommand(1.0, ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectVisualEffect(VFX_DUR_FREEZE_ANIMATION), oObject)));
}
}
}
else if (iType == OBJECT_TYPE_DOOR)
{
// Checks to see if the door should be unlocked, if so then unlock it.
if (GetLocalInt(OBJECT_SELF, DMSTART_UNLOCK+GetTag(oObject)))
{
AssignCommand(oObject, SetLocked(oObject, FALSE));
AssignCommand(oObject, ActionOpenDoor(oObject));
}
}
oObject = GetNextObjectInArea(OBJECT_SELF);
}
// If no listener NPC was found, write an error.
if (!GetIsObjectValid(GetLocalObject(OBJECT_SELF, DMSTART_SETTINGS_NPC))) WriteTimestampedLogEntry("ERROR: DMFI Start Area: there is no listener NPC!");
// Find the waypoint for storing the listener NPC.
SetLocalObject(OBJECT_SELF, DMSTART_SETTINGS_WP, GetWaypointByTag(DMSTART_SETTINGS_WP_TAG));
if (!GetIsObjectValid(GetLocalObject(OBJECT_SELF, DMSTART_SETTINGS_WP))) WriteTimestampedLogEntry("ERROR: DMFI Start Area: could not find waypoint for listening NPC!");
}
// *****************************************************************************
// Show the configuration settings.
// oArea - the DM start area.
// oPC - the DM to show the settings to.
void DMStartViewSettings (object oArea, object oPC);
void DMStartViewSettings (object oArea, object oPC)
{
string sMsg = "";
int iXP = GetLocalInt(oArea, DMSTART_XP);
int iGPByLevel = GetLocalInt(oArea, DMSTART_GP_BY_LEVEL);
int iGP = GetLocalInt(oArea, DMSTART_GP);
int iItemsDM = GetLocalInt(oArea, DMSTART_ITEMS_DM);
int iItemsPC = GetLocalInt(oArea, DMSTART_ITEMS_PC);
int iItemsLanguage = GetLocalInt(oArea, DMSTART_ITEMS_LANGUAGE);
int iMercAppraise = GetLocalInt(oArea, DMSTART_MERC_APPRAISE);
int iMercBuy = GetLocalInt(oArea, DMSTART_MERC_BUY);
int iMercSell = GetLocalInt(oArea, DMSTART_MERC_SELL);
sMsg += "Starting XP: "+IntToString(iXP)+" (Level: "+IntToString(DMStartGetLevelByXP(iXP))+")\n";
if ((iGPByLevel) && (iXP < 1000)) sMsg += "Starting Gold: by starting class\n";
else if ((iGPByLevel) && (iXP >= 1000)) sMsg += "Starting Gold: "+IntToString(DMStartGetGPForXP(oPC, iXP))+"\n";
else sMsg += "Starting Gold: "+IntToString(iGP)+"\n";
if (iMercAppraise) sMsg += "Starting merchant prices are affected by appraise.\n";
else sMsg += "Starting merchant prices are not affected by appraise.\n";
sMsg += "Starting merchants are buying for "+IntToString(100+iMercBuy)+"% of item price.\n";
sMsg += "Starting merchants are selling for "+IntToString(100+iMercSell)+"% of item price.\n";
if (iItemsDM) sMsg += "DMs are given items from the DM starting chest.\n";
if (iItemsPC) sMsg += "Players are given items from the PC starting chest.\n";
if (iItemsLanguage) sMsg += "Players are given their racial and class languages.\n";
SendMessageToPC(oPC, sMsg);
}
// *****************************************************************************
// NOTE: This script is by Bioware and it was taken from NW_I0_PLOT. I am directly including it in
// this script to reduce dependancies and prevent compile issues for people who do not have SOU installed.
void DMStartAppraiseOpenStore(object oStore, object oPC, int nBonusMarkUp = 0, int nBonusMarkDown = 0);
void DMStartAppraiseOpenStore(object oStore, object oPC, int nBonusMarkUp = 0, int nBonusMarkDown = 0)
{
int STATE_FAILED = 1;
int STATE_TIE = 2;
int STATE_WON = 3;
string sTag = ObjectToString(OBJECT_SELF);
int nPlayerSkillRank = GetSkillRank(SKILL_APPRAISE, oPC);
int nNPCSkillRank = GetSkillRank(SKILL_APPRAISE, OBJECT_SELF);
int nAdjust = 0;
/*
New System:
An opposed skill check (a d10 roll instead). Your appraise skill versus the shopkeepers appraise skill.
Possible Results:
Percentage Rebate/Penalty: The 'difference'
Feedback: [Appraise Skill]: Merchant's reaction is unfavorable.
[Appraise Skill]: Merchant's reaction is neutral.
[Appraise Skill]: Merchant's reaction is favorable.
Additional: Remember last reaction for this particular skill.
When the player gets a new skill rank in this skill they'll get a
reroll against this merchant.
*/
int nState = 0;
int nPreviousRank = GetLocalInt(oPC, "X0_APPRAISERANK"+ sTag);
// * if the player's rank has improved, let them have another appraise check
// * against this merchant
if ( (nPlayerSkillRank > nPreviousRank) || !GetLocalInt(oPC, "X0_APPRAISEVISITED"+sTag) )
{
SetLocalInt(oPC, "X0_APPRAISERANK"+ sTag, nPlayerSkillRank);
SetLocalInt(oPC, "X0_APPRAISEVISITED"+sTag, 1);
nPlayerSkillRank = nPlayerSkillRank + d10();
nNPCSkillRank = nNPCSkillRank + d10();
nAdjust = nNPCSkillRank - nPlayerSkillRank; // * determines the level of price modification
if (nNPCSkillRank > nPlayerSkillRank)
{
nState = STATE_FAILED;
}
else
if (nNPCSkillRank < nPlayerSkillRank)
{
nState = STATE_WON;
}
else
if (nNPCSkillRank == nPlayerSkillRank)
{
nState = STATE_TIE;
}
}
else
{
// * recover last reaction
nAdjust = GetLocalInt(oPC, "X0_APPRAISEADJUST" + sTag);
if (nAdjust > 0)
{
nState = STATE_FAILED;
}
else
if (nAdjust < 0)
{
nState = STATE_WON;
}
else
if (nAdjust == 0)
{
nState = STATE_TIE;
}
}
if (nState == STATE_FAILED )
{
FloatingTextStrRefOnCreature(8963, oPC, FALSE);
}
else
if (nState == STATE_WON)
{
FloatingTextStrRefOnCreature(8965, oPC, FALSE);
}
else
if (nState == STATE_TIE)
{
FloatingTextStrRefOnCreature(8964, oPC, FALSE);
}
SetLocalInt(oPC, "X0_APPRAISEADJUST"+ sTag, nAdjust);
// * Hard cap of 30% max up or down
if (nAdjust > 30)
nAdjust = 30;
if (nAdjust < -30)
nAdjust = -30;
nBonusMarkUp = nBonusMarkUp + nAdjust;
nBonusMarkDown = nBonusMarkDown - nAdjust;
OpenStore(oStore, oPC, nBonusMarkUp, nBonusMarkDown);
}
// *****************************************************************************
// Give all the items in a comma separated list to oPC.
// oPC - the player to give the items to.
// sResRef - a comma separated list of ResRefs.
void DMStartGiveItemList (object oPC, string sResRefList);
void DMStartGiveItemList (object oPC, string sResRefList)
{
object oItem;
int i = 1;
string sResRef = DMStartStrTok(sResRefList, i);
while (sResRef != "")
{
if (!GetIsObjectValid( GetItemPossessedBy(oPC, sResRef) ))
{
oItem = CreateItemOnObject(sResRef, oPC);
if (!GetIsObjectValid(oItem)) WriteTimestampedLogEntry("ERROR: dmfi_start_area could not create item with ResRef: "+sResRef);
}
i++;
sResRef = DMStartStrTok(sResRefList, i);
}
}
// *****************************************************************************
// Give a player the DMFI Voice language widgets they are entitled to.
// oPC - the player to give the language widgets to.
void DMStartGiveLanguages(object oPC);
void DMStartGiveLanguages(object oPC)
{
string sList = "";
if (MyPRCGetRacialType(oPC) == RACIAL_TYPE_DWARF)
{
if (sList != "") sList += ",";
sList += "hlslang_4";
}
if (MyPRCGetRacialType(oPC) == RACIAL_TYPE_ELF)
{
if (sList != "") sList += ",";
sList += "hlslang_1";
}
if (MyPRCGetRacialType(oPC) == RACIAL_TYPE_HALFELF)
{
if (sList != "") sList += ",";
sList += "hlslang_1";
}
if (MyPRCGetRacialType(oPC) == RACIAL_TYPE_GNOME)
{
if (sList != "") sList += ",";
sList += "hlslang_2";
}
if (MyPRCGetRacialType(oPC) == RACIAL_TYPE_HALFLING)
{
if (sList != "") sList += ",";
sList += "hlslang_3";
}
if (MyPRCGetRacialType(oPC) == RACIAL_TYPE_HALFORC)
{
if (sList != "") sList += ",";
sList += "hlslang_5";
}
if (GetLevelByClass(CLASS_TYPE_DRUID, oPC) || GetLevelByClass(CLASS_TYPE_RANGER, oPC))
{
if (sList != "") sList += ",";
sList += "hlslang_8";
}
if (GetLevelByClass(CLASS_TYPE_ROGUE, oPC))
{
if (sList != "") sList += ",";
sList += "hlslang_9";
}
// Now that the list specific to this player is build, process it.
// Note: if the blueprints do not exist then the items will not be created.
DMStartGiveItemList(oPC, sList);
}
// *****************************************************************************
// Give starting items from a chest to a player.
// oPC - the player to give items to.
// sTag - the tag of the chest containing the starting items.
// bOnlyOne - if true, then only give them the item if they do not already possess it.
void DMStartGiveItems(object oPC, string sTag, int bOnlyOne = TRUE);
void DMStartGiveItems(object oPC, string sTag, int bOnlyOne = TRUE)
{
object oChest = GetNearestObjectByTag(sTag);
object oItem;
object oNewItem;
// Try to find the chest with the items.
if (!GetIsObjectValid(oChest))
{
WriteTimestampedLogEntry("ERROR: dmfi_start_area could not find placeable with Tag: "+sTag);
return;
}
if (bOnlyOne)
{
oItem = GetFirstItemInInventory(oChest);
while (GetIsObjectValid(oItem))
{
// Only give items to players if they do not already have them.
if (!GetIsObjectValid( GetItemPossessedBy(oPC, GetTag(oItem)) ))
{
oNewItem = CopyItem(oItem, oPC);
// If this item is armor, and the player has no armor, then try
// to equip it.
if (GetBaseItemType(oNewItem) == BASE_ITEM_ARMOR)
{
if (!GetIsObjectValid( GetItemInSlot(INVENTORY_SLOT_CHEST, oPC) ))
{
AssignCommand(oPC, ActionEquipItem(oNewItem, INVENTORY_SLOT_CHEST));
}
}
} else {
SendMessageToPC(oPC, "You already have "+GetTag(oItem));
}
oItem = GetNextItemInInventory(oChest);
}
} else {
oItem = GetFirstItemInInventory(oChest);
while (GetIsObjectValid(oItem))
{
// Always give items to players.
oNewItem = CopyItem(oItem, oPC);
// If this item is armor, and the player has no armor, then try
// to equip it.
if (GetBaseItemType(oNewItem) == BASE_ITEM_ARMOR)
{
if (!GetIsObjectValid( GetItemInSlot(INVENTORY_SLOT_CHEST, oPC) ))
{
AssignCommand(oPC, ActionEquipItem(oNewItem, INVENTORY_SLOT_CHEST));
}
}
oItem = GetNextItemInInventory(oChest);
}
}
}
// *****************************************************************************
// Strip a player of all their items/gold and give them the amount of gold they
// are supposed to have as well as the starting items.
// oArea - the DMFI DM Start Area.
// oPC - the player to strip the items from.
void DMStartStripPlayer (object oArea, object oPC);
void DMStartStripPlayer (object oArea, object oPC)
{
// Do not attempt to strip DMs!
if (!GetIsPC(oPC) || GetIsDM(oPC) || GetIsDMPossessed(oPC)) return;
// Try to find the chest for storing the stripped items.
object oChest = GetNearestObjectByTag(DMSTART_STRIP_CHEST);
if (!GetIsObjectValid(oChest))
{
WriteTimestampedLogEntry("ERROR: dmfi_start_area could not find placeable with Tag: "+DMSTART_STRIP_CHEST);
return;
}
SendMessageToPC(oPC, "Removing items.");
// Destroy gold.
TakeGoldFromCreature(GetGold(oPC), oPC, TRUE);
// Remove the equipped items.
object oItem;
int i;
for(i=0; i < NUM_INVENTORY_SLOTS; i++)
{
oItem = GetItemInSlot(i, oPC);
if (GetIsObjectValid(oItem))
{
CopyItem(oItem, oChest);
DestroyObject(oItem);
}
}
// Remove the inventory items.
oItem = GetFirstItemInInventory(oPC);
while (GetIsObjectValid(oItem))
{
CopyItem(oItem, oChest);
DestroyObject(oItem);
oItem = GetNextItemInInventory(oPC);
}
// Give them the starting GP.
int iGPByLevel = GetLocalInt(oArea, DMSTART_GP_BY_LEVEL);
int iGP = GetLocalInt(oArea, DMSTART_GP);
if (iGPByLevel) iGP = DMStartGetGPForXP(oPC, GetXP(oPC));
GiveGoldToCreature(oPC, iGP);
SendMessageToAllDMs(GetName(oPC)+" was given "+IntToString(iGP)+" starting gold.");
// Give them the player starting items.
// Items that are given to the player only if they don't possess them.
if (GetLocalInt(oArea, DMSTART_ITEMS_PC)) AssignCommand(oPC, DMStartGiveItems(oPC, DMSTART_CHEST_PC_ONCE));
// Items that are always given to the player.
if (GetLocalInt(oArea, DMSTART_ITEMS_PC)) AssignCommand(oPC, DMStartGiveItems(oPC, DMSTART_CHEST_PC_ALWAYS, FALSE));
// Items that are always given to the player by class.
if (GetLocalInt(oArea, DMSTART_ITEMS_PC)) AssignCommand(oPC, DMStartGiveItems(oPC, DMSTART_CHEST_PC_CLASS+IntToString(GetClassByPosition(1, oPC)), FALSE));
// Give them the player language items.
if (GetLocalInt(oArea, DMSTART_ITEMS_LANGUAGE)) AssignCommand(oPC, DMStartGiveLanguages(oPC));
}
// *****************************************************************************
// Give a player/DM the automatic journals.
// oPC - the player to give the journals to.
void DMStartGiveJournals (object oPC);
void DMStartGiveJournals (object oPC)
{
if (GetIsDM(oPC) || GetIsDMPossessed(oPC))
{
// Is a DM.
if (DMSTART_JOURNAL_NAME_DM_1 != "") AddJournalQuestEntry(DMSTART_JOURNAL_NAME_DM_1, DMSTART_JOURNAL_ENTRY_DM_1, oPC, FALSE, FALSE, TRUE);
if (DMSTART_JOURNAL_NAME_DM_2 != "") AddJournalQuestEntry(DMSTART_JOURNAL_NAME_DM_2, DMSTART_JOURNAL_ENTRY_DM_2, oPC, FALSE, FALSE, TRUE);
if (DMSTART_JOURNAL_NAME_DM_3 != "") AddJournalQuestEntry(DMSTART_JOURNAL_NAME_DM_3, DMSTART_JOURNAL_ENTRY_DM_3, oPC, FALSE, FALSE, TRUE);
if (DMSTART_JOURNAL_NAME_DM_4 != "") AddJournalQuestEntry(DMSTART_JOURNAL_NAME_DM_4, DMSTART_JOURNAL_ENTRY_DM_4, oPC, FALSE, FALSE, TRUE);
if (DMSTART_JOURNAL_NAME_DM_5 != "") AddJournalQuestEntry(DMSTART_JOURNAL_NAME_DM_5, DMSTART_JOURNAL_ENTRY_DM_5, oPC, FALSE, FALSE, TRUE);
return;
} else {
// Is a player.
if (DMSTART_JOURNAL_NAME_PC_1 != "") AddJournalQuestEntry(DMSTART_JOURNAL_NAME_PC_1, DMSTART_JOURNAL_ENTRY_PC_1, oPC, FALSE, FALSE, TRUE);
if (DMSTART_JOURNAL_NAME_PC_2 != "") AddJournalQuestEntry(DMSTART_JOURNAL_NAME_PC_2, DMSTART_JOURNAL_ENTRY_PC_2, oPC, FALSE, FALSE, TRUE);
if (DMSTART_JOURNAL_NAME_PC_3 != "") AddJournalQuestEntry(DMSTART_JOURNAL_NAME_PC_3, DMSTART_JOURNAL_ENTRY_PC_3, oPC, FALSE, FALSE, TRUE);
if (DMSTART_JOURNAL_NAME_PC_4 != "") AddJournalQuestEntry(DMSTART_JOURNAL_NAME_PC_4, DMSTART_JOURNAL_ENTRY_PC_4, oPC, FALSE, FALSE, TRUE);
if (DMSTART_JOURNAL_NAME_PC_5 != "") AddJournalQuestEntry(DMSTART_JOURNAL_NAME_PC_5, DMSTART_JOURNAL_ENTRY_PC_5, oPC, FALSE, FALSE, TRUE);
if (DMSTART_JOURNAL_NAME_PC_6 != "") AddJournalQuestEntry(DMSTART_JOURNAL_NAME_PC_6, DMSTART_JOURNAL_ENTRY_PC_6, oPC, FALSE, FALSE, TRUE);
if (DMSTART_JOURNAL_NAME_PC_7 != "") AddJournalQuestEntry(DMSTART_JOURNAL_NAME_PC_7, DMSTART_JOURNAL_ENTRY_PC_7, oPC, FALSE, FALSE, TRUE);
if (DMSTART_JOURNAL_NAME_PC_8 != "") AddJournalQuestEntry(DMSTART_JOURNAL_NAME_PC_8, DMSTART_JOURNAL_ENTRY_PC_8, oPC, FALSE, FALSE, TRUE);
if (DMSTART_JOURNAL_NAME_PC_9 != "") AddJournalQuestEntry(DMSTART_JOURNAL_NAME_PC_9, DMSTART_JOURNAL_ENTRY_PC_9, oPC, FALSE, FALSE, TRUE);
if (DMSTART_JOURNAL_NAME_PC_10 != "") AddJournalQuestEntry(DMSTART_JOURNAL_NAME_PC_10, DMSTART_JOURNAL_ENTRY_PC_10, oPC, FALSE, FALSE, TRUE);
return;
}
}
// *****************************************************************************
// Handle a player/DM that just entered the area.
// oArea - the DMFI DM Start Area
// oPC - the player who just entered.
void DMStartHandlePlayers (object oArea, object oPC);
void DMStartHandlePlayers (object oArea, object oPC)
{
// Give the journals.
DMStartGiveJournals(oPC);
// If this is a DM, give them their items and quit.
if (GetIsDM(oPC) || GetIsDMPossessed(oPC))
{
// Give them the DM Items
if (GetLocalInt(oArea, DMSTART_ITEMS_DM)) AssignCommand(oPC, DMStartGiveItems(oPC, DMSTART_CHEST_DM_ONCE));
// Tell the DM the current settings.
AssignCommand(oPC, DMStartViewSettings(oArea, oPC));
return;
}
// This is a player.
// Give new players the XP/GP and strip their items.
if (GetXP(oPC) == 0)
{
// Set the XP for the player. Always add 1 XP to keep DMs from setting players
// at zero XP so that they keep getting restripped when the log in.
int iXP = GetLocalInt(oArea, DMSTART_XP) + 1;
SetXP(oPC, iXP);
SendMessageToAllDMs(GetName(oPC)+" was given "+IntToString(iXP)+" starting experience.");
// Strip new characters. These prevents people who are trying to hack their
// starting kit by modifying 2DAs in their override directory.
AssignCommand(oPC, DMStartStripPlayer(oArea, oPC));
}
}
// *****************************************************************************
// A DM has just toggled a boolean setting.
// oArea - the DM start area.
// oPC - the DM.
// sInt - the name of the LocalInt variable on oArea.
// sDesc - a description of the variable.
void DMStartControlToggle(object oArea, object oPC, string sInt, string sDesc);
void DMStartControlToggle(object oArea, object oPC, string sInt, string sDesc)
{
string sDir = "";
if (GetLocalInt(oArea, sInt) == 0)
{
sDir = "On";
SetLocalInt(oArea, sInt, 1);
} else {
sDir = "Off";
SetLocalInt(oArea, sInt, 0);
}
SendMessageToAllDMs(GetName(oPC)+" has turned "+sDir+" "+sDesc);
}
// *****************************************************************************
// A DM would like to change an integer setting. Summon a listener NPC so that they
// can speak the setting outloud.
// oArea - the DM start area.
// oPC - the DM.
// sInt - the name of the LocalInt variable on oArea.
// sDesc - a description of the variable.
void DMStartControlSetting(object oArea, object oPC, string sInt, string sDesc);
void DMStartControlSetting(object oArea, object oPC, string sInt, string sDesc)
{
object oListener = GetLocalObject(oArea, DMSTART_SETTINGS_NPC);
if (!GetIsObjectValid(oListener))
{
SendMessageToPC(oPC, "ERROR: Could not find listener NPC");
WriteTimestampedLogEntry("ERROR: DMFI Start Area: could not find listener NPC");
return;
}
SetLocalString(oPC, DMSTART_SETTINGS_VAR, sInt);
SetLocalString(oPC, DMSTART_SETTINGS_DESC, sDesc);
AssignCommand(oListener, JumpToObject(oPC));
DelayCommand(0.1, AssignCommand(oListener, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectVisualEffect(VFX_DUR_PARALYZE_HOLD), oListener, 3.0)));
DelayCommand(0.2, AssignCommand(oListener, ActionSpeakString("Appear and speak a number to change "+sDesc)));
}
// *****************************************************************************
// A DM would like to reset the XP for all of the players in the area.
// oArea - the DM start area.
// oPC - the DM.
int DMStartControlResetXP (object oArea, object oPC);
int DMStartControlResetXP (object oArea, object oPC)
{
if (GetLocalInt(OBJECT_SELF, DMSTART_PROTECTION) == 0)
{
SetLocalInt(OBJECT_SELF, DMSTART_PROTECTION, 1);
FloatingTextStringOnCreature("Pull lever again if you are sure you want to reset XP for all players in area.", oPC, FALSE);
DelayCommand(15.0, DeleteLocalInt(OBJECT_SELF, DMSTART_PROTECTION));
return FALSE;
}
int iXP = GetLocalInt(oArea, DMSTART_XP);
SendMessageToAllDMs(GetName(oPC)+" is reseting the XP for all players in starting area.");
object oPlayer = GetFirstPC();
while (GetIsObjectValid(oPlayer))
{
if ((!GetIsDM(oPlayer)) && (!GetIsDMPossessed(oPlayer)))
{
SetXP(oPlayer, iXP);
}
oPlayer = GetNextPC();
}
return TRUE;
}
// *****************************************************************************
// A DM would like to reset the GP/items for all of the players in the area.
// oArea - the DM start area.
// oPC - the DM.
int DMStartControlResetGPItems (object oArea, object oPC);
int DMStartControlResetGPItems (object oArea, object oPC)
{
if (GetLocalInt(OBJECT_SELF, DMSTART_PROTECTION) == 0)
{
SetLocalInt(OBJECT_SELF, DMSTART_PROTECTION, 1);
FloatingTextStringOnCreature("Pull lever again if you are sure you want to reset gp/items for all players in area.", oPC, FALSE);
DelayCommand(15.0, DeleteLocalInt(OBJECT_SELF, DMSTART_PROTECTION));
return FALSE;
}
SendMessageToAllDMs(GetName(oPC)+" is reseting the GP/items for all players in starting area.");
object oPlayer = GetFirstPC();
while (GetIsObjectValid(oPlayer))
{
if ((!GetIsDM(oPlayer)) && (!GetIsDMPossessed(oPlayer)))
{
AssignCommand(oPlayer, DMStartStripPlayer(oArea, oPlayer));
}
oPlayer = GetNextPC();
}
return TRUE;
}
// *****************************************************************************
// A DM would like to "top up" the GP for all of the players in the area.
// oArea - the DM start area.
// oPC - the DM.
int DMStartControlTopUpGP (object oArea, object oPC);
int DMStartControlTopUpGP (object oArea, object oPC)
{
if (GetLocalInt(OBJECT_SELF, DMSTART_PROTECTION) == 0)
{
SetLocalInt(OBJECT_SELF, DMSTART_PROTECTION, 1);
FloatingTextStringOnCreature("Pull lever again if you are sure you want to top up GP for all players in area.", oPC, FALSE);
DelayCommand(15.0, DeleteLocalInt(OBJECT_SELF, DMSTART_PROTECTION));
return FALSE;
}
int iGPByLevel = GetLocalInt(oArea, DMSTART_GP_BY_LEVEL);
SendMessageToAllDMs(GetName(oPC)+" is topping up the GP for all players in starting area.");
object oPlayer = GetFirstPC();
int iGP;
int i;
object oItem;
while (GetIsObjectValid(oPlayer))
{
if ((!GetIsDM(oPlayer)) && (!GetIsDMPossessed(oPlayer)))
{
// Get the GP value the player should have.
int iGPShouldHave = GetLocalInt(oArea, DMSTART_GP);
if (iGPByLevel) iGPShouldHave = DMStartGetGPForXP(oPC, GetXP(oPC));
// Get the GP value of the player.
iGP = GetGold(oPlayer);
for(i=0; i < NUM_INVENTORY_SLOTS; i++)
{
oItem = GetItemInSlot(i, oPlayer);
if (GetIsObjectValid(oItem))
{
iGP += GetGoldPieceValue(oItem);
}
}
oItem = GetFirstItemInInventory(oPlayer);
while (GetIsObjectValid(oItem))
{
iGP += GetGoldPieceValue(oItem);
oItem = GetNextItemInInventory(oPlayer);
}
if (iGPShouldHave == iGP) SendMessageToPC(oPC, GetName(oPlayer)+" has "+IntToString(iGP)+" GP (correct amount).");
if (iGPShouldHave > iGP) SendMessageToPC(oPC, GetName(oPlayer)+" has "+IntToString(iGP)+" GP (over by "+IntToString(iGP - iGPShouldHave)+").");
if (iGPShouldHave < iGP)
{
GiveGoldToCreature(oPlayer, iGPShouldHave - iGP);
SendMessageToPC(oPC, GetName(oPlayer)+" now has "+IntToString(iGPShouldHave)+" GP (given "+IntToString(iGPShouldHave - iGP)+").");
}
}
oPlayer = GetNextPC();
}
return TRUE;
}
// *****************************************************************************
// A DM would like to view the xp/gp for all of the players in the area.
// oArea - the DM start area.
// oPC - the DM.
int DMStartControlViewXPGP (object oArea, object oPC);
int DMStartControlViewXPGP (object oArea, object oPC)
{
int iXP;
int iGP;
int i;
object oItem;
object oPlayer = GetFirstPC();
while (GetIsObjectValid(oPlayer))
{
if ((!GetIsDM(oPlayer)) && (!GetIsDMPossessed(oPlayer)))
{
iXP = GetXP(oPlayer);
// Get the GP value of the player.
iGP = GetGold(oPlayer);
for(i=0; i < NUM_INVENTORY_SLOTS; i++)
{
oItem = GetItemInSlot(i, oPlayer);
if (GetIsObjectValid(oItem))
{
iGP += GetGoldPieceValue(oItem);
}
}
oItem = GetFirstItemInInventory(oPlayer);
while (GetIsObjectValid(oItem))
{
iGP += GetGoldPieceValue(oItem);
oItem = GetNextItemInInventory(oPlayer);
}
SendMessageToPC(oPC, GetName(oPlayer)+" has "+IntToString(iXP)+" XP and items totalling "+IntToString(iGP)+" GP.");
}
oPlayer = GetNextPC();
}
return TRUE;
}
// *****************************************************************************
// oPC has used a placeable. Handle the placeable based on its tag.
// oArea - the DM start area.
// oPC - the person who used the placeable.
void DMStartHandlePlaceable (object oArea, object oPC);
void DMStartHandlePlaceable (object oArea, object oPC)
{
string sTag = GetTag(OBJECT_SELF);
if (sTag == "dmfi_start_sit_chair")
{
object oChair = OBJECT_SELF;
AssignCommand(oPC, ActionSit(oChair));
return;
}
if (sTag == "dmfi_start_sit_dm_chair")
{
if (!GetIsDM(oPC)) return;
object oChair = OBJECT_SELF;
AssignCommand(oPC, ActionSit(oChair));
return;
}
else if (sTag == "dmfi_start_control_view") DMStartViewSettings(oArea, oPC);
else if (sTag == "dmfi_start_control_view_players") DMStartControlViewXPGP(oArea, oPC);
else if (sTag == "dmfi_start_toggle_chest_dm") DMStartControlToggle(oArea, oPC, DMSTART_ITEMS_DM, "giving items to DMs on login.");
else if (sTag == "dmfi_start_toggle_chest_pc") DMStartControlToggle(oArea, oPC, DMSTART_ITEMS_PC, "giving items to new players on login.");
else if (sTag == "dmfi_start_toggle_chest_language") DMStartControlToggle(oArea, oPC, DMSTART_ITEMS_LANGUAGE, "giving DMFI Voice languages to new players on login.");
else if (sTag == "dmfi_start_toggle_merc_appraise") DMStartControlToggle(oArea, oPC, DMSTART_MERC_APPRAISE, "starting merchant prices affected by Appraise skill.");
else if (sTag == "dmfi_start_toggle_merc_buy") DMStartControlSetting(oArea, oPC, DMSTART_MERC_BUY, "starting merchant prices for buying items");
else if (sTag == "dmfi_start_toggle_merc_sell") DMStartControlSetting(oArea, oPC, DMSTART_MERC_SELL, "starting merchant prices for selling items");
else if (sTag == "dmfi_start_toggle_gp_by_level") DMStartControlToggle(oArea, oPC, DMSTART_GP_BY_LEVEL, "GP based off of character level.");
else if (sTag == "dmfi_start_toggle_gp") DMStartControlSetting(oArea, oPC, DMSTART_GP, "GP given to new players");
else if (sTag == "dmfi_start_toggle_xp_by_level") DMStartControlSetting(oArea, oPC, DMSTART_XP_BY_LEVEL, "level given to new players");
else if (sTag == "dmfi_start_toggle_xp") DMStartControlSetting(oArea, oPC, DMSTART_XP, "XP given to new players");
else if (sTag == "dmfi_start_control_reset_xp")
{
if (DMStartControlResetXP(oArea, oPC) == FALSE) return;
}
else if (sTag == "dmfi_start_control_reset_gp_item")
{
if (DMStartControlResetGPItems(oArea, oPC) == FALSE) return;
}
else if (sTag == "dmfi_start_control_top_up_gp")
{
if (DMStartControlTopUpGP(oArea, oPC) == FALSE) return;
}
else
{
WriteTimestampedLogEntry("ERROR: DMFI Start Area: unknown placeable with Tag "+sTag);
return;
}
PlayAnimation (ANIMATION_PLACEABLE_DEACTIVATE);
DelayCommand(1.5, PlayAnimation (ANIMATION_PLACEABLE_ACTIVATE));
PlaySound("as_sw_metalop1");
}
// *****************************************************************************
// The listener NPC has heard something. Process what it heard. This NPC is used
// to get integers from the DMs.
// oArea - the DM start area.
void DMStartListener (object oArea);
void DMStartListener (object oArea)
{
string sSaid;
string sVar;
string sDesc;
int nMatch = GetListenPatternNumber();
object oShouter = GetLastSpeaker();
if (nMatch == 20600 && GetIsObjectValid(oShouter) && GetIsDM(oShouter))
{
sSaid = GetMatchedSubstring(0);
sVar = GetLocalString(oShouter, DMSTART_SETTINGS_VAR);
sDesc = GetLocalString(oShouter, DMSTART_SETTINGS_DESC);
int iValue = StringToInt(sSaid);
SetLocalInt(oArea, sVar, iValue);
// Sanity checking on the inputs.
if (sVar == DMSTART_XP_BY_LEVEL)
{
if ((iValue < 1) || (iValue > 20))
{
SpeakString(IntToString(iValue)+" is not a valid level. (1-20)");
return;
}
// Special case, this variable doesn't really do anything. It acts
// as a wrapper for another variable.
SetLocalInt(oArea, DMSTART_XP, DMStartGetXPForLevel(iValue));
sVar = DMSTART_XP;
}
else if ((sVar == DMSTART_MERC_BUY) || (sVar == DMSTART_MERC_SELL))
{
if ((iValue < -100) || (iValue > 100))
{
SpeakString(IntToString(iValue)+" is not a valid value. (-100 to 100)");
return;
}
}
DeleteLocalString(oShouter, DMSTART_SETTINGS_VAR);
DeleteLocalString(oShouter, DMSTART_SETTINGS_DESC);
if (sVar == DMSTART_XP)
{
SendMessageToAllDMs(GetName(oShouter)+" changed " + sDesc + " to " + IntToString(GetLocalInt(oArea, sVar))+" XP (Level: "+IntToString(DMStartGetLevelByXP(GetLocalInt(oArea, sVar)))+")");
}
else if (sVar == DMSTART_GP)
{
string sMsg;
int iXP = GetLocalInt(oArea, DMSTART_XP);
int iGPByLevel = GetLocalInt(oArea, DMSTART_GP_BY_LEVEL);
int iGP = GetLocalInt(oArea, DMSTART_GP);
if ((iGPByLevel) && (iXP < 1000)) sMsg += "Starting Gold: by starting class\n";
else if ((iGPByLevel) && (iXP >= 1000)) sMsg += "Starting Gold: "+IntToString(DMStartGetGPForXP(oShouter, iXP))+"\n";
else sMsg += "Starting Gold: "+IntToString(iGP)+"\n";
SendMessageToAllDMs(GetName(oShouter)+" changed " + sDesc + " to "+sMsg);
}
else if ((sVar == DMSTART_MERC_BUY) || (sVar == DMSTART_MERC_SELL))
{
SendMessageToAllDMs(GetName(oShouter)+" changed " + sDesc + " to " + IntToString(GetLocalInt(oArea, sVar)+100)+"% of base price.");
}
else SendMessageToAllDMs(GetName(oShouter)+" changed " + sDesc + " to " + IntToString(GetLocalInt(oArea, sVar)));
DelayCommand(1.5, AssignCommand(OBJECT_SELF, ActionJumpToObject(GetLocalObject(oArea, DMSTART_SETTINGS_WP))));
}
}
// *****************************************************************************
// ** MAIN
// *****************************************************************************
void main()
{
// NOTE: The Area OnEnter event fires for all creatures that are spawned in
// that area!
object oMod = GetModule();
object oPC = GetEnteringObject();
// If we are not initialized, then initialize.
if (GetLocalInt(oMod, DMSTART_INITIALIZED) == 0)
{
// Only run when the first player logs in.
if(GetIsPC(oPC))
{
SetLocalInt(oMod, DMSTART_INITIALIZED, 1);
PrintString("Initializing DMFI DM Start Area");
// Initialize the state right away.
DMStartInitializeState();
// Initialize the objects when done processing the new creature.
AssignCommand(OBJECT_SELF, DMStartInitializeObjects());
} else {
// A creature is calling this script when it spawns in.
return;
}
}
// There is a listen NPC that let's DMs configure settings to anything they want.
if (GetTag(OBJECT_SELF) == DMSTART_SETTINGS_NPC_TAG)
{
DMStartListener(GetArea(OBJECT_SELF));
return;
}
// Players can be stripped of items when they log in with 0XP or it can
// manually be done by the DM by jumping them to a trigger.
if (GetTag(OBJECT_SELF) == DMSTART_STRIP_TRIGGER)
{
AssignCommand(oPC, DMStartStripPlayer(GetArea(OBJECT_SELF), oPC));
return;
}
// If a player has entered the area, then handle them.
if (GetIsPC(oPC) || GetIsDM(oPC) || GetIsDMPossessed(oPC))
{
AssignCommand(OBJECT_SELF, DMStartHandlePlayers(OBJECT_SELF, oPC));
return;
}
int iObjectType = GetObjectType(OBJECT_SELF);
if (iObjectType == OBJECT_TYPE_CREATURE)
{
// Running on a merchant.
oPC = GetLastSpeaker();
object oArea = GetArea(OBJECT_SELF);
object oStore = GetNearestObjectByTag(GetTag(OBJECT_SELF));
if (GetLocalInt(oArea, DMSTART_MERC_APPRAISE)) DMStartAppraiseOpenStore(oStore, oPC, GetLocalInt(oArea, DMSTART_MERC_SELL), GetLocalInt(oArea, DMSTART_MERC_BUY));
else OpenStore(oStore, oPC, GetLocalInt(oArea, DMSTART_MERC_SELL), GetLocalInt(oArea, DMSTART_MERC_BUY));
return;
}
else if (iObjectType == OBJECT_TYPE_PLACEABLE)
{
DMStartHandlePlaceable(GetArea(OBJECT_SELF), GetLastUsedBy());
CreateItemOnObject("x3_it_pchide ", oPC);
}
}