#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); } }