//:://///////////////////////////////////////////// //:: Greater Wild Shape, Humanoid Shape //:: x2_s2_gwildshp //:: Copyright (c) 2003 Bioware Corp. //::////////////////////////////////////////////// /* Allows the character to shift into one of these forms, gaining special abilities Credits must be given to mr_bumpkin from the NWN community who had the idea of merging item properties from weapon and armor to the creatures new forms. */ //::////////////////////////////////////////////// //:: Created By: Georg Zoeller //:: Created On: 2003-07-02 //::////////////////////////////////////////////// #include "x2_inc_shifter" #include "x2_inc_itemprop" void LDAddItemProperty(itemproperty ip,object oNew, int First=FALSE, int Last=FALSE) { if(First) { SetLocalInt(oNew,"AC",0);SetLocalInt(oNew,"CHA",0);SetLocalInt(oNew,"DEX",0); SetLocalInt(oNew,"INT",0);SetLocalInt(oNew,"WIS",0);SetLocalInt(oNew,"STR",0); SetLocalInt(oNew,"CON",0);SetLocalInt(oNew,"REGEN",0); } if(GetItemPropertyType(ip) == ITEM_PROPERTY_AC_BONUS) {int iAC = GetLocalInt(oNew,"AC")+GetItemPropertyCostTableValue(ip); SetLocalInt(oNew,"AC",(iAC > 20 ? 20 : iAC));} else if(GetItemPropertyType(ip) == ITEM_PROPERTY_ABILITY_BONUS) { switch(GetItemPropertySubType(ip)) { case ABILITY_CHARISMA:{int iAB = GetLocalInt(oNew,"CHA")+GetItemPropertyCostTableValue(ip); SetLocalInt(oNew,"CHA",(iAB > 12 ? 12 : iAB));}break; case ABILITY_CONSTITUTION:{int iAB = GetLocalInt(oNew,"CON")+GetItemPropertyCostTableValue(ip); SetLocalInt(oNew,"CON",(iAB > 12 ? 12 : iAB));}break; case ABILITY_DEXTERITY:{int iAB = GetLocalInt(oNew,"DEX")+GetItemPropertyCostTableValue(ip); SetLocalInt(oNew,"DEX",(iAB > 12 ? 12 : iAB));}break; case ABILITY_INTELLIGENCE:{int iAB = GetLocalInt(oNew,"INT")+GetItemPropertyCostTableValue(ip); SetLocalInt(oNew,"INT",(iAB > 12 ? 12 : iAB));}break; case ABILITY_WISDOM:{int iAB = GetLocalInt(oNew,"WIS")+GetItemPropertyCostTableValue(ip); SetLocalInt(oNew,"WIS",(iAB > 12 ? 12 : iAB));}break; case ABILITY_STRENGTH:{int iAB = GetLocalInt(oNew,"STR")+GetItemPropertyCostTableValue(ip); SetLocalInt(oNew,"STR",(iAB > 12 ? 12 : iAB));}break; } } else if(GetItemPropertyType(ip) == ITEM_PROPERTY_REGENERATION) { int iREG = GetLocalInt(oNew,"REGEN")+GetItemPropertyCostTableValue(ip); SetLocalInt(oNew,"REGEN",(iREG > 20 ? 20 : iREG)); } else { AddItemProperty(DURATION_TYPE_PERMANENT,ip,oNew); } if(Last) { if(GetItemPropertyType(ip) != ITEM_PROPERTY_ABILITY_BONUS && GetItemPropertyType(ip) != ITEM_PROPERTY_AC_BONUS && GetItemPropertyType(ip) != ITEM_PROPERTY_REGENERATION) {AddItemProperty(DURATION_TYPE_PERMANENT,ip,oNew);} if(GetLocalInt(oNew,"AC") > 0) {AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyACBonus(GetLocalInt(oNew,"AC")),oNew); DeleteLocalInt(oNew,"AC");} if(GetLocalInt(oNew,"CHA") > 0) {AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyAbilityBonus(ABILITY_CHARISMA,GetLocalInt(oNew,"CHA")),oNew); DeleteLocalInt(oNew,"CHA");} if(GetLocalInt(oNew,"CON") > 0) {AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyAbilityBonus(ABILITY_CONSTITUTION,GetLocalInt(oNew,"CON")),oNew); DeleteLocalInt(oNew,"CON");} if(GetLocalInt(oNew,"DEX") > 0) {AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyAbilityBonus(ABILITY_DEXTERITY,GetLocalInt(oNew,"DEX")),oNew); DeleteLocalInt(oNew,"DEX");} if(GetLocalInt(oNew,"WIS") > 0) {AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyAbilityBonus(ABILITY_WISDOM,GetLocalInt(oNew,"WIS")),oNew); DeleteLocalInt(oNew,"WIS");} if(GetLocalInt(oNew,"INT") > 0) {AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyAbilityBonus(ABILITY_INTELLIGENCE,GetLocalInt(oNew,"INT")),oNew); DeleteLocalInt(oNew,"INT");} if(GetLocalInt(oNew,"STR") > 0) {AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyAbilityBonus(ABILITY_STRENGTH,GetLocalInt(oNew,"STR")),oNew); DeleteLocalInt(oNew,"STR");} if(GetLocalInt(oNew,"REGEN") > 0) {AddItemProperty(DURATION_TYPE_PERMANENT,ItemPropertyRegeneration(GetLocalInt(oNew,"REGEN")),oNew); DeleteLocalInt(oNew,"REGEN");} } } void LDWildShapeCopyItemProperties(object oOld, object oNew, int Last=FALSE, int First=FALSE, int bWeapon=FALSE) { if (GetIsObjectValid(oOld) && GetIsObjectValid(oNew)) { int Count = 0;int Current = 0; itemproperty ip = GetFirstItemProperty(oOld); while (GetIsItemPropertyValid(ip)) { Count ++; ip = GetNextItemProperty(oOld); } itemproperty iip = GetFirstItemProperty(oOld); while (GetIsItemPropertyValid(iip)) { if (bWeapon) { if (GetWeaponRanged(oOld) == GetWeaponRanged(oNew)) { AddItemProperty(DURATION_TYPE_PERMANENT,iip,oNew); } } else { if(First && (Current == 0)) {LDAddItemProperty(iip,oNew,TRUE); Current ++; } else if(Last && (Current == Count-1)) {LDAddItemProperty(iip,oNew,FALSE,TRUE); Current ++; } else { LDAddItemProperty(iip,oNew); Current ++; } } iip = GetNextItemProperty(oOld); } } } int GetIsDamageing(object oGlove) { int Result = FALSE; itemproperty ip = GetFirstItemProperty(oGlove); while(GetIsItemPropertyValid(ip)) { if(GetItemPropertyType(ip) == ITEM_PROPERTY_DAMAGE_BONUS || GetItemPropertyType(ip) == ITEM_PROPERTY_DAMAGE_BONUS_VS_ALIGNMENT_GROUP || GetItemPropertyType(ip) == ITEM_PROPERTY_DAMAGE_BONUS_VS_RACIAL_GROUP || GetItemPropertyType(ip) == ITEM_PROPERTY_DAMAGE_BONUS_VS_SPECIFIC_ALIGNMENT) {Result = TRUE;} ip = GetNextItemProperty(oGlove); } return Result; } int GetIsUnarmed() { return (GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,OBJECT_SELF) == OBJECT_INVALID && GetItemInSlot(INVENTORY_SLOT_LEFTHAND,OBJECT_SELF) == OBJECT_INVALID); } void LDShifterSetGWildshapeSpellLimits(int nSpellId) { string sId; int nLevel = GetLevelByClass(CLASS_TYPE_SHIFTER); switch (nSpellId) { case 673: // Drider Shape sId = "688"; // SpellIndex of Drider Darkness Ability SetLocalInt(OBJECT_SELF,"X2_GWILDSHP_LIMIT_" + sId, 1 + nLevel/2); break; case 670 : // Basilisk Shape sId = "687"; // SpellIndex of Petrification Gaze Ability SetLocalInt(OBJECT_SELF,"X2_GWILDSHP_LIMIT_" + sId, 1 + nLevel/2); break; case 679 : // Medusa Shape sId = "687"; // SpellIndex of Petrification Gaze Ability SetLocalInt(OBJECT_SELF,"X2_GWILDSHP_LIMIT_" + sId, 1+ nLevel); break; case 682 : // Drow shape sId = "688"; // Darkness Ability SetLocalInt(OBJECT_SELF,"X2_GWILDSHP_LIMIT_" + sId,1+ nLevel); break; case 691 : // Mindflayer shape sId = "693"; // SpellIndex Mind Blast Ability SetLocalInt(OBJECT_SELF,"X2_GWILDSHP_LIMIT_" + sId, 1 + nLevel); break; case 705: // Vampire Domination Gaze sId = "800"; SetLocalInt(OBJECT_SELF,"X2_GWILDSHP_LIMIT_" + sId, 1 + nLevel); break; } } void main() { //-------------------------------------------------------------------------- // Declare major variables //-------------------------------------------------------------------------- int nSpell = GetSpellId(); object oTarget = GetSpellTargetObject(); effect eVis = EffectVisualEffect(VFX_IMP_POLYMORPH); int nShifter = GetLevelByClass(CLASS_TYPE_SHIFTER); effect ePoly; int nPoly; int Unarmed = GetIsUnarmed(); // Feb 13, 2004, Jon: Added scripting to take care of case where it's an NPC // using one of the feats. It will randomly pick one of the shapes associated // with the feat. switch(nSpell) { // Greater Wildshape I case 646: nSpell = Random(5)+658; break; // Greater Wildshape II case 675: switch(Random(3)) { case 0: nSpell = 672; break; case 1: nSpell = 678; break; case 2: nSpell = 680; } break; // Greater Wildshape III case 676: switch(Random(3)) { case 0: nSpell = 670; break; case 1: nSpell = 673; break; case 2: nSpell = 674; } break; // Greater Wildshape IV case 677: switch(Random(3)) { case 0: nSpell = 679; break; case 1: nSpell = 691; break; case 2: nSpell = 694; } break; // Humanoid Shape case 681: nSpell = Random(3)+682; break; // Undead Shape case 685: nSpell = Random(3)+704; break; // Dragon Shape case 725: nSpell = Random(3)+707; break; // Outsider Shape case 732: nSpell = Random(3)+733; break; // Construct Shape case 737: nSpell = Random(3)+738; break; } //-------------------------------------------------------------------------- // Determine which form to use based on spell id, gender and level //-------------------------------------------------------------------------- switch (nSpell) { //----------------------------------------------------------------------- // Greater Wildshape I - Wyrmling Shape //----------------------------------------------------------------------- case 658: nPoly = POLYMORPH_TYPE_WYRMLING_RED; break; case 659: nPoly = POLYMORPH_TYPE_WYRMLING_BLUE; break; case 660: nPoly = POLYMORPH_TYPE_WYRMLING_BLACK; break; case 661: nPoly = POLYMORPH_TYPE_WYRMLING_WHITE; break; case 662: nPoly = POLYMORPH_TYPE_WYRMLING_GREEN; break; //----------------------------------------------------------------------- // Greater Wildshape II - Minotaur, Gargoyle, Harpy //----------------------------------------------------------------------- case 672: if (nShifter < X2_GW2_EPIC_THRESHOLD) nPoly = POLYMORPH_TYPE_HARPY; else nPoly = 97; break; case 678: if (nShifter < X2_GW2_EPIC_THRESHOLD) nPoly = POLYMORPH_TYPE_GARGOYLE; else nPoly = 98; break; case 680: if (nShifter < X2_GW2_EPIC_THRESHOLD) // minotaur { if(Unarmed) {nPoly = 182;} else {nPoly = POLYMORPH_TYPE_MINOTAUR;} } else { if(Unarmed) {nPoly = 190;} else {nPoly = 96;} } break; case 1501: if (nShifter < X2_GW2_EPIC_THRESHOLD) //ogre { if(Unarmed) {nPoly = 203;} else {nPoly = 159;} } else { if(Unarmed) {nPoly = 204;} else {nPoly = 160;} } break; case 1502: if (nShifter < X2_GW2_EPIC_THRESHOLD) // gorgon nPoly = 158; else nPoly = 173; break; //----------------------------------------------------------------------- // Greater Wildshape III - Drider, Basilisk, Manticore //----------------------------------------------------------------------- case 670: if (nShifter < X2_GW3_EPIC_THRESHOLD) nPoly = POLYMORPH_TYPE_BASILISK; else nPoly = 99; break; case 673: if (nShifter < X2_GW3_EPIC_THRESHOLD) { if(Unarmed) {nPoly = 181;} else {nPoly = POLYMORPH_TYPE_DRIDER;} } else { if(Unarmed) {nPoly = 191;} else {nPoly = 100;} } break; case 674: if (nShifter < X2_GW3_EPIC_THRESHOLD) nPoly = POLYMORPH_TYPE_MANTICORE; else nPoly = 101; break; case 1503: if (nShifter < X2_GW3_EPIC_THRESHOLD) nPoly = 162; else //will o wisp nPoly = 175; break; case 1504: if (nShifter < X2_GW3_EPIC_THRESHOLD) nPoly = 161; else //umber hulk nPoly = 174; break; //----------------------------------------------------------------------- // Greater Wildshape IV - Dire Tiger, Medusa, MindFlayer //----------------------------------------------------------------------- case 679: nPoly = POLYMORPH_TYPE_MEDUSA; break; case 691: nPoly = 68; break; // Mindflayer case 694: nPoly = 69; break; // DireTiger case 1507: if(GetGender(OBJECT_SELF) == GENDER_MALE) // frost giant { if(Unarmed) {nPoly = 200;} else {nPoly = 155;} } else { if(Unarmed) {nPoly = 201;} else {nPoly = 156;} }break; case 1508: nPoly = 176; break; // grey render //----------------------------------------------------------------------- // Humanoid Shape - Kobold Commando, Drow, Lizard Crossbow Specialist //----------------------------------------------------------------------- case 682: if(nShifter< 17) { if (GetGender(OBJECT_SELF) == GENDER_MALE) //drow {if(Unarmed) {nPoly = 179;} else {nPoly = 59;}} else {if(Unarmed) {nPoly = 180;} else {nPoly = 70;}} } else { if (GetGender(OBJECT_SELF) == GENDER_MALE) //drow {if(Unarmed) {nPoly = 194;} else {nPoly = 105;}} else {if(Unarmed) {nPoly = 195;} else {nPoly = 106;}} } break; case 683: if(nShifter< 17) { if(Unarmed) {nPoly = 184;} else {nPoly = 82;} break; // Lizard } else { if(Unarmed) {nPoly = 193;} else {nPoly =104;} break; // Epic Lizard } case 684: if(nShifter< 17) { if(Unarmed) {nPoly = 185;} else {nPoly = 83;} break; // Kobold Commando } else { if(Unarmed) {nPoly = 192;} else {nPoly = 103;} break; // Kobold Commando } case 1505: if(nShifter< 17) { if(Unarmed) {nPoly = 207;} else {nPoly = 165;} break; // Stinger } else { if(Unarmed) {nPoly = 208;} else {nPoly = 166;} break; // Epic Stinger } case 1506: if(nShifter< 17) { if(Unarmed) {nPoly = 205;} else {nPoly = 163;} break; // Gnoll } else { if(Unarmed) {nPoly = 206;} else {nPoly = 164;} break; // Epic Gnoll } //----------------------------------------------------------------------- // Undead Shape - Spectre, Risen Lord, Vampire //----------------------------------------------------------------------- case 704: if(Unarmed) // Risen lord {nPoly = 183;} else {nPoly = 75;} break; case 705: if (GetGender(OBJECT_SELF) == GENDER_MALE) // vampire nPoly = 74; else nPoly = 77; break; case 706: nPoly = 76; break; /// spectre case 1509:if(Unarmed) /// mummy lord {nPoly = 202;} else {nPoly = 157;} break; case 1510: nPoly = 168; break; /// alhoon //----------------------------------------------------------------------- // Dragon Shape - Red Blue and Green Dragons //----------------------------------------------------------------------- case 707: nPoly = 72; break; // Ancient Red Dragon case 708: nPoly = 71; break; // Ancient Blue Dragon case 709: nPoly = 73; break; // Ancient Green Dragon case 1515: nPoly = 171; break; // Prismatic Dragon case 1516: nPoly = 170; break; // Ancient Shadow Dragon //----------------------------------------------------------------------- // Outsider Shape - Rakshasa, Azer Chieftain, Black Slaad //----------------------------------------------------------------------- case 733: if (GetGender(OBJECT_SELF) == GENDER_MALE) //azer { if(Unarmed) {nPoly = 186;} else {nPoly = 85;} } else // anything else is female { if(Unarmed) {nPoly = 187;} else {nPoly = 86;} } break; case 734: if (GetGender(OBJECT_SELF) == GENDER_MALE) //rakshasa { if(Unarmed) {nPoly = 188;} else {nPoly = 88;} } else // anything else is female { if(Unarmed) {nPoly = 189;} else {nPoly = 89;} } break; case 735: nPoly =87; break; // slaad case 1511: if(Unarmed) // hound archon {nPoly = 196;} else {nPoly =151;} break; case 1512: if(Unarmed) // formian {nPoly = 209;} else {nPoly =172;} break; //----------------------------------------------------------------------- // Construct Shape - Stone Golem, Iron Golem, Demonflesh Golem //----------------------------------------------------------------------- case 738: nPoly =91; break; // stone golem case 739: nPoly =92; break; // demonflesh golem case 740: nPoly =90; break; // iron golem case 1513: if(Unarmed) // battle horror {nPoly = 197;} else {nPoly =152;} break; case 1514: nPoly =169; break; // mithral golem } //-------------------------------------------------------------------------- // Determine which items get their item properties merged onto the shifters // new form. //-------------------------------------------------------------------------- int bWeapon = ShifterMergeWeapon(nPoly); int bArmor = TRUE; int bItems = TRUE; //-------------------------------------------------------------------------- // Store the old objects so we can access them after the character has // changed into his new form //-------------------------------------------------------------------------- object oWeaponOld = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,OBJECT_SELF); object oArmorOld = GetItemInSlot(INVENTORY_SLOT_CHEST,OBJECT_SELF); object oRing1Old = GetItemInSlot(INVENTORY_SLOT_LEFTRING,OBJECT_SELF); object oRing2Old = GetItemInSlot(INVENTORY_SLOT_RIGHTRING,OBJECT_SELF); object oAmuletOld = GetItemInSlot(INVENTORY_SLOT_NECK,OBJECT_SELF); object oCloakOld = GetItemInSlot(INVENTORY_SLOT_CLOAK,OBJECT_SELF); object oBootsOld = GetItemInSlot(INVENTORY_SLOT_BOOTS,OBJECT_SELF); object oBeltOld = GetItemInSlot(INVENTORY_SLOT_BELT,OBJECT_SELF); object oHelmetOld = GetItemInSlot(INVENTORY_SLOT_HEAD,OBJECT_SELF); object oShield = GetItemInSlot(INVENTORY_SLOT_LEFTHAND,OBJECT_SELF); object oArmsOld = GetItemInSlot(INVENTORY_SLOT_ARMS,OBJECT_SELF); object oHandsOld = GetItemInSlot(INVENTORY_SLOT_ARMS,OBJECT_SELF); if (GetIsObjectValid(oShield)) { if (GetBaseItemType(oShield) !=BASE_ITEM_LARGESHIELD && GetBaseItemType(oShield) !=BASE_ITEM_SMALLSHIELD && GetBaseItemType(oShield) !=BASE_ITEM_TOWERSHIELD) { oShield = OBJECT_INVALID; } } if(Unarmed) { if(GetIsDamageing(oHandsOld)) {oArmsOld = OBJECT_INVALID;} else {oHandsOld = OBJECT_INVALID;} } string sCopied = " Copied properties from:"; sCopied += " Armor, Helmet"; if(GetIsObjectValid(oShield)) {sCopied += ", Shield";} sCopied += ", Rings, Amulet, Cloak, Boots, Belt"; if(GetIsObjectValid(oArmsOld) && GetBaseItemType(oArmsOld) == BASE_ITEM_BRACER) {sCopied += ", Bracers";} //-------------------------------------------------------------------------- // Here the actual polymorphing is done //-------------------------------------------------------------------------- ePoly = EffectPolymorph(nPoly); ePoly = ExtraordinaryEffect(ePoly); ClearAllActions(); // prevents an exploit ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, OBJECT_SELF); ApplyEffectToObject(DURATION_TYPE_PERMANENT, ePoly, OBJECT_SELF); SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, GetSpellId(), FALSE)); //-------------------------------------------------------------------------- // This code handles the merging of item properties //-------------------------------------------------------------------------- object oWeaponNew = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND,OBJECT_SELF); object oArmorNew = GetItemInSlot(INVENTORY_SLOT_CARMOUR,OBJECT_SELF); object oClawNew = GetItemInSlot(INVENTORY_SLOT_CWEAPON_R,OBJECT_SELF); object oSlamNew = GetItemInSlot(INVENTORY_SLOT_CWEAPON_L,OBJECT_SELF); object oBiteNew = GetItemInSlot(INVENTORY_SLOT_CWEAPON_B,OBJECT_SELF); SetIdentified(oWeaponNew, TRUE); if (bWeapon) { LDWildShapeCopyItemProperties(oWeaponOld,oWeaponNew, FALSE,FALSE,TRUE); if(GetIsObjectValid(oWeaponOld)){sCopied += ", Weapon";} } else { if(Unarmed){ if(GetIsObjectValid(oHandsOld)) { LDWildShapeCopyItemProperties(oHandsOld,oClawNew, FALSE,FALSE); LDWildShapeCopyItemProperties(oHandsOld,oSlamNew, FALSE,FALSE); LDWildShapeCopyItemProperties(oHandsOld,oBiteNew, FALSE,FALSE); sCopied += ", Gloves to unarmed attacks"; }} } LDWildShapeCopyItemProperties(oArmorOld,oArmorNew,FALSE,TRUE); LDWildShapeCopyItemProperties(oHelmetOld,oArmorNew); LDWildShapeCopyItemProperties(oShield,oArmorNew); LDWildShapeCopyItemProperties(oArmsOld,oArmorNew); LDWildShapeCopyItemProperties(oBeltOld,oArmorNew); LDWildShapeCopyItemProperties(oAmuletOld,oArmorNew); LDWildShapeCopyItemProperties(oCloakOld,oArmorNew); LDWildShapeCopyItemProperties(oBootsOld,oArmorNew); LDWildShapeCopyItemProperties(oRing1Old,oArmorNew); LDWildShapeCopyItemProperties(oRing2Old,oArmorNew,TRUE); LDShifterSetGWildshapeSpellLimits(nSpell); SendMessageToPC(oTarget,sCopied); }