generated from Jaysyn/ModuleTemplate
4228 lines
175 KiB
Plaintext
4228 lines
175 KiB
Plaintext
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||
//:::::::::::::::::::::::: Shayan's Subrace Engine :::::::::::::::::::::::::::::
|
||
//::::::::::::::::::::::: File Name: sha_subr_methds :::::::::::::::::::::::::::
|
||
//:::::::::::::::::::::::::: Include script ::::::::::::::::::::::::::::::::::::
|
||
//:: Written by: Shayan :://
|
||
//:: Contact: mail_shayan@yhaoo.com :://
|
||
//
|
||
// ::Description: Holds all the methods used in the Subrace System. DO NOT CHANGE
|
||
// :: ANYTHING UNLESS YOU ARE CERTAIN.
|
||
// :: This is the 'core engine script'. In updates, more than likely
|
||
// :: this script is changed... so unless you do not plan to update to
|
||
// :: possible future releases of this engine, it will be in your best
|
||
// :: interest NOT to make any changes to this script. Because then you
|
||
// :: will have to redo them again.
|
||
// :: Should you disregard this warning and proceed to editing...
|
||
// :: Remember that:
|
||
// :: * If you have made a change you must recompile all scripts for
|
||
// :: changes to take place.
|
||
//
|
||
// ::Please refer to the script file 'sha_subr_consts' to change any values of the
|
||
// ::constants or default values.
|
||
|
||
|
||
|
||
|
||
|
||
|
||
// ::Version 1.4: Reduced the numbers of local variables, by "encoding a single interger
|
||
// :: variable to hold several 'bits' of information". - Using Axe Murderer's Flag-sets.
|
||
|
||
// ::Version 1.2: Support for NWNX added. Refer to Lines: 37, 3890, 3905, 3914, and 3983.
|
||
|
||
//Uncomment the line below if you wish to use NWNX Database instead.
|
||
//(Make sure you have imported in these files from the NWNX package, available from
|
||
// :: http://www.nwnx.org)
|
||
|
||
//#include "aps_include"
|
||
|
||
#include "sha_subr_consts"
|
||
#include "sha_misc_funcs"
|
||
|
||
//Version 1.1: Changed from storing the data on the module to an object.
|
||
//object oStorer = GetObjectByTag(SUBRACE_INFO_STORER_TAG);
|
||
//Version 1.1a Revision: Changed it back to Module for faster access.
|
||
object oStorer = GetModule();
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
/*
|
||
::::::::::::::::::::::::::: Function definers ::::::::::::::::::::::::::::::::::
|
||
*/
|
||
// :: Below lies the list of all the functions useable OnModuleLoad to setup
|
||
// :: a subrace.
|
||
|
||
|
||
|
||
//:: - ALL SUBRACE RELATED METHODS MUST BE CALLED AFTER THIS METHOD! -
|
||
//:: -- The Main function. Call this OnModuleLoad.
|
||
//
|
||
// ::Race: This is the base race that you want to create your subrace from
|
||
// :: Use ONLY: RACIAL_TYPE_ALL, or RACIAL_TYPE_DWARF, RACIAL_TYPE_ELF,
|
||
// :: RACIAL_TYPE_GNOME, RACIAL_TYPE_HALFELF, RACIAL_TYPE_HALFLING,
|
||
// :: RACIAL_TYPE_HALFORC, or RACIAL_TYPE_HUMAN.
|
||
// :: If you want to add additional races that can become part of this subrace call
|
||
// :: AddAdditionalBaseRaceToSubrace() AFTER this method.
|
||
//
|
||
// ::SubraceName: The subrace's name. This is what the PC will have to type in his/her
|
||
// :: Subrace field. DO NOT HAVE SPACES IN NAMES.
|
||
// :: IE: Use "Dark-elf" NOT "Dark elf".
|
||
// :: (Not case sensitive.)
|
||
//
|
||
// ::HideResRef: This is the resref of the Creature Hide/Skin you want to equip on the PC.
|
||
// :: This will have all the subrace traits like ability modifiers and base feats etc.
|
||
//
|
||
// :: If you do not want a skin, write either "none" or leave it as blank.
|
||
//
|
||
// ::UniqueItemResref: This is the resref of the item that you want given to the player. For example this item
|
||
// :: could hold can spells on it, or just description of the subrace. Ideally this item will not be droppable,
|
||
// :: and is marked as being a plot item. Regardless of what type of item this is it will be given to player when they enter the module.
|
||
// :: (If they lose it or drop it they will again get it back on the next time they enter).
|
||
//
|
||
// :: If you do not want to give the PC a unique item then, write either "none" or leave it as blank.
|
||
//
|
||
// ::IsLightSensitive: Set to TRUE if the subrace is light senstive. IE: Blinded when in Sunlight and/or gets saves and AB decreases.
|
||
// :: If the PC does not pass the fort saving throw, then it is blinded for that round.
|
||
// :: The DC for the saving throw can be changed by changing the value of
|
||
// :: LIGHT_SENSITIVE_SAVING_THROW_DC in the file sha_subr_consts. Also you can change the interval (rounds) between each time the PC
|
||
// :: is 'struk' by light by changing the value of LIGHT_BLINDNESS_STRIKES_EVERY_ROUND. And also you can change the number of rounds
|
||
// :: the PC stays blinded for if it fails the saving throw by changing tha value of LIGHT_STRUCK_BLIND_FOR_ROUNDS.
|
||
//
|
||
// :: If APPLY_AB_AND_SAVING_THROW_DECREASES_IN_LIGHT is set to TRUE, then the PC also suffers
|
||
// :: an attack bonus decrease of LIGHT_AB_DECREASE and saving throw decrease of LIGHT_SAVE_DECREASE for a number of rounds
|
||
// :: determined by: LIGHT_CAUSES_AB_AND_SAVES_DECREASE_FOR_ROUNDS.
|
||
//
|
||
// :: Rememeber: IF YOU CHANGE ANYTHING IN THE CONSTANTS FILE, IT WILL APPLY TO ALL SUBRACES.
|
||
// :: (IE: If you change the DC for the saving throw then all subraces that have light sensitivity will have to make that saving throw).
|
||
//
|
||
// ::DamageTakenWhileInLight: The amount of divine Damage the PC suffers ever round while
|
||
// :: it is in sunlight. Note: PC does not necessarily have to be Light Sensitive
|
||
// :: for this to work.
|
||
// :: If this value is negative then the PC will regenerate that amount.
|
||
//
|
||
// ::IsUndergroundSensitive: Same as IsLightSenstive but this applies when the PC is in
|
||
// :: Underground type of areas. This does not mean the PC is affected by Night time.
|
||
//
|
||
// ::DamageTakenWhileInUnderground: The amount of Negative Damage taken per round while in the Underground.
|
||
// :: Note: This too doesn't need the PC to be Under ground sensitive to apply.
|
||
// :: If this value is negative then the PC will regenerate that amount.
|
||
//
|
||
// :: ECL: Effective Character Level: Use any integer value.
|
||
// :: (For those that do not know what this is...
|
||
// :: Effective Character Level is a way of lessening your subrace's bonus abilities
|
||
// :: by reducing the amount of experience points gained per kill.)
|
||
// :: IE: If you have a Subrace with ECL of 3, then a PC (Player character) of level 10 belonging to
|
||
// :: that subrace is regarded being level 13 when gaining XP points per kill.
|
||
// :: Thus will get less experience points.
|
||
// :: NOTE: This can work for negative values as well.
|
||
//
|
||
// :: IsUndead: Mark the PC belonging to this sub-race as being Undead. It will mean that Healing spells will hurt the PC.
|
||
// :: And harming spells will heal the PC.
|
||
//
|
||
// :: PrestigiousSubrace: Mark this sub-race as being prestigious. Which means players can't become part of it when they enter in with a level 1 character with this as their chosen subrace.
|
||
// :: (Set this to TRUE, if you are making a subrace that players can become part of once they reach a certain level in another sub-race)
|
||
// :: -Refer to SetupSubraceSwitch() for more information -
|
||
//
|
||
// :: Example: You wish to create a subrace called Drow, and you have created a Creature Skin/Hide in the toolset with
|
||
// :: resref "sha_pc_drow". The Unique item (which contains spell like abilities and information about the Drow subrace)
|
||
// :: has the resref "sha_subrace_drow". And you want to make the Drow light sensitive and take 2 divine damage while in light areas.
|
||
// :: Also you would like to mark the Drow as having an Effective Character level of +1.
|
||
// :: Simply call this OnModuleLoad. (Remember to #include "sha_subr_methds", in the script)
|
||
//
|
||
// :: CreateSubrace(RACIAL_TYPE_ELF, "drow", "sha_pc_drow", "sha_subrace_drow", TRUE, 2, FALSE, 0, 1);
|
||
void CreateSubrace(int Race, string SubraceName, string HideResRef = "", string UniqueItemResref = "", int IsLightSensitive = FALSE, int DamageTakenWhileInLight = 0, int IsUndergroundSensitive = FALSE, int DamageTakenWhileInUnderground = 0, int ECL = 0, int IsUndead = FALSE, int PrestigiousSubrace = FALSE);
|
||
|
||
|
||
//- Add another Race that can be part of the subrace.
|
||
// :: subraceName should be the same as the Subrace's name used in CreateSubrace()
|
||
// :: AdditionalBaseRace can only be RACIAL_TYPE_ALL, RACIAL_TYPE_DWARF, RACIAL_TYPE_ELF, RACIAL_TYPE_GNOME,
|
||
// :: RACIAL_TYPE_HALFELF, RACIAL_TYPE_HALFLING, RACIAL_TYPE_HALFORC, or RACIAL_TYPE_HUMAN.
|
||
void AddAdditionalBaseRaceToSubrace(string subraceName, int AdditionalBaseRace);
|
||
|
||
|
||
// ::Limit the classes the PC can be, when trying to be part of this subrace.
|
||
// :: subraceName should be the same as the Subrace's name used in CreateSubrace()
|
||
// :: Set the CanBe_<Class> values as desired.
|
||
//
|
||
// ::Note: This will only check PC's first class. IE: You limit your subrace's classes to only Fighter and Rogue
|
||
// :: A player with classes Wizard/Fighter/Cleric will not meet the criteria, nor will a Monk/Cleric/Rogue.
|
||
// :: Only a PC with either Rogue or Fighter as their first class will meet the requirement.
|
||
// :: IE: Rogue/WeaponMaster or Fighter/Wizard/Cleric.
|
||
void CreateSubraceClassRestriction(string subraceName, int CanBe_Barbarian = TRUE, int CanBe_Bard = TRUE, int CanBe_Cleric = TRUE, int CanBe_Druid = TRUE, int CanBe_Fighter = TRUE, int CanBe_Monk = TRUE, int CanBe_Paladin = TRUE, int CanBe_Ranger = TRUE, int CanBe_Rogue = TRUE, int CanBe_Sorcerer = TRUE, int CanBe_Wizard = TRUE);
|
||
|
||
|
||
//Limit the Alignment the PC can be, when trying to be part of this subrace.
|
||
//Note this alignment restriction only applies when the PC enters the module for the first time. (A database entry is made).
|
||
// :: IE: It will not stop the PC from being part of the subrace after the PC adventures and changes in alignment.
|
||
//
|
||
// :: subraceName should be the same as the Subrace's name used in CreateSubrace()
|
||
// :: Set the CanBe_<Alignment> to as desired.
|
||
void CreateSubraceAlignmentRestriction(string subraceName, int CanBeAlignment_Good = TRUE , int CanBeAlignment_Neutral1 = TRUE, int CanBeAlignment_Evil = TRUE, int CanBeAlignment_Lawful = TRUE, int CanBeAlignment_Neutral2 = TRUE, int CanBeAlignment_Chaotic = TRUE);
|
||
|
||
|
||
//Use this method of Spell resistance if you want the Spell resistance to increase (or decrease) with the PC's level.
|
||
// :: subraceName should be the same as the Subrace's name used in CreateSubrace()
|
||
//
|
||
// :: SpellResistanceBase: Is the vaule of SR the PC gains at level 1
|
||
// :: int SpellResistanceMax: Is the value of the SR PC gains at the maximum level achievable (default is 40, you can change the maximum level value in "sha_subr_consts")
|
||
void CreateSubraceSpellResistance(string subraceName, int SpellResistanceBase, int SpellResistanceMax);
|
||
|
||
|
||
//Use this method if you want the PC's Appearance to change for the subrace.
|
||
//
|
||
// :: subraceName should be the same as the Subrace's name used in CreateSubrace()
|
||
// :: AppearanceChangeTime: Time of day you want the Appearance to change.
|
||
// :: if you want to have a permanent appearance change then use: TIME_BOTH.
|
||
// :: if you want the appearance to only change when it is night time and revert back when it is day time then use: TIME_DAY.
|
||
// :: if you want the appearance to only change when it is day time and revert back to the PC's original form when it is night time then use: TIME_NIGHT.
|
||
// :: if you plan on making a controlable appearance, then set to TIME_NONE. (Refer to .pdf tutorial for more information)
|
||
//
|
||
// ::MaleAppearance: This is the appearance of a Male PC. Use any of the APPEARANCE_TYPE_* values.
|
||
// ::FemaleAppearance: This is the appearance of a Female PC. Use any of the APPEARANCE_TYPE_* values.
|
||
// ::Level: From which level to apply this appearance change from...
|
||
//
|
||
// ::NOTE: Not all APPEARANCE_TYPE_* constants work in standard NWN. IE: If you use APPEARANCE_TYPE_WYRMLING_BLACK, and you only have installed just NWN (no expansions),
|
||
// :: Then your appearance will be different... (in the case of wyrmiling, you will look like a mephit) - You have been warned.
|
||
void CreateSubraceAppearance(string subraceName, int AppearanceChangeTime, int MaleAppearance, int FemaleAppearance, int Level = 1);
|
||
|
||
// - (You may use this twice per subrace. Once for TIME_DAY, and once for TIME_NIGHT) -
|
||
//
|
||
// Use this method if you want the PC's ability scores or AC or AB to change when it is either day or night.
|
||
// (The use of this function is slightly more complicated)
|
||
//
|
||
// :: subraceName: Should be the same as the Subrace's name used in CreateSubrace()
|
||
//
|
||
// :: struct SubraceStats Stats: (Explained below)
|
||
//
|
||
// :: TimeToApply: if you want the stats/ability scores to only change when it is night time and revert back when it is day time then use: TIME_NIGHT.
|
||
// :: if you want the stats/ability scores to only change when it is day time and revert back to the PC's original stats/ability scores when it is night time then use: TIME_DAY.
|
||
//
|
||
// :: InInteriorArea: Set to TRUE if you want these changes to ability scores to happen in Interior Areas.
|
||
// :: InExteriorArea: Set to TRUE if you want these changes to ability scores to happen in Exterior Areas.
|
||
// :: InNaturalArea: Set to TRUE if you want these changes to ability scores to happen in Natural Areas.
|
||
// :: InArtifacialArea: Set to TRUE if you want these changes to ability scores to happen in Artifical Areas.
|
||
// :: InUndergroundArea: Set to TRUE if you want these changes to ability scores to happen in Underground Areas.
|
||
// :: InAbovegroundArea: Set to TRUE if you want these changes to ability scores to happen in Above Ground Areas.
|
||
//
|
||
// :: How to use this function.
|
||
//
|
||
// :: First create a structure of SubraceStats. It can be done by:
|
||
//
|
||
// :: struct SubraceStats mystats = CreateCustomeStats(<fill in appropriate values. Look at CreateCustomeStats method for more details>).
|
||
//
|
||
// :: then you want to add this to your subrace. So call
|
||
//
|
||
// :: CreateTemporaryStatModifier("mysubrace", mystats, TIME_DAY, TRUE, FALSE);
|
||
//
|
||
// ::Hence the PC belonging to "mysubrace" will have it's ability scores changed during day time, when they are in Exterior (IE: outdoors) areas.
|
||
void CreateTemporaryStatModifier(string subraceName, struct SubraceStats Stats, int TimeToApply, int InInteriorArea = TRUE, int InExteriorArea = TRUE, int InNaturalArea = TRUE, int InArtifacialArea = TRUE, int InUndergroundArea = TRUE, int InAbovegroundArea = TRUE);
|
||
|
||
|
||
//This is the first half of CreateTemporaryStatModifier function.
|
||
//
|
||
//(The use of this function is slightly more complicated)
|
||
//
|
||
// :: StatModiferType: Use only SUBRACE_STAT_MODIFIER_TYPE_PERCENTAGE (if you wish to increase or decrease a PC's ability scores/AC/AB based on the percentage of the PC's current ability scores)
|
||
// :: or SUBRACE_STAT_MODIFIER_TYPE_POINTS (if you wish to increase or decrease a PC's ability scores/AC/AB by constant number.
|
||
// :: Fill in the values of the floats appropriately.
|
||
//
|
||
// ::Example: You wish to change reduce the PC's strength by 80% and increase it's dexterity by 50% and increase it's consitituion by 60%, whilst you want to increase the AC by 65%, but reduce the AB by 10%.
|
||
//
|
||
// ::so you create your stats:
|
||
//
|
||
// ::struct SubraceStats mystats = CreateCustomStats(SUBRACE_STAT_MODIFIER_TYPE_PERCENTAGE, -0.80, 0.50, 0.60, 0.0, 0.0, 0.0, 0.65, -0.10);
|
||
//
|
||
// ::You then use this in CreateTemporaryStatModifier().
|
||
struct SubraceStats CreateCustomStats(int StatModifierType, float StrengthModifier, float DexterityModifier, float ConstitutionModifier, float IntelligenceModifier, float WisdomModifier, float CharismaModifier, float ACModifier, float ABModifier);
|
||
|
||
|
||
|
||
//(Use this only ONCE per subrace. It will not work correctly if used more than once per subrace)
|
||
//
|
||
//This method will allow you to disable/enable the use of Melee or ranged weapons or other types of weapons by the particular subrace.
|
||
//
|
||
// :: subraceName: Should be the same as the Subrace's name used in CreateSubrace()
|
||
// :: WeaponType: The type of weapon you want the restriction to apply to...
|
||
// :: Use either SUBRACE_RESTRICTION_WEAPON_MELEE (gloves are excluded)
|
||
// :: or SUBRACE_RESTRICTION_WEAPON_RANGED (ranged and throwing type of weapons)
|
||
// :: or SUBRACE_RESTRICTION_WEAPON_EXOTIC or SUBRACE_RESTRICTION_WEAPON_LARGE or
|
||
// :: or SUBRACE_RESTRICTION_WEAPON_MARTIAL or SUBRACE_RESTRICTION_WEAPON_SIMPLE
|
||
// :: or SUBRACE_RESTRICTION_WEAPON_TINY or SUBRACE_RESTRICTION_WEAPON_ALL
|
||
//
|
||
// :: TimeOfDay: To Restrict the use of WeaponType at various times: Use TIME_NIGHT, TIME_DAY or TIME_BOTH
|
||
//
|
||
// :: Allow: If you want to allow the use of ONLY these weapons, then set it to TRUE. If set to FALSE, the engine
|
||
// :: will prohibit the use of WeaponType.
|
||
void SubraceRestrictUseOfWeaponsOfType(string subraceName, int WeaponType, int TimeOfDay = TIME_BOTH, int Allow = FALSE);
|
||
|
||
|
||
|
||
//(Use this only ONCE per subrace. It will not work correctly if used more than once per subrace)
|
||
//
|
||
// ::This method will allow you to disable/enable the use of items that grant defense. (Shields and Armour)
|
||
//
|
||
// :: subraceName: Should be the same as the Subrace's name used in CreateSubrace()
|
||
// :: Type: The category of armor and shield thats you want the restriction to apply to...
|
||
//
|
||
// :: SUBRACE_RESTRICTION_DEFENSE_ALL (All shields and Armor -including cloths)
|
||
// :: SUBRACE_RESTRICTION_DEFENSE_CLOTHING (Cloths only, no shields)
|
||
// :: SUBRACE_RESTRICTION_DEFENSE_HEAVY (Full plates, half plates and Tower shields, and helms)
|
||
// :: SUBRACE_RESTRICTION_DEFENSE_MEDIUM (Chain Shirt, Scale Mail, Chainmail, Breastplate, Splint Mail, Banded Mail and Large Shields and helms)
|
||
// :: SUBRACE_RESTRICTION_DEFENSE_LIGHT (Padded, Leather armour,Studded Armor and small shields.)
|
||
//
|
||
// :: TimeOfDay: To Restrict the use of WeaponType at various times: Use TIME_NIGHT, TIME_DAY or TIME_BOTH
|
||
//
|
||
// :: Allow: If you want to allow the use of ONLY these weapons, then set it to TRUE. If set to FALSE, the engine
|
||
// :: will prohibit the use of WeaponType.
|
||
void SubraceRestrictUseOfArmourAndShieldsOfType(string subraceName, int Type, int TimeOfDay = TIME_BOTH, int Allow = FALSE);
|
||
|
||
|
||
//:: Add a favored class to the subrace.
|
||
//
|
||
// (Use this only ONCE per subrace. It will not work correctly if used more than once per subrace)
|
||
// This would mean that when determining XP penalty for multiclassing, the favored
|
||
// classes do not apply when determining it (Works the same way as default NWN favored classes)
|
||
// ::(This will work ONLY if you are using the attached Shayan's XP System script).
|
||
//
|
||
//NOTE: You can use any playable base CLASS_TYPE_* constant. Do NOT USE Prestige classes,
|
||
// :: as they are not taken into consideration when determining multiclassing penalty by NWN.
|
||
// :: Also if you do specify a prestige class it will end up giving players a 20% boost to the XP gained.
|
||
// :: (Thanks to Masterlexx for spotting this bug)
|
||
void AddSubraceFavoredClass(string subraceName, int MaleFavoredClass, int FamaleFavoredClass);
|
||
|
||
//Add a permanent or a temporary subrace effect on the PC, during day or night or permanently.
|
||
//
|
||
//:: subraceName: Should be the same as the Subrace's name used in CreateSubrace()
|
||
//:: EffectID: There are a limited number of effects you can use here...
|
||
//:: EFFECT_TYPE_ARCANE_SPELL_FAILURE
|
||
//:: EFFECT_TYPE_BLINDNESS
|
||
//:: EFFECT_TYPE_CHARMED
|
||
//:: EFFECT_TYPE_CONCEALMENT
|
||
//:: EFFECT_TYPE_CONFUSED
|
||
//:: EFFECT_TYPE_CUTSCENEGHOST
|
||
//:: EFFECT_TYPE_HASTE
|
||
//:: EFFECT_TYPE_IMMUNITY
|
||
//:: EFFECT_TYPE_IMPROVEDINVISIBILITY
|
||
//:: EFFECT_TYPE_INVISIBILITY
|
||
//:: EFFECT_TYPE_MISS_CHANCE
|
||
//:: EFFECT_TYPE_MOVEMENT_SPEED_DECREASE
|
||
//:: EFFECT_TYPE_MOVEMENT_SPEED_INCREASE
|
||
//:: EFFECT_TYPE_POLYMORPH
|
||
//:: EFFECT_TYPE_REGENERATE
|
||
//:: EFFECT_TYPE_SANCTUARY
|
||
//:: EFFECT_TYPE_SLOW
|
||
//:: EFFECT_TYPE_TEMPORARY_HITPOINTS
|
||
//:: EFFECT_TYPE_TRUESEEING
|
||
//:: EFFECT_TYPE_ULTRAVISION
|
||
//:: EFFECT_TYPE_VISUALEFFECT
|
||
//
|
||
// :: Value1: This is the value of the first parameter (from left) that you can input for the effect.
|
||
// :: IE: If you choose EFFECT_TYPE_CONCEALMENT, which means the effect applied will be:
|
||
// :: EffectConcealment(int nPercentage, int nMissType=MISS_CHANCE_TYPE_NORMAL)
|
||
// :: Thus Value1 will be the value of nPercentage.
|
||
// :: YOU MUST INPUT A VALUE! IF NOT THE SCRIPT WILL PUT IN 0!!
|
||
//
|
||
// :: Value2: This is the value of the second parameter you can input for the effect.
|
||
// :: IE: (Refer to Value1's example) This will be the value of nMissType.
|
||
// :: YOU MUST INPUT A VALUE! IF NOT THE SCRIPT WILL PUT IN 0!!
|
||
//
|
||
// ::nDurationType: Duration type of the effect being applied...
|
||
// :: DURATION_TYPE_INSTANT, DURATION_TYPE_PERMANENT, or DURATION_TYPE_TEMPORARY.
|
||
//
|
||
// ::fDuration: The number of seconds the effect should last for...
|
||
// :: (Put 0.0 if you are making it last "forever" -IE: Whole of day time, or night time or permanetly)
|
||
//
|
||
// ::TimeOfDay: The time of day you want this applied. Use TIME_BOTH if you want this permanently applied on the PC.
|
||
//
|
||
// Use as many times as desired.
|
||
void AddSubraceEffect(string subraceName, int EffectID, int Value1, int Value2, int nDurationType, float fDuration, int TimeOfDay);
|
||
|
||
//Add a different skin to the subrace at specified level. (Use as many times as desired)
|
||
//
|
||
//:: subraceName: Should be the same as the Subrace's name used in CreateSubrace()
|
||
//:: SkinResRef: The Blueprint ResRef of the skin that you want the subrace to be equipped.
|
||
//:: EquipLevel: The level at which you want the skin to be applied.
|
||
//:: iTime: The time at which you want the skin to be equipped. (Use TIME_DAY, TIME_NIGHT, or TIME_BOTH.)
|
||
//
|
||
// ::Example: You want to add a skin for the subrace Illithid to use at level 15, during day time.
|
||
//
|
||
// ::Then call onModuleLoad script:
|
||
// :: AddAdditionalSkinsToSubrace("Illithid", "my_illithid_skin", 15, TIME_DAY);
|
||
//
|
||
// ::(Where "my_illithid_skin" is the resref of the skin you want equipped.)
|
||
//
|
||
// ::::
|
||
// :::: Remeber: If you say add a skin for a subrace to be equipped at level 15, then all PCs belonging to the
|
||
// :::: subrace above level 15 will also use the same skin for that time -unless you add a different skin for those levels.)
|
||
//
|
||
// ::::Use as many times as desired.
|
||
void AddAdditionalSkinsToSubrace(string subraceName, string SkinResRef, int EquipLevel, int iTime = TIME_BOTH);
|
||
|
||
|
||
//::: Add equipable creature claws to the subrace. (Use as many times as desired)
|
||
//
|
||
// :: This allows you to add 'Claws' to your subrace. You simply specify the Blue print resref of
|
||
// :: the claw you want equipped on the player, and at what level.
|
||
// :: (You can use this to equip claws/slams/gore or what ever else that maybe equipped in a PC's claw item slots
|
||
//
|
||
//
|
||
//:: subraceName: Should be the same as the Subrace's name used in CreateSubrace()
|
||
//:: RightClawResRef: The resref of the right hand claw. (Use "" if you do not want to specify a claw, use "none" if you want any existing right claws to be removed from the player.)
|
||
//:: LeftClawResRef: The resref of the left hand claw. (Use "" if you do not want to specify a claw, use "none" if you want any existing right claws to be removed from the player.)
|
||
//:: EquipLevel: The level at which these claws should be equipped.
|
||
//
|
||
// ::NOTE: 1. Make sure the PCs have weapon proficiency in creature weapons!!! I can't stress this enough.
|
||
// :: (Give the feat through the subrace Skin)
|
||
//
|
||
// :: 2. If you are going to use one claw, make sure it is the right claw.
|
||
//
|
||
// :: 3. Also note that you need not change both claws at once.
|
||
// :: (IE: Say you equipped a right and left claw at level 5, then say at level 10, if you want to change the left claw
|
||
// :: then you only need to specify the resref of the left claw... the PC keeps the existing right claw.)
|
||
void AddClawsToSubrace(string subraceName, string RightClawResRef, string LeftClawResRef , int EquipLevel, int iTime = TIME_BOTH);
|
||
|
||
|
||
//::: Switch the player from one subrace to another ::::
|
||
//
|
||
// ::(Use only once per Level)
|
||
//
|
||
// :: This allows you to switch a player from one subrace to another.
|
||
//
|
||
//:: subraceName: Should be the same as the Subrace's name used in CreateSubrace()
|
||
//:: switchSubraceName: The syntax of the subraces, you wish to switch the player (Should be the same as whatever the new subraces' name used in it's CreateSubrace())
|
||
//:: Level: The level at which this switch should take place.
|
||
//:: MustMeetRequirements: Set to FALSE, if you want the switching to bypass any class/race/alignment restriction the new subrace might have.
|
||
//
|
||
// :: If MustMeetRequirements set to TRUE, and the character fails to meet a requirement... then they will continue on as part of their current sub-race.
|
||
//
|
||
// ::IDEA: You can set the subrace you want the player to switch to as a hidden and unaccessible subrace for new characters, by setting
|
||
// :: PrestigiousSubrace to TRUE, in CreateSubrace().
|
||
// :: That way, players must earn their way to this new subrace (switchSubraceNames).
|
||
//
|
||
// ::Note: Inorder for this to work the subrace you wish to switch the player to does NOT have to be marked as prestigious.
|
||
//
|
||
// ::IE: If I had set up three subraces like:
|
||
// :: CreateSubrace(RACIAL_TYPE_HUMAN, "illithid", "sha_pc_illithid", "sha_subrace_illi", TRUE, 0, FALSE, 0, 3);
|
||
// :: //(Along with other setting for subrace, like class restrictions, appearance, additional skins, etc)
|
||
//
|
||
// :: CreateSubrace(RACIAL_TYPE_HUMAN, "vampire", "sha_pc_vamp001", "sha_subrace_vamp", TRUE, 2, FALSE, 0, 3, TRUE);
|
||
// :: //Can only be evil.
|
||
// :: CreateSubraceAlignmentRestriction("vampire", FALSE, FALSE, TRUE);
|
||
// :: //(Along with other setting for subrace, like class restrictions, appearance, additional skins, etc)
|
||
//
|
||
// :: CreateSubrace(RACIAL_TYPE_HUMAN, "wolkier", "sha_pc_wolk", "sha_subrace_wolk", TRUE);
|
||
// :: //Can only be Neutra;.
|
||
// :: CreateSubraceAlignmentRestriction("wolkier", FALSE, TRUE, FALSE);
|
||
// :: //(Along with other setting for subrace, like class restrictions, appearance, additional skins, etc)
|
||
//
|
||
// ::And I wished that PCs belonging to illithid be switched to vampire or wolkier at level 15, depending on which criteria they meet, then I would call:
|
||
//
|
||
// :: SetupSubraceSwitch("illithid", "vampire_wolkier", 15, TRUE);
|
||
//
|
||
// ::If I didn't want the alignment criteria to be check during switching then I would call:
|
||
//
|
||
// :: SetupSubraceSwitch("illithid", "vampire_wolkier", 15, FALSE);
|
||
//
|
||
// :: The order in which you choose the subrace to be switched is important. If the player can meet both requirements, it gives prioirty to the first one.
|
||
//
|
||
//
|
||
// :: You can put in any number of subraces to switch to..
|
||
// :: IE:
|
||
// SetupSubraceSwitch("illithid", "vampire_wolkier_pixie_shadow", 8, TRUE);
|
||
//
|
||
// If a player doesn't meet the criteria for any one of the subraces, he/she wil remain part of thier usual subrace: subraceName.
|
||
//
|
||
// You can use SetupSwitchSubrace() as many times as you like. EG:
|
||
//
|
||
// SetupSubraceSwitch("illithid", "vampire_wolkier_pixie_shadow", 12, TRUE);
|
||
// SetupSubraceSwitch("illithid", "air-genasi_underminion", 18, TRUE);
|
||
// SetupSubraceSwitch("illithid", "mindbreaker_telephathest_darkmoon", 32, TRUE);
|
||
// SetupSubraceSwitch("illithid", "greatone", 40, FALSE);
|
||
//
|
||
// Where: vampire, wolkier, pixie, shadow, air-genasi, underminion, mindbreaker,
|
||
// telephathest, darkmoon, and greatone are all subraces.
|
||
void SetupSubraceSwitch(string subraceName, string switchSubraceName, int Level, int MustMeetRequirements = TRUE);
|
||
|
||
// :: Give the player belonging to a subrace, additional unique items ::
|
||
// (Use as many times as desired for any levels)
|
||
//
|
||
// This allows you to give players belonging to a subrace additional unique items, at any level.
|
||
//
|
||
// :: subraceName: Should be the same as the Subrace's name used in CreateSubrace()
|
||
// :: ItemResRef: The blueprint res-ref of the item to give.
|
||
// :: Level: The level at which to give the item.
|
||
//
|
||
// Example:
|
||
//
|
||
// Say I wanted to give my players belonging to the vampire subrace, an armour and a scythe at level 2.
|
||
// And then an amulet at level 10.
|
||
// The armor's resref is: "sha_vamp_arm"
|
||
// The scythe's resref is: "sha_vamp_scythe"
|
||
// The amulet's resref is: "sha_vamp_ammy"
|
||
//
|
||
// So I simply call:
|
||
// AddSubraceItem("vampire", "sha_vamp_arm", 2);
|
||
// AddSubraceItem("vampire", "sha_vamp_scythe", 2);
|
||
// AddSubraceItem("vampire", "sha_vamp_ammy", 10);
|
||
//
|
||
//// NOTE: You can only give ONE item of each. IE: You CAN'T do this expecting to give 2 amulets:
|
||
//
|
||
// AddSubraceItem("vampire", "sha_vamp_ammy", 10);
|
||
// AddSubraceItem("vampire", "sha_vamp_ammy", 10);
|
||
void AddSubraceItem(string subraceName, string ItemResRef, int Level = 1);
|
||
|
||
|
||
|
||
|
||
|
||
// :: Setup a Prestige class restriction for a 'Prestige' subrace.
|
||
//
|
||
// NOTE: This will only be checked during a 'subrace switch' for obvious reasons. Refer to SetupSubraceSwitch(...)
|
||
//
|
||
// subraceName = Should be the same as the Subrace's name used in CreateSubrace().
|
||
// MinimumLevels = The minimum number of levels in a/any particular prestigious class allowed to pass the restriction.
|
||
// Set CanBe_<Class> values as desired.
|
||
//
|
||
// Example:
|
||
//
|
||
// Say I have a subrace 'Phantasm' and I wanted to add a restriction so that only Shadow Dancers, Blackguards, and Assasin can be part of.
|
||
// AND they must have atleast 5 levels in any of those classes.
|
||
// So I set:
|
||
//
|
||
// CreateSubracePrestigiousClassRestriction("phantasm", 5, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
|
||
//
|
||
// * A player with class combination like <Any base class>/Assasin(2)/ShadowDancer(3) will meet this criteria.
|
||
//
|
||
// NOTE: This can be used in combination with CreateSubraceClassRestriction(...)
|
||
//
|
||
// If you wanted to you can also set-up a primary/base class restriction with CreateSubraceClassRestriction(...) and also create a Prestigious class restriction with this.
|
||
void CreateSubracePrestigiousClassRestriction(string subraceName, int MinimumLevels = 1, int CanBe_ArcaneArcher = TRUE, int CanBe_Assasin = TRUE, int CanBe_Blackguard = TRUE, int CanBe_ChampionOfTorm = TRUE, int CanBe_RedDragonDisciple = TRUE, int CanBe_DwarvenDefender = TRUE, int CanBe_HarperScout = TRUE, int CanBe_PaleMaster = TRUE, int CanBe_ShadowDancer = TRUE, int CanBe_Shifter = TRUE, int CanBe_WeaponMaster = TRUE);
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
/*
|
||
:::::::::::::::::::::::: Function Definers usuable anywhere ::::::::::::::::::::
|
||
*/
|
||
//:: You may use these functions anywhere, and they would work appropriately.
|
||
|
||
|
||
// ::Erases all "temporary" subracial abilities, so that after respawn or a restoring spell is cast
|
||
// ::the heartbeat script will then reapply the stats again.
|
||
void ReapplySubraceAbilities(object oPC);
|
||
|
||
//Add this on the Module OnClientEnter script.
|
||
void SubraceOnClientEnter();
|
||
|
||
//Add this to Module OnPlayerRespawn script.
|
||
void SubraceOnPlayerRespawn();
|
||
|
||
//Add this to Module OnPlayerLevelUp script.
|
||
void SubraceOnPlayerLevelUp();
|
||
|
||
//Add this to Module OnPlayerEquipItem script.
|
||
void SubraceOnPlayerEquipItem();
|
||
|
||
//Add this to the Module OnItemActivated script.
|
||
void SubraceOnItemActivated();
|
||
|
||
//Subrace Heartbeat function - For use in default.nss
|
||
void SubraceHeartbeat(object oPC = OBJECT_SELF);
|
||
|
||
//:: Force the player to properly un-equip the item.
|
||
void SHA_SubraceForceUnequipItem(object oItem);
|
||
|
||
//:: Force the player to properly equip oItem in the inventory slot: InvoSlot.
|
||
void SHA_SubraceForceEquipItem(object oItem, int InvoSlot);
|
||
|
||
//Return the XP modifier for being part of the Subrace
|
||
//(Calclates modifer value for Subrace Favored classes)
|
||
float GetSubraceXPModifier(object oPC);
|
||
|
||
//:: Returns TRUE if the player is marked as being part of an undead subrace.
|
||
//:: (Shayan's Subrace Engine)
|
||
int Subrace_GetIsUndead(object oPC);
|
||
|
||
//:: Returns the Effective Character level of oPC.
|
||
//:: (Shayan's Subrace Engine)
|
||
int GetECL(object oPC);
|
||
|
||
//:: Deletes every bit of subracial information stored on the PC. Also destroys equipped skins and claws.
|
||
//:: (Does not however delete the 'subrace' set on the PC. Use SetSubRace(oPC, "") AFTER calling this, if you wish to remove the PC from the subrace completely.)
|
||
//:: (Shayan's Subrace Engine)
|
||
void DeleteSubraceInfoOnPC(object oPC);
|
||
|
||
//:: Change the PC to his/her default humaniod appearance.
|
||
//:: IE: If the player is human and his/her appearance is Illithid, this will turn them back
|
||
//:: to looking like human again.
|
||
//:: (Shayan's Subrace Engine)
|
||
void ChangeToPCDefaultAppearance(object oPC);
|
||
|
||
|
||
//:: Returns TRUE if PC belongs to a subrace which is Light sensitive.
|
||
//:: (Shayan's Subrace Engine)
|
||
int GetIsPCLightSensitive(object oPC);
|
||
|
||
//:: Reads al the subraces avaliable in this module to the object oDM.
|
||
//:: (Shayan's Subrace Engine)
|
||
void ReadAllSubraces(object oDM);
|
||
|
||
//:: Return the Favored class of the PC. Returns -1 if there is none.
|
||
//:: (Shayan's Subrace Engine)
|
||
int Subrace_GetFavouredClass(object oPC);
|
||
|
||
//:: Send's a message to PC, with a Subrace Engine title. Set Important to TRUE if
|
||
//:: it is an important message. (Refer to sha_subr_consts for more info.)
|
||
//:: (Shayan's Subrace Engine)
|
||
void SHA_SendSubraceMessageToPC(object oPC, string message, int Important = TRUE);
|
||
|
||
//:: Traverses through oPC's inventory, destroying all Skins, and creature items.
|
||
void SearchAndDestroySkinsAndClaws(object oPC);
|
||
|
||
//:: Removes temporary subrace ability scores and AB boosts.
|
||
void ClearSubraceEffects(object oPC);
|
||
|
||
//:: Returns TIME_DAY, or TIME_NIGHT depending on the current hour of day.
|
||
int SHA_GetCurrentTime();
|
||
|
||
//:: Returns the default appearance type of oPC. (It ignores any appearance
|
||
//:: change by SetAppearance()).
|
||
//:: NOTE: oPC must be a player character in order for this to work.
|
||
int SHA_GetDefaultAppearanceType(object oPC);
|
||
|
||
|
||
|
||
|
||
|
||
//
|
||
//::::::::::::::::::::::::: Interal Function definers:::::::::::::::::::::::::::
|
||
//
|
||
// :: Do not use these functions outside this script. They may not work correctly.
|
||
|
||
void SaveSubraceOnModule(struct Subrace shaSubrace);
|
||
void GiveSubraceUniqueItem(string SubraceTag, object oPC);
|
||
void SaveSubraceAlignmentRestrictionOnModule(struct SubraceAlignmentRestriction shaSubraceAlignRes);
|
||
void SaveSubraceClassRestrictionOnModule(struct SubraceClassRestriction shaSubraceClassRes);
|
||
void SaveSubraceSpellResistanceOnModule(struct SubraceSpellResistance shaSubraceSpellRes);
|
||
void SaveSubraceAppearanceChangeOnModule(struct SubraceDifferentAppearance shaSubraceApp);
|
||
int CheckIfPCMeetsClassCriteria(object oPC, string SubraceTag);
|
||
int CheckIfPCMeetsAlignmentCriteria(object oPC, string SubraceTag);
|
||
int CheckIfPCMeetsAnySubraceCriteria(object oPC);
|
||
void SHA_ApplyTemporaryStats(object oPC, string SubraceTag, int iCurrentTime, int iTimeDay, int iTimeNight,int AreaUndAbove, int AreaIntExt, int AreaNatArt);
|
||
void ApplyTemporarySubraceStats(object oPC, string SubraceTag, int iCurrentTime, int AreaUndAbove, int AreaIntExt, int AreaNatArt);
|
||
void ApplyStat_AbilityByPercentage(int AbilityToMod, float percentage, object oPC);
|
||
void ApplySubraceBonusStatsByPercentage(object oPC, string SubraceTag);
|
||
void ApplyAttackBonusByPercentage(float percentage, object oPC);
|
||
void ApplyArmourClassBonusByPercentage(float percentage, object oPC);
|
||
void ApplySubraceBonusStatsByPoints(object oPC, string SubraceTag);
|
||
void ApplyStat_AbilityByPoints(int AbilityToMod, float points, object oPC);
|
||
void ApplyAttackBonusByPoints(float points, object oPC);
|
||
void ApplyArmourClassBonusByPoints(float points, object oPC);
|
||
void ClearSubraceTemporaryStats(object oPC);
|
||
void LoadSubraceInfoOnPC(object oPC, string subraceName);
|
||
void ApplyPermanentSubraceSpellResistance(string subrace, object oPC);
|
||
void InitiateSubraceChecking(object oPC);
|
||
int GetFavoredClassExceedsGap(int Race1Favored, int Race2Favored, int Class1, int Class2, int Class3, int Class13Gap, int Class23Gap, int Class12Gap);
|
||
void ApplySubraceEffect(object oPC, string SubraceTag, int TimeOfDay);
|
||
void CheckIfCanUseEquipedWeapon(object oPC);
|
||
void ReadSubraceInformation(string subraceName, object oDM, object oTarget = OBJECT_INVALID);
|
||
void ReadSubrace(object oDM, int MaxCount, int CurrentCount);
|
||
void EquipTemporarySubraceClaw(string subraceTag, object oPC, int iTime);
|
||
void EquipTemporarySubraceSkin(string subraceTag, object oPC, int iTime);
|
||
void CheckAndSwitchSubrace(object oPC);
|
||
void SubraceCheckItemActivated(object oPC, object oItem);
|
||
string Subrace_DefenseRestrictionToString(int ResType);
|
||
string Subrace_WeaponRestrictionToString(int ResType);
|
||
string Subrace_TimeToString(int iTime);
|
||
int CheckIfPCMeetsPrestigiousClassCriteria(object oPC, string SubraceTag);
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
//:: ---------------------------------------------------------------------------
|
||
//:: Functions for the Subrace Engine.
|
||
//:: ---------------------------------------------------------------------------
|
||
void SHA_SendSubraceMessageToPC(object oPC, string message, int Important = TRUE)
|
||
{
|
||
if(MINIMALISE_SUBRACE_MESSAGES_TO_PC)
|
||
{
|
||
if(Important)
|
||
{
|
||
SendMessageToPC(oPC, SUBRACE_ENGINE + message);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
SendMessageToPC(oPC, SUBRACE_ENGINE + message);
|
||
}
|
||
}
|
||
|
||
|
||
void CreateSubrace(int Race, string SubraceName, string HideResRef = "", string UniqueItemResRef = "", int IsLightSensitive = FALSE, int DamageTakenWhileInLight = 0, int IsUndergroundSensitive = FALSE, int DamageTakenWhileInUnderground = 0, int ECL = 0, int IsUndead = FALSE, int PrestigiousSubrace = FALSE)
|
||
{
|
||
struct Subrace shaSubrace;
|
||
|
||
shaSubrace.BaseRace = Race;
|
||
shaSubrace.Name = SubraceName;
|
||
shaSubrace.SkinResRef = HideResRef;
|
||
shaSubrace.UniqueItemResRef = UniqueItemResRef;
|
||
shaSubrace.IsLightSensitive = IsLightSensitive;
|
||
shaSubrace.DamageTakenWhileInLight = DamageTakenWhileInLight;
|
||
shaSubrace.IsUndergroundSensitive = IsUndergroundSensitive;
|
||
shaSubrace.DamageTakenWhileInUnderground = DamageTakenWhileInUnderground;
|
||
shaSubrace.ECL = ECL;
|
||
shaSubrace.IsUndead = IsUndead;
|
||
shaSubrace.PrestigiousSubrace = PrestigiousSubrace;
|
||
|
||
SaveSubraceOnModule(shaSubrace);
|
||
}
|
||
|
||
void CreateSubraceAlignmentRestriction(string subraceName, int CanBeAlignment_Good = TRUE , int CanBeAlignment_Neutral1 = TRUE, int CanBeAlignment_Evil = TRUE, int CanBeAlignment_Lawful = TRUE, int CanBeAlignment_Neutral2 = TRUE, int CanBeAlignment_Chaotic = TRUE)
|
||
{
|
||
struct SubraceAlignmentRestriction shaSubraceAlignRes;
|
||
|
||
shaSubraceAlignRes.subraceName = subraceName;
|
||
shaSubraceAlignRes.CanBeAlignment_Good = CanBeAlignment_Good;
|
||
shaSubraceAlignRes.CanBeAlignment_Neutral1 = CanBeAlignment_Neutral1;
|
||
shaSubraceAlignRes.CanBeAlignment_Evil =CanBeAlignment_Evil;
|
||
shaSubraceAlignRes.CanBeAlignment_Lawful = CanBeAlignment_Lawful;
|
||
shaSubraceAlignRes.CanBeAlignment_Neutral2 = CanBeAlignment_Neutral2;
|
||
shaSubraceAlignRes.CanBeAlignment_Chaotic = CanBeAlignment_Chaotic;
|
||
|
||
SaveSubraceAlignmentRestrictionOnModule(shaSubraceAlignRes);
|
||
}
|
||
|
||
void CreateSubraceClassRestriction(string subraceName, int CanBe_Barbarian = TRUE, int CanBe_Bard = TRUE, int CanBe_Cleric = TRUE, int CanBe_Druid = TRUE, int CanBe_Fighter = TRUE, int CanBe_Monk = TRUE, int CanBe_Paladin = TRUE, int CanBe_Ranger = TRUE, int CanBe_Rogue = TRUE, int CanBe_Sorcerer = TRUE, int CanBe_Wizard = TRUE)
|
||
{
|
||
struct SubraceClassRestriction shaSubraceClassRes;
|
||
|
||
shaSubraceClassRes.subraceName = subraceName;
|
||
|
||
shaSubraceClassRes.CanBe_Barbarian = CanBe_Barbarian;
|
||
shaSubraceClassRes.CanBe_Bard = CanBe_Bard;
|
||
shaSubraceClassRes.CanBe_Cleric = CanBe_Cleric;
|
||
shaSubraceClassRes.CanBe_Druid = CanBe_Druid;
|
||
shaSubraceClassRes.CanBe_Fighter = CanBe_Fighter;
|
||
shaSubraceClassRes.CanBe_Monk = CanBe_Monk;
|
||
shaSubraceClassRes.CanBe_Paladin = CanBe_Paladin;
|
||
shaSubraceClassRes.CanBe_Ranger = CanBe_Ranger;
|
||
shaSubraceClassRes.CanBe_Rogue = CanBe_Rogue;
|
||
shaSubraceClassRes.CanBe_Sorcerer = CanBe_Sorcerer;
|
||
shaSubraceClassRes.CanBe_Wizard = CanBe_Wizard;
|
||
|
||
SaveSubraceClassRestrictionOnModule(shaSubraceClassRes);
|
||
}
|
||
|
||
void CreateSubraceSpellResistance(string subraceName, int SpellResistanceBase, int SpellResistanceMax)
|
||
{
|
||
struct SubraceSpellResistance shaSubraceSpellRes;
|
||
|
||
shaSubraceSpellRes.subraceName = subraceName;
|
||
shaSubraceSpellRes.SpellResistanceBase = SpellResistanceBase;
|
||
shaSubraceSpellRes.SpellResistanceMax = SpellResistanceMax;
|
||
|
||
SaveSubraceSpellResistanceOnModule(shaSubraceSpellRes);
|
||
}
|
||
|
||
void CreateSubraceAppearance(string subraceName, int AppearanceChangeTime, int MaleAppearance, int FemaleAppearance, int Level = 1)
|
||
{
|
||
struct SubraceDifferentAppearance shaSubraceApp;
|
||
|
||
shaSubraceApp.subraceName = subraceName;
|
||
shaSubraceApp.ChangeAppearanceTime = AppearanceChangeTime;
|
||
shaSubraceApp.MaleAppearance = MaleAppearance;
|
||
shaSubraceApp.FemaleAppearance = FemaleAppearance;
|
||
shaSubraceApp.Level = Level;
|
||
|
||
SaveSubraceAppearanceChangeOnModule(shaSubraceApp);
|
||
}
|
||
|
||
void AddAdditionalBaseRaceToSubrace(string subraceName, int AdditionalBaseRace)
|
||
{
|
||
subraceName = GetStringLowerCase(subraceName);
|
||
string SubraceTag = SUBRACE_TAG + "_" + subraceName;
|
||
int Flag = NOFLAGS;
|
||
switch(AdditionalBaseRace)
|
||
{
|
||
case RACIAL_TYPE_DWARF: Flag = FLAG1; break;
|
||
case RACIAL_TYPE_ELF: Flag = FLAG2; break;
|
||
case RACIAL_TYPE_GNOME: Flag = FLAG3; break;
|
||
case RACIAL_TYPE_HALFELF: Flag = FLAG4; break;
|
||
case RACIAL_TYPE_HALFLING: Flag = FLAG5; break;
|
||
case RACIAL_TYPE_HALFORC: Flag = FLAG6; break;
|
||
case RACIAL_TYPE_HUMAN: Flag = FLAG7; break;
|
||
case RACIAL_TYPE_ALL: Flag = ALLFLAGS; break;
|
||
default: Flag = NOFLAGS; break;
|
||
}
|
||
SetLocalGroupFlag(oStorer, SubraceTag + "_" + SUBRACE_BASE_RACE, Flag, SUBRACE_BASE_RACE_FLAGS);
|
||
}
|
||
|
||
void AddSubraceEffect(string subraceName, int EffectID, int Value1, int Value2, int nDurationType, float fDuration, int TimeOfDay)
|
||
{
|
||
subraceName = GetStringLowerCase(subraceName);
|
||
string SubraceTag = SUBRACE_TAG + "_" + subraceName;
|
||
int Count = GetLocalInt(oStorer, SubraceTag + "_" + SUBRACE_EFFECT_COUNT);
|
||
Count++;
|
||
SetLocalInt(oStorer, SubraceTag + "_" + SUBRACE_EFFECT_COUNT, Count);
|
||
SubraceTag = SubraceTag + IntToString(Count);
|
||
SetLocalInt(oStorer, SubraceTag + "_" + SUBRACE_EFFECT, EffectID);
|
||
SetLocalInt(oStorer, SubraceTag + "_" + SUBRACE_EFFECT_VALUE_1, Value1);
|
||
SetLocalInt(oStorer, SubraceTag + "_" + SUBRACE_EFFECT_VALUE_2, Value2);
|
||
SetLocalInt(oStorer, SubraceTag + "_" + SUBRACE_EFFECT_DURATION_TYPE, nDurationType);
|
||
SetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_EFFECT_DURATION, fDuration);
|
||
SetLocalInt(oStorer, SubraceTag + "_" + SUBRACE_EFFECT_APPLY_TIME, TimeOfDay);
|
||
}
|
||
|
||
void AddSubraceFavoredClass(string subraceName, int MaleFavoredClass, int FamaleFavoredClass)
|
||
{
|
||
subraceName = GetStringLowerCase(subraceName);
|
||
string SubraceTag = SUBRACE_TAG + "_" + subraceName;
|
||
SetLocalGroupFlagValue(oStorer, SubraceTag + "_" + SUBRACE_FAVORED_CLASS, MaleFavoredClass + 1, SUBRACE_FAVORED_CLASS_MALE_FLAG);
|
||
SetLocalGroupFlagValue(oStorer, SubraceTag + "_" + SUBRACE_FAVORED_CLASS, FamaleFavoredClass + 1, SUBRACE_FAVORED_CLASS_FEMALE_FLAG);
|
||
}
|
||
|
||
void CreateSubracePrestigiousClassRestriction(string subraceName, int MinimumLevels = 1, int CanBe_ArcaneArcher = TRUE, int CanBe_Assasin = TRUE, int CanBe_Blackguard = TRUE, int CanBe_ChampionOfTorm = TRUE, int CanBe_RedDragonDisciple = TRUE, int CanBe_DwarvenDefender = TRUE, int CanBe_HarperScout = TRUE, int CanBe_PaleMaster = TRUE, int CanBe_ShadowDancer = TRUE, int CanBe_Shifter = TRUE, int CanBe_WeaponMaster = TRUE)
|
||
{
|
||
subraceName = GetStringLowerCase(subraceName);
|
||
string SubraceTag = SUBRACE_TAG + "_" + subraceName;
|
||
|
||
SetLocalInt(oStorer, SubraceTag + "_" + SUBRACE_PRESTIGIOUS_CLASS_RESTRICTION_MINIMUM_LEVELS, MinimumLevels);
|
||
//Flags
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_PRESTIGIOUS_CLASS_RESTRICTION, FLAG1, TRUE);
|
||
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_PRESTIGIOUS_CLASS_RESTRICTION, FLAG2, CanBe_ArcaneArcher);
|
||
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_PRESTIGIOUS_CLASS_RESTRICTION, FLAG3, CanBe_Assasin);
|
||
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_PRESTIGIOUS_CLASS_RESTRICTION, FLAG4, CanBe_Blackguard);
|
||
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_PRESTIGIOUS_CLASS_RESTRICTION, FLAG5, CanBe_ChampionOfTorm);
|
||
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_PRESTIGIOUS_CLASS_RESTRICTION, FLAG6, CanBe_RedDragonDisciple);
|
||
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_PRESTIGIOUS_CLASS_RESTRICTION, FLAG7, CanBe_DwarvenDefender);
|
||
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_PRESTIGIOUS_CLASS_RESTRICTION, FLAG8, CanBe_PaleMaster);
|
||
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_PRESTIGIOUS_CLASS_RESTRICTION, FLAG9, CanBe_ShadowDancer);
|
||
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_PRESTIGIOUS_CLASS_RESTRICTION, FLAG10, CanBe_Shifter);
|
||
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_PRESTIGIOUS_CLASS_RESTRICTION, FLAG11, CanBe_WeaponMaster);
|
||
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_PRESTIGIOUS_CLASS_RESTRICTION, FLAG12, CanBe_HarperScout);
|
||
}
|
||
|
||
void CreateTemporaryStatModifier(string subraceName, struct SubraceStats Stats, int TimeToApply, int InInteriorArea = TRUE, int InExteriorArea = TRUE, int InNaturalArea = TRUE, int InArtifacialArea = TRUE, int InUndergroundArea = TRUE, int InAbovegroundArea = TRUE)
|
||
{
|
||
subraceName = GetStringLowerCase(subraceName);
|
||
string SubraceTag = SUBRACE_TAG + "_" + subraceName;
|
||
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG1, TRUE);
|
||
|
||
if(TimeToApply == TIME_DAY)
|
||
{
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG2, TRUE);
|
||
}
|
||
else if(TimeToApply == TIME_NIGHT)
|
||
{
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG3, TRUE);
|
||
}
|
||
|
||
int ModType = Stats.ModType;
|
||
float StrengthModifier = Stats.StrengthModifier;
|
||
float DexterityModifier = Stats.DexterityModifier;
|
||
float ConstitutionModifier = Stats.ConstitutionModifier;
|
||
float IntelligenceModifier = Stats.IntelligenceModifier;
|
||
float WisdomModifier = Stats.WisdomModifier;
|
||
float CharismaModifier = Stats.CharismaModifier;
|
||
float ACModifier = Stats.ACModifier;
|
||
float ABModifier = Stats.ABModifier;
|
||
|
||
SubraceTag = SubraceTag + IntToString(TimeToApply);
|
||
|
||
SetLocalInt(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIER_TYPE, ModType);
|
||
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG4, InInteriorArea);
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG5, InExteriorArea);
|
||
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG6, InArtifacialArea);
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG7, InNaturalArea);
|
||
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG8, InAbovegroundArea);
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG9, InUndergroundArea);
|
||
|
||
SetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_STR_MODIFIER, StrengthModifier);
|
||
SetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_DEX_MODIFIER, DexterityModifier);
|
||
SetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_CON_MODIFIER, ConstitutionModifier);
|
||
SetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_WIS_MODIFIER, WisdomModifier);
|
||
SetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_INT_MODIFIER, IntelligenceModifier);
|
||
SetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_CHA_MODIFIER, CharismaModifier);
|
||
|
||
SetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_AB_MODIFIER, ABModifier);
|
||
SetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_AC_MODIFIER, ACModifier);
|
||
}
|
||
|
||
|
||
//For StatModiferType use only SUBRACE_STAT_MODIFIER_TYPE_PERCENTAGE or SUBRACE_STAT_MODIFIER_TYPE_POINTS
|
||
struct SubraceStats CreateCustomStats(int StatModifierType, float StrengthModifier, float DexterityModifier, float ConstitutionModifier, float IntelligenceModifier, float WisdomModifier, float CharismaModifier, float ACModifier, float ABModifier)
|
||
{
|
||
struct SubraceStats Stats;
|
||
Stats.ModType = StatModifierType;
|
||
Stats.StrengthModifier = StrengthModifier;
|
||
Stats.DexterityModifier = DexterityModifier;
|
||
Stats.ConstitutionModifier = ConstitutionModifier;
|
||
Stats.IntelligenceModifier = IntelligenceModifier;
|
||
Stats.WisdomModifier = WisdomModifier;
|
||
Stats.CharismaModifier = CharismaModifier;
|
||
Stats.ACModifier = ACModifier;
|
||
Stats.ABModifier = ABModifier;
|
||
return Stats;
|
||
}
|
||
|
||
void SubraceRestrictUseOfWeaponsOfType(string subraceName, int WeaponType, int TimeOfDay = TIME_BOTH, int Allow = FALSE)
|
||
{
|
||
//Why bother adding a restriction if you are going to allow the use of all weapons?!
|
||
if(WeaponType == SUBRACE_RESTRICTION_WEAPON_ALL && Allow)
|
||
{ return; }
|
||
subraceName = GetStringLowerCase(subraceName);
|
||
string SubraceTag = SUBRACE_TAG + "_" + subraceName;
|
||
|
||
SetLocalGroupFlag(oStorer, SubraceTag + "_" + SUBRACE_WEAPON_RESTRICTION, SUBRACE_ALLOW_ONLY_THIS_TYPE, SUBRACE_RESTRICTION_FLAGS, Allow);
|
||
SetLocalGroupFlag(oStorer, SubraceTag + "_" + SUBRACE_WEAPON_RESTRICTION, SUBRACE_HAS_RESTRICTION, SUBRACE_RESTRICTION_FLAGS);
|
||
SetLocalGroupFlagValue(oStorer, SubraceTag + "_" + SUBRACE_WEAPON_RESTRICTION, WeaponType, SUBRACE_RESTRICTION_WEAPON);
|
||
SetLocalGroupFlagValue(oStorer, SubraceTag + "_" + SUBRACE_WEAPON_RESTRICTION, TimeOfDay, TIME_FLAGS);
|
||
}
|
||
|
||
void SubraceRestrictUseOfArmourAndShieldsOfType(string subraceName, int Type, int TimeOfDay = TIME_BOTH, int Allow = FALSE)
|
||
{
|
||
//Why bother adding a restriction if you are going to allow the use of all armour?!
|
||
if(Type == SUBRACE_RESTRICTION_DEFENSE_ALL && Allow)
|
||
{ return; }
|
||
subraceName = GetStringLowerCase(subraceName);
|
||
string SubraceTag = SUBRACE_TAG + "_" + subraceName;
|
||
|
||
SetLocalGroupFlag(oStorer, SubraceTag + "_" + SUBRACE_ARMOUR_RESTRICTION, SUBRACE_ALLOW_ONLY_THIS_TYPE, SUBRACE_RESTRICTION_FLAGS, Allow);
|
||
SetLocalGroupFlag(oStorer, SubraceTag + "_" + SUBRACE_ARMOUR_RESTRICTION, SUBRACE_HAS_RESTRICTION, SUBRACE_RESTRICTION_FLAGS);
|
||
SetLocalGroupFlagValue(oStorer, SubraceTag + "_" + SUBRACE_ARMOUR_RESTRICTION, Type, SUBRACE_RESTRICTION_DEFENSE);
|
||
SetLocalGroupFlagValue(oStorer, SubraceTag + "_" + SUBRACE_ARMOUR_RESTRICTION, TimeOfDay, TIME_FLAGS);
|
||
|
||
}
|
||
|
||
void SetupSubraceSwitch(string subraceName, string switchSubraceNames, int Level, int MustMeetRequirements = TRUE)
|
||
{
|
||
subraceName = GetStringLowerCase(subraceName);
|
||
string SubraceTag = SUBRACE_TAG + "_" + subraceName;
|
||
SetLocalString(oStorer, SubraceTag + "_" + SUBRACE_SWITCH_NAME + IntToString(Level), switchSubraceNames);
|
||
if(MustMeetRequirements)
|
||
{
|
||
SetLocalInt(oStorer, SubraceTag + "_" + SUBRACE_SWITCH_MUST_MEET_REQUIREMENTS + IntToString(Level), TRUE);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
//:: Internal Functions
|
||
void SaveSubraceOnModule(struct Subrace shaSubrace)
|
||
{
|
||
|
||
string subraceName = GetStringLowerCase(shaSubrace.Name);
|
||
string SubraceTag = SUBRACE_TAG + "_" + subraceName;
|
||
SetLocalInt(oStorer, SubraceTag, TRUE);
|
||
//Save the count, and the name of the subrace.
|
||
int iCount = GetLocalInt(oStorer, MODULE_SUBRACE_COUNT);
|
||
iCount++;
|
||
SetLocalInt(oStorer, MODULE_SUBRACE_COUNT, iCount);
|
||
SetLocalString(oStorer, MODULE_SUBRACE_NUMBER + IntToString(iCount), subraceName);
|
||
|
||
|
||
int Flag = NOFLAGS;
|
||
switch(shaSubrace.BaseRace)
|
||
{
|
||
case RACIAL_TYPE_DWARF: Flag = FLAG1; break;
|
||
case RACIAL_TYPE_ELF: Flag = FLAG2; break;
|
||
case RACIAL_TYPE_GNOME: Flag = FLAG3; break;
|
||
case RACIAL_TYPE_HALFELF: Flag = FLAG4; break;
|
||
case RACIAL_TYPE_HALFLING: Flag = FLAG5; break;
|
||
case RACIAL_TYPE_HALFORC: Flag = FLAG6; break;
|
||
case RACIAL_TYPE_HUMAN: Flag = FLAG7; break;
|
||
case RACIAL_TYPE_ALL: Flag = ALLFLAGS; break;
|
||
default: Flag = NOFLAGS; break;
|
||
}
|
||
SetLocalGroupFlag(oStorer, SubraceTag + "_" + SUBRACE_BASE_RACE, Flag, SUBRACE_BASE_RACE_FLAGS);
|
||
|
||
if(shaSubrace.SkinResRef != "none" && shaSubrace.SkinResRef != "")
|
||
{
|
||
SetLocalString(oStorer, SubraceTag + "_" + SUBRACE_SKIN + "_1" + "_" + IntToString(TIME_BOTH), shaSubrace.SkinResRef);
|
||
}
|
||
if(shaSubrace.UniqueItemResRef != "" && shaSubrace.UniqueItemResRef != "none")
|
||
{
|
||
int SubraceUniqueItemCount = 1;
|
||
SetLocalInt(oStorer, SubraceTag + "_" + SUBRACE_UNIQUEITEM_COUNT, SubraceUniqueItemCount);
|
||
SetLocalString(oStorer, SubraceTag + "_" + SUBRACE_UNIQUEITEM + "_1", shaSubrace.UniqueItemResRef + "_1");
|
||
}
|
||
SetLocalGroupFlag(oStorer, SubraceTag + "_" + SUBRACE_BASE_INFORMATION, SUBRACE_BASE_INFORMATION_LIGHT_SENSITIVE, SUBRACE_BASE_INFORMATION_FLAGS, shaSubrace.IsLightSensitive);
|
||
SetLocalGroupFlag(oStorer, SubraceTag + "_" + SUBRACE_BASE_INFORMATION, SUBRACE_BASE_INFORMATION_UNDERGROUND_SENSITIVE, SUBRACE_BASE_INFORMATION_FLAGS, shaSubrace.IsUndergroundSensitive);
|
||
SetLocalGroupFlag(oStorer, SubraceTag + "_" + SUBRACE_BASE_INFORMATION, SUBRACE_BASE_INFORMATION_UNDEAD, SUBRACE_BASE_INFORMATION_FLAGS, shaSubrace.IsUndead);
|
||
SetLocalGroupFlag(oStorer, SubraceTag + "_" + SUBRACE_BASE_INFORMATION, SUBRACE_BASE_INFORMATION_PRESTIGIOUS_SUBRACE, SUBRACE_BASE_INFORMATION_FLAGS, shaSubrace.PrestigiousSubrace);
|
||
|
||
if(shaSubrace.DamageTakenWhileInLight != 0)
|
||
{
|
||
SetLocalInt(oStorer, SubraceTag + "_" + DAMAGE_AMOUNT_IN_LIGHT, shaSubrace.DamageTakenWhileInLight);
|
||
}
|
||
|
||
if(shaSubrace.DamageTakenWhileInUnderground != 0)
|
||
{
|
||
SetLocalInt(oStorer, SubraceTag + "_" + DAMAGE_AMOUNT_IN_UNDERGROUND, shaSubrace.DamageTakenWhileInUnderground);
|
||
}
|
||
if(shaSubrace.ECL != 0)
|
||
{
|
||
SetLocalGroupFlagValue(oStorer, SubraceTag + "_" + SUBRACE_BASE_INFORMATION, shaSubrace.ECL, SUBRACE_BASE_INFORMATION_ECL);
|
||
}
|
||
|
||
}
|
||
|
||
void SaveSubraceAlignmentRestrictionOnModule(struct SubraceAlignmentRestriction shaSubraceAlignRes)
|
||
{
|
||
string subraceName = GetStringLowerCase(shaSubraceAlignRes.subraceName);
|
||
string SubraceTag = SUBRACE_TAG + "_" + subraceName;
|
||
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_ALIGNMENT_RESTRICTION, FLAG1, TRUE);
|
||
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_ALIGNMENT_RESTRICTION, FLAG2, shaSubraceAlignRes.CanBeAlignment_Good);
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_ALIGNMENT_RESTRICTION, FLAG3, shaSubraceAlignRes.CanBeAlignment_Neutral1);
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_ALIGNMENT_RESTRICTION, FLAG4, shaSubraceAlignRes.CanBeAlignment_Evil);
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_ALIGNMENT_RESTRICTION, FLAG5, shaSubraceAlignRes.CanBeAlignment_Lawful);
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_ALIGNMENT_RESTRICTION, FLAG6, shaSubraceAlignRes.CanBeAlignment_Neutral2);
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_ALIGNMENT_RESTRICTION, FLAG7, shaSubraceAlignRes.CanBeAlignment_Chaotic);
|
||
|
||
}
|
||
|
||
void SaveSubraceClassRestrictionOnModule(struct SubraceClassRestriction shaSubraceClassRes)
|
||
{
|
||
|
||
string subraceName = GetStringLowerCase(shaSubraceClassRes.subraceName);
|
||
string SubraceTag = SUBRACE_TAG + "_" + subraceName;
|
||
//Flags
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_CLASS_RESTRICTION, FLAG1, TRUE);
|
||
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_CLASS_RESTRICTION, FLAG2, shaSubraceClassRes.CanBe_Barbarian);
|
||
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_CLASS_RESTRICTION, FLAG3, shaSubraceClassRes.CanBe_Bard);
|
||
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_CLASS_RESTRICTION, FLAG4, shaSubraceClassRes.CanBe_Cleric);
|
||
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_CLASS_RESTRICTION, FLAG5, shaSubraceClassRes.CanBe_Druid);
|
||
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_CLASS_RESTRICTION, FLAG6, shaSubraceClassRes.CanBe_Fighter);
|
||
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_CLASS_RESTRICTION, FLAG7, shaSubraceClassRes.CanBe_Monk);
|
||
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_CLASS_RESTRICTION, FLAG8, shaSubraceClassRes.CanBe_Paladin);
|
||
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_CLASS_RESTRICTION, FLAG9, shaSubraceClassRes.CanBe_Ranger);
|
||
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_CLASS_RESTRICTION, FLAG10, shaSubraceClassRes.CanBe_Rogue);
|
||
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_CLASS_RESTRICTION, FLAG11, shaSubraceClassRes.CanBe_Sorcerer);
|
||
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_CLASS_RESTRICTION, FLAG12, shaSubraceClassRes.CanBe_Wizard);
|
||
}
|
||
|
||
void SaveSubraceSpellResistanceOnModule(struct SubraceSpellResistance shaSubraceSpellRes)
|
||
{
|
||
string subraceName = GetStringLowerCase(shaSubraceSpellRes.subraceName);
|
||
string SubraceTag = SUBRACE_TAG + "_" + subraceName;
|
||
|
||
SetLocalGroupFlagValue(oStorer, SubraceTag + "_" + SUBRACE_SPELL_RESISTANCE, shaSubraceSpellRes.SpellResistanceBase,SUBRACE_SPELL_RESISTANCE_BASE_FLAGS);
|
||
SetLocalGroupFlagValue(oStorer, SubraceTag + "_" + SUBRACE_SPELL_RESISTANCE, shaSubraceSpellRes.SpellResistanceMax, SUBRACE_SPELL_RESISTANCE_MAX_FLAGS);
|
||
}
|
||
|
||
void SaveSubraceAppearanceChangeOnModule(struct SubraceDifferentAppearance shaSubraceApp)
|
||
{
|
||
string subraceName = GetStringLowerCase(shaSubraceApp.subraceName);
|
||
string SubraceTag = SUBRACE_TAG + "_" + subraceName;
|
||
SubraceTag = SubraceTag + "_" + IntToString(shaSubraceApp.Level);
|
||
SetLocalGroupFlag(oStorer, SubraceTag + "_" + APPEARANCE_CHANGE, shaSubraceApp.ChangeAppearanceTime, TIME_FLAGS);
|
||
SetLocalGroupFlagValue(oStorer, SubraceTag + "_" + APPEARANCE_CHANGE, shaSubraceApp.MaleAppearance, APPEARANCE_CHANGE_MALE_FLAG);
|
||
SetLocalGroupFlagValue(oStorer, SubraceTag + "_" + APPEARANCE_CHANGE, shaSubraceApp.FemaleAppearance, APPEARANCE_CHANGE_FEMALE_FLAG);
|
||
}
|
||
|
||
void AddAdditionalSkinsToSubrace(string subraceName, string SkinResRef, int EquipLevel, int iTime = TIME_BOTH)
|
||
{
|
||
subraceName = GetStringLowerCase(subraceName);
|
||
string SubraceTag = SUBRACE_TAG + "_" + subraceName;
|
||
SetLocalString(oStorer, SubraceTag + "_" + SUBRACE_SKIN + "_" + IntToString(EquipLevel) + "_" + IntToString(iTime), SkinResRef);
|
||
}
|
||
|
||
void AddClawsToSubrace(string subraceName, string RightClawResRef, string LeftClawResRef , int EquipLevel, int iTime = TIME_BOTH)
|
||
{
|
||
subraceName = GetStringLowerCase(subraceName);
|
||
string SubraceTag = SUBRACE_TAG + "_" + subraceName;
|
||
if(RightClawResRef != "")
|
||
{
|
||
SetLocalString(oStorer, SubraceTag + "_" + SUBRACE_RIGHT_CLAW + "_" + IntToString(EquipLevel) + "_" + IntToString(iTime), RightClawResRef);
|
||
}
|
||
if(LeftClawResRef != "")
|
||
{
|
||
SetLocalString(oStorer, SubraceTag + "_" + SUBRACE_LEFT_CLAW + "_" + IntToString(EquipLevel) + "_" + IntToString(iTime), LeftClawResRef);
|
||
}
|
||
}
|
||
void AddSubraceItem(string subraceName, string ItemResRef, int Level = 1)
|
||
{
|
||
subraceName = GetStringLowerCase(subraceName);
|
||
string SubraceTag = SUBRACE_TAG + "_" + subraceName;
|
||
int SubraceUniqueItemCount = GetLocalInt(oStorer, SubraceTag + "_" + SUBRACE_UNIQUEITEM_COUNT);
|
||
SubraceUniqueItemCount++;
|
||
SetLocalInt(oStorer, SubraceTag + "_" + SUBRACE_UNIQUEITEM_COUNT, SubraceUniqueItemCount);
|
||
|
||
SetLocalString(oStorer, SubraceTag + "_" + SUBRACE_UNIQUEITEM + "_" + IntToString(SubraceUniqueItemCount), ItemResRef + "_" + IntToString(Level));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
void SetIsInDarkness(object oPC, int Flag)
|
||
{
|
||
string subrace = GetStringLowerCase(GetSubRace(oPC));
|
||
if(subrace == "")
|
||
{ return; }
|
||
string SubraceTag = SUBRACE_TAG + "_" + subrace;
|
||
int IsLightSens = GetLocalGroupFlag(oPC, SubraceTag + "_" + SUBRACE_BASE_INFORMATION, SUBRACE_BASE_INFORMATION_LIGHT_SENSITIVE, SUBRACE_BASE_INFORMATION_FLAGS);
|
||
int DmgTakenL = GetLocalInt(oPC, SubraceTag + "_" + DAMAGE_AMOUNT_IN_LIGHT);
|
||
if(IsLightSens || DmgTakenL > 0)
|
||
{
|
||
SetLocalInt(oPC, SUBRACE_IN_SPELL_DARKNESS, Flag);
|
||
}
|
||
}
|
||
|
||
int Subrace_GetIsInDarkness(object oPC)
|
||
{
|
||
return GetLocalInt(oPC, SUBRACE_IN_SPELL_DARKNESS);
|
||
}
|
||
|
||
void ApplyLightSensitivity(object oPC)
|
||
{
|
||
if(SPELL_DARKNESS_STOPS_LIGHT_SENSITIVITY && Subrace_GetIsInDarkness(oPC))
|
||
{
|
||
return;
|
||
}
|
||
if(!GetLocalInt(oPC, "STRUCK_BLIND"))
|
||
{
|
||
if(APPLY_LIGHT_BLINDNESS)
|
||
{
|
||
if(FortitudeSave(oPC, LIGHT_SENSITIVE_SAVING_THROW_DC) == 0)
|
||
{
|
||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBlindness(), oPC, RoundsToSeconds(LIGHT_STRUCK_BLIND_FOR_ROUNDS));
|
||
}
|
||
SetLocalInt(oPC, "STRUCK_BLIND", TRUE);
|
||
DelayCommand(RoundsToSeconds(LIGHT_BLINDNESS_STRIKES_EVERY_ROUND), SetLocalInt(oPC, "STRUCK_BLIND", FALSE));
|
||
}
|
||
}
|
||
if(APPLY_AB_AND_SAVING_THROW_DECREASES_IN_LIGHT && !GetLocalInt(oPC, "STRUCK_LIGHT_DEC"))
|
||
{
|
||
effect ABDecrease = EffectAttackDecrease(LIGHT_AB_DECREASE, ATTACK_BONUS_ONHAND);
|
||
effect ABDecrease1 = EffectAttackDecrease(LIGHT_AB_DECREASE, ATTACK_BONUS_OFFHAND);
|
||
effect SaveDecrease = EffectSavingThrowDecrease(SAVING_THROW_ALL, LIGHT_SAVE_DECREASE, SAVING_THROW_TYPE_ALL);
|
||
effect Link = EffectLinkEffects(ABDecrease, ABDecrease1);
|
||
Link = SupernaturalEffect(EffectLinkEffects(SaveDecrease, Link));
|
||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, Link, oPC, RoundsToSeconds(LIGHT_CAUSES_AB_AND_SAVES_DECREASE_FOR_ROUNDS + 1));
|
||
SetLocalInt(oPC, "STRUCK_LIGHT_DEC", TRUE);
|
||
DelayCommand(RoundsToSeconds(LIGHT_CAUSES_AB_AND_SAVES_DECREASE_FOR_ROUNDS), SetLocalInt(oPC, "STRUCK_LIGHT_DEC", FALSE));
|
||
}
|
||
}
|
||
|
||
int GetIsPCLightSensitive(object oPC)
|
||
{
|
||
string SubraceTag = SUBRACE_TAG + "_" + GetStringLowerCase(GetSubRace(oPC));
|
||
return GetLocalGroupFlag(oPC, SubraceTag + "_" + SUBRACE_BASE_INFORMATION, SUBRACE_BASE_INFORMATION_LIGHT_SENSITIVE, SUBRACE_BASE_INFORMATION_FLAGS);
|
||
}
|
||
|
||
void ApplyUndergroundSensitivity(object oPC)
|
||
{
|
||
if(!GetLocalInt(oPC, "STRUCK_BLIND_UND"))
|
||
{
|
||
if(FortitudeSave(oPC, DARK_SENSITIVE_SAVING_THROW_DC) == 0)
|
||
{
|
||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectBlindness(), oPC, DARK_STRUCK_BLIND_FOR_ROUNDS*6.0);
|
||
}
|
||
SetLocalInt(oPC, "STRUCK_BLIND_UND", TRUE);
|
||
DelayCommand(RoundsToSeconds(DARK_BLINDNESS_STRIKES_EVERY_ROUND), SetLocalInt(oPC, "STRUCK_BLIND_UND", FALSE));
|
||
}
|
||
}
|
||
|
||
void SubraceSpontaneouslyCombust(object oPC)
|
||
{
|
||
if(ReflexSave(oPC, SUBRACE_SPONTANEOUSLY_COMBUST_DC) != 0)
|
||
{ return; }
|
||
effect FireDmg = EffectDamage(d8(), DAMAGE_TYPE_FIRE, DAMAGE_POWER_NORMAL);
|
||
effect VisEffect = EffectVisualEffect(VFX_IMP_FLAME_S);
|
||
effect iLink = EffectLinkEffects(FireDmg, VisEffect);
|
||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, iLink, oPC, 6.0);
|
||
|
||
}
|
||
void ApplyDamageWhileInLight(object oPC, int DmgTaken)
|
||
{
|
||
if(SPELL_DARKNESS_STOPS_LIGHT_SENSITIVITY && Subrace_GetIsInDarkness(oPC))
|
||
{
|
||
return;
|
||
}
|
||
if(!GetLocalInt(oPC, "SB_LGHT_DMGED"))
|
||
{
|
||
SetLocalInt(oPC, "SB_LGHT_DMGED", TRUE);
|
||
effect LightDamage;
|
||
if(DmgTaken > 0)
|
||
{
|
||
LightDamage = EffectDamage(DmgTaken, DAMAGE_TYPE_DIVINE, DAMAGE_POWER_ENERGY);
|
||
}
|
||
else if(DmgTaken < 0)
|
||
{
|
||
DmgTaken = abs(DmgTaken);
|
||
LightDamage = EffectRegenerate(DmgTaken, 1.0);
|
||
}
|
||
if(SUBRACE_SPONTANEOUS_COMBUSTION_WHILE_IN_LIGHT)
|
||
{
|
||
if(d100() <= SUBRACE_SPONTANEOUS_COMBUSTION_PERCENTAGE)
|
||
{
|
||
int i = 0;
|
||
//Combust visual effect.
|
||
effect eDur = EffectVisualEffect(498);
|
||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eDur, oPC, RoundsToSeconds(LIGHT_DAMAGES_EVERY_ROUNDS));
|
||
|
||
while(i != LIGHT_DAMAGES_EVERY_ROUNDS)
|
||
{
|
||
DelayCommand(RoundsToSeconds(i), SubraceSpontaneouslyCombust(oPC));
|
||
i++;
|
||
}
|
||
}
|
||
}
|
||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, LightDamage, oPC, 1.0);
|
||
DelayCommand(RoundsToSeconds(LIGHT_DAMAGES_EVERY_ROUNDS), SetLocalInt(oPC,"SB_LGHT_DMGED", FALSE));
|
||
}
|
||
}
|
||
|
||
void ApplyDamageWhileInDark(object oPC, int DmgTaken)
|
||
{
|
||
if(!GetLocalInt(oPC, "SB_DARK_DMGED"))
|
||
{
|
||
SetLocalInt(oPC, "SB_DARK_DMGED", TRUE);
|
||
effect DarkDamage;
|
||
if(DmgTaken > 0)
|
||
{
|
||
DarkDamage = EffectDamage(DmgTaken, DAMAGE_TYPE_NEGATIVE, DAMAGE_POWER_ENERGY);
|
||
}
|
||
else if(DmgTaken < 0)
|
||
{
|
||
DmgTaken = abs(DmgTaken);
|
||
DarkDamage = EffectRegenerate(DmgTaken, 1.0);
|
||
}
|
||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, DarkDamage, oPC, 1.0);
|
||
DelayCommand(RoundsToSeconds(DARKNESS_DAMAGES_EVERY_ROUNDS), SetLocalInt(oPC,"SB_DARK_DMGED", FALSE));
|
||
}
|
||
}
|
||
int CheckIfPCMeetsBaseRaceCriteria(object oPC, string SubraceTag)
|
||
{
|
||
int PCRace = GetRacialType(oPC);
|
||
int iResult = FALSE;
|
||
switch(PCRace)
|
||
{
|
||
case RACIAL_TYPE_DWARF:
|
||
{
|
||
if(GetLocalGroupFlag(oStorer, SubraceTag + "_" + SUBRACE_BASE_RACE, FLAG1, SUBRACE_BASE_RACE_FLAGS))
|
||
{
|
||
iResult = TRUE;
|
||
}
|
||
break;
|
||
}
|
||
case RACIAL_TYPE_ELF:
|
||
{
|
||
if(GetLocalGroupFlag(oStorer, SubraceTag + "_" + SUBRACE_BASE_RACE, FLAG2, SUBRACE_BASE_RACE_FLAGS))
|
||
{
|
||
iResult = TRUE;
|
||
}
|
||
break;
|
||
}
|
||
case RACIAL_TYPE_GNOME:
|
||
{
|
||
if(GetLocalGroupFlag(oStorer, SubraceTag + "_" + SUBRACE_BASE_RACE, FLAG3, SUBRACE_BASE_RACE_FLAGS))
|
||
{
|
||
iResult = TRUE;
|
||
}
|
||
break;
|
||
}
|
||
case RACIAL_TYPE_HALFELF:
|
||
{
|
||
if(GetLocalGroupFlag(oStorer, SubraceTag + "_" + SUBRACE_BASE_RACE, FLAG4, SUBRACE_BASE_RACE_FLAGS))
|
||
{
|
||
iResult = TRUE;
|
||
}
|
||
break;
|
||
}
|
||
case RACIAL_TYPE_HALFLING:
|
||
{
|
||
if(GetLocalGroupFlag(oStorer, SubraceTag + "_" + SUBRACE_BASE_RACE, FLAG5, SUBRACE_BASE_RACE_FLAGS))
|
||
{
|
||
iResult = TRUE;
|
||
}
|
||
break;
|
||
}
|
||
case RACIAL_TYPE_HALFORC:
|
||
{
|
||
if(GetLocalGroupFlag(oStorer, SubraceTag + "_" + SUBRACE_BASE_RACE, FLAG6, SUBRACE_BASE_RACE_FLAGS))
|
||
{
|
||
iResult = TRUE;
|
||
}
|
||
break;
|
||
}
|
||
case RACIAL_TYPE_HUMAN:
|
||
{
|
||
if(GetLocalGroupFlag(oStorer, SubraceTag + "_" + SUBRACE_BASE_RACE, FLAG7, SUBRACE_BASE_RACE_FLAGS))
|
||
{
|
||
iResult = TRUE;
|
||
}
|
||
break;
|
||
}
|
||
case RACIAL_TYPE_ALL:
|
||
{
|
||
if(GetLocalGroupFlag(oStorer, SubraceTag + "_" + SUBRACE_BASE_RACE, ALLFLAGS, SUBRACE_BASE_RACE_FLAGS))
|
||
{
|
||
iResult = TRUE;
|
||
}
|
||
break;
|
||
}
|
||
default:
|
||
{
|
||
if(GetLocalGroupFlag(oStorer, SubraceTag + "_" + SUBRACE_BASE_RACE, NOFLAGS, SUBRACE_BASE_RACE_FLAGS))
|
||
{
|
||
iResult = TRUE;
|
||
}
|
||
break;
|
||
}
|
||
|
||
}
|
||
return iResult;
|
||
//return CheckPCRaceFitsAdditionalBaseRace(oPC, SubraceTag, NumberOfBaseRace);
|
||
}
|
||
|
||
int CheckIfPCMeetsClassCriteria(object oPC, string SubraceTag)
|
||
{
|
||
int check = FALSE;
|
||
int PCClass = GetClassByPosition(1, oPC);
|
||
|
||
int canBeBarbarian = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_CLASS_RESTRICTION, FLAG2);
|
||
int canBeBard = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_CLASS_RESTRICTION, FLAG3);
|
||
int canBeCleric = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_CLASS_RESTRICTION, FLAG4);
|
||
int canBeDruid = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_CLASS_RESTRICTION, FLAG5);
|
||
int canBeFighter = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_CLASS_RESTRICTION, FLAG6);
|
||
int canBeMonk = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_CLASS_RESTRICTION, FLAG7);
|
||
int canBePaladin = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_CLASS_RESTRICTION, FLAG8);
|
||
int canBeRanger = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_CLASS_RESTRICTION, FLAG9);
|
||
int canBeRogue = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_CLASS_RESTRICTION, FLAG10);
|
||
int canBeSorcerer = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_CLASS_RESTRICTION, FLAG11);
|
||
int canBeWizard = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_CLASS_RESTRICTION, FLAG12);
|
||
|
||
if((PCClass == CLASS_TYPE_BARBARIAN && canBeBarbarian) || (PCClass == CLASS_TYPE_BARD && canBeBard) || (PCClass == CLASS_TYPE_CLERIC && canBeCleric) || (PCClass == CLASS_TYPE_DRUID && canBeDruid) || (PCClass == CLASS_TYPE_FIGHTER && canBeFighter) || (PCClass == CLASS_TYPE_MONK && canBeMonk) || (PCClass == CLASS_TYPE_PALADIN && canBePaladin) || (PCClass == CLASS_TYPE_RANGER && canBeRanger) || (PCClass == CLASS_TYPE_ROGUE && canBeRogue) || (PCClass == CLASS_TYPE_SORCERER && canBeSorcerer) || (PCClass == CLASS_TYPE_WIZARD && canBeWizard))
|
||
{ check = TRUE; }
|
||
return check;
|
||
}
|
||
|
||
int CheckIfPCMeetsPrestigiousClassCriteria(object oPC, string SubraceTag)
|
||
{
|
||
|
||
int MinLevel = GetLocalInt(oStorer, SubraceTag + "_" + SUBRACE_PRESTIGIOUS_CLASS_RESTRICTION_MINIMUM_LEVELS);
|
||
|
||
//Flags
|
||
SetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_PRESTIGIOUS_CLASS_RESTRICTION, FLAG1, TRUE);
|
||
|
||
int CanBe_AA = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_PRESTIGIOUS_CLASS_RESTRICTION, FLAG2);
|
||
|
||
int CanBe_ASS = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_PRESTIGIOUS_CLASS_RESTRICTION, FLAG3);
|
||
|
||
int CanBe_BG = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_PRESTIGIOUS_CLASS_RESTRICTION, FLAG4);
|
||
|
||
int CanBe_COT = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_PRESTIGIOUS_CLASS_RESTRICTION, FLAG5);
|
||
|
||
int CanBe_RDD = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_PRESTIGIOUS_CLASS_RESTRICTION, FLAG6);
|
||
|
||
int CanBe_DD = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_PRESTIGIOUS_CLASS_RESTRICTION, FLAG7);
|
||
|
||
int CanBe_PM = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_PRESTIGIOUS_CLASS_RESTRICTION, FLAG8);
|
||
|
||
int CanBe_SD = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_PRESTIGIOUS_CLASS_RESTRICTION, FLAG9);
|
||
|
||
int CanBe_SHF = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_PRESTIGIOUS_CLASS_RESTRICTION, FLAG10);
|
||
|
||
int CanBe_WM = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_PRESTIGIOUS_CLASS_RESTRICTION, FLAG11);
|
||
|
||
int CanBe_Harper = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_PRESTIGIOUS_CLASS_RESTRICTION, FLAG12);
|
||
|
||
int PClass1 = GetClassByPosition(2, oPC);
|
||
int PClass2 = GetClassByPosition(3, oPC);
|
||
|
||
int PClass1Level = GetLevelByClass(PClass1, oPC);
|
||
int PClass2Level = GetLevelByClass(PClass2, oPC);
|
||
|
||
int Class1Check = FALSE;
|
||
int Class2Check = FALSE;
|
||
switch(PClass1)
|
||
{
|
||
case CLASS_TYPE_ARCANE_ARCHER:
|
||
if(CanBe_AA)
|
||
{
|
||
Class1Check = TRUE;
|
||
}
|
||
break;
|
||
case CLASS_TYPE_ASSASSIN:
|
||
if(CanBe_ASS)
|
||
{
|
||
Class1Check = TRUE;
|
||
}
|
||
break;
|
||
case CLASS_TYPE_BLACKGUARD:
|
||
if(CanBe_BG)
|
||
{
|
||
Class1Check = TRUE;
|
||
}
|
||
break;
|
||
case CLASS_TYPE_DIVINE_CHAMPION:
|
||
if(CanBe_COT)
|
||
{
|
||
Class1Check = TRUE;
|
||
}
|
||
break;
|
||
case CLASS_TYPE_DRAGON_DISCIPLE:
|
||
if(CanBe_RDD)
|
||
{
|
||
Class1Check = TRUE;
|
||
}
|
||
break;
|
||
case CLASS_TYPE_DWARVEN_DEFENDER:
|
||
if(CanBe_DD)
|
||
{
|
||
Class1Check = TRUE;
|
||
}
|
||
break;
|
||
case CLASS_TYPE_HARPER:
|
||
if(CanBe_Harper)
|
||
{
|
||
Class1Check = TRUE;
|
||
}
|
||
break;
|
||
case CLASS_TYPE_PALE_MASTER:
|
||
if(CanBe_PM)
|
||
{
|
||
Class1Check = TRUE;
|
||
}
|
||
break;
|
||
case CLASS_TYPE_SHADOWDANCER:
|
||
if(CanBe_SD)
|
||
{
|
||
Class1Check = TRUE;
|
||
}
|
||
break;
|
||
case CLASS_TYPE_SHIFTER:
|
||
if(CanBe_SHF)
|
||
{
|
||
Class1Check = TRUE;
|
||
}
|
||
break;
|
||
case CLASS_TYPE_WEAPON_MASTER:
|
||
if(CanBe_WM)
|
||
{
|
||
Class1Check = TRUE;
|
||
}
|
||
break;
|
||
default: break;
|
||
|
||
}
|
||
|
||
switch(PClass2)
|
||
{
|
||
case CLASS_TYPE_ARCANE_ARCHER:
|
||
if(CanBe_AA)
|
||
{
|
||
Class2Check = TRUE;
|
||
}
|
||
break;
|
||
case CLASS_TYPE_ASSASSIN:
|
||
if(CanBe_ASS)
|
||
{
|
||
Class2Check = TRUE;
|
||
}
|
||
break;
|
||
case CLASS_TYPE_BLACKGUARD:
|
||
if(CanBe_BG)
|
||
{
|
||
Class2Check = TRUE;
|
||
}
|
||
break;
|
||
case CLASS_TYPE_DIVINE_CHAMPION:
|
||
if(CanBe_COT)
|
||
{
|
||
Class2Check = TRUE;
|
||
}
|
||
break;
|
||
case CLASS_TYPE_DRAGON_DISCIPLE:
|
||
if(CanBe_RDD)
|
||
{
|
||
Class2Check = TRUE;
|
||
}
|
||
break;
|
||
case CLASS_TYPE_DWARVEN_DEFENDER:
|
||
if(CanBe_DD)
|
||
{
|
||
Class2Check = TRUE;
|
||
}
|
||
break;
|
||
case CLASS_TYPE_HARPER:
|
||
if(CanBe_Harper)
|
||
{
|
||
Class2Check = TRUE;
|
||
}
|
||
break;
|
||
case CLASS_TYPE_PALE_MASTER:
|
||
if(CanBe_PM)
|
||
{
|
||
Class2Check = TRUE;
|
||
}
|
||
break;
|
||
case CLASS_TYPE_SHADOWDANCER:
|
||
if(CanBe_SD)
|
||
{
|
||
Class2Check = TRUE;
|
||
}
|
||
break;
|
||
case CLASS_TYPE_SHIFTER:
|
||
if(CanBe_SHF)
|
||
{
|
||
Class2Check = TRUE;
|
||
}
|
||
break;
|
||
case CLASS_TYPE_WEAPON_MASTER:
|
||
if(CanBe_WM)
|
||
{
|
||
Class2Check = TRUE;
|
||
}
|
||
break;
|
||
default: break;
|
||
|
||
}
|
||
|
||
if(!Class1Check && !Class2Check)
|
||
{ return FALSE; }
|
||
|
||
if(Class1Check && Class2Check)
|
||
{
|
||
if(PClass1Level + PClass2Level >= MinLevel)
|
||
{
|
||
return TRUE;
|
||
}
|
||
else
|
||
{
|
||
return FALSE;
|
||
}
|
||
}
|
||
if(Class1Check)
|
||
{
|
||
if(PClass1Level >= MinLevel)
|
||
{
|
||
return TRUE;
|
||
}
|
||
else
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
}
|
||
if(Class2Check)
|
||
{
|
||
if(PClass2Level >= MinLevel)
|
||
{
|
||
return TRUE;
|
||
}
|
||
else
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
}
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
|
||
int CheckIfPCMeetsAlignmentCriteria(object oPC, string SubraceTag)
|
||
{
|
||
int check1 = FALSE;
|
||
int check2 = FALSE;
|
||
|
||
int PCAlign1 = GetAlignmentGoodEvil(oPC);
|
||
int PCAlign2 = GetAlignmentLawChaos(oPC);
|
||
|
||
int align1 = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_ALIGNMENT_RESTRICTION, FLAG2);
|
||
int align2 = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_ALIGNMENT_RESTRICTION, FLAG3);
|
||
int align3 = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_ALIGNMENT_RESTRICTION, FLAG4);
|
||
int align4 = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_ALIGNMENT_RESTRICTION, FLAG5);
|
||
int align5 = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_ALIGNMENT_RESTRICTION, FLAG6);
|
||
int align6 = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_ALIGNMENT_RESTRICTION, FLAG7);
|
||
if((PCAlign1 == ALIGNMENT_GOOD && align1) || (PCAlign1 == ALIGNMENT_NEUTRAL && align2) || (PCAlign1 == ALIGNMENT_EVIL && align3))
|
||
{check1 = TRUE;}
|
||
if((PCAlign2 == ALIGNMENT_LAWFUL && align4) || (PCAlign2 == ALIGNMENT_NEUTRAL && align5) || (PCAlign2 == ALIGNMENT_CHAOTIC && align6))
|
||
{check2 = TRUE;}
|
||
|
||
if(check1 && check2)
|
||
{ return TRUE; }
|
||
else
|
||
{ return FALSE;}
|
||
}
|
||
|
||
|
||
|
||
|
||
int CheckIfPCMeetsAnySubraceCriteria(object oPC)
|
||
{
|
||
|
||
string subraceName = GetStringLowerCase(GetSubRace(oPC));
|
||
int check = FALSE;
|
||
|
||
string SubraceTag = SUBRACE_TAG + "_" + subraceName;
|
||
|
||
int CheckForSubrace = GetLocalInt(oStorer, SubraceTag);
|
||
|
||
if(CheckForSubrace)
|
||
{
|
||
int IsPrestigious = GetLocalGroupFlag(oPC, SubraceTag + "_" + SUBRACE_BASE_INFORMATION, SUBRACE_BASE_INFORMATION_PRESTIGIOUS_SUBRACE, SUBRACE_BASE_INFORMATION_FLAGS);
|
||
if(IsPrestigious && GetPlayerLevel(oPC) == 1)
|
||
{
|
||
SHA_SendSubraceMessageToPC(oPC, "The sub-race you had chosen was a prestigious sub-race... you cannot become part of this sub-race directly (Contact a DM for more info)!", TRUE);
|
||
check = FALSE;
|
||
SetSubRace(oPC, "");
|
||
return check;
|
||
}
|
||
if(IsPrestigious && GetPlayerLevel(oPC) > 1)
|
||
{
|
||
int checkPClass = GetLocalInt(oStorer, SubraceTag + "_" + SUBRACE_PRESTIGIOUS_CLASS_RESTRICTION);
|
||
if(checkPClass != 0)
|
||
{
|
||
if(!CheckIfPCMeetsPrestigiousClassCriteria(oPC, SubraceTag))
|
||
{
|
||
SHA_SendSubraceMessageToPC(oPC, "You have failed to meet the prestigious class restrictions!", TRUE);
|
||
SetSubRace(oPC, "");
|
||
return FALSE;
|
||
}
|
||
}
|
||
|
||
}
|
||
int checkRace = CheckIfPCMeetsBaseRaceCriteria(oPC, SubraceTag);
|
||
if(checkRace)
|
||
{
|
||
int CheckForAlignment = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_ALIGNMENT_RESTRICTION, FLAG1);
|
||
if(CheckForAlignment)
|
||
{
|
||
int checkAlign = CheckIfPCMeetsAlignmentCriteria(oPC, SubraceTag);
|
||
if(checkAlign)
|
||
{
|
||
int CheckForClass = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_CLASS_RESTRICTION, FLAG1);
|
||
if(CheckForClass)
|
||
{
|
||
int checkClass = CheckIfPCMeetsClassCriteria(oPC,SubraceTag);
|
||
if(checkClass)
|
||
{
|
||
SHA_SendSubraceMessageToPC(oPC, "You have met all the requirements for your chosen subrace!", TRUE);
|
||
check = TRUE;
|
||
}
|
||
else
|
||
{
|
||
SHA_SendSubraceMessageToPC(oPC, "You have not met the class requirements for your chosen subrace.", TRUE);
|
||
check = FALSE;
|
||
SetSubRace(oPC, "");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//NO NEED FOR CLASS CHECKING
|
||
SHA_SendSubraceMessageToPC(oPC, "You have met all the requirements for your chosen subrace!", TRUE);
|
||
check = TRUE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//FAILED ALIGNMENT CRITERIA
|
||
SHA_SendSubraceMessageToPC(oPC, "You have not met the alignment requirements for your chosen subrace.", TRUE);
|
||
check = FALSE;
|
||
SetSubRace(oPC, "");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//NO NEED FOR ALIGNMENT CHECKING
|
||
int CheckForClass = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_CLASS_RESTRICTION, FLAG1);
|
||
if(CheckForClass)
|
||
{
|
||
int checkClass = CheckIfPCMeetsClassCriteria(oPC,SubraceTag);
|
||
if(checkClass)
|
||
{
|
||
SHA_SendSubraceMessageToPC(oPC, "You have met all the requirements for your chosen subrace!", TRUE);
|
||
check = TRUE;
|
||
}
|
||
else
|
||
{
|
||
SHA_SendSubraceMessageToPC(oPC, "You have not met the class requirements for your chosen subrace.", TRUE);
|
||
check = FALSE;
|
||
SetSubRace(oPC, "");
|
||
}
|
||
|
||
}
|
||
else
|
||
{
|
||
//NO NEED FOR CLASS CHECKING
|
||
SHA_SendSubraceMessageToPC(oPC, "You have met all the requirements for your chosen subrace!", TRUE);
|
||
check = TRUE;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
SHA_SendSubraceMessageToPC(oPC, "You are not part of the base race required in order to be part of your chosen sub-race.", TRUE);
|
||
check = FALSE;
|
||
SetSubRace(oPC, "");
|
||
//FAILED BASE RACE
|
||
}
|
||
}
|
||
else
|
||
{
|
||
SHA_SendSubraceMessageToPC(oPC, "You are part of an unrecognised sub-race: " + GetSubRace(oPC), TRUE);
|
||
check = SUBRACE_UNRECOGNISED;
|
||
//FAILED TO FIND ANY SUCH SUBRACE
|
||
}
|
||
return check;
|
||
}
|
||
|
||
string GetTemporarySubraceSkin(object oPC, string SubraceTag, int iTime)
|
||
{
|
||
int Level = GetPlayerLevel(oPC);
|
||
string SkinResRef;
|
||
while(Level > 0)
|
||
{
|
||
string resref = GetLocalString(oPC, SubraceTag + "_" + SUBRACE_SKIN + "_" + IntToString(Level) + "_" + IntToString(iTime));
|
||
if(resref != "")
|
||
{
|
||
SkinResRef = resref;
|
||
break;
|
||
}
|
||
Level--;
|
||
}
|
||
return SkinResRef;
|
||
}
|
||
|
||
|
||
void EquipTemporarySubraceSkin(string subraceTag, object oPC, int iTime)
|
||
{
|
||
string oSkin = GetTemporarySubraceSkin(oPC, subraceTag, iTime);
|
||
if(oSkin == "")
|
||
{
|
||
oSkin = GetTemporarySubraceSkin(oPC, subraceTag, TIME_BOTH);
|
||
}
|
||
object ExistingSkin = GetItemInSlot(INVENTORY_SLOT_CARMOUR, oPC);
|
||
string ResrefExistingSkin = GetStringLowerCase(GetResRef(ExistingSkin));
|
||
if(ResrefExistingSkin != oSkin)
|
||
{
|
||
object NewSkin = CreateItemOnObject(oSkin, oPC);
|
||
if(GetIsObjectValid(ExistingSkin))
|
||
{
|
||
SetPlotFlag(ExistingSkin, FALSE);
|
||
DestroyObject(ExistingSkin, 0.2);
|
||
}
|
||
SetIdentified(NewSkin, TRUE);
|
||
DelayCommand(1.0, AssignCommand(oPC, SHA_SubraceForceEquipItem(NewSkin, INVENTORY_SLOT_CARMOUR)));
|
||
}
|
||
}
|
||
|
||
string GetTemporarySubraceClaw(object oPC, string subraceTag, string Claw, int iTime)
|
||
{
|
||
int Level = GetPlayerLevel(oPC);
|
||
string ClawResRef = "";
|
||
while(Level > 0)
|
||
{
|
||
string resref = GetLocalString(oPC, subraceTag + "_" + Claw + "_" + IntToString(Level) + "_" + IntToString(iTime));
|
||
if(resref != "")
|
||
{
|
||
ClawResRef = resref;
|
||
break;
|
||
}
|
||
Level--;
|
||
}
|
||
return ClawResRef;
|
||
}
|
||
|
||
|
||
void EquipTemporarySubraceClaw(string subraceTag, object oPC, int iTime)
|
||
{
|
||
string sLeftClaw = GetTemporarySubraceClaw(oPC, subraceTag, SUBRACE_LEFT_CLAW, iTime);
|
||
string sRightClaw = GetTemporarySubraceClaw(oPC, subraceTag, SUBRACE_RIGHT_CLAW, iTime);
|
||
|
||
if(sLeftClaw == "")
|
||
{
|
||
sLeftClaw = GetTemporarySubraceClaw(oPC, subraceTag, SUBRACE_LEFT_CLAW, TIME_BOTH);
|
||
}
|
||
if(sRightClaw == "")
|
||
{
|
||
sRightClaw = GetTemporarySubraceClaw(oPC, subraceTag, SUBRACE_RIGHT_CLAW, TIME_BOTH);
|
||
}
|
||
object ExistingLeftClaw = GetItemInSlot(INVENTORY_SLOT_CWEAPON_L, oPC);
|
||
object ExistingRightClaw = GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oPC);
|
||
string ResrefExistingLClaw = GetStringLowerCase(GetResRef(ExistingLeftClaw));
|
||
string ResrefExistingRClaw = GetStringLowerCase(GetResRef(ExistingRightClaw));
|
||
if((ResrefExistingRClaw != sRightClaw) || (ResrefExistingLClaw != sLeftClaw))
|
||
{
|
||
SHA_SendSubraceMessageToPC(oPC, "Please wait... while your sub-racial claws are checked and equipped or unequipped.", FALSE);
|
||
if(!GetHasFeat(FEAT_WEAPON_PROFICIENCY_CREATURE, oPC))
|
||
{
|
||
SHA_SendSubraceMessageToPC(oPC, "You do not have creature weapon proficiency... yet your subrace wants to equip a creature claw. Inform a DM!", TRUE);
|
||
return;
|
||
}
|
||
DelayCommand(9.0, SHA_SendSubraceMessageToPC(oPC, "Your new sub-racial claws should have now been properly equipped or unequipped.", FALSE));
|
||
}
|
||
if(ResrefExistingRClaw != sRightClaw)
|
||
{
|
||
object NewRClaw = CreateItemOnObject(sRightClaw, oPC);
|
||
if(sRightClaw == "none" || GetIsObjectValid(ExistingRightClaw))
|
||
{
|
||
SetPlotFlag(ExistingRightClaw, FALSE);
|
||
DestroyObject(ExistingRightClaw, 0.2);
|
||
}
|
||
SetIdentified(NewRClaw, TRUE);
|
||
DelayCommand(1.0, AssignCommand(oPC, SHA_SubraceForceEquipItem(NewRClaw, INVENTORY_SLOT_CWEAPON_R)));
|
||
}
|
||
if(ResrefExistingLClaw != sLeftClaw)
|
||
{
|
||
object NewLClaw = CreateItemOnObject(sLeftClaw, oPC);
|
||
if(sLeftClaw == "none" || GetIsObjectValid(ExistingLeftClaw))
|
||
{
|
||
SetPlotFlag(ExistingLeftClaw, FALSE);
|
||
DestroyObject(ExistingLeftClaw, 0.3);
|
||
}
|
||
SetIdentified(NewLClaw, TRUE);
|
||
DelayCommand(5.0, AssignCommand(oPC, SHA_SubraceForceEquipItem(NewLClaw, INVENTORY_SLOT_CWEAPON_L)));
|
||
}
|
||
}
|
||
|
||
void SearchAndDestroySkinsAndClaws(object oPC)
|
||
{
|
||
object oItem = GetFirstItemInInventory(oPC);
|
||
while(GetIsObjectValid(oItem))
|
||
{
|
||
int iType = GetBaseItemType(oItem);
|
||
if(iType == BASE_ITEM_CREATUREITEM || iType == BASE_ITEM_CPIERCWEAPON || iType == BASE_ITEM_CSLASHWEAPON || iType == BASE_ITEM_CSLSHPRCWEAP)
|
||
{
|
||
SetPlotFlag(oItem, FALSE);
|
||
DestroyObject(oItem, 0.1);
|
||
}
|
||
oItem = GetNextItemInInventory(oPC);
|
||
}
|
||
|
||
|
||
}
|
||
|
||
void GiveSubraceUniqueItem(string SubraceTag, object oPC)
|
||
{
|
||
int SubraceUniqueItemCount = GetLocalInt(oStorer, SubraceTag + "_" + SUBRACE_UNIQUEITEM_COUNT);
|
||
int i = 0;
|
||
while(i <= SubraceUniqueItemCount)
|
||
{
|
||
i++;
|
||
string resref = GetLocalString(oStorer, SubraceTag + "_" + SUBRACE_UNIQUEITEM + "_" + IntToString(i));
|
||
if(resref != "")
|
||
{
|
||
string sLevel = GetStringRight(resref, 2);
|
||
if(GetStringLeft(sLevel, 1) == "_")
|
||
{
|
||
sLevel = GetStringRight(sLevel, 1);
|
||
}
|
||
int iLevel = StringToInt(sLevel);
|
||
resref = GetStringLeft(resref, GetStringLength(resref) - 2);
|
||
if(iLevel <= GetPlayerLevel(oPC))
|
||
{
|
||
object oItem = GetFirstItemInInventory(oPC);
|
||
int HasUniqueItem = FALSE;
|
||
while(GetIsObjectValid(oItem))
|
||
{
|
||
if(GetResRef(oItem) == resref)
|
||
{
|
||
HasUniqueItem = TRUE;
|
||
break;
|
||
}
|
||
oItem = GetNextItemInInventory(oPC);
|
||
}
|
||
if(!HasUniqueItem)
|
||
{
|
||
object oItem = CreateItemOnObject(resref, oPC, 1);
|
||
SHA_SendSubraceMessageToPC(oPC, "You have acquired <c<>)>" + GetName(oItem) + "</c>; a sub-racial item.", FALSE);
|
||
SetIdentified(oItem, TRUE);
|
||
SetPlotFlag(oItem, TRUE);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void CheckAndGiveSubraceItems(object oPC)
|
||
{
|
||
string subrace = GetSubRace(oPC);
|
||
string SubraceTag = SUBRACE_TAG + "_" + GetStringLowerCase(subrace);
|
||
GiveSubraceUniqueItem(SubraceTag, oPC);
|
||
}
|
||
int SHA_GetDefaultAppearanceType(object oPC)
|
||
{
|
||
int iRace = GetRacialType(oPC);
|
||
int DefaultAppearance;
|
||
switch(iRace)
|
||
{
|
||
case RACIAL_TYPE_DWARF: DefaultAppearance = APPEARANCE_TYPE_DWARF; break;
|
||
case RACIAL_TYPE_ELF: DefaultAppearance = APPEARANCE_TYPE_ELF; break;
|
||
case RACIAL_TYPE_GNOME: DefaultAppearance = APPEARANCE_TYPE_GNOME; break;
|
||
case RACIAL_TYPE_HALFELF: DefaultAppearance = APPEARANCE_TYPE_HALF_ELF; break;
|
||
case RACIAL_TYPE_HALFLING: DefaultAppearance = APPEARANCE_TYPE_HALFLING; break;
|
||
case RACIAL_TYPE_HALFORC: DefaultAppearance = APPEARANCE_TYPE_HALF_ORC; break;
|
||
case RACIAL_TYPE_HUMAN: DefaultAppearance = APPEARANCE_TYPE_HUMAN; break;
|
||
default: DefaultAppearance = APPEARANCE_TYPE_HUMAN; break;
|
||
}
|
||
return DefaultAppearance;
|
||
}
|
||
|
||
int Subrace_GetFavouredClass(object oPC)
|
||
{
|
||
int iClass = -1;
|
||
|
||
if(GetLocalInt(oPC, SUBRACE_FAVORED_CLASS) != 0)
|
||
{
|
||
iClass = GetLocalInt(oPC, SUBRACE_FAVORED_CLASS) - 1;
|
||
}
|
||
return iClass;
|
||
}
|
||
|
||
int GetRacialFavoredClass(int Race)
|
||
{
|
||
int Class = CLASS_TYPE_NONE;
|
||
switch(Race)
|
||
{
|
||
case RACIAL_TYPE_DWARF: Class = CLASS_TYPE_FIGHTER; break;
|
||
case RACIAL_TYPE_HUMAN: Class = CLASS_TYPE_ANY; break;
|
||
case RACIAL_TYPE_ELF: Class = CLASS_TYPE_WIZARD; break;
|
||
case RACIAL_TYPE_GNOME: Class = CLASS_TYPE_WIZARD; break;
|
||
case RACIAL_TYPE_HALFELF: Class = CLASS_TYPE_ANY; break;
|
||
case RACIAL_TYPE_HALFORC: Class = CLASS_TYPE_BARBARIAN; break;
|
||
case RACIAL_TYPE_HALFLING: Class = CLASS_TYPE_ROGUE; break;
|
||
}
|
||
return Class;
|
||
}
|
||
|
||
int GetFavoredClassExceedsGap(int Race1Favored, int Race2Favored, int Class1, int Class2, int Class3, int Class13Gap, int Class23Gap, int Class12Gap)
|
||
{
|
||
//Has PC got Race 1 Favored class?
|
||
int iR1Class1Favored = FALSE;
|
||
int iR1Class2Favored = FALSE;
|
||
int iR1Class3Favored = FALSE;
|
||
|
||
//Has PC got Race 2 Favored class?
|
||
int iR2Class1Favored = FALSE;
|
||
int iR2Class2Favored = FALSE;
|
||
int iR2Class3Favored = FALSE;
|
||
|
||
if(Race1Favored == Class1)
|
||
{
|
||
iR1Class1Favored = TRUE;
|
||
}
|
||
if(Race1Favored == Class2 && Class2 != CLASS_TYPE_INVALID)
|
||
{
|
||
iR1Class2Favored = TRUE;
|
||
}
|
||
if(Race1Favored == Class3 && Class3 != CLASS_TYPE_INVALID)
|
||
{
|
||
iR1Class3Favored = TRUE;
|
||
}
|
||
|
||
if(Race2Favored == Class1)
|
||
{
|
||
iR2Class1Favored = TRUE;
|
||
}
|
||
if(Race2Favored == Class2 && Class2 != CLASS_TYPE_INVALID)
|
||
{
|
||
iR2Class2Favored = TRUE;
|
||
}
|
||
if(Race2Favored == Class3 && Class3 != CLASS_TYPE_INVALID)
|
||
{
|
||
iR2Class3Favored = TRUE;
|
||
}
|
||
|
||
int Exceed12 = FALSE;
|
||
int Exceed13 = FALSE;
|
||
int Exceed23 = FALSE;
|
||
|
||
int iResult12 = FALSE;
|
||
int iResult13 = FALSE;
|
||
int iResult23 = FALSE;
|
||
|
||
if(abs(Class12Gap) >=2)
|
||
{
|
||
Exceed12 = TRUE;
|
||
}
|
||
else if(abs(Class13Gap) >=2)
|
||
{
|
||
Exceed13 = TRUE;
|
||
}
|
||
else if(abs(Class23Gap) >=2)
|
||
{
|
||
Exceed23 = TRUE;
|
||
}
|
||
|
||
if(Exceed12)
|
||
{
|
||
if(iR1Class1Favored || iR1Class2Favored)
|
||
{
|
||
iResult12 = TRUE;
|
||
if((iR2Class1Favored && Class3 != CLASS_TYPE_INVALID) || (iR2Class2Favored && Class3 != CLASS_TYPE_INVALID))
|
||
{
|
||
iResult12 = FALSE;
|
||
}
|
||
}
|
||
}
|
||
if(Exceed13)
|
||
{
|
||
if(iR1Class1Favored || iR1Class3Favored)
|
||
{
|
||
iResult13 = TRUE;
|
||
if(iR2Class1Favored ||iR2Class3Favored)
|
||
{
|
||
iResult13 = FALSE;
|
||
}
|
||
}
|
||
}
|
||
if(Exceed23)
|
||
{
|
||
if(iR1Class2Favored || iR1Class3Favored)
|
||
{
|
||
iResult23 = TRUE;
|
||
if(iR2Class2Favored ||iR2Class3Favored)
|
||
{
|
||
iResult23 = FALSE;
|
||
}
|
||
}
|
||
}
|
||
|
||
if(iResult12 || iResult13 || iResult23)
|
||
{
|
||
return TRUE;
|
||
}
|
||
else
|
||
{
|
||
return FALSE;
|
||
}
|
||
}
|
||
|
||
int XPPenaltyOrBoostForSubrace(object oPC, int FClass)
|
||
{
|
||
int iRace = GetRacialType(oPC);
|
||
int iRFavored = GetRacialFavoredClass(iRace);
|
||
|
||
int iSFavored = FClass;
|
||
if(iSFavored == iRFavored)
|
||
{
|
||
return SUBRACE_XP_UNCHANGED;
|
||
}
|
||
|
||
int Class1 = GetClassByPosition(1, oPC);
|
||
int Class2 = GetClassByPosition(2, oPC);
|
||
int Class3 = GetClassByPosition(3, oPC);
|
||
|
||
int Class1Level = GetLevelByClass(Class1, oPC);
|
||
int Class2Level = GetLevelByClass(Class2, oPC);
|
||
int Class3Level = GetLevelByClass(Class3, oPC);
|
||
|
||
if(iRFavored == CLASS_TYPE_ANY)
|
||
{
|
||
int Max1 = Max(Class1Level, Class2Level);
|
||
int Max2 = Max(Max1, Class3Level);
|
||
|
||
if(Max2 == Class1Level)
|
||
{
|
||
iRFavored = Class1;
|
||
}
|
||
else if(Max2 == Class2Level)
|
||
{
|
||
iRFavored = Class2;
|
||
}
|
||
else if(Max2 == Class3Level)
|
||
{
|
||
iRFavored = Class3;
|
||
}
|
||
}
|
||
|
||
if(iSFavored == CLASS_TYPE_ANY)
|
||
{
|
||
int Max1 = Max(Class1Level, Class2Level);
|
||
int Max2 = Max(Max1, Class3Level);
|
||
|
||
if(Max2 == Class1Level)
|
||
{
|
||
iSFavored = Class1;
|
||
}
|
||
else if(Max2 == Class2Level)
|
||
{
|
||
iSFavored = Class2;
|
||
}
|
||
else if(Max2 == Class3Level)
|
||
{
|
||
iSFavored = Class3;
|
||
}
|
||
}
|
||
|
||
int Class12Gap = Class1Level - Class2Level;
|
||
int Class13Gap = Class1Level - Class3Level;
|
||
int Class23Gap = Class2Level - Class3Level;
|
||
|
||
if(Class2Level == 0)
|
||
{
|
||
Class12Gap = 0;
|
||
Class23Gap = 0;
|
||
}
|
||
if(Class3Level == 0)
|
||
{
|
||
Class13Gap = 0;
|
||
}
|
||
int SubraceFClassExcGap = FALSE;
|
||
int RacialFClassExcGap = FALSE;
|
||
|
||
if(SUBRACE_IGNORE_BASE_RACE_FAVORED_CLASS)
|
||
{
|
||
RacialFClassExcGap = GetFavoredClassExceedsGap(iRFavored, iSFavored, Class1, Class2, Class3, Class13Gap, Class23Gap, Class12Gap);
|
||
}
|
||
|
||
SubraceFClassExcGap = GetFavoredClassExceedsGap(iSFavored, iRFavored, Class1, Class2, Class3, Class13Gap, Class23Gap, Class12Gap);
|
||
//Racial Favored Class Exceeds the Multiclass Level gap, and Subrace Favored class does not
|
||
//So give a decrease in XP to counter NWN engine XP distribution.
|
||
if(RacialFClassExcGap && !SubraceFClassExcGap)
|
||
{
|
||
return SUBRACE_XP_DECREASE;
|
||
}
|
||
//Subrace Favored Class Exceeds the Multiclass Level gap, and Racial Favored class does not
|
||
//So give a boost in XP to override the NWN engine XP distribution.
|
||
else if(!RacialFClassExcGap && SubraceFClassExcGap)
|
||
{
|
||
return SUBRACE_XP_BOOST;
|
||
}
|
||
//Both exceed the Multiclass Level gap or do not.
|
||
//So since the effects of both exceeding cancel each other out, return normal XP.
|
||
return SUBRACE_XP_UNCHANGED;
|
||
}
|
||
|
||
float GetSubraceXPModifier(object oPC)
|
||
{
|
||
int FClass = Subrace_GetFavouredClass(oPC);
|
||
float iMod = 1.0;
|
||
if(FClass != -1)
|
||
{
|
||
int XPMod = XPPenaltyOrBoostForSubrace(oPC, FClass);
|
||
|
||
if(XPMod == SUBRACE_XP_BOOST)
|
||
{
|
||
iMod = 1.25;
|
||
}
|
||
else if(XPMod == SUBRACE_XP_DECREASE)
|
||
{
|
||
iMod = 0.8;
|
||
}
|
||
else if(XPMod == SUBRACE_XP_UNCHANGED)
|
||
{ }
|
||
}
|
||
return iMod;
|
||
|
||
}
|
||
|
||
int GetECL(object oPC)
|
||
{
|
||
string SubraceTag = SUBRACE_TAG + "_" + GetStringLowerCase(GetSubRace(oPC));
|
||
return GetLocalGroupFlagValue(oPC, SubraceTag + "_" + SUBRACE_BASE_INFORMATION, SUBRACE_BASE_INFORMATION_ECL);
|
||
}
|
||
|
||
int Subrace_GetIsUndead(object oTarget)
|
||
{
|
||
if(!GetIsPC(oTarget))
|
||
{
|
||
return FALSE;
|
||
}
|
||
string subraceName = GetStringLowerCase(GetSubRace(oTarget));
|
||
|
||
if(subraceName == "")
|
||
{ return FALSE; }
|
||
string SubraceTag = SUBRACE_TAG + "_" + subraceName;
|
||
int IsUndead = GetLocalGroupFlag(oTarget, SubraceTag + "_" + SUBRACE_BASE_INFORMATION, SUBRACE_BASE_INFORMATION_UNDEAD, SUBRACE_BASE_INFORMATION_FLAGS);
|
||
return IsUndead;
|
||
|
||
}
|
||
void ApplyUniqueSubraceEffect(object oPC, string SubraceTag, int iEffect)
|
||
{
|
||
if(iEffect == 0)
|
||
{ return; }
|
||
int Value1 = GetLocalInt(oPC, SubraceTag + "_" + SUBRACE_EFFECT_VALUE_1);
|
||
int Value2 = GetLocalInt(oPC, SubraceTag + "_" + SUBRACE_EFFECT_VALUE_2);
|
||
int DurationType = GetLocalInt(oPC, SubraceTag + "_" + SUBRACE_EFFECT_DURATION_TYPE);
|
||
float fDuration = GetLocalFloat(oPC, SubraceTag + "_" + SUBRACE_EFFECT_DURATION);
|
||
|
||
effect eEffect = SHA_GetEffectFromID(iEffect, Value1, Value2);
|
||
effect eEffectApp = SupernaturalEffect(eEffect);
|
||
ApplyEffectToObject(DurationType, eEffectApp, oPC, fDuration);
|
||
}
|
||
void ApplySubraceEffect(object oPC, string SubraceTag, int TimeOfDay)
|
||
{
|
||
int EffectCount = GetLocalInt(oPC, SubraceTag + "_" + SUBRACE_EFFECT_COUNT);
|
||
if(EffectCount == 0)
|
||
{
|
||
return;
|
||
}
|
||
|
||
ClearSubraceEffects(oPC);
|
||
int i = 0;
|
||
while(i != EffectCount)
|
||
{
|
||
i++;
|
||
string SubraceTag1 = SubraceTag + IntToString(i);
|
||
int Effect = GetLocalInt(oPC, SubraceTag1 + "_" + SUBRACE_EFFECT);
|
||
int EffectTimeOfDay = GetLocalInt(oPC, SubraceTag1 + "_" + SUBRACE_EFFECT_APPLY_TIME);
|
||
if(EffectTimeOfDay == TIME_BOTH || EffectTimeOfDay == TimeOfDay)
|
||
{
|
||
ApplyUniqueSubraceEffect(oPC, SubraceTag1, Effect);
|
||
}
|
||
}
|
||
SHA_SendSubraceMessageToPC(oPC, "Sub-racial effects have been appiled", FALSE);
|
||
}
|
||
|
||
|
||
|
||
void LoadSubraceInfoOnPC(object oPC, string subraceName)
|
||
{
|
||
if(GetLocalInt(oPC, SUBRACE_INFO_LOADED_ON_PC))
|
||
{
|
||
ReapplySubraceAbilities(oPC);
|
||
return;
|
||
}
|
||
if(subraceName == "")
|
||
{ return; }
|
||
string SubraceTag = SUBRACE_TAG + "_" + subraceName;
|
||
|
||
//Oh oh, someone has removed the subrace! >.<
|
||
if(!GetLocalInt(oStorer, SubraceTag))
|
||
{
|
||
SHA_SendSubraceMessageToPC(oPC, "Data for your sub-race is missing or support for your sub-race has been removed from the server! Contact a DM", TRUE);
|
||
return;
|
||
}
|
||
SHA_SendSubraceMessageToPC(oPC, "Loading your sub-race; " + CapitalizeString(subraceName) + "'s data...", FALSE);
|
||
//Load all skin resrefs
|
||
int Level = 1;
|
||
while(Level <= MAXIMUM_PLAYER_LEVEL)
|
||
{
|
||
string resref = GetLocalString(oStorer, SubraceTag + "_" + SUBRACE_SKIN + "_" + IntToString(Level) + "_" + IntToString(TIME_BOTH));
|
||
if(resref != "")
|
||
{
|
||
SetLocalString(oPC, SubraceTag + "_" + SUBRACE_SKIN + "_" + IntToString(Level) + "_" + IntToString(TIME_BOTH), resref);
|
||
}
|
||
//and the temporary skins
|
||
resref = GetLocalString(oStorer, SubraceTag + "_" + SUBRACE_SKIN + "_" + IntToString(Level) + "_" + IntToString(TIME_DAY));
|
||
if(resref != "")
|
||
{
|
||
SetLocalString(oPC, SubraceTag + "_" + SUBRACE_SKIN + "_" + IntToString(Level) + "_" + IntToString(TIME_DAY), resref);
|
||
}
|
||
resref = GetLocalString(oStorer, SubraceTag + "_" + SUBRACE_SKIN + "_" + IntToString(Level) + "_" + IntToString(TIME_NIGHT));
|
||
if(resref != "")
|
||
{
|
||
SetLocalString(oPC, SubraceTag + "_" + SUBRACE_SKIN + "_" + IntToString(Level) + "_" + IntToString(TIME_NIGHT), resref);
|
||
}
|
||
string switchSubraceName = GetLocalString(oStorer, SubraceTag + "_" + SUBRACE_SWITCH_NAME + IntToString(Level));
|
||
if(switchSubraceName != "")
|
||
{
|
||
SetLocalString(oPC, SubraceTag + "_" + SUBRACE_SWITCH_NAME + IntToString(Level), switchSubraceName);
|
||
int requirements = GetLocalInt(oStorer, SubraceTag + "_" + SUBRACE_SWITCH_MUST_MEET_REQUIREMENTS + IntToString(Level));
|
||
if(requirements)
|
||
{
|
||
SetLocalInt(oPC, SubraceTag + "_" + SUBRACE_SWITCH_MUST_MEET_REQUIREMENTS + IntToString(Level), requirements);
|
||
}
|
||
}
|
||
Level++;
|
||
}
|
||
|
||
//Load all creature claws.
|
||
Level = 1;
|
||
while(Level <= MAXIMUM_PLAYER_LEVEL)
|
||
{
|
||
string resref = GetLocalString(oStorer, SubraceTag + "_" + SUBRACE_LEFT_CLAW + "_" + IntToString(Level) + "_" + IntToString(TIME_BOTH));
|
||
if(resref != "")
|
||
{
|
||
SetLocalString(oPC, SubraceTag + "_" + SUBRACE_LEFT_CLAW + "_" + IntToString(Level) + "_" + IntToString(TIME_BOTH), resref);
|
||
}
|
||
resref = GetLocalString(oStorer, SubraceTag + "_" + SUBRACE_RIGHT_CLAW + "_" + IntToString(Level) + "_" + IntToString(TIME_BOTH));
|
||
if(resref != "")
|
||
{
|
||
SetLocalString(oPC, SubraceTag + "_" + SUBRACE_RIGHT_CLAW + "_" + IntToString(Level) + "_" + IntToString(TIME_BOTH), resref);
|
||
}
|
||
|
||
resref = GetLocalString(oStorer, SubraceTag + "_" + SUBRACE_LEFT_CLAW + "_" + IntToString(Level) + "_" + IntToString(TIME_DAY));
|
||
if(resref != "")
|
||
{
|
||
SetLocalString(oPC, SubraceTag + "_" + SUBRACE_LEFT_CLAW + "_" + IntToString(Level) + "_" + IntToString(TIME_DAY), resref);
|
||
}
|
||
resref = GetLocalString(oStorer, SubraceTag + "_" + SUBRACE_RIGHT_CLAW + "_" + IntToString(Level) + "_" + IntToString(TIME_DAY));
|
||
if(resref != "")
|
||
{
|
||
SetLocalString(oPC, SubraceTag + "_" + SUBRACE_RIGHT_CLAW + "_" + IntToString(Level) + "_" + IntToString(TIME_DAY), resref);
|
||
}
|
||
|
||
resref = GetLocalString(oStorer, SubraceTag + "_" + SUBRACE_LEFT_CLAW + "_" + IntToString(Level) + "_" + IntToString(TIME_NIGHT));
|
||
if(resref != "")
|
||
{
|
||
SetLocalString(oPC, SubraceTag + "_" + SUBRACE_LEFT_CLAW + "_" + IntToString(Level) + "_" + IntToString(TIME_NIGHT), resref);
|
||
}
|
||
resref = GetLocalString(oStorer, SubraceTag + "_" + SUBRACE_RIGHT_CLAW + "_" + IntToString(Level) + "_" + IntToString(TIME_NIGHT));
|
||
if(resref != "")
|
||
{
|
||
SetLocalString(oPC, SubraceTag + "_" + SUBRACE_RIGHT_CLAW + "_" + IntToString(Level) + "_" + IntToString(TIME_NIGHT), resref);
|
||
}
|
||
|
||
Level++;
|
||
}
|
||
|
||
|
||
int iDmgTakenInLight = GetLocalInt(oStorer, SubraceTag + "_" + DAMAGE_AMOUNT_IN_LIGHT);
|
||
int iDmgTakenInUnder = GetLocalInt(oStorer, SubraceTag + "_" + DAMAGE_AMOUNT_IN_UNDERGROUND);
|
||
|
||
SetLocalString(oPC, SUBRACE_TAG, subraceName);
|
||
|
||
int BaseFlags = GetLocalGroupFlagValue(oStorer, SubraceTag + "_" + SUBRACE_BASE_INFORMATION, SUBRACE_BASE_INFORMATION_FLAGS);
|
||
SetLocalGroupFlagValue(oPC, SubraceTag + "_" + SUBRACE_BASE_INFORMATION, BaseFlags, SUBRACE_BASE_INFORMATION_FLAGS);
|
||
|
||
if(iDmgTakenInLight != 0)
|
||
{
|
||
SetLocalInt(oPC, SubraceTag + "_" + DAMAGE_AMOUNT_IN_LIGHT, iDmgTakenInLight);
|
||
}
|
||
|
||
if(iDmgTakenInUnder != 0)
|
||
{
|
||
SetLocalInt(oPC, SubraceTag + "_" + DAMAGE_AMOUNT_IN_UNDERGROUND, iDmgTakenInUnder);
|
||
}
|
||
|
||
|
||
|
||
|
||
Level = 1;
|
||
while(Level <=40)
|
||
{
|
||
string SubraceTag1 = SubraceTag + "_" + IntToString(Level);
|
||
if(GetLocalInt(oStorer, SubraceTag1 + "_" + APPEARANCE_CHANGE) != 0)
|
||
{
|
||
int iTime = GetLocalGroupFlagValue(oStorer, SubraceTag1 + "_" + APPEARANCE_CHANGE,TIME_FLAGS);
|
||
int MaleAppearance = GetLocalGroupFlagValue(oStorer, SubraceTag1 + "_" + APPEARANCE_CHANGE, APPEARANCE_CHANGE_MALE_FLAG);
|
||
int FemaleAppearance = GetLocalGroupFlagValue(oStorer, SubraceTag1 + "_" + APPEARANCE_CHANGE, APPEARANCE_CHANGE_FEMALE_FLAG);
|
||
if(iTime != 0 && (MaleAppearance != 0 || FemaleAppearance !=0))
|
||
{
|
||
SetLocalGroupFlagValue(oPC, SubraceTag1 + "_" + APPEARANCE_CHANGE, iTime ,TIME_FLAGS);
|
||
if(GetGender(oPC) == GENDER_MALE)
|
||
{
|
||
SetLocalGroupFlagValue(oPC, SubraceTag1 + "_" + APPEARANCE_CHANGE,MaleAppearance, APPEARANCE_CHANGE_APPEARANCE_FLAG);
|
||
}
|
||
else
|
||
{
|
||
SetLocalGroupFlagValue(oPC, SubraceTag1 + "_" + APPEARANCE_CHANGE,FemaleAppearance, APPEARANCE_CHANGE_APPEARANCE_FLAG);
|
||
}
|
||
}
|
||
}
|
||
Level++;
|
||
}
|
||
SubraceTag = SUBRACE_TAG + "_" + subraceName;
|
||
|
||
|
||
int HasDiffStats = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG1);
|
||
SetLocalFlag(oPC, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG1, HasDiffStats);
|
||
if(HasDiffStats)
|
||
{
|
||
//day
|
||
int iTime = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG2);
|
||
SetLocalFlag(oPC, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG2, iTime);
|
||
|
||
if(iTime)
|
||
{
|
||
SubraceTag = SubraceTag + IntToString(TIME_DAY);
|
||
|
||
int ModType = GetLocalInt(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIER_TYPE);
|
||
|
||
int AreaInt = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG4);
|
||
SetLocalFlag(oPC, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG4, AreaInt);
|
||
int AreaExt = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG5);
|
||
SetLocalFlag(oPC, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG5, AreaExt);
|
||
|
||
int AreaUnd = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG9);
|
||
SetLocalFlag(oPC, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG9, AreaUnd);
|
||
int AreaAbove = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG8);
|
||
SetLocalFlag(oPC, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG8, AreaAbove);
|
||
|
||
int AreaArt = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG6);
|
||
SetLocalFlag(oPC, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG6, AreaArt);
|
||
int AreaNat = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG7);
|
||
SetLocalFlag(oPC, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG7, AreaNat);
|
||
|
||
float StrengthModifier = GetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_STR_MODIFIER);
|
||
float DexterityModifier = GetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_DEX_MODIFIER);
|
||
float ConstitutionModifier = GetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_CON_MODIFIER);
|
||
float WisdomModifier = GetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_WIS_MODIFIER);
|
||
float IntelligenceModifier = GetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_INT_MODIFIER);
|
||
float CharismaModifier = GetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_CHA_MODIFIER);
|
||
|
||
float ABModifier = GetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_AB_MODIFIER);
|
||
float ACModifier = GetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_AC_MODIFIER);
|
||
|
||
SetLocalInt(oPC, SubraceTag + "_" + SUBRACE_STAT_MODIFIER_TYPE, ModType);
|
||
|
||
SetLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_STR_MODIFIER, StrengthModifier);
|
||
SetLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_DEX_MODIFIER, DexterityModifier);
|
||
SetLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_CON_MODIFIER, ConstitutionModifier);
|
||
SetLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_WIS_MODIFIER, WisdomModifier);
|
||
SetLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_INT_MODIFIER, IntelligenceModifier);
|
||
SetLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_CHA_MODIFIER, CharismaModifier);
|
||
|
||
SetLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_AB_MODIFIER, ABModifier);
|
||
SetLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_AC_MODIFIER, ACModifier);
|
||
}
|
||
|
||
SubraceTag = SUBRACE_TAG + "_" + subraceName;
|
||
//night
|
||
iTime = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG3);
|
||
SetLocalFlag(oPC, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG3, iTime);
|
||
if(iTime)
|
||
{
|
||
|
||
SubraceTag = SubraceTag + IntToString(TIME_NIGHT);
|
||
|
||
|
||
int AreaInt = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG4);
|
||
SetLocalFlag(oPC, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG4, AreaInt);
|
||
int AreaExt = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG5);
|
||
SetLocalFlag(oPC, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG5, AreaExt);
|
||
|
||
int AreaUnd = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG9);
|
||
SetLocalFlag(oPC, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG9, AreaUnd);
|
||
int AreaAbove = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG8);
|
||
SetLocalFlag(oPC, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG8, AreaAbove);
|
||
|
||
int AreaArt = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG6);
|
||
SetLocalFlag(oPC, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG6, AreaArt);
|
||
int AreaNat = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG7);
|
||
SetLocalFlag(oPC, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG7, AreaNat);
|
||
|
||
|
||
float StrengthModifier = GetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_STR_MODIFIER);
|
||
float DexterityModifier = GetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_DEX_MODIFIER);
|
||
float ConstitutionModifier = GetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_CON_MODIFIER);
|
||
float WisdomModifier = GetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_WIS_MODIFIER);
|
||
float IntelligenceModifier = GetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_INT_MODIFIER);
|
||
float CharismaModifier = GetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_CHA_MODIFIER);
|
||
|
||
float ABModifier = GetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_AB_MODIFIER);
|
||
float ACModifier = GetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_AC_MODIFIER);
|
||
int ModType = GetLocalInt(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIER_TYPE);
|
||
SetLocalInt(oPC, SubraceTag + "_" + SUBRACE_STAT_MODIFIER_TYPE, ModType);
|
||
|
||
SetLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_STR_MODIFIER, StrengthModifier);
|
||
SetLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_DEX_MODIFIER, DexterityModifier);
|
||
SetLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_CON_MODIFIER, ConstitutionModifier);
|
||
SetLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_WIS_MODIFIER, WisdomModifier);
|
||
SetLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_INT_MODIFIER, IntelligenceModifier);
|
||
SetLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_CHA_MODIFIER, CharismaModifier);
|
||
|
||
SetLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_AB_MODIFIER, ABModifier);
|
||
SetLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_AC_MODIFIER, ACModifier);
|
||
}
|
||
|
||
}
|
||
SubraceTag = SUBRACE_TAG + "_" + subraceName;
|
||
|
||
int HasRes = GetLocalGroupFlag(oStorer, SubraceTag + "_" + SUBRACE_WEAPON_RESTRICTION, SUBRACE_HAS_RESTRICTION, SUBRACE_RESTRICTION_FLAGS);
|
||
|
||
if(HasRes)
|
||
{
|
||
int WepResData = GetLocalInt(oStorer, SubraceTag + "_" + SUBRACE_WEAPON_RESTRICTION);
|
||
SetLocalInt(oPC, SubraceTag + "_" + SUBRACE_WEAPON_RESTRICTION, WepResData);
|
||
}
|
||
|
||
HasRes = GetLocalGroupFlag(oStorer, SubraceTag + "_" + SUBRACE_ARMOUR_RESTRICTION, SUBRACE_HAS_RESTRICTION, SUBRACE_RESTRICTION_FLAGS);
|
||
if(HasRes)
|
||
{
|
||
int DefResData = GetLocalInt(oStorer, SubraceTag + "_" + SUBRACE_ARMOUR_RESTRICTION);
|
||
SetLocalInt(oPC, SubraceTag + "_" + SUBRACE_ARMOUR_RESTRICTION, DefResData);
|
||
}
|
||
|
||
int Count = GetLocalInt(oStorer, SubraceTag + "_" + SUBRACE_EFFECT_COUNT);
|
||
if(Count != 0 )
|
||
{
|
||
SetLocalInt(oPC, SubraceTag + "_" + SUBRACE_EFFECT_COUNT, Count);
|
||
int i = 0;
|
||
while(i != Count)
|
||
{
|
||
i++;
|
||
string SubraceTag1 = SubraceTag + IntToString(i);
|
||
int Effect = GetLocalInt(oStorer, SubraceTag1 + "_" + SUBRACE_EFFECT);
|
||
int Value1 = GetLocalInt(oStorer, SubraceTag1 + "_" + SUBRACE_EFFECT_VALUE_1);
|
||
int Value2 = GetLocalInt(oStorer, SubraceTag1 + "_" + SUBRACE_EFFECT_VALUE_2);
|
||
int TimeOfDay = GetLocalInt(oStorer, SubraceTag1 + "_" + SUBRACE_EFFECT_APPLY_TIME);
|
||
int DurationType = GetLocalInt(oStorer, SubraceTag1 + "_" + SUBRACE_EFFECT_DURATION_TYPE);
|
||
float fDuration = GetLocalFloat(oStorer, SubraceTag1 + "_" + SUBRACE_EFFECT_DURATION);
|
||
SetLocalInt(oPC, SubraceTag1 + "_" + SUBRACE_EFFECT, Effect);
|
||
SetLocalInt(oPC, SubraceTag1 + "_" + SUBRACE_EFFECT_VALUE_1, Value1);
|
||
SetLocalInt(oPC, SubraceTag1 + "_" + SUBRACE_EFFECT_VALUE_2, Value2);
|
||
SetLocalInt(oPC, SubraceTag1 + "_" + SUBRACE_EFFECT_DURATION_TYPE, DurationType);
|
||
SetLocalInt(oPC, SubraceTag1 + "_" + SUBRACE_EFFECT_APPLY_TIME, TimeOfDay);
|
||
SetLocalFloat(oPC, SubraceTag1 + "_" + SUBRACE_EFFECT_DURATION, fDuration);
|
||
}
|
||
}
|
||
int HasFClass = GetLocalInt(oStorer, SubraceTag + "_" + SUBRACE_FAVORED_CLASS);
|
||
|
||
if(HasFClass != 0)
|
||
{
|
||
int MaleFavoredClass = GetLocalGroupFlagValue(oStorer, SubraceTag + "_" + SUBRACE_FAVORED_CLASS, SUBRACE_FAVORED_CLASS_MALE_FLAG);
|
||
int FemaleFavoredClass = GetLocalGroupFlagValue(oStorer, SubraceTag + "_" + SUBRACE_FAVORED_CLASS, SUBRACE_FAVORED_CLASS_FEMALE_FLAG);
|
||
if(GetGender(oPC) == GENDER_MALE)
|
||
{
|
||
SetLocalInt(oPC, SUBRACE_FAVORED_CLASS, MaleFavoredClass);
|
||
}
|
||
else
|
||
{
|
||
SetLocalInt(oPC, SUBRACE_FAVORED_CLASS, FemaleFavoredClass);
|
||
}
|
||
}
|
||
GiveSubraceUniqueItem(SubraceTag, oPC);
|
||
|
||
DelayCommand(3.0, SetLocalInt(oPC, SUBRACE_INFO_LOADED_ON_PC, TRUE));
|
||
DelayCommand(12.0, SHA_SendSubraceMessageToPC(oPC, "Your sub-racial data has been loaded on your character.", FALSE));
|
||
}
|
||
|
||
void DeleteSubraceInfoOnPC(object oPC)
|
||
{
|
||
string subraceName = GetStringLowerCase(GetSubRace(oPC));
|
||
string SubraceTag = SUBRACE_TAG + "_" + subraceName;
|
||
if(subraceName == "")
|
||
{ return; }
|
||
SHA_SendSubraceMessageToPC(oPC, "Purging sub-race...", FALSE);
|
||
ClearSubraceTemporaryStats(oPC);
|
||
ClearSubraceEffects(oPC);
|
||
ChangeToPCDefaultAppearance(oPC);
|
||
effect iEffect = GetFirstEffect(oPC);
|
||
while(GetIsEffectValid(iEffect))
|
||
{
|
||
int iEffectType = GetEffectType(iEffect);
|
||
if(iEffectType == EFFECT_TYPE_SPELL_RESISTANCE_INCREASE ||
|
||
iEffectType == EFFECT_TYPE_SPELL_RESISTANCE_DECREASE)
|
||
{
|
||
RemoveEffect(oPC, iEffect);
|
||
}
|
||
iEffect = GetNextEffect(oPC);
|
||
}
|
||
|
||
DeleteLocalInt(oPC, SUBRACE_INFO_LOADED_ON_PC);
|
||
|
||
int Level = 1;
|
||
while(Level <= MAXIMUM_PLAYER_LEVEL)
|
||
{
|
||
DeleteLocalString(oPC, SubraceTag + "_" + SUBRACE_LEFT_CLAW + "_" + IntToString(Level) + "_" + IntToString(TIME_BOTH));
|
||
DeleteLocalString(oPC, SubraceTag + "_" + SUBRACE_RIGHT_CLAW + "_" + IntToString(Level) + "_" + IntToString(TIME_BOTH));
|
||
DeleteLocalString(oPC, SubraceTag + "_" + SUBRACE_LEFT_CLAW + "_" + IntToString(Level) + "_" + IntToString(TIME_DAY));
|
||
DeleteLocalString(oPC, SubraceTag + "_" + SUBRACE_RIGHT_CLAW + "_" + IntToString(Level) + "_" + IntToString(TIME_DAY));
|
||
DeleteLocalString(oPC, SubraceTag + "_" + SUBRACE_LEFT_CLAW + "_" + IntToString(Level) + "_" + IntToString(TIME_NIGHT));
|
||
DeleteLocalString(oPC, SubraceTag + "_" + SUBRACE_RIGHT_CLAW + "_" + IntToString(Level) + "_" + IntToString(TIME_NIGHT));
|
||
|
||
DeleteLocalString(oPC, SubraceTag + "_" + SUBRACE_SWITCH_NAME + IntToString(Level));
|
||
DeleteLocalInt(oPC, SubraceTag + "_" + SUBRACE_SWITCH_MUST_MEET_REQUIREMENTS + IntToString(Level));
|
||
|
||
DeleteLocalInt(oPC, SubraceTag + "_" + IntToString(Level) + "_" + APPEARANCE_CHANGE);
|
||
|
||
DeleteLocalString(oPC, SubraceTag + "_" + SUBRACE_SKIN + "_" + IntToString(Level) + "_" + IntToString(TIME_BOTH));
|
||
DeleteLocalString(oPC, SubraceTag + "_" + SUBRACE_SKIN + "_" + IntToString(Level) + "_" + IntToString(TIME_DAY));
|
||
DeleteLocalString(oPC, SubraceTag + "_" + SUBRACE_SKIN + "_" + IntToString(Level) + "_" + IntToString(TIME_NIGHT));
|
||
|
||
Level++;
|
||
}
|
||
|
||
Level = 40;
|
||
while(Level != 0)
|
||
{
|
||
string SubraceTag1 = SubraceTag + "_" + IntToString(Level);
|
||
DeleteLocalInt(oStorer, SubraceTag1 + "_" + APPEARANCE_CHANGE);
|
||
Level--;
|
||
}
|
||
DeleteLocalInt(oPC, SubraceTag + "_" + DAMAGE_AMOUNT_IN_LIGHT);
|
||
DeleteLocalInt(oPC, SubraceTag + "_" + DAMAGE_AMOUNT_IN_UNDERGROUND);
|
||
DeleteLocalInt(oPC, SubraceTag + "_" + SUBRACE_BASE_INFORMATION);
|
||
|
||
|
||
DeleteLocalInt(oPC, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS);
|
||
|
||
SubraceTag = SubraceTag + IntToString(TIME_DAY);
|
||
|
||
DeleteLocalInt(oPC, SubraceTag + "_" + SUBRACE_STAT_MODIFIER_TYPE);
|
||
|
||
DeleteLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_STR_MODIFIER);
|
||
DeleteLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_DEX_MODIFIER);
|
||
DeleteLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_CON_MODIFIER);
|
||
DeleteLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_WIS_MODIFIER);
|
||
DeleteLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_INT_MODIFIER);
|
||
DeleteLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_CHA_MODIFIER);
|
||
|
||
DeleteLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_AB_MODIFIER);
|
||
DeleteLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_AC_MODIFIER);
|
||
|
||
|
||
SubraceTag = SUBRACE_TAG + "_" + subraceName;
|
||
|
||
SubraceTag = SubraceTag + IntToString(TIME_NIGHT);
|
||
|
||
|
||
DeleteLocalInt(oPC, SubraceTag + "_" + SUBRACE_STAT_MODIFIER_TYPE);
|
||
|
||
|
||
DeleteLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_STR_MODIFIER);
|
||
DeleteLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_DEX_MODIFIER);
|
||
DeleteLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_CON_MODIFIER);
|
||
DeleteLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_WIS_MODIFIER);
|
||
DeleteLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_INT_MODIFIER);
|
||
DeleteLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_CHA_MODIFIER);
|
||
|
||
DeleteLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_AB_MODIFIER);
|
||
DeleteLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_AC_MODIFIER);
|
||
|
||
SubraceTag = SUBRACE_TAG + "_" + subraceName;
|
||
|
||
DeleteLocalInt(oPC, SubraceTag + "_" + SUBRACE_WEAPON_RESTRICTION);
|
||
|
||
|
||
DeleteLocalInt(oPC, SubraceTag + "_" + SUBRACE_ARMOUR_RESTRICTION);
|
||
|
||
int Count = GetLocalInt(oPC, SubraceTag + "_" + SUBRACE_EFFECT_COUNT);
|
||
DeleteLocalInt(oPC, SubraceTag + "_" + SUBRACE_EFFECT_COUNT);
|
||
if(Count != 0)
|
||
{
|
||
int i = 0;
|
||
while(i != Count)
|
||
{
|
||
i++;
|
||
string SubraceTag1 = SubraceTag + IntToString(i);
|
||
DeleteLocalInt(oPC, SubraceTag1 + "_" + SUBRACE_EFFECT);
|
||
DeleteLocalInt(oPC, SubraceTag1 + "_" + SUBRACE_EFFECT_VALUE_1);
|
||
DeleteLocalInt(oPC, SubraceTag1 + "_" + SUBRACE_EFFECT_VALUE_2);
|
||
DeleteLocalInt(oPC, SubraceTag1 + "_" + SUBRACE_EFFECT_DURATION_TYPE);
|
||
DeleteLocalInt(oPC, SubraceTag1 + "_" + SUBRACE_EFFECT_APPLY_TIME);
|
||
DeleteLocalFloat(oPC, SubraceTag1 + "_" + SUBRACE_EFFECT_DURATION);
|
||
}
|
||
}
|
||
DeleteLocalInt(oPC, SUBRACE_FAVORED_CLASS);
|
||
|
||
object Skin = GetItemInSlot(INVENTORY_SLOT_CARMOUR, oPC);
|
||
SetPlotFlag(Skin, FALSE);
|
||
DestroyObject(Skin, 0.1);
|
||
|
||
object ClawLeft = GetItemInSlot(INVENTORY_SLOT_CWEAPON_L, oPC);
|
||
object ClawRight = GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oPC);
|
||
SetPlotFlag(ClawLeft, FALSE);
|
||
SetPlotFlag(ClawRight, FALSE);
|
||
DestroyObject(ClawLeft, 0.5);
|
||
DestroyObject(ClawRight, 0.5);
|
||
|
||
string oResRef = GetLocalString(oStorer, SubraceTag + "_" + SUBRACE_UNIQUEITEM + "_1");
|
||
object oItem = GetFirstItemInInventory(oPC);
|
||
while(GetIsObjectValid(oItem))
|
||
{
|
||
if(GetResRef(oItem) == oResRef)
|
||
{
|
||
SetPlotFlag(oItem, FALSE);
|
||
DestroyObject(oItem, 0.1);
|
||
}
|
||
oItem = GetNextItemInInventory(oPC);
|
||
}
|
||
DeleteLocalInt(oPC, SUBRACE_TAG + "SB_NITE_OCE");
|
||
DeleteLocalInt(oPC, SUBRACE_TAG + "SB_DAY_OCE");
|
||
DeleteLocalInt(oPC, APPEARANCE_TEMP_CHANGED);
|
||
DeleteLocalInt(oPC, SUBRACE_IN_SPELL_DARKNESS);
|
||
DeleteLocalInt(oPC, "SUB_EFCT_D_APD");
|
||
DeleteLocalInt(oPC, "SUB_EFCT_N_APD");
|
||
|
||
DeleteLocalInt(oPC,"SB_LGHT_DMGED");
|
||
|
||
DeleteLocalInt(oPC,"SB_DARK_DMGED");
|
||
|
||
DeleteLocalInt(oPC, SUBRACE_STATS_STATUS);
|
||
DelayCommand(4.0, SHA_SendSubraceMessageToPC(oPC, "Purging sub-race...DONE.", FALSE));
|
||
|
||
}
|
||
|
||
|
||
void SHA_SubraceReadSubrace(object oDM, string sStuff)
|
||
{
|
||
SendMessageToPC(oDM, sStuff);
|
||
//PrintString(sStuff);
|
||
}
|
||
void ReadAllSubraces(object oDM)
|
||
{
|
||
//Save the count, and the name of the subrace.
|
||
int iCount = GetLocalInt(oStorer, MODULE_SUBRACE_COUNT);
|
||
SHA_SubraceReadSubrace(oDM, "--------- Module Subraces ----------");
|
||
ReadSubrace(oDM, iCount, 1);
|
||
|
||
|
||
}
|
||
|
||
void ReadSubrace(object oDM, int MaxCount, int CurrentCount)
|
||
{
|
||
if(CurrentCount <= MaxCount)
|
||
{
|
||
string subraceName = GetLocalString(oStorer, MODULE_SUBRACE_NUMBER + IntToString(CurrentCount));
|
||
string Name = GetStringUpperCase(GetStringLeft(subraceName, 1)) + GetStringRight(subraceName, GetStringLength(subraceName) - 1);
|
||
SHA_SubraceReadSubrace(oDM, IntToString(CurrentCount) + ".");
|
||
SHA_SubraceReadSubrace(oDM, " <ck<63>u>Subrace: </c>" + Name);
|
||
ReadSubraceInformation(subraceName, oDM);
|
||
SHA_SubraceReadSubrace(oDM, " ");
|
||
CurrentCount++;
|
||
DelayCommand(0.1, ReadSubrace(oDM, MaxCount, CurrentCount));
|
||
}
|
||
if(CurrentCount == MaxCount)
|
||
{
|
||
DelayCommand(0.2, SHA_SubraceReadSubrace(oDM, "--------- End Module Subraces --------"));
|
||
DelayCommand(0.2,SHA_SubraceReadSubrace(oDM, "-- Total Subrace Count: " + IntToString(MaxCount)));
|
||
}
|
||
|
||
}
|
||
|
||
void ReadSubraceInformation(string subraceName, object oDM, object oTarget = OBJECT_INVALID)
|
||
{
|
||
string SubraceTag = SUBRACE_TAG + "_" + subraceName;
|
||
if(subraceName == "")
|
||
{
|
||
SHA_SubraceReadSubrace(oDM, " This player character is not part of a subrace.");
|
||
return;
|
||
}
|
||
if(oTarget != OBJECT_INVALID)
|
||
{
|
||
SHA_SubraceReadSubrace(oDM, " <ck<63>u>Player Subrace: </c>" + CapitalizeString(subraceName));
|
||
SHA_SubraceReadSubrace(oDM, " Race: " + race(GetRacialType(oTarget)));
|
||
if(!GetLocalInt(oStorer, SubraceTag))
|
||
{
|
||
SHA_SubraceReadSubrace(oDM, " This subrace is not supported by this world.");
|
||
return;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
SHA_SubraceReadSubrace(oDM, " Races that qualify: ");
|
||
if(GetLocalGroupFlag(oStorer, SubraceTag + "_" + SUBRACE_BASE_RACE, FLAG1, SUBRACE_BASE_RACE_FLAGS))
|
||
{
|
||
SHA_SubraceReadSubrace(oDM, " Dwarf");
|
||
}
|
||
if(GetLocalGroupFlag(oStorer, SubraceTag + "_" + SUBRACE_BASE_RACE, FLAG2, SUBRACE_BASE_RACE_FLAGS))
|
||
{
|
||
SHA_SubraceReadSubrace(oDM, " Elf");
|
||
}
|
||
if(GetLocalGroupFlag(oStorer, SubraceTag + "_" + SUBRACE_BASE_RACE, FLAG3, SUBRACE_BASE_RACE_FLAGS))
|
||
{
|
||
SHA_SubraceReadSubrace(oDM, " Gnome");
|
||
}
|
||
if(GetLocalGroupFlag(oStorer, SubraceTag + "_" + SUBRACE_BASE_RACE, FLAG4, SUBRACE_BASE_RACE_FLAGS))
|
||
{
|
||
SHA_SubraceReadSubrace(oDM, " Half-elf");
|
||
}
|
||
if(GetLocalGroupFlag(oStorer, SubraceTag + "_" + SUBRACE_BASE_RACE, FLAG5, SUBRACE_BASE_RACE_FLAGS))
|
||
{
|
||
SHA_SubraceReadSubrace(oDM, " Halfling");
|
||
}
|
||
if(GetLocalGroupFlag(oStorer, SubraceTag + "_" + SUBRACE_BASE_RACE, FLAG6, SUBRACE_BASE_RACE_FLAGS))
|
||
{
|
||
SHA_SubraceReadSubrace(oDM, " Half-Orc");
|
||
}
|
||
if(GetLocalGroupFlag(oStorer, SubraceTag + "_" + SUBRACE_BASE_RACE, FLAG7, SUBRACE_BASE_RACE_FLAGS))
|
||
{
|
||
SHA_SubraceReadSubrace(oDM, " Human");
|
||
}
|
||
}
|
||
SHA_SubraceReadSubrace(oDM, " ");
|
||
|
||
SHA_SubraceReadSubrace(oDM, " Base information: ");
|
||
|
||
int iDmgTakenInLight = GetLocalInt(oStorer, SubraceTag + "_" + DAMAGE_AMOUNT_IN_LIGHT);
|
||
int iDmgTakenInUnder = GetLocalInt(oStorer, SubraceTag + "_" + DAMAGE_AMOUNT_IN_UNDERGROUND);
|
||
|
||
|
||
if(GetLocalGroupFlag(oStorer, SubraceTag + "_" + SUBRACE_BASE_INFORMATION, SUBRACE_BASE_INFORMATION_LIGHT_SENSITIVE, SUBRACE_BASE_INFORMATION_FLAGS))
|
||
{
|
||
SHA_SubraceReadSubrace(oDM, " *Light Sensitive");
|
||
}
|
||
if(iDmgTakenInLight != 0)
|
||
{
|
||
if(iDmgTakenInLight > 0)
|
||
{
|
||
SHA_SubraceReadSubrace(oDM, " *Takes " + IntToString(iDmgTakenInLight) + " damage in sunlight.");
|
||
}
|
||
else
|
||
{
|
||
SHA_SubraceReadSubrace(oDM, " *Regenerates " + IntToString(abs(iDmgTakenInLight)) + " hitpoints in sunlight.");
|
||
}
|
||
}
|
||
if(GetLocalGroupFlag(oStorer, SubraceTag + "_" + SUBRACE_BASE_INFORMATION, SUBRACE_BASE_INFORMATION_UNDERGROUND_SENSITIVE, SUBRACE_BASE_INFORMATION_FLAGS))
|
||
{
|
||
SHA_SubraceReadSubrace(oDM, " *Underground Sensitive");
|
||
}
|
||
if(iDmgTakenInUnder != 0)
|
||
{
|
||
if(iDmgTakenInUnder > 0)
|
||
{
|
||
SHA_SubraceReadSubrace(oDM, " *Takes " + IntToString(iDmgTakenInUnder) + " damage in underground.");
|
||
}
|
||
else
|
||
{
|
||
SHA_SubraceReadSubrace(oDM, " *Regenerates " + IntToString(abs(iDmgTakenInUnder)) + " hitpoints in underground areas.");
|
||
}
|
||
}
|
||
if(GetLocalGroupFlag(oStorer, SubraceTag + "_" + SUBRACE_BASE_INFORMATION, SUBRACE_BASE_INFORMATION_UNDEAD, SUBRACE_BASE_INFORMATION_FLAGS))
|
||
{
|
||
SHA_SubraceReadSubrace(oDM, " *Undead subrace");
|
||
}
|
||
if(GetLocalGroupFlag(oStorer, SubraceTag + "_" + SUBRACE_BASE_INFORMATION, SUBRACE_BASE_INFORMATION_PRESTIGIOUS_SUBRACE, SUBRACE_BASE_INFORMATION_FLAGS))
|
||
{
|
||
SHA_SubraceReadSubrace(oDM, " *Prestigious subrace");
|
||
}
|
||
int ECL = GetLocalGroupFlagValue(oStorer, SubraceTag + "_" + SUBRACE_BASE_INFORMATION, SUBRACE_BASE_INFORMATION_ECL);
|
||
if(ECL != 0)
|
||
{
|
||
SHA_SubraceReadSubrace(oDM, " *ECL: " + IntToString(ECL));
|
||
}
|
||
SHA_SubraceReadSubrace(oDM, " ");
|
||
int HasFClass = GetLocalInt(oStorer, SubraceTag + "_" + SUBRACE_FAVORED_CLASS);
|
||
|
||
if(HasFClass != 0)
|
||
{
|
||
SHA_SubraceReadSubrace(oDM, " *Favored Classs:");
|
||
int MaleFavoredClass = GetLocalGroupFlagValue(oStorer, SubraceTag + "_" + SUBRACE_FAVORED_CLASS, SUBRACE_FAVORED_CLASS_MALE_FLAG);
|
||
int FemaleFavoredClass = GetLocalGroupFlagValue(oStorer, SubraceTag + "_" + SUBRACE_FAVORED_CLASS, SUBRACE_FAVORED_CLASS_FEMALE_FLAG);
|
||
SHA_SubraceReadSubrace(oDM, " Male: " + class(MaleFavoredClass - 1));
|
||
SHA_SubraceReadSubrace(oDM, " Female: " + class(FemaleFavoredClass - 1));
|
||
SHA_SubraceReadSubrace(oDM, " ");
|
||
}
|
||
|
||
int Level = 1;
|
||
while(Level <=40)
|
||
{
|
||
string SubraceTag1 = SubraceTag + "_" + IntToString(Level);
|
||
if(GetLocalInt(oStorer, SubraceTag1 + "_" + APPEARANCE_CHANGE) != 0)
|
||
{
|
||
SHA_SubraceReadSubrace(oDM, " Appearance is altered.");
|
||
SHA_SubraceReadSubrace(oDM, " ");
|
||
break;
|
||
}
|
||
Level++;
|
||
|
||
}
|
||
|
||
int HasDiffStats = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG1);
|
||
|
||
if(HasDiffStats)
|
||
{
|
||
SHA_SubraceReadSubrace(oDM, " Ability scores change:");
|
||
//day
|
||
int iTime = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG2);
|
||
if(iTime)
|
||
{
|
||
SubraceTag = SubraceTag + IntToString(TIME_DAY);
|
||
SHA_SubraceReadSubrace(oDM, " For day time:");
|
||
int ModType = GetLocalInt(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIER_TYPE);
|
||
float multiplier = 1.0;
|
||
string percent = "";
|
||
if(ModType == SUBRACE_STAT_MODIFIER_TYPE_PERCENTAGE)
|
||
{
|
||
multiplier = 100.0;
|
||
percent = "%";
|
||
}
|
||
|
||
float StrengthModifier = GetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_STR_MODIFIER);
|
||
float DexterityModifier = GetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_DEX_MODIFIER);
|
||
float ConstitutionModifier = GetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_CON_MODIFIER);
|
||
float WisdomModifier = GetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_WIS_MODIFIER);
|
||
float IntelligenceModifier = GetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_INT_MODIFIER);
|
||
float CharismaModifier = GetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_CHA_MODIFIER);
|
||
|
||
float ABModifier = GetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_AB_MODIFIER);
|
||
float ACModifier = GetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_AC_MODIFIER);
|
||
|
||
SHA_SubraceReadSubrace(oDM, " STR: " + FloatToString(multiplier*StrengthModifier, 18, 2) + percent);
|
||
SHA_SubraceReadSubrace(oDM, " DEX: " + FloatToString(multiplier*DexterityModifier, 18, 2) + percent);
|
||
SHA_SubraceReadSubrace(oDM, " CON: " + FloatToString(multiplier*ConstitutionModifier, 18, 2) + percent);
|
||
SHA_SubraceReadSubrace(oDM, " WIS: " + FloatToString(multiplier*WisdomModifier, 18, 2) + percent);
|
||
SHA_SubraceReadSubrace(oDM, " INT: " + FloatToString(multiplier*IntelligenceModifier, 18, 2) + percent);
|
||
SHA_SubraceReadSubrace(oDM, " CHA: " + FloatToString(multiplier*CharismaModifier, 18, 2) + percent);
|
||
SHA_SubraceReadSubrace(oDM, " AB : " + FloatToString(multiplier*ABModifier, 18, 2) + percent);
|
||
SHA_SubraceReadSubrace(oDM, " AC : " + FloatToString(multiplier*ACModifier, 18, 2) + percent);
|
||
|
||
SHA_SubraceReadSubrace(oDM, " Changes happen in:");
|
||
if(GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG4))
|
||
{
|
||
SHA_SubraceReadSubrace(oDM, " Interior Areas");
|
||
}
|
||
|
||
if(GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG5))
|
||
{
|
||
SHA_SubraceReadSubrace(oDM, " Exterior Areas");
|
||
}
|
||
if(GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG9))
|
||
{
|
||
SHA_SubraceReadSubrace(oDM, " Underground Areas");
|
||
}
|
||
if(GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG8))
|
||
{
|
||
SHA_SubraceReadSubrace(oDM, " Above-ground Areas");
|
||
}
|
||
if(GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG6))
|
||
{
|
||
SHA_SubraceReadSubrace(oDM, " Artificial Areas");
|
||
}
|
||
if(GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG7))
|
||
{
|
||
SHA_SubraceReadSubrace(oDM, " Natural Areas");
|
||
}
|
||
}
|
||
|
||
SubraceTag = SUBRACE_TAG + "_" + subraceName;
|
||
//night
|
||
iTime = GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG3);
|
||
if(iTime)
|
||
{
|
||
|
||
SubraceTag = SubraceTag + IntToString(TIME_NIGHT);
|
||
SHA_SubraceReadSubrace(oDM, " For night time:");
|
||
int ModType = GetLocalInt(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIER_TYPE);
|
||
float multiplier = 1.0;
|
||
string percent = "";
|
||
if(ModType == SUBRACE_STAT_MODIFIER_TYPE_PERCENTAGE)
|
||
{
|
||
multiplier = 100.0;
|
||
percent = "%";
|
||
}
|
||
|
||
float StrengthModifier = GetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_STR_MODIFIER);
|
||
float DexterityModifier = GetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_DEX_MODIFIER);
|
||
float ConstitutionModifier = GetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_CON_MODIFIER);
|
||
float WisdomModifier = GetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_WIS_MODIFIER);
|
||
float IntelligenceModifier = GetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_INT_MODIFIER);
|
||
float CharismaModifier = GetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_CHA_MODIFIER);
|
||
|
||
float ABModifier = GetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_AB_MODIFIER);
|
||
float ACModifier = GetLocalFloat(oStorer, SubraceTag + "_" + SUBRACE_STAT_AC_MODIFIER);
|
||
|
||
SHA_SubraceReadSubrace(oDM, " STR: " + FloatToString(multiplier*StrengthModifier, 18, 2) + percent);
|
||
SHA_SubraceReadSubrace(oDM, " DEX: " + FloatToString(multiplier*DexterityModifier, 18, 2) + percent);
|
||
SHA_SubraceReadSubrace(oDM, " CON: " + FloatToString(multiplier*ConstitutionModifier, 18, 2) + percent);
|
||
SHA_SubraceReadSubrace(oDM, " WIS: " + FloatToString(multiplier*WisdomModifier, 18, 2) + percent);
|
||
SHA_SubraceReadSubrace(oDM, " INT: " + FloatToString(multiplier*IntelligenceModifier, 18, 2) + percent);
|
||
SHA_SubraceReadSubrace(oDM, " CHA: " + FloatToString(multiplier*CharismaModifier, 18, 2) + percent);
|
||
SHA_SubraceReadSubrace(oDM, " AB : " + FloatToString(multiplier*ABModifier, 18, 2) + percent);
|
||
SHA_SubraceReadSubrace(oDM, " AC : " + FloatToString(multiplier*ACModifier, 18, 2) + percent);
|
||
|
||
SHA_SubraceReadSubrace(oDM, " Changes happen in:");
|
||
if(GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG4))
|
||
{
|
||
SHA_SubraceReadSubrace(oDM, " Interior Areas");
|
||
}
|
||
|
||
if(GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG5))
|
||
{
|
||
SHA_SubraceReadSubrace(oDM, " Exterior Areas");
|
||
}
|
||
if(GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG9))
|
||
{
|
||
SHA_SubraceReadSubrace(oDM, " Underground Areas");
|
||
}
|
||
if(GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG8))
|
||
{
|
||
SHA_SubraceReadSubrace(oDM, " Above-ground Areas");
|
||
}
|
||
if(GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG6))
|
||
{
|
||
SHA_SubraceReadSubrace(oDM, " Artificial Areas");
|
||
}
|
||
if(GetLocalFlag(oStorer, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG7))
|
||
{
|
||
SHA_SubraceReadSubrace(oDM, " Natural Areas");
|
||
}
|
||
}
|
||
SHA_SubraceReadSubrace(oDM, " ");
|
||
}
|
||
SubraceTag = SUBRACE_TAG + "_" + subraceName;
|
||
|
||
int HasRes = GetLocalGroupFlag(oStorer, SubraceTag + "_" + SUBRACE_WEAPON_RESTRICTION, SUBRACE_HAS_RESTRICTION, SUBRACE_RESTRICTION_FLAGS);
|
||
|
||
if(HasRes)
|
||
{
|
||
SHA_SubraceReadSubrace(oDM, " Subrace has weapon restrictions: ");
|
||
int ResType = GetLocalGroupFlagValue(oStorer, SubraceTag + "_" + SUBRACE_WEAPON_RESTRICTION, SUBRACE_RESTRICTION_WEAPON);
|
||
int ResTime = GetLocalGroupFlagValue(oStorer, SubraceTag + "_" + SUBRACE_WEAPON_RESTRICTION, TIME_FLAGS);
|
||
int Allow = GetLocalGroupFlag(oStorer, SubraceTag + "_" + SUBRACE_WEAPON_RESTRICTION, SUBRACE_ALLOW_ONLY_THIS_TYPE, SUBRACE_RESTRICTION_FLAGS);
|
||
|
||
string isonly = "Not allowed to use ";
|
||
if(Allow)
|
||
{
|
||
isonly = "Is only allowed to use ";
|
||
}
|
||
|
||
SHA_SubraceReadSubrace(oDM, " -" + isonly + " " + Subrace_WeaponRestrictionToString(ResType));
|
||
SHA_SubraceReadSubrace(oDM, " -Restriction applies during: " + Subrace_TimeToString(ResTime));
|
||
SHA_SubraceReadSubrace(oDM, " ");
|
||
}
|
||
|
||
HasRes = GetLocalGroupFlag(oStorer, SubraceTag + "_" + SUBRACE_ARMOUR_RESTRICTION, SUBRACE_HAS_RESTRICTION, SUBRACE_RESTRICTION_FLAGS);
|
||
if(HasRes)
|
||
{
|
||
SHA_SubraceReadSubrace(oDM, " Subrace has armor/shield restrictions:");
|
||
string isonly = "";
|
||
if(GetLocalGroupFlag(oStorer, SubraceTag + "_" + SUBRACE_ARMOUR_RESTRICTION, SUBRACE_ALLOW_ONLY_THIS_TYPE, SUBRACE_RESTRICTION_FLAGS))
|
||
{
|
||
isonly = "Is only allowed to use ";
|
||
}
|
||
int ResType = GetLocalGroupFlagValue(oStorer, SubraceTag + "_" + SUBRACE_ARMOUR_RESTRICTION, SUBRACE_RESTRICTION_DEFENSE);
|
||
int ResTime = GetLocalGroupFlagValue(oStorer, SubraceTag + "_" + SUBRACE_ARMOUR_RESTRICTION, TIME_FLAGS);
|
||
SHA_SubraceReadSubrace(oDM, " -" + isonly + Subrace_DefenseRestrictionToString(ResType));
|
||
SHA_SubraceReadSubrace(oDM, " -Restriction applies during: " + Subrace_TimeToString(ResTime));
|
||
SHA_SubraceReadSubrace(oDM, " ");
|
||
}
|
||
|
||
}
|
||
string Subrace_TimeToString(int iTime)
|
||
{
|
||
string ret = "ERROR";
|
||
switch(iTime)
|
||
{
|
||
case TIME_DAY: ret = "Day time"; break;
|
||
case TIME_NIGHT: ret = "Night time"; break;
|
||
case TIME_BOTH: ret = "Day & Night time"; break;
|
||
case TIME_NONE: ret = "None - Special"; break;
|
||
default: break;
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
void ChangePCAppearance(object oPC, string SubraceTag)
|
||
{
|
||
int App = GetLocalGroupFlagValue(oPC, SubraceTag + "_" + APPEARANCE_CHANGE, APPEARANCE_CHANGE_APPEARANCE_FLAG);
|
||
if(App == GetAppearanceType(oPC))
|
||
{ return; }
|
||
int Alignment = GetAlignmentGoodEvil(oPC);
|
||
int VFX_ID = VFX_IMP_UNSUMMON;
|
||
if(Alignment == ALIGNMENT_GOOD)
|
||
{
|
||
VFX_ID = VFX_IMP_GOOD_HELP;
|
||
}
|
||
else if (Alignment == ALIGNMENT_NEUTRAL)
|
||
{
|
||
VFX_ID = VFX_FNF_SUMMON_MONSTER_3;
|
||
}
|
||
else if (Alignment == ALIGNMENT_EVIL)
|
||
{
|
||
VFX_ID = VFX_IMP_EVIL_HELP;
|
||
}
|
||
effect VisualBurst = EffectVisualEffect(VFX_ID);
|
||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, VisualBurst, oPC);
|
||
|
||
if(PC_SCREAMS_WHEN_CHANGING_IN_APPEARANCE)
|
||
{
|
||
AssignCommand(oPC, SpeakString(SUBRACE_WORDS_SPOKEN_ON_APPEARANCE_CHANGE_TO_MONSTER));
|
||
}
|
||
SetCreatureAppearanceType(oPC, App);
|
||
if(GetAppearanceType(oPC) == App)
|
||
{ SHA_SendSubraceMessageToPC(oPC, "Your appearance has been changed to better suit your sub-racial features.", FALSE); }
|
||
}
|
||
|
||
void ChangeToPCDefaultAppearance(object oPC)
|
||
{
|
||
int App = SHA_GetDefaultAppearanceType(oPC);
|
||
if(App == GetAppearanceType(oPC))
|
||
{ return; }
|
||
|
||
int Alignment = GetAlignmentGoodEvil(oPC);
|
||
int VFX_ID = VFX_IMP_UNSUMMON;
|
||
if(Alignment == ALIGNMENT_GOOD)
|
||
{
|
||
VFX_ID = VFX_IMP_GOOD_HELP;
|
||
}
|
||
else if (Alignment == ALIGNMENT_NEUTRAL)
|
||
{
|
||
VFX_ID = VFX_FNF_SUMMON_MONSTER_3;
|
||
}
|
||
else if (Alignment == ALIGNMENT_EVIL)
|
||
{
|
||
VFX_ID = VFX_IMP_EVIL_HELP;
|
||
}
|
||
effect VisualBurst = EffectVisualEffect(VFX_ID);
|
||
|
||
if(PC_SCREAMS_WHEN_CHANGING_IN_APPEARANCE)
|
||
{
|
||
AssignCommand(oPC, SpeakString(SUBRACE_WORDS_SPOKEN_ON_APPEARANCE_CHANGE_TO_DEFAULT_RACIAL_TYPE));
|
||
}
|
||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, VisualBurst, oPC);
|
||
SetCreatureAppearanceType(oPC, App);
|
||
SHA_SendSubraceMessageToPC(oPC, "Your appearance has been reverted back to your typical racial appearance.", FALSE);
|
||
}
|
||
|
||
|
||
void ApplyPermanentSubraceAppearance(string subrace, object oPC)
|
||
{
|
||
string SubraceTag = SUBRACE_TAG + "_" + subrace;
|
||
int Level = GetPlayerLevel(oPC);
|
||
while(Level != 0)
|
||
{
|
||
string SubraceTag1 = SubraceTag + "_" + IntToString(Level);
|
||
int iTime = GetLocalGroupFlagValue(oStorer, SubraceTag1 + "_" + APPEARANCE_CHANGE, TIME_FLAGS);
|
||
if(iTime == TIME_BOTH)
|
||
{
|
||
ChangePCAppearance(oPC, SubraceTag1);
|
||
return;
|
||
}
|
||
Level--;
|
||
}
|
||
ChangeToPCDefaultAppearance(oPC);
|
||
}
|
||
|
||
void ApplyTemporarySubraceAppearance(string SubraceTag, object oPC, int iCurrentTime)
|
||
{
|
||
int Level = GetPlayerLevel(oPC);
|
||
while(Level != 0)
|
||
{
|
||
string SubraceTag1 = SubraceTag + "_" + IntToString(Level);
|
||
int iTime = GetLocalGroupFlagValue(oStorer, SubraceTag1 + "_" + APPEARANCE_CHANGE, TIME_FLAGS);
|
||
if(iTime != 0 && iTime != TIME_NONE)
|
||
{
|
||
if(iTime == TIME_BOTH)
|
||
{ }
|
||
else if(iTime == iCurrentTime)
|
||
{
|
||
ChangePCAppearance(oPC, SubraceTag1);
|
||
}
|
||
else if(iTime != iCurrentTime)
|
||
{
|
||
ChangeToPCDefaultAppearance(oPC);
|
||
}
|
||
return;
|
||
}
|
||
Level--;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
void ApplyPermanentSubraceSpellResistance(string subrace, object oPC)
|
||
{
|
||
string SubraceTag = SUBRACE_TAG + "_" + subrace;
|
||
|
||
|
||
if(GetLocalInt(oStorer, SubraceTag + "_" + SUBRACE_SPELL_RESISTANCE) == 0)
|
||
{ return; }
|
||
|
||
//Remove all spell resistances so we can get the correct base spell resistance
|
||
//given by items
|
||
if(SUBRACE_SPELL_RESISTANCE_STACKS && (GetHasSpellEffect(SPELL_SPELL_RESISTANCE, oPC) || GetHasSpellEffect(SPELL_GREATER_SPELL_BREACH, oPC)))
|
||
{
|
||
effect iEffect = GetFirstEffect(oPC);
|
||
while(GetIsEffectValid(iEffect))
|
||
{
|
||
int iEffectType = GetEffectType(iEffect);
|
||
if(iEffectType == EFFECT_TYPE_SPELL_RESISTANCE_INCREASE ||
|
||
iEffectType == EFFECT_TYPE_SPELL_RESISTANCE_DECREASE)
|
||
{
|
||
RemoveEffect(oPC, iEffect);
|
||
}
|
||
iEffect = GetNextEffect(oPC);
|
||
}
|
||
}
|
||
int SpellResAtLevel1 = GetLocalGroupFlagValue(oStorer, SubraceTag + "_" + SUBRACE_SPELL_RESISTANCE, SUBRACE_SPELL_RESISTANCE_BASE_FLAGS);
|
||
int SpellResAtLevelMax = GetLocalGroupFlagValue(oStorer, SubraceTag + "_" + SUBRACE_SPELL_RESISTANCE, SUBRACE_SPELL_RESISTANCE_MAX_FLAGS);
|
||
float AvgSR;
|
||
effect SpellResistance;
|
||
float baseSR = IntToFloat(SpellResAtLevel1);
|
||
float maxSR = IntToFloat(SpellResAtLevelMax);
|
||
AvgSR = maxSR - baseSR;
|
||
float SRPerLevel = AvgSR/IntToFloat(MAXIMUM_PLAYER_LEVEL);
|
||
float PCLevel = IntToFloat(GetPlayerLevel(oPC));
|
||
float SR = (PCLevel*SRPerLevel)+ baseSR;
|
||
int SR_int = FloatToInt(SR);
|
||
if(SUBRACE_SPELL_RESISTANCE_STACKS)
|
||
{
|
||
SR_int = SR_int + GetSpellResistance(oPC);
|
||
|
||
}
|
||
if(SR_int < 0)
|
||
{
|
||
int SR1 = abs(SR_int);
|
||
SpellResistance = EffectSpellResistanceDecrease(SR1);
|
||
}
|
||
else
|
||
{
|
||
SpellResistance = EffectSpellResistanceIncrease(SR_int);
|
||
}
|
||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, SupernaturalEffect(SpellResistance), oPC);
|
||
SHA_SendSubraceMessageToPC(oPC, "Your spell resistance has been modified to fit your sub-racial features.", FALSE);
|
||
}
|
||
|
||
void ApplyTemporarySubraceStats(object oPC, string SubraceTag, int iCurrentTime, int AreaUndAbove, int AreaIntExt, int AreaNatArt)
|
||
{
|
||
int iTimeDay = GetLocalFlag(oPC, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG2);
|
||
int iTimeNight = GetLocalFlag(oPC, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG3);
|
||
|
||
if(iTimeDay || iTimeNight)
|
||
{
|
||
SHA_ApplyTemporaryStats(oPC, SubraceTag, iCurrentTime, iTimeDay, iTimeNight, AreaUndAbove, AreaIntExt, AreaNatArt);
|
||
}
|
||
}
|
||
void TemporaryStatsVisualFX(object oPC)
|
||
{
|
||
effect eVis = EffectVisualEffect(VFX_IMP_IMPROVE_ABILITY_SCORE);
|
||
effect eDur = EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE);
|
||
effect Vfx = EffectLinkEffects(eVis, eDur);
|
||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, Vfx, oPC);
|
||
|
||
}
|
||
|
||
|
||
void SHA_ApplyTemporaryStats(object oPC, string SubraceTag, int iCurrentTime, int iTimeDay, int iTimeNight,int AreaUndAbove, int AreaIntExt, int AreaNatArt)
|
||
{
|
||
if(AreaUndAbove == AREA_INVALID)
|
||
{ return; }
|
||
string SubraceTag1 = SubraceTag + IntToString(iCurrentTime);
|
||
|
||
int AreaInt = GetLocalFlag(oPC, SubraceTag1 + "_" + SUBRACE_STAT_MODIFIERS, FLAG4);
|
||
|
||
int AreaExt = GetLocalFlag(oPC, SubraceTag1 + "_" + SUBRACE_STAT_MODIFIERS, FLAG5);
|
||
|
||
int AreaUnd = GetLocalFlag(oPC, SubraceTag1 + "_" + SUBRACE_STAT_MODIFIERS, FLAG9);
|
||
|
||
int AreaAbove = GetLocalFlag(oPC, SubraceTag1 + "_" + SUBRACE_STAT_MODIFIERS, FLAG8);
|
||
|
||
int AreaArt = GetLocalFlag(oPC, SubraceTag1 + "_" + SUBRACE_STAT_MODIFIERS, FLAG6);
|
||
|
||
int AreaNat = GetLocalFlag(oPC, SubraceTag1 + "_" + SUBRACE_STAT_MODIFIERS, FLAG7);
|
||
|
||
int check1 = TRUE;
|
||
int check2 = TRUE;
|
||
int check3 = TRUE;
|
||
//current area: Is above ground.... subrace infor says: apply the stats in Underground only or Don't apply it anywhere.
|
||
if(AreaUndAbove == AREA_ABOVEGROUND && !AreaAbove)
|
||
{
|
||
check2 = FALSE;
|
||
}
|
||
|
||
if(AreaUndAbove == AREA_UNDERGROUND && !AreaUnd)
|
||
{
|
||
check2 = FALSE;
|
||
}
|
||
|
||
//interior
|
||
if(AreaIntExt && !AreaInt)
|
||
{
|
||
check3 = FALSE;
|
||
}
|
||
//exterior
|
||
if(!AreaIntExt && !AreaExt)
|
||
{
|
||
check3 = FALSE;
|
||
}
|
||
//natural
|
||
if(AreaNatArt == AREA_NATURAL && !AreaNat)
|
||
{
|
||
check1 = FALSE;
|
||
}
|
||
if(AreaNatArt == AREA_ARTIFICIAL && !AreaArt)
|
||
{
|
||
check1 = FALSE;
|
||
}
|
||
if(iCurrentTime == TIME_DAY)
|
||
{
|
||
if(iTimeDay && check1 && check2 && check3)
|
||
{
|
||
if(GetLocalFlag(oPC, SUBRACE_STATS_STATUS, SUBRACE_DAY_STATS_APPLIED))
|
||
{ return; }
|
||
}
|
||
if(GetLocalFlag(oPC, SUBRACE_STATS_STATUS, SUBRACE_DAY_STATS_APPLIED))
|
||
{
|
||
ClearSubraceTemporaryStats(oPC);
|
||
SHA_SendSubraceMessageToPC(oPC, "Your ability scores have been reverted.", FALSE);
|
||
SetLocalFlag(oPC, SUBRACE_STATS_STATUS, SUBRACE_DAY_STATS_APPLIED, FALSE);
|
||
}
|
||
if(GetLocalFlag(oPC, SUBRACE_STATS_STATUS, SUBRACE_NIGHT_STATS_APPLIED))
|
||
{
|
||
ClearSubraceTemporaryStats(oPC);
|
||
SHA_SendSubraceMessageToPC(oPC, "Your ability scores have been reverted.", FALSE);
|
||
SetLocalFlag(oPC, SUBRACE_STATS_STATUS, SUBRACE_NIGHT_STATS_APPLIED, FALSE);
|
||
}
|
||
}
|
||
else if(iCurrentTime == TIME_NIGHT)
|
||
{
|
||
if(iTimeNight && check1 && check2 && check3)
|
||
{
|
||
if(GetLocalFlag(oPC, SUBRACE_STATS_STATUS, SUBRACE_NIGHT_STATS_APPLIED))
|
||
{ return; }
|
||
}
|
||
if(GetLocalFlag(oPC, SUBRACE_STATS_STATUS, SUBRACE_NIGHT_STATS_APPLIED))
|
||
{
|
||
ClearSubraceTemporaryStats(oPC);
|
||
SHA_SendSubraceMessageToPC(oPC, "Your ability scores have been reverted.", FALSE);
|
||
SetLocalFlag(oPC, SUBRACE_STATS_STATUS, SUBRACE_NIGHT_STATS_APPLIED, FALSE);
|
||
}
|
||
if(GetLocalFlag(oPC, SUBRACE_STATS_STATUS, SUBRACE_DAY_STATS_APPLIED))
|
||
{
|
||
ClearSubraceTemporaryStats(oPC);
|
||
SHA_SendSubraceMessageToPC(oPC, "Your ability scores have been reverted.", FALSE);
|
||
SetLocalFlag(oPC, SUBRACE_STATS_STATUS, SUBRACE_DAY_STATS_APPLIED, FALSE);
|
||
}
|
||
}
|
||
|
||
if((!iTimeNight && iCurrentTime == TIME_NIGHT) && (!iTimeDay && iCurrentTime == TIME_DAY))
|
||
{
|
||
return;
|
||
}
|
||
if(!check1 || !check2 || !check3)
|
||
{
|
||
return;
|
||
}
|
||
int iType = GetLocalInt(oPC, SubraceTag + IntToString(iCurrentTime) + "_" + SUBRACE_STAT_MODIFIER_TYPE);
|
||
SubraceTag = SubraceTag + IntToString(iCurrentTime);
|
||
if(GetIsResting(oPC))
|
||
{
|
||
AssignCommand(oPC, ClearAllActions(TRUE));
|
||
}
|
||
|
||
if(iType == SUBRACE_STAT_MODIFIER_TYPE_PERCENTAGE)
|
||
{
|
||
ApplySubraceBonusStatsByPercentage(oPC, SubraceTag);
|
||
}
|
||
else if(iType == SUBRACE_STAT_MODIFIER_TYPE_POINTS)
|
||
{
|
||
ApplySubraceBonusStatsByPoints(oPC, SubraceTag);
|
||
}
|
||
else
|
||
{ return; }
|
||
//STAT MODIFIER TYPE Unrecognised
|
||
|
||
TemporaryStatsVisualFX(oPC);
|
||
SHA_SendSubraceMessageToPC(oPC, "Your ability scores have changed...", FALSE);
|
||
|
||
if(iCurrentTime == TIME_DAY)
|
||
{
|
||
SetLocalFlag(oPC, SUBRACE_STATS_STATUS, SUBRACE_DAY_STATS_APPLIED, TRUE);
|
||
}
|
||
else if(iCurrentTime == TIME_NIGHT)
|
||
{
|
||
SetLocalFlag(oPC, SUBRACE_STATS_STATUS, SUBRACE_NIGHT_STATS_APPLIED, TRUE);
|
||
}
|
||
}
|
||
|
||
|
||
void ClearSubraceEffects(object oPC)
|
||
{
|
||
effect eBad = GetFirstEffect(oPC);
|
||
while(GetIsEffectValid(eBad))
|
||
{
|
||
int iType = GetEffectType(eBad);
|
||
|
||
if (iType == EFFECT_TYPE_ARCANE_SPELL_FAILURE ||
|
||
iType == EFFECT_TYPE_BLINDNESS ||
|
||
iType == EFFECT_TYPE_CHARMED ||
|
||
iType == EFFECT_TYPE_CONCEALMENT ||
|
||
iType == EFFECT_TYPE_CONFUSED ||
|
||
iType == EFFECT_TYPE_CUTSCENEGHOST ||
|
||
iType == EFFECT_TYPE_HASTE ||
|
||
iType == EFFECT_TYPE_IMMUNITY ||
|
||
iType == EFFECT_TYPE_IMPROVEDINVISIBILITY ||
|
||
iType == EFFECT_TYPE_INVISIBILITY ||
|
||
iType == EFFECT_TYPE_MISS_CHANCE ||
|
||
iType == EFFECT_TYPE_MOVEMENT_SPEED_DECREASE ||
|
||
iType == EFFECT_TYPE_MOVEMENT_SPEED_INCREASE ||
|
||
iType == EFFECT_TYPE_POLYMORPH ||
|
||
iType == EFFECT_TYPE_REGENERATE ||
|
||
iType == EFFECT_TYPE_SANCTUARY ||
|
||
iType == EFFECT_TYPE_SLOW ||
|
||
iType == EFFECT_TYPE_TEMPORARY_HITPOINTS ||
|
||
iType == EFFECT_TYPE_TRUESEEING ||
|
||
iType == EFFECT_TYPE_ULTRAVISION ||
|
||
iType == EFFECT_TYPE_VISUALEFFECT)
|
||
{
|
||
if(GetEffectSubType(eBad) == SUBTYPE_SUPERNATURAL)
|
||
{
|
||
RemoveEffect(oPC, eBad);
|
||
}
|
||
}
|
||
eBad = GetNextEffect(oPC);
|
||
}
|
||
}
|
||
|
||
void ClearSubraceTemporaryStats(object oPC)
|
||
{
|
||
effect eBad = GetFirstEffect(oPC);
|
||
while(GetIsEffectValid(eBad))
|
||
{
|
||
int iType = GetEffectType(eBad);
|
||
|
||
if (iType == EFFECT_TYPE_ABILITY_DECREASE ||
|
||
iType == EFFECT_TYPE_ABILITY_INCREASE ||
|
||
iType == EFFECT_TYPE_AC_DECREASE ||
|
||
iType == EFFECT_TYPE_AC_INCREASE ||
|
||
iType == EFFECT_TYPE_ATTACK_INCREASE ||
|
||
iType == EFFECT_TYPE_ATTACK_DECREASE ||
|
||
iType == EFFECT_TYPE_SPELL_RESISTANCE_DECREASE ||
|
||
iType == EFFECT_TYPE_SPELL_RESISTANCE_INCREASE ||
|
||
iType == EFFECT_TYPE_SAVING_THROW_DECREASE)
|
||
{
|
||
if(GetEffectSubType(eBad) == SUBTYPE_SUPERNATURAL)
|
||
{
|
||
RemoveEffect(oPC, eBad);
|
||
}
|
||
}
|
||
eBad = GetNextEffect(oPC);
|
||
}
|
||
}
|
||
|
||
void ApplySubraceBonusStatsByPoints(object oPC, string SubraceTag)
|
||
{
|
||
float strMod = GetLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_STR_MODIFIER);
|
||
float dexMod = GetLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_DEX_MODIFIER);
|
||
float conMod = GetLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_CON_MODIFIER);
|
||
float wisMod = GetLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_WIS_MODIFIER);
|
||
float intMod = GetLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_INT_MODIFIER);
|
||
float chaMod = GetLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_CHA_MODIFIER);
|
||
|
||
float ABMod = GetLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_AB_MODIFIER);
|
||
float ACMod = GetLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_AC_MODIFIER);
|
||
|
||
if(strMod != 0.0)
|
||
{
|
||
ApplyStat_AbilityByPoints(ABILITY_STRENGTH, strMod, oPC);
|
||
}
|
||
if(dexMod !=0.0)
|
||
{
|
||
ApplyStat_AbilityByPoints(ABILITY_DEXTERITY, dexMod, oPC);
|
||
}
|
||
if(conMod != 0.0)
|
||
{
|
||
ApplyStat_AbilityByPoints(ABILITY_CONSTITUTION, conMod, oPC);
|
||
}
|
||
if(wisMod != 0.0)
|
||
{
|
||
ApplyStat_AbilityByPoints(ABILITY_WISDOM, wisMod, oPC);
|
||
}
|
||
if(intMod != 0.0)
|
||
{
|
||
ApplyStat_AbilityByPoints(ABILITY_INTELLIGENCE, intMod, oPC);
|
||
}
|
||
if(chaMod != 0.0)
|
||
{
|
||
ApplyStat_AbilityByPoints(ABILITY_CHARISMA, chaMod, oPC);
|
||
}
|
||
if(ABMod != 0.0)
|
||
{
|
||
ApplyAttackBonusByPoints(ABMod, oPC);
|
||
}
|
||
if(ACMod != 0.0)
|
||
{
|
||
ApplyArmourClassBonusByPoints(ACMod, oPC);
|
||
}
|
||
}
|
||
|
||
void ApplyStat_AbilityByPoints(int AbilityToMod, float points, object oPC)
|
||
{
|
||
int StatIncrease = FloatToInt(points);
|
||
effect StatEffect;
|
||
if(StatIncrease > 0)
|
||
{
|
||
StatEffect = EffectAbilityIncrease(AbilityToMod, StatIncrease);
|
||
}
|
||
else if(StatIncrease < 0)
|
||
{
|
||
int StatIncrease1 = abs(StatIncrease);
|
||
StatEffect = EffectAbilityDecrease(AbilityToMod, StatIncrease1);
|
||
}
|
||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, SupernaturalEffect(StatEffect), oPC);
|
||
}
|
||
|
||
void ApplyAttackBonusByPoints(float points, object oPC)
|
||
{
|
||
int ABChange = FloatToInt(points);
|
||
effect StatEffect;
|
||
effect StatEffect1;
|
||
if(ABChange > 0)
|
||
{
|
||
StatEffect = EffectAttackIncrease(ABChange, ATTACK_BONUS_ONHAND);
|
||
StatEffect1 = EffectAttackIncrease(ABChange, ATTACK_BONUS_OFFHAND);
|
||
}
|
||
else if(ABChange < 0)
|
||
{
|
||
int ABChange1 = abs(ABChange);
|
||
StatEffect = EffectAttackDecrease(ABChange1, ATTACK_BONUS_ONHAND);
|
||
StatEffect1 = EffectAttackDecrease(ABChange1, ATTACK_BONUS_OFFHAND);
|
||
}
|
||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, SupernaturalEffect(StatEffect), oPC);
|
||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, SupernaturalEffect(StatEffect1), oPC);
|
||
}
|
||
|
||
void ApplyArmourClassBonusByPoints(float points, object oPC)
|
||
{
|
||
int ACChange = FloatToInt(points);
|
||
effect StatEffect;
|
||
if(ACChange > 0)
|
||
{
|
||
StatEffect = EffectACIncrease(ACChange, AC_NATURAL_BONUS);
|
||
}
|
||
else if(ACChange < 0)
|
||
{
|
||
int ACChange1 = abs(ACChange);
|
||
StatEffect = EffectACDecrease(ACChange1, AC_NATURAL_BONUS);
|
||
}
|
||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, SupernaturalEffect(StatEffect), oPC);
|
||
}
|
||
|
||
void ApplySubraceBonusStatsByPercentage(object oPC, string SubraceTag)
|
||
{
|
||
float strMod = GetLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_STR_MODIFIER);
|
||
float dexMod = GetLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_DEX_MODIFIER);
|
||
float conMod = GetLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_CON_MODIFIER);
|
||
float wisMod = GetLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_WIS_MODIFIER);
|
||
float intMod = GetLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_INT_MODIFIER);
|
||
float chaMod = GetLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_CHA_MODIFIER);
|
||
|
||
float ABMod = GetLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_AB_MODIFIER);
|
||
float ACMod = GetLocalFloat(oPC, SubraceTag + "_" + SUBRACE_STAT_AC_MODIFIER);
|
||
|
||
if(strMod != 0.0)
|
||
{
|
||
ApplyStat_AbilityByPercentage(ABILITY_STRENGTH, strMod, oPC);
|
||
}
|
||
if(dexMod !=0.0)
|
||
{
|
||
ApplyStat_AbilityByPercentage(ABILITY_DEXTERITY, dexMod, oPC);
|
||
}
|
||
if(conMod != 0.0)
|
||
{
|
||
ApplyStat_AbilityByPercentage(ABILITY_CONSTITUTION, conMod, oPC);
|
||
}
|
||
if(wisMod != 0.0)
|
||
{
|
||
ApplyStat_AbilityByPercentage(ABILITY_WISDOM, wisMod, oPC);
|
||
}
|
||
if(intMod != 0.0)
|
||
{
|
||
ApplyStat_AbilityByPercentage(ABILITY_INTELLIGENCE, intMod, oPC);
|
||
}
|
||
if(chaMod != 0.0)
|
||
{
|
||
ApplyStat_AbilityByPercentage(ABILITY_CHARISMA, chaMod, oPC);
|
||
}
|
||
if(ABMod != 0.0)
|
||
{
|
||
ApplyAttackBonusByPercentage(ABMod, oPC);
|
||
}
|
||
if(ACMod != 0.0)
|
||
{
|
||
ApplyArmourClassBonusByPercentage(ACMod, oPC);
|
||
}
|
||
}
|
||
|
||
void ApplyStat_AbilityByPercentage(int AbilityToMod, float percentage, object oPC)
|
||
{
|
||
int currentStat = GetAbilityScore(oPC, AbilityToMod);
|
||
float cStat = IntToFloat(currentStat);
|
||
|
||
float Stat = cStat*percentage;
|
||
int newStat = FloatToInt(Stat);
|
||
effect StatEffect;
|
||
if(newStat > 0)
|
||
{
|
||
StatEffect = EffectAbilityIncrease(AbilityToMod, newStat);
|
||
}
|
||
else if(newStat < 0)
|
||
{
|
||
int newStat1 = abs(newStat);
|
||
StatEffect = EffectAbilityDecrease(AbilityToMod, newStat1);
|
||
}
|
||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, SupernaturalEffect(StatEffect), oPC);
|
||
}
|
||
|
||
void ApplyAttackBonusByPercentage(float percentage, object oPC)
|
||
{
|
||
float currentAB = IntToFloat(GetBaseAttackBonus(oPC));
|
||
int Neg = FALSE;
|
||
int Neg2 = FALSE;
|
||
if(currentAB < 0.0 )
|
||
{ Neg = TRUE; }
|
||
if(percentage < 0.0 )
|
||
{ Neg2 = TRUE; }
|
||
int newAB = FloatToInt(currentAB*percentage);
|
||
if(Neg && Neg2 )
|
||
{ newAB = -newAB; }
|
||
effect StatEffect;
|
||
effect StatEffect1;
|
||
if(newAB > 0)
|
||
{
|
||
StatEffect = EffectAttackIncrease(newAB, ATTACK_BONUS_ONHAND);
|
||
StatEffect1 = EffectAttackIncrease(newAB, ATTACK_BONUS_OFFHAND);
|
||
}
|
||
else if(newAB < 0)
|
||
{
|
||
int newAB1 = abs(newAB);
|
||
StatEffect = EffectAttackDecrease(newAB1, ATTACK_BONUS_ONHAND);
|
||
StatEffect1 = EffectAttackDecrease(newAB1, ATTACK_BONUS_OFFHAND);
|
||
}
|
||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, SupernaturalEffect(StatEffect), oPC);
|
||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, SupernaturalEffect(StatEffect1), oPC);
|
||
}
|
||
|
||
void ApplyArmourClassBonusByPercentage(float percentage, object oPC)
|
||
{
|
||
float currentAC = IntToFloat(GetAC(oPC));
|
||
int newAC = FloatToInt(currentAC*percentage);
|
||
effect StatEffect;
|
||
if(newAC > 0)
|
||
{
|
||
StatEffect = EffectACIncrease(newAC, AC_NATURAL_BONUS, AC_VS_DAMAGE_TYPE_ALL);
|
||
}
|
||
else if(newAC < 0)
|
||
{
|
||
int newAC1 = abs(newAC);
|
||
StatEffect = EffectACDecrease(newAC1, AC_NATURAL_BONUS, AC_VS_DAMAGE_TYPE_ALL);
|
||
}
|
||
ApplyEffectToObject(DURATION_TYPE_PERMANENT, SupernaturalEffect(StatEffect), oPC);
|
||
}
|
||
|
||
|
||
|
||
void SHA_SubraceForceUnequipItem(object oItem)
|
||
{
|
||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectCutsceneImmobilize(), OBJECT_SELF, 0.1);
|
||
ClearAllActions(TRUE);
|
||
ActionUnequipItem(oItem);
|
||
ActionDoCommand(SetCommandable(TRUE));
|
||
SetCommandable(FALSE);
|
||
}
|
||
|
||
void SHA_SubraceForceEquipItem(object oItem, int InvoSlot)
|
||
{
|
||
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectCutsceneImmobilize(), OBJECT_SELF, 0.1);
|
||
ClearAllActions(TRUE);
|
||
ActionEquipItem(oItem, InvoSlot);
|
||
ActionDoCommand(SetCommandable(TRUE));
|
||
SetCommandable(FALSE);
|
||
}
|
||
string Subrace_WeaponRestrictionToString(int ResType)
|
||
{
|
||
string ret = "";
|
||
switch(ResType)
|
||
{
|
||
case SUBRACE_RESTRICTION_WEAPON_MELEE: ret = "Melee Weapons"; break;
|
||
case SUBRACE_RESTRICTION_WEAPON_RANGED: ret = "Ranged Weapons"; break;
|
||
case SUBRACE_RESTRICTION_WEAPON_TINY: ret = "Tiny Weapons"; break;
|
||
case SUBRACE_RESTRICTION_WEAPON_LARGE: ret = "Large Weapons"; break;
|
||
case SUBRACE_RESTRICTION_WEAPON_SIMPLE: ret = "Simple Weapons"; break;
|
||
case SUBRACE_RESTRICTION_WEAPON_MARTIAL: ret = "Martial Weapons"; break;
|
||
case SUBRACE_RESTRICTION_WEAPON_EXOTIC: ret = "Exotic Weapons"; break;
|
||
case SUBRACE_RESTRICTION_WEAPON_ALL: ret = "All types of Weapons"; break;
|
||
default: ret = "ERROR"; break;
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
|
||
string Subrace_DefenseRestrictionToString(int ResType)
|
||
{
|
||
string ret = "";
|
||
switch(ResType)
|
||
{
|
||
case SUBRACE_RESTRICTION_DEFENSE_CLOTHING: ret = "Clothing"; break;
|
||
case SUBRACE_RESTRICTION_DEFENSE_HEAVY: ret = "Heavy Defense"; break;
|
||
case SUBRACE_RESTRICTION_DEFENSE_LIGHT: ret = "Light Defense"; break;
|
||
case SUBRACE_RESTRICTION_DEFENSE_MEDIUM: ret = "Medium Weapons"; break;
|
||
case SUBRACE_RESTRICTION_DEFENSE_ALL: ret = "All Defenses"; break;
|
||
default: ret = "ERROR"; break;
|
||
}
|
||
return ret;
|
||
}
|
||
void CheckCanUseWeapon(object oItem, object oPC, string SubraceTag)
|
||
{
|
||
int HasRes = GetLocalGroupFlag(oPC, SubraceTag + "_" + SUBRACE_WEAPON_RESTRICTION, SUBRACE_HAS_RESTRICTION, SUBRACE_RESTRICTION_FLAGS);
|
||
if(HasRes)
|
||
{
|
||
|
||
int ResType = GetLocalGroupFlagValue(oPC, SubraceTag + "_" + SUBRACE_WEAPON_RESTRICTION, SUBRACE_RESTRICTION_WEAPON);
|
||
int ResTime = GetLocalGroupFlagValue(oPC, SubraceTag + "_" + SUBRACE_WEAPON_RESTRICTION, TIME_FLAGS);
|
||
int Allow = GetLocalGroupFlag(oPC, SubraceTag + "_" + SUBRACE_WEAPON_RESTRICTION, SUBRACE_ALLOW_ONLY_THIS_TYPE, SUBRACE_RESTRICTION_FLAGS);
|
||
|
||
//First make sure it is a weapon...
|
||
if(!SHA_GetIsRangedWeapon(oItem) && !SHA_GetIsMeleeWeapon(oItem))
|
||
{
|
||
return;
|
||
}
|
||
|
||
int iResult = 100;
|
||
if(ResTime == TIME_NIGHT)
|
||
{
|
||
if(!GetIsNight() && !GetIsDusk())
|
||
{ return; }
|
||
}
|
||
else if(ResTime == TIME_DAY)
|
||
{
|
||
if(!GetIsDay() && !GetIsDawn())
|
||
{ return; }
|
||
}
|
||
|
||
switch(ResType)
|
||
{
|
||
case SUBRACE_RESTRICTION_WEAPON_MELEE: iResult = SHA_GetIsMeleeWeapon(oItem); break;
|
||
case SUBRACE_RESTRICTION_WEAPON_RANGED: iResult = SHA_GetIsRangedWeapon(oItem); break;
|
||
case SUBRACE_RESTRICTION_WEAPON_TINY: iResult = SHA_GetIsWeaponTiny(oItem); break;
|
||
case SUBRACE_RESTRICTION_WEAPON_LARGE: iResult = SHA_GetIsWeaponLarge(oItem); break;
|
||
case SUBRACE_RESTRICTION_WEAPON_SIMPLE: iResult = SHA_GetIsSimpleWeapon(oItem); break;
|
||
case SUBRACE_RESTRICTION_WEAPON_MARTIAL: iResult = SHA_GetIsMartialWeapon(oItem); break;
|
||
case SUBRACE_RESTRICTION_WEAPON_EXOTIC: iResult = SHA_GetIsExoticWeapon(oItem); break;
|
||
case SUBRACE_RESTRICTION_WEAPON_ALL: iResult = TRUE;
|
||
default: iResult = FALSE;
|
||
}
|
||
//It is the type of weapon the sub-race is restricted against.
|
||
if(iResult && !Allow)
|
||
{
|
||
iResult = FALSE;
|
||
}
|
||
if(!iResult)
|
||
{
|
||
SHA_SendSubraceMessageToPC(oPC, "You cannot equip this weapon because of your sub-race's limitations.", TRUE);
|
||
DelayCommand(0.3, AssignCommand(oPC, SHA_SubraceForceUnequipItem(oItem)));
|
||
}
|
||
}
|
||
}
|
||
|
||
void CheckCanUseArmor(object oItem, object oPC, string SubraceTag)
|
||
{
|
||
int HasRes = GetLocalGroupFlag(oPC, SubraceTag + "_" + SUBRACE_ARMOUR_RESTRICTION, SUBRACE_HAS_RESTRICTION, SUBRACE_RESTRICTION_FLAGS);
|
||
|
||
if(HasRes)
|
||
{
|
||
int ResType = GetLocalGroupFlagValue(oPC, SubraceTag + "_" + SUBRACE_ARMOUR_RESTRICTION, SUBRACE_RESTRICTION_DEFENSE);
|
||
int ResTime = GetLocalGroupFlagValue(oPC, SubraceTag + "_" + SUBRACE_ARMOUR_RESTRICTION, TIME_FLAGS);
|
||
int Allow = GetLocalGroupFlag(oPC, SubraceTag + "_" + SUBRACE_ARMOUR_RESTRICTION, SUBRACE_ALLOW_ONLY_THIS_TYPE, SUBRACE_RESTRICTION_FLAGS);
|
||
|
||
int iCheck = FALSE;
|
||
int iType = GetBaseItemType(oItem);
|
||
|
||
if(iType == BASE_ITEM_ARMOR || iType == BASE_ITEM_LARGESHIELD || iType == BASE_ITEM_TOWERSHIELD || iType == BASE_ITEM_SMALLSHIELD || iType == BASE_ITEM_HELMET)
|
||
{
|
||
iCheck = TRUE;
|
||
}
|
||
if(iCheck)
|
||
{
|
||
int iResult = 100;
|
||
if(ResTime == TIME_NIGHT)
|
||
{
|
||
if(!GetIsNight() && !GetIsDusk())
|
||
{ return; }
|
||
}
|
||
else if(ResTime == TIME_DAY)
|
||
{
|
||
if(!GetIsDay() && !GetIsDawn())
|
||
{ return; }
|
||
}
|
||
|
||
int BaseAC = GetArmorType(oItem);
|
||
|
||
if(ResType == SUBRACE_RESTRICTION_DEFENSE_HEAVY)
|
||
{
|
||
if(BaseAC >= 7 || iType == BASE_ITEM_TOWERSHIELD || iType == BASE_ITEM_HELMET)
|
||
{
|
||
iResult = TRUE;
|
||
}
|
||
else
|
||
{
|
||
iResult = FALSE;
|
||
}
|
||
}
|
||
else if(ResType == SUBRACE_RESTRICTION_DEFENSE_MEDIUM)
|
||
{
|
||
if((BaseAC >= 4 && BaseAC < 7) || iType == BASE_ITEM_LARGESHIELD || iType == BASE_ITEM_HELMET)
|
||
{
|
||
iResult = TRUE;
|
||
}
|
||
else
|
||
{
|
||
iResult = FALSE;
|
||
}
|
||
}
|
||
else if(ResType == SUBRACE_RESTRICTION_DEFENSE_LIGHT)
|
||
{
|
||
if((BaseAC >= 1 && BaseAC < 4) || iType == BASE_ITEM_SMALLSHIELD)
|
||
{
|
||
iResult = TRUE;
|
||
}
|
||
else
|
||
{
|
||
iResult = FALSE;
|
||
}
|
||
}
|
||
else if(ResType == SUBRACE_RESTRICTION_DEFENSE_CLOTHING)
|
||
{
|
||
if(BaseAC == 0 && iType != BASE_ITEM_LARGESHIELD && iType != BASE_ITEM_TOWERSHIELD && iType != BASE_ITEM_SMALLSHIELD && iType != BASE_ITEM_HELMET)
|
||
{
|
||
iResult = TRUE;
|
||
}
|
||
else
|
||
{
|
||
iResult = FALSE;
|
||
}
|
||
}
|
||
else if(ResType == SUBRACE_RESTRICTION_DEFENSE_ALL)
|
||
{
|
||
iResult = TRUE;
|
||
}
|
||
|
||
if(iResult && !Allow)
|
||
{
|
||
iResult = FALSE;
|
||
}
|
||
|
||
if(!iResult)
|
||
{
|
||
SHA_SendSubraceMessageToPC(oPC, "You cannot equip this armor because of your sub-race's limitations.", TRUE);
|
||
DelayCommand(0.3, AssignCommand(oPC, SHA_SubraceForceUnequipItem(oItem)));
|
||
}
|
||
}
|
||
}
|
||
}
|
||
void CheckCanUseItem(object oItem, object oPC)
|
||
{
|
||
string subrace = GetStringLowerCase(GetSubRace(oPC));
|
||
if(subrace == "")
|
||
{ return; }
|
||
string SubraceTag = SUBRACE_TAG + "_" + subrace;
|
||
CheckCanUseArmor(oItem, oPC, SubraceTag);
|
||
CheckCanUseWeapon(oItem, oPC, SubraceTag);
|
||
}
|
||
void SubraceOnPlayerEquipItem()
|
||
{
|
||
object oItem = GetPCItemLastEquipped();
|
||
object oPC = GetPCItemLastEquippedBy();
|
||
CheckCanUseItem(oItem, oPC);
|
||
}
|
||
|
||
void CheckIfCanUseEquipedWeapon(object oPC)
|
||
{
|
||
string subrace = GetStringLowerCase(GetSubRace(oPC));
|
||
if(subrace == "")
|
||
{ return; }
|
||
|
||
string SubraceTag = SUBRACE_TAG + "_" + subrace;
|
||
int HasRes = GetLocalGroupFlag(oPC, SubraceTag + "_" + SUBRACE_WEAPON_RESTRICTION, SUBRACE_HAS_RESTRICTION, SUBRACE_RESTRICTION_FLAGS);
|
||
if(!HasRes)
|
||
{ return; }
|
||
object Wep1 = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oPC);
|
||
object Wep2 = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oPC);
|
||
CheckCanUseItem(Wep1, oPC);
|
||
CheckCanUseItem(Wep2, oPC);
|
||
}
|
||
|
||
void InitiateSubraceChecking(object oPC)
|
||
{
|
||
string subrace = GetStringLowerCase(GetSubRace(oPC));
|
||
|
||
if(subrace != "")
|
||
{
|
||
int check1 = GetCampaignInt(SUBRACE_DATABASE, SUBRACE_TAG + "_" + subrace, oPC);
|
||
//NWNX Equivalent of the above. If using NWNX, then comment the above line, and uncomment the line below.
|
||
//int check1 = GetPersistentInt(oPC, SUBRACE_TAG + "_" + subrace, SUBRACE_DATABASE);
|
||
|
||
if(check1 == SUBRACE_UNINITIALIZED)
|
||
{
|
||
int check2 = CheckIfPCMeetsAnySubraceCriteria(oPC);
|
||
if(check2 == SUBRACE_UNRECOGNISED)
|
||
{
|
||
return;
|
||
}
|
||
else if(!check2)
|
||
{
|
||
|
||
SetCampaignInt(SUBRACE_DATABASE, SUBRACE_TAG + "_" + subrace, SUBRACE_REJECTED, oPC);
|
||
|
||
//NWNX Equivalent of the above. If using NWNX, then comment the above line, and uncomment the line below.
|
||
//SetPersistentInt(oPC, SUBRACE_TAG + "_" + subrace , SUBRACE_REJECTED, 0, SUBRACE_DATABASE);
|
||
|
||
return;
|
||
}
|
||
else if(check2)
|
||
{
|
||
|
||
SetCampaignInt(SUBRACE_DATABASE, SUBRACE_TAG + "_" + subrace, SUBRACE_ACCEPTED, oPC);
|
||
//NWNX Equivalent of the above. If using NWNX, then comment the above line, and uncomment the line below.
|
||
//SetPersistentInt(oPC, SUBRACE_TAG + "_" + subrace, SUBRACE_ACCEPTED, 0, SUBRACE_DATABASE);
|
||
}
|
||
}
|
||
else if(check1 == SUBRACE_ACCEPTED)
|
||
{
|
||
}
|
||
else if(check1 == SUBRACE_REJECTED)
|
||
{
|
||
//SUBRACE was rejected previously.
|
||
return;
|
||
}
|
||
if(SEARCH_AND_DESTROY_SKINS_IN_INVENTORY)
|
||
{
|
||
SearchAndDestroySkinsAndClaws(oPC);
|
||
}
|
||
DelayCommand(1.0, LoadSubraceInfoOnPC(oPC, subrace));
|
||
DelayCommand(2.0, ApplyPermanentSubraceSpellResistance(subrace, oPC));
|
||
DelayCommand(4.0, ApplyPermanentSubraceAppearance(subrace, oPC));
|
||
}
|
||
}
|
||
|
||
void CheckAndSwitchSubrace(object oPC)
|
||
{
|
||
string subrace = GetStringLowerCase(GetSubRace(oPC));
|
||
if(subrace == "")
|
||
{ return; }
|
||
string SubraceTag = SUBRACE_TAG + "_" + subrace;
|
||
int Level = GetPlayerLevel(oPC);
|
||
int End = FALSE;
|
||
string switchSubraceNames = GetLocalString(oPC, SubraceTag + "_" + SUBRACE_SWITCH_NAME + IntToString(Level));
|
||
if(switchSubraceNames != "")
|
||
{
|
||
while(switchSubraceNames != "")
|
||
{
|
||
int iPos = FindSubString(switchSubraceNames, "_");
|
||
string sSubrace;
|
||
if(iPos != -1)
|
||
{
|
||
sSubrace = GetStringLeft(switchSubraceNames, iPos);
|
||
}
|
||
else
|
||
{
|
||
sSubrace = switchSubraceNames;
|
||
End = TRUE;
|
||
}
|
||
switchSubraceNames = GetStringRight(switchSubraceNames, GetStringLength(switchSubraceNames) - iPos - 1);
|
||
string CurrentSubrace = GetSubRace(oPC);
|
||
string NewSubrace = CapitalizeString(sSubrace);
|
||
SetSubRace(oPC, NewSubrace);
|
||
subrace = GetStringLowerCase(GetSubRace(oPC));
|
||
SHA_SendSubraceMessageToPC(oPC, "Checking whether your character meets the requirements for the '" + NewSubrace +"' sub-race...", TRUE);
|
||
int check = TRUE;
|
||
int NeedToMeetRequirements = GetLocalInt(oPC, SubraceTag + "_" + SUBRACE_SWITCH_MUST_MEET_REQUIREMENTS + IntToString(Level));
|
||
//only check restrictions if need be.
|
||
if(NeedToMeetRequirements)
|
||
{
|
||
check = CheckIfPCMeetsAnySubraceCriteria(oPC);
|
||
}
|
||
if(check == SUBRACE_UNRECOGNISED)
|
||
{
|
||
return;
|
||
}
|
||
else if(!check)
|
||
{
|
||
SHA_SendSubraceMessageToPC(oPC, "Your character has failed to meet criteria for the '" + NewSubrace + "' sub-race!", TRUE);
|
||
SetSubRace(oPC, CurrentSubrace);
|
||
if(End == TRUE)
|
||
{ return; }
|
||
}
|
||
else if(check)
|
||
{
|
||
SetCampaignInt(SUBRACE_DATABASE, SUBRACE_TAG + "_" + subrace, SUBRACE_ACCEPTED, oPC);
|
||
//NWNX Equivalent of the above. If using NWNX, then comment the above line, and uncomment the line below.
|
||
//SetPersistentInt(oPC, SUBRACE_TAG + "_" + subrace, SUBRACE_ACCEPTED, 0, SUBRACE_DATABASE);
|
||
|
||
//revert it back to delete the stored info.
|
||
SetSubRace(oPC, CurrentSubrace);
|
||
DeleteSubraceInfoOnPC(oPC);
|
||
subrace = GetStringLowerCase(NewSubrace);
|
||
DelayCommand(4.2, SHA_SendSubraceMessageToPC(oPC, "Switching sub-races to: " + NewSubrace + "...", TRUE));
|
||
DelayCommand(4.2, SetSubRace(oPC, NewSubrace));
|
||
DelayCommand(5.1, LoadSubraceInfoOnPC(oPC, subrace));
|
||
DelayCommand(7.0, ApplyPermanentSubraceSpellResistance(subrace, oPC));
|
||
DelayCommand(8.5, ApplyPermanentSubraceAppearance(subrace, oPC));
|
||
DelayCommand(9.0, SHA_SendSubraceMessageToPC(oPC, "Sub-race was switched!", TRUE));
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
void SubraceOnPlayerLevelUp()
|
||
{
|
||
object oPC = GetPCLevellingUp();
|
||
ReapplySubraceAbilities(oPC);
|
||
DelayCommand(2.0, CheckAndGiveSubraceItems(oPC));
|
||
DelayCommand(6.0, CheckAndSwitchSubrace(oPC));
|
||
}
|
||
|
||
void SubraceOnPlayerRespawn()
|
||
{
|
||
object oPC = GetLastRespawnButtonPresser();
|
||
ReapplySubraceAbilities(oPC);
|
||
}
|
||
void ReapplySubraceAbilities(object oPC)
|
||
{
|
||
string subrace = GetStringLowerCase(GetSubRace(oPC));
|
||
|
||
if(subrace == "")
|
||
{ return; }
|
||
SetLocalInt(oPC, SUBRACE_INFO_LOADED_ON_PC, FALSE);
|
||
DeleteLocalInt(oPC, SUBRACE_TAG + "SB_NITE_OCE");
|
||
DeleteLocalInt(oPC, SUBRACE_TAG + "SB_DAY_OCE");
|
||
DeleteLocalInt(oPC, APPEARANCE_TEMP_CHANGED);
|
||
DeleteLocalInt(oPC, SUBRACE_IN_SPELL_DARKNESS);
|
||
DeleteLocalInt(oPC, "SUB_EFCT_D_APD");
|
||
DeleteLocalInt(oPC, "SUB_EFCT_N_APD");
|
||
string SubraceTag = SUBRACE_TAG + "_" + subrace;
|
||
int IsLightSens = GetLocalGroupFlag(oPC, SubraceTag + "_" + SUBRACE_BASE_INFORMATION, SUBRACE_BASE_INFORMATION_LIGHT_SENSITIVE, SUBRACE_BASE_INFORMATION_FLAGS);
|
||
int IsUndergSens = GetLocalGroupFlag(oPC, SubraceTag + "_" + SUBRACE_BASE_INFORMATION, SUBRACE_BASE_INFORMATION_UNDERGROUND_SENSITIVE, SUBRACE_BASE_INFORMATION_FLAGS);
|
||
if(IsLightSens)
|
||
{
|
||
DeleteLocalInt(oPC,"SB_LGHT_DMGED");
|
||
}
|
||
if(IsUndergSens)
|
||
{
|
||
DeleteLocalInt(oPC,"SB_DARK_DMGED");
|
||
}
|
||
ApplyPermanentSubraceSpellResistance(subrace, oPC);
|
||
int HasDiffStats = GetLocalFlag(oPC, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG1);
|
||
if(HasDiffStats)
|
||
{
|
||
DeleteLocalInt(oPC, SUBRACE_STATS_STATUS);
|
||
ClearSubraceTemporaryStats(oPC);
|
||
}
|
||
DelayCommand(2.0, ApplyPermanentSubraceAppearance(subrace, oPC));
|
||
DelayCommand(3.0, SearchAndDestroySkinsAndClaws(oPC));
|
||
DelayCommand(4.0, SetLocalInt(oPC, SUBRACE_INFO_LOADED_ON_PC, TRUE));
|
||
}
|
||
|
||
int SHA_GetCurrentTime()
|
||
{
|
||
if(GetIsNight() || GetIsDusk())
|
||
{
|
||
return TIME_NIGHT;
|
||
}
|
||
return TIME_DAY;
|
||
}
|
||
|
||
void SwapAppearance(object oPC, string subrace)
|
||
{
|
||
string SubraceTag = SUBRACE_TAG + "_" + subrace;
|
||
int Level = GetPlayerLevel(oPC);
|
||
while(Level != 0)
|
||
{
|
||
string SubraceTag1 = SubraceTag + "_" + IntToString(Level);
|
||
int iTime = GetLocalGroupFlagValue(oStorer, SubraceTag1 + "_" + APPEARANCE_CHANGE, TIME_FLAGS);
|
||
if(iTime != 0)
|
||
{
|
||
if(SHA_GetDefaultAppearanceType(oPC) == GetAppearanceType(oPC))
|
||
{
|
||
ChangePCAppearance(oPC, SubraceTag1);
|
||
}
|
||
else
|
||
{
|
||
ChangeToPCDefaultAppearance(oPC);
|
||
}
|
||
return;
|
||
}
|
||
Level--;
|
||
}
|
||
}
|
||
void SubraceCheckItemActivated(object oPC, object oItem)
|
||
{
|
||
string subrace = GetStringLowerCase(GetSubRace(oPC));
|
||
if(subrace == "")
|
||
{ return; }
|
||
string sTag = GetStringLowerCase(GetTag(oItem));
|
||
if(subrace == sTag)
|
||
{
|
||
SwapAppearance(oPC, subrace);
|
||
}
|
||
|
||
}
|
||
|
||
void SubraceOnItemActivated()
|
||
{
|
||
object oPC = GetItemActivator();
|
||
object oItem = GetItemActivated();
|
||
SubraceCheckItemActivated(oPC, oItem);
|
||
}
|
||
|
||
void SubraceOnClientEnter()
|
||
{
|
||
object oPC = GetEnteringObject();
|
||
int infoLoaded = GetLocalInt(oPC, SUBRACE_INFO_LOADED_ON_PC);
|
||
if(!infoLoaded)
|
||
{
|
||
string subrace = GetStringLowerCase(GetSubRace(oPC));
|
||
if(subrace == "")
|
||
{ return; }
|
||
DelayCommand(1.0, InitiateSubraceChecking(oPC));
|
||
}
|
||
else
|
||
{
|
||
ReapplySubraceAbilities(oPC);
|
||
}
|
||
}
|
||
|
||
|
||
//Subrace Default Heartbeat. (For use in default.nss)
|
||
void SubraceHeartbeat(object oPC = OBJECT_SELF)
|
||
{
|
||
if(!GetLocalInt(oPC, SUBRACE_INFO_LOADED_ON_PC))
|
||
{ return; }
|
||
string subrace = GetLocalString(oPC, SUBRACE_TAG);
|
||
if(subrace == "")
|
||
{ return; }
|
||
|
||
string SubraceTag = SUBRACE_TAG + "_" + subrace;
|
||
|
||
int IsDay = GetIsDay();
|
||
int IsDawn = GetIsDawn();
|
||
|
||
int IsNight = GetIsNight();
|
||
int IsDusk = GetIsDusk();
|
||
|
||
object oArea = GetArea(oPC);
|
||
int AreaLocation = GetIsAreaAboveGround(oArea);
|
||
int Interior = GetIsAreaInterior(oArea);
|
||
int Natural = GetIsAreaNatural(oArea);
|
||
|
||
string oAreaTag = GetTag(oArea);
|
||
|
||
int HasDiffStats = GetLocalFlag(oPC, SubraceTag + "_" + SUBRACE_STAT_MODIFIERS, FLAG1);
|
||
|
||
if(IsDay || IsDawn)
|
||
{
|
||
if(AreaLocation == AREA_ABOVEGROUND && !Interior)
|
||
{
|
||
int IsLightSens = GetLocalGroupFlag(oPC, SubraceTag + "_" + SUBRACE_BASE_INFORMATION, SUBRACE_BASE_INFORMATION_LIGHT_SENSITIVE, SUBRACE_BASE_INFORMATION_FLAGS);
|
||
int DmgTakenL = GetLocalInt(oPC, SubraceTag + "_" + DAMAGE_AMOUNT_IN_LIGHT);
|
||
if(IsLightSens)
|
||
{
|
||
ApplyLightSensitivity(oPC);
|
||
}
|
||
if(DmgTakenL != 0)
|
||
{
|
||
ApplyDamageWhileInLight(oPC, DmgTakenL);
|
||
}
|
||
}
|
||
if(AreaLocation == AREA_UNDERGROUND)
|
||
{
|
||
int IsUndergSens = GetLocalGroupFlag(oPC, SubraceTag + "_" + SUBRACE_BASE_INFORMATION, SUBRACE_BASE_INFORMATION_UNDERGROUND_SENSITIVE, SUBRACE_BASE_INFORMATION_FLAGS);
|
||
int DmgTakenU = GetLocalInt(oPC, SubraceTag + "_" + DAMAGE_AMOUNT_IN_UNDERGROUND);
|
||
if(IsUndergSens)
|
||
{
|
||
ApplyUndergroundSensitivity(oPC);
|
||
}
|
||
if(DmgTakenU != 0)
|
||
{
|
||
ApplyDamageWhileInDark(oPC, DmgTakenU);
|
||
}
|
||
}
|
||
if(HasDiffStats)
|
||
{
|
||
ApplyTemporarySubraceStats(oPC, SubraceTag, TIME_DAY, AreaLocation, Interior, Natural);
|
||
}
|
||
if(!GetLocalInt(oPC, SUBRACE_TAG + "SB_DAY_OCE"))
|
||
{
|
||
ApplyTemporarySubraceAppearance(SubraceTag, oPC, TIME_DAY);
|
||
ApplySubraceEffect(oPC, SubraceTag, TIME_DAY);
|
||
CheckIfCanUseEquipedWeapon(oPC);
|
||
DelayCommand(2.0, EquipTemporarySubraceSkin(SubraceTag, oPC, TIME_DAY));
|
||
DelayCommand(6.0, EquipTemporarySubraceClaw(SubraceTag, oPC, TIME_DAY));
|
||
SetLocalInt(oPC, SUBRACE_TAG + "SB_DAY_OCE", TRUE);
|
||
DeleteLocalInt(oPC, SUBRACE_TAG + "SB_NITE_OCE");
|
||
}
|
||
}
|
||
else if(IsNight || IsDusk)
|
||
{
|
||
if(AreaLocation == AREA_UNDERGROUND)
|
||
{
|
||
int IsUndergSens = GetLocalGroupFlag(oPC, SubraceTag + "_" + SUBRACE_BASE_INFORMATION, SUBRACE_BASE_INFORMATION_UNDERGROUND_SENSITIVE, SUBRACE_BASE_INFORMATION_FLAGS);
|
||
int DmgTakenU = GetLocalInt(oPC, SubraceTag + "_" + DAMAGE_AMOUNT_IN_UNDERGROUND);
|
||
if(IsUndergSens)
|
||
{
|
||
ApplyUndergroundSensitivity(oPC);
|
||
}
|
||
if(DmgTakenU > 0)
|
||
{
|
||
ApplyDamageWhileInDark(oPC, DmgTakenU);
|
||
}
|
||
}
|
||
if(HasDiffStats)
|
||
{
|
||
ApplyTemporarySubraceStats(oPC, SubraceTag, TIME_NIGHT, AreaLocation, Interior, Natural);
|
||
}
|
||
if(!GetLocalInt(oPC, SUBRACE_TAG + "SB_NITE_OCE"))
|
||
{
|
||
ApplyTemporarySubraceAppearance(SubraceTag, oPC, TIME_NIGHT);
|
||
|
||
ApplySubraceEffect(oPC, SubraceTag, TIME_NIGHT);
|
||
CheckIfCanUseEquipedWeapon(oPC);
|
||
DelayCommand(2.0, EquipTemporarySubraceSkin(SubraceTag, oPC, TIME_NIGHT));
|
||
DelayCommand(6.0, EquipTemporarySubraceClaw(SubraceTag, oPC, TIME_NIGHT));
|
||
SetLocalInt(oPC, SUBRACE_TAG + "SB_NITE_OCE", TRUE);
|
||
DeleteLocalInt(oPC, SUBRACE_TAG + "SB_DAY_OCE");
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
//void main() { }
|