Polymorph Self
-
Yeah, OnPlayerChat is pretty crowded, and only likely to get moreso. Dumping 100some line tables into it would get pretty bloated to try and find any sort of bugs.
-
I still think you want to make sure the value set is valid at the time it is being set or the caster will get a nasty surprise when polymorphing in the heat of battle, and by then any feedback wouldn't be as useful anymore
You can keep the player chat 'clean' (although according to other posts it is already pretty messy: /forum/viewtopic.php?t=107485&start=3 ) the way set kept the wildshape one clean, just call a worker script (or if the compiler/preprocessor being used allows it, use an include file.)
-
I still think you want to make sure the value set is valid at the time it is being set or the caster will get a nasty surprise when polymorphing in the heat of battle
Very good thinking. I suppose we can extract a function to check and determine the form and place it in a already included script, if CoA wishes to avoid new scripts.
But… If we don't include the same function call in the polymorph spell script, a non-valid form ID may its way to the poly spell script and the spell will fail or something strange will happen. Still, I dunno how anything but zero or undefined can make its way there, unless the 2da file is altered. We can check for those two and default to some neutral form. -
We can check for those two and default to some neutral form.
yes, you do have to do some checking of the validity of the stored state just before blindly using it, as it might be corrupted, not initialised etc. so that you know that if it's not what you expect it to be, you won't crash your plane or do something really unexpected, but some more or less harmless default instead. You (should) do this for digital circuits in hardware, it makes sense to do it for software too.
Anyway, if the state is already an integer instead of a string, your state-space is smaller, and also you can use a 'switch' instead of a big 'if-then-else'. I don't know if the 'switch' is compiled to anything different than the 'if-then-else', even if it isn't, a 'switch' is easier to read, especially if you have a few simple checks in advance to make sure the integer is between 0 and some MAX_POLY_ID constant you'd set up, and use fall through for ranges of invalid/undefined IDs.
Normally it's also a lot cheaper to use an integer as an index into a jump table (switch) than to repeatedly compare values until you find a match (if-tree).The conversion function is going to be rather a lot of work to type in, as you can't just use a hash table, or even iterate over an array, so I hope you're (or will be) using a program to generate the script text from the plain list of IDs and their Strings, so it's easier to change your mind on how to exactly implement/streamline the conversion function without having to do a lot of re-typing.
-
Um… yes. I did use a python script to generate the nwscript, but it's just bad practice to repeat the same code twice. Nwscript doesn't support hashtables, and arrays have to be done via a string codec or some similar hack.
It's easy to check if 0 < nPoly < MAX_POLY_ID, but the unexpected can occur if it's a valid value not found in the ploymorph.2da
If we get a valid nPoly into the polymorph spell script, we don't need a switch. Not unless CoA wishes to maintain two separate, identical tables.
That said, I vote to keep it simple. On each restart, reset the nPoly to zero, which keeps the original spell working as it is. If someone uses the chat command to change it, they risk miss-spelling, or using a wrong number. And they will find out when the poly spell is cast - it will end up being a normal poly spell. Wizardry is a dangerous business and miscasts happen. :)
I'll do the changes tomorrow.
-
if you're finding yourself typing the same code twice, you're not using functions enough, (or down to unrolling loops and inlining functions by hand because your compiler can't do it for you :) )
-
Here are the scripts with some modifications:
- Fixed spelling on basilisk and intellect devourer
- Added an option to cast spell right away (end cmd with "!")
- Now checking only for start of string (so ".ps mino" is as good as ".ps minotaur")
- Some feedback if you type ".ps" with no param, some defensive checks
- If bad param or no param, defaults to chicken. This will be a pixie.
- Reduced the number of ifs each time spell is cast to a perfectly acceptable amount, in average case.
- sFormID converted to uppercase at the start
Remaining to be considered:
- Currently no feedback after chat command, only after spell is cast
- Currently can't use number (i.e. .ps 140). Since it still has to be checked for HD and existence, it's same as alias.
- Add aliases as OR conditions.
- Better feedback (Bad spelling or not enough HD?)
// -------- From onPlayerChat ----------- object oPC = GetPCChatSpeaker(); string sCommand = GetPCChatMessage(); if (GetStringLeft(sCommand, 3) == ".ps") { int nCmdLength = GetStringLength(sCommand); int nCastNow = FALSE; // Check if there's any param to the chat command if (nCmdLength <= 4) { SendMessageToPC(oPC, "Usage: .ps <shape>"); return; } // Does it end with "!"? if (GetStringRight(sCommand, 1) == "!") nCastNow = TRUE; string sPolyFormID = GetSubString(sCommand, 4, nCmdLength - (nCastNow?5:4)); SetLocalString(oPC, "sPolyFormID", sPolyFormID); SendMessageToPC(oPC, "Poly set at: " + sPolyFormID); // Assign cast spell if ends with "!" if (nCastNow) AssignCommand(oPC, ActionCastSpellAtObject(SPELL_POLYMORPH_SELF, oPC)); }</shape>
// -------- nw_s0_polyself -------
#include "x2_inc_spellhook"// Returns true if sCreatureName starts with sFormID
int ComparePolyStr(string sFormID, string sCreatureName) {
return GetStringLeft(sCreatureName, GetStringLength(sFormID)) == sFormID;
}void main()
{/*
Spellcast Hook Code
Added 2003-06-23 by GeorgZ
If you want to make changes to all spells,
check x2_inc_spellhook.nss to find out more*/
if (!X2PreSpellCastCode())
{
// If code within the PreSpellCastHook (i.e. UMD) reports FALSE, do not run this spell
return;
}// End of Spell Cast Hook
//Declare major variables int nSpell = GetSpellId(); object oTarget = GetSpellTargetObject(); effect eVis = EffectVisualEffect(VFX_IMP_POLYMORPH); effect ePoly; int nPoly = 0; string sFormID = GetStringUpperCase(GetLocalString(OBJECT_SELF, "sPolyFormID")); int nCasterLevel = GetCasterLevel(OBJECT_SELF); int nTargetHD = GetHitDice(oTarget); int nMaxHD = (nCasterLevel < nTargetHD) ? nCasterLevel : nTargetHD; // Determine duration int nMetaMagic = GetMetaMagicFeat(); int nDuration = nCasterLevel; if (nMetaMagic == METAMAGIC_EXTEND) { nDuration = nDuration *2; //Duration is +100% } // -------------------------------- // --- Determine Polymorph type --- // HD 1 if (nMaxHD >= 1 && nPoly == 0) { if(ComparePolyStr(sFormID, "EYEBALL")) { nPoly = 213; } else if(ComparePolyStr(sFormID, "GOBLIN")) { nPoly = 157; } else if(ComparePolyStr(sFormID, "HOBGOBLIN")) { nPoly = 163; } else if(ComparePolyStr(sFormID, "KOBOLD")) { nPoly = 165; } else if(ComparePolyStr(sFormID, "ORC")) { nPoly = 166; } else if(ComparePolyStr(sFormID, "FIRE BEETLE")) { nPoly = 177; } else if(ComparePolyStr(sFormID, "CHICKEN")) { nPoly = 40; } else if(ComparePolyStr(sFormID, "FALCON")) { nPoly = 133; } else if(ComparePolyStr(sFormID, "PENGUIN")) { nPoly = 26; } else if(ComparePolyStr(sFormID, "RAVEN")) { nPoly = 134; } else if(ComparePolyStr(sFormID, "RAT")) { nPoly = 144; } else if(ComparePolyStr(sFormID, "OX")) { nPoly = 143; } else if(ComparePolyStr(sFormID, "BADGER")) { nPoly = 25; } else if(ComparePolyStr(sFormID, "BAT")) { nPoly = 140; } else if(ComparePolyStr(sFormID, "COW")) { nPoly = 27; } else if(ComparePolyStr(sFormID, "DEER")) { nPoly = 142; } else if(ComparePolyStr(sFormID, "DIRE RAT")) { nPoly = 149; } else if(ComparePolyStr(sFormID, "CHICKEN")) { nPoly = 40; } else if(ComparePolyStr(sFormID, "WHITE STAG")) { nPoly = 145; } } // HD 2 if (nMaxHD >= 2 && nPoly == 0) { if(ComparePolyStr(sFormID, "TROGLODYTE")) { nPoly = 312; } else if(ComparePolyStr(sFormID, "LIZARDFOLK")) { nPoly = 170; } else if(ComparePolyStr(sFormID, "GNOLL")) { nPoly = 158; } else if(ComparePolyStr(sFormID, "DEEP ROTHE")) { nPoly = 190; } else if(ComparePolyStr(sFormID, "KRENSHAR")) { nPoly = 194; } else if(ComparePolyStr(sFormID, "BOMBADIER BEETLE")) { nPoly = 176; } else if(ComparePolyStr(sFormID, "FAERIE DRAGON")) { nPoly = 224; } else if(ComparePolyStr(sFormID, "PSEUDODRAGON")) { nPoly = 225; } else if(ComparePolyStr(sFormID, "DOG")) { nPoly = 130; } else if(ComparePolyStr(sFormID, "WOLF")) { nPoly = 23; } } // HD 3 if (nMaxHD >= 3 && nPoly == 0) { if(ComparePolyStr(sFormID, "BUGBEAR")) { nPoly = 152; } else if(ComparePolyStr(sFormID, "SEA HAG")) { nPoly = 168; } else if(ComparePolyStr(sFormID, "STINK BEETLE")) { nPoly = 179; } else if(ComparePolyStr(sFormID, "SWORD SPIDER")) { nPoly = 181; } else if(ComparePolyStr(sFormID, "WYRMLING WHITE DRAGON")) { nPoly = 235; } else if(ComparePolyStr(sFormID, "BLACK BEAR")) { nPoly = 131; } else if(ComparePolyStr(sFormID, "COUGAR")) { nPoly = 135; } else if(ComparePolyStr(sFormID, "CRAG CAT")) { nPoly = 136; } else if(ComparePolyStr(sFormID, "LEOPARD")) { nPoly = 138; } else if(ComparePolyStr(sFormID, "PANTHER")) { nPoly = 22; } else if(ComparePolyStr(sFormID, "BOAR")) { nPoly = 24; } else if(ComparePolyStr(sFormID, "DIRE BADGER")) { nPoly = 37; } } // HD 4 if (nMaxHD >= 4 && nPoly == 0) { if(ComparePolyStr(sFormID, "OGRE")) { nPoly = 174; } else if(ComparePolyStr(sFormID, "STINGER")) { nPoly = 169; } else if(ComparePolyStr(sFormID, "GELATINOUS CUBE")) { nPoly = 208; } else if(ComparePolyStr(sFormID, "GARGOYLE")) { nPoly = 191; } else if(ComparePolyStr(sFormID, "GIANT SPIDER")) { nPoly = 180; } else if(ComparePolyStr(sFormID, "WYRMLING BLACK DRAGON")) { nPoly = 226; } else if(ComparePolyStr(sFormID, "WYRMLING BRASS DRAGON")) { nPoly = 228; } else if(ComparePolyStr(sFormID, "WORG")) { nPoly = 258; } } // HD 5 if (nMaxHD >= 5 && nPoly == 0) { if(ComparePolyStr(sFormID, "ETTERCAP")) { nPoly = 212; } else if(ComparePolyStr(sFormID, "HOOK HORROR")) { nPoly = 214; } else if(ComparePolyStr(sFormID, "COCKATRICE")) { nPoly = 189; } else if(ComparePolyStr(sFormID, "WYRMLING COPPER DRAGON")) { nPoly = 230; } else if(ComparePolyStr(sFormID, "WYRMLING GREEN DRAGON")) { nPoly = 232; } else if(ComparePolyStr(sFormID, "JAGUAR")) { nPoly = 137; } else if(ComparePolyStr(sFormID, "LION")) { nPoly = 139; } } // HD 6 if (nMaxHD >= 6 && nPoly == 0) { if(ComparePolyStr(sFormID, "DRIDER")) { nPoly = 211; } else if(ComparePolyStr(sFormID, "FEMALE DRIDER")) { nPoly = 307; } else if(ComparePolyStr(sFormID, "INTELLECT DEVOURER")) { nPoly = 215; } else if(ComparePolyStr(sFormID, "TROLL")) { nPoly = 175; } else if(ComparePolyStr(sFormID, "YUAN-TI")) { nPoly = 171; } else if(ComparePolyStr(sFormID, "MINOTAUR")) { nPoly = 172; } else if(ComparePolyStr(sFormID, "MEDUSA")) { nPoly = 167; } else if(ComparePolyStr(sFormID, "BASILISK")) { nPoly = 197; } else if(ComparePolyStr(sFormID, "MANTICORE")) { nPoly = 195; } else if(ComparePolyStr(sFormID, "WYRMLING BLUE DRAGON")) { nPoly = 227; } else if(ComparePolyStr(sFormID, "WYRMLING BRONZE DRAGON")) { nPoly = 229; } else if(ComparePolyStr(sFormID, "BROWN BEAR")) { nPoly = 21; } else if(ComparePolyStr(sFormID, "WINTER WOLF")) { nPoly = 257; } else if(ComparePolyStr(sFormID, "DIRE WOLF")) { nPoly = 35; } } // HD 7 if (nMaxHD >= 7 && nPoly == 0) { if(ComparePolyStr(sFormID, "HARPY")) { nPoly = 173; } else if(ComparePolyStr(sFormID, "STAG BEETLE")) { nPoly = 178; } else if(ComparePolyStr(sFormID, "WYRMLING RED DRAGON")) { nPoly = 233; } else if(ComparePolyStr(sFormID, "WYRMLING SILVER DRAGON")) { nPoly = 234; } else if(ComparePolyStr(sFormID, "DIRE BOAR")) { nPoly = 36; } } // HD 8 if (nMaxHD >= 8 && nPoly == 0) { if(ComparePolyStr(sFormID, "MIND FLAYER")) { nPoly = 216; } else if(ComparePolyStr(sFormID, "UMBER HULK")) { nPoly = 217; } else if(ComparePolyStr(sFormID, "GORGON")) { nPoly = 192; } else if(ComparePolyStr(sFormID, "SPHINX")) { nPoly = 193; } else if(ComparePolyStr(sFormID, "WYRMLING GOLD DRAGON")) { nPoly = 231; } else if(ComparePolyStr(sFormID, "POLAR BEAR")) { nPoly = 148; } else if(ComparePolyStr(sFormID, "GRIZZLY BEAR")) { nPoly = 14; } } // HD 9 if (nMaxHD >= 9 && nPoly == 0) { if(ComparePolyStr(sFormID, "BATTLE DEVOURER")) { nPoly = 209; } else if(ComparePolyStr(sFormID, "WILL O WISP")) { nPoly = 218; } else if(ComparePolyStr(sFormID, "BULLETTE")) { nPoly = 313; } } // HD 10 if (nMaxHD >= 10 && nPoly == 0) { if(ComparePolyStr(sFormID, "ETTIN")) { nPoly = 187; } else if(ComparePolyStr(sFormID, "GREY RENDER")) { nPoly = 221; } else if(ComparePolyStr(sFormID, "DIRE SPIDER")) { nPoly = 188; } } // HD 11 if (nMaxHD >= 11 && nPoly == 0) { if(ComparePolyStr(sFormID, "BEHOLDER")) { nPoly = 210; } } // HD 12 if (nMaxHD >= 12 && nPoly == 0) { if(ComparePolyStr(sFormID, "HILL GIANT")) { nPoly = 222; } else if(ComparePolyStr(sFormID, "DIRE BEAR")) { nPoly = 33; } } // HD 13 if (nMaxHD >= 13 && nPoly == 0) { } // HD 14 if (nMaxHD >= 14 && nPoly == 0) { if(ComparePolyStr(sFormID, "FROST GIANT")) { nPoly = 259; } else if(ComparePolyStr(sFormID, "FROST GIANT FEMALE")) { nPoly = 308; } } // HD 15 if (nMaxHD >= 15 && nPoly == 0) { if(ComparePolyStr(sFormID, "FIRE GIANT")) { nPoly = 289; } else if(ComparePolyStr(sFormID, "FIRE GIANT FEMALE")) { nPoly = 309; } } //couldn't determine the form and npoly is still 0 if (nPoly == 0) { SendMessageToPC(OBJECT_SELF, "Unknown form type or not enough HD. Check spelling."); // Default to chicken! nPoly = 40; } ePoly = EffectPolymorph(nPoly); //Fire cast spell at event for the specified target SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, SPELL_POLYMORPH_SELF, FALSE)); //Apply the VFX impact and effects AssignCommand(oTarget, ClearAllActions()); // prevents an exploit ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget); ApplyEffectToObject(DURATION_TYPE_TEMPORARY, ePoly, oTarget, TurnsToSeconds(nDuration));
}
-
@omg:
- Currently can't use number (i.e. .ps 140). Since it still has to be checked for HD and existence, it's same as alias.
Given there's something like 350 polymorphs in the 2da, and you're trying to make sure they stick to the 70 or so available there, doing the numbers while blocking access to the other stuff would be an incredible PITA. And I can't see too many people using a numbered list anyhow, even if it was published, since you can quickslot it either way in the same fashion.
-
well, there's only a very limited number of quickslots, so I'd probably not want to waste them on things you can type in quickly, like ".ps 132!"; but rather use them for things tht you'd have to click through a few layers of menu for to access..
(oh another feature could be having .ps ! just cast the spell with whatever is the current polymorph target.)
-
To provide proper feedback (is it bad spelling or not enough caster levels, or not enough target HD), the script needs to be changed like so:
if(ComparePolyStr(sFormID, "EYEBALL")) { nPoly = 213; nHD = 1; } else if(ComparePolyStr(sFormID, "GOBLIN")) { nPoly = 157; nHD = 1; } //... ```The top level conditions (if nMaxHD >= <n>) need to be removed, and the check for HD done after you know which form caster desires. I think that would keep the script readable, so we may want to do it. Any takers?</n>
-
Added proper feedback.
Prevented casting the spell while already polymorphed.#include "x2_inc_spellhook" // Returns true if sCreatureName starts with sFormID int ComparePolyStr(string sFormID, string sCreatureName) { return GetStringLeft(sCreatureName, GetStringLength(sFormID)) == sFormID; } void main() { /* Spellcast Hook Code Added 2003-06-23 by GeorgZ If you want to make changes to all spells, check x2_inc_spellhook.nss to find out more */ if (!X2PreSpellCastCode()) { // If code within the PreSpellCastHook (i.e. UMD) reports FALSE, do not run this spell return; } // End of Spell Cast Hook // No spell if already polymorphed. if (GetHasEffect(EFFECT_TYPE_POLYMORPH, OBJECT_SELF)) return; //Declare major variables object oTarget = GetSpellTargetObject(); effect eVis = EffectVisualEffect(VFX_IMP_POLYMORPH); effect ePoly; int nPoly = 0; int nHD = 0; string sFormID = GetStringUpperCase(GetLocalString(OBJECT_SELF, "sPolyFormID")); int nCasterLevel = GetCasterLevel(OBJECT_SELF); int nTargetHD = GetHitDice(oTarget); // Determine duration int nMetaMagic = GetMetaMagicFeat(); int nDuration = nCasterLevel; if (nMetaMagic == METAMAGIC_EXTEND) { nDuration = nDuration *2; //Duration is +100% } // -------------------------------- // --- Determine Polymorph type --- // HD 1 if(ComparePolyStr(sFormID, "EYEBALL")) { nPoly = 213; nHD = 1; } else if(ComparePolyStr(sFormID, "GOBLIN")) { nPoly = 157; nHD = 1; } else if(ComparePolyStr(sFormID, "HOBGOBLIN")) { nPoly = 163; nHD = 1; } else if(ComparePolyStr(sFormID, "KOBOLD")) { nPoly = 165; nHD = 1; } else if(ComparePolyStr(sFormID, "ORC")) { nPoly = 166; nHD = 1; } else if(ComparePolyStr(sFormID, "FIRE BEETLE")) { nPoly = 177; nHD = 1; } else if(ComparePolyStr(sFormID, "CHICKEN")) { nPoly = 40; nHD = 1; } else if(ComparePolyStr(sFormID, "FALCON")) { nPoly = 133; nHD = 1; } else if(ComparePolyStr(sFormID, "PENGUIN")) { nPoly = 26; nHD = 1; } else if(ComparePolyStr(sFormID, "RAVEN")) { nPoly = 134; nHD = 1; } else if(ComparePolyStr(sFormID, "RAT")) { nPoly = 144; nHD = 1; } else if(ComparePolyStr(sFormID, "OX")) { nPoly = 143; nHD = 1; } else if(ComparePolyStr(sFormID, "BADGER")) { nPoly = 25; nHD = 1; } else if(ComparePolyStr(sFormID, "BAT")) { nPoly = 140; nHD = 1; } else if(ComparePolyStr(sFormID, "COW")) { nPoly = 27; nHD = 1; } else if(ComparePolyStr(sFormID, "DEER")) { nPoly = 142; nHD = 1; } else if(ComparePolyStr(sFormID, "DIRE RAT")) { nPoly = 149; nHD = 1; } else if(ComparePolyStr(sFormID, "CHICKEN")) { nPoly = 40; nHD = 1; } else if(ComparePolyStr(sFormID, "WHITE STAG")) { nPoly = 145; nHD = 1; } // HD 2 else if(ComparePolyStr(sFormID, "TROGLODYTE")) { nPoly = 312; nHD = 2; } else if(ComparePolyStr(sFormID, "LIZARDFOLK")) { nPoly = 170; nHD = 2; } else if(ComparePolyStr(sFormID, "GNOLL")) { nPoly = 158; nHD = 2; } else if(ComparePolyStr(sFormID, "DEEP ROTHE")) { nPoly = 190; nHD = 2; } else if(ComparePolyStr(sFormID, "KRENSHAR")) { nPoly = 194; nHD = 2; } else if(ComparePolyStr(sFormID, "BOMBADIER BEETLE")) { nPoly = 176; nHD = 2; } else if(ComparePolyStr(sFormID, "FAERIE DRAGON")) { nPoly = 224; nHD = 2; } else if(ComparePolyStr(sFormID, "PSEUDODRAGON")) { nPoly = 225; nHD = 2; } else if(ComparePolyStr(sFormID, "DOG")) { nPoly = 130; nHD = 2; } else if(ComparePolyStr(sFormID, "WOLF")) { nPoly = 23; nHD = 2; } // HD 3 else if(ComparePolyStr(sFormID, "BUGBEAR")) { nPoly = 152; nHD = 3; } else if(ComparePolyStr(sFormID, "SEA HAG")) { nPoly = 168; nHD = 3; } else if(ComparePolyStr(sFormID, "STINK BEETLE")) { nPoly = 179; nHD = 3; } else if(ComparePolyStr(sFormID, "SWORD SPIDER")) { nPoly = 181; nHD = 3; } else if(ComparePolyStr(sFormID, "WYRMLING WHITE DRAGON")) { nPoly = 235; nHD = 3; } else if(ComparePolyStr(sFormID, "BLACK BEAR")) { nPoly = 131; nHD = 3; } else if(ComparePolyStr(sFormID, "COUGAR")) { nPoly = 135; nHD = 3; } else if(ComparePolyStr(sFormID, "CRAG CAT")) { nPoly = 136; nHD = 3; } else if(ComparePolyStr(sFormID, "LEOPARD")) { nPoly = 138; nHD = 3; } else if(ComparePolyStr(sFormID, "PANTHER")) { nPoly = 22; nHD = 3; } else if(ComparePolyStr(sFormID, "BOAR")) { nPoly = 24; nHD = 3; } else if(ComparePolyStr(sFormID, "DIRE BADGER")) { nPoly = 37; nHD = 3; } // HD 4 else if(ComparePolyStr(sFormID, "OGRE")) { nPoly = 174; nHD = 4; } else if(ComparePolyStr(sFormID, "STINGER")) { nPoly = 169; nHD = 4; } else if(ComparePolyStr(sFormID, "GELATINOUS CUBE")) { nPoly = 208; nHD = 4; } else if(ComparePolyStr(sFormID, "GARGOYLE")) { nPoly = 191; nHD = 4; } else if(ComparePolyStr(sFormID, "GIANT SPIDER")) { nPoly = 180; nHD = 4; } else if(ComparePolyStr(sFormID, "WYRMLING BLACK DRAGON")) { nPoly = 226; nHD = 4; } else if(ComparePolyStr(sFormID, "WYRMLING BRASS DRAGON")) { nPoly = 228; nHD = 4; } else if(ComparePolyStr(sFormID, "WORG")) { nPoly = 258; nHD = 4; } // HD 5 else if(ComparePolyStr(sFormID, "ETTERCAP")) { nPoly = 212; nHD = 5; } else if(ComparePolyStr(sFormID, "HOOK HORROR")) { nPoly = 214; nHD = 5; } else if(ComparePolyStr(sFormID, "COCKATRICE")) { nPoly = 189; nHD = 5; } else if(ComparePolyStr(sFormID, "WYRMLING COPPER DRAGON")) { nPoly = 230; nHD = 5; } else if(ComparePolyStr(sFormID, "WYRMLING GREEN DRAGON")) { nPoly = 232; nHD = 5; } else if(ComparePolyStr(sFormID, "JAGUAR")) { nPoly = 137; nHD = 5; } else if(ComparePolyStr(sFormID, "LION")) { nPoly = 139; nHD = 5; } // HD 6 else if(ComparePolyStr(sFormID, "DRIDER")) { nPoly = 211; nHD = 6; } else if(ComparePolyStr(sFormID, "FEMALE DRIDER")) { nPoly = 307; nHD = 6; } else if(ComparePolyStr(sFormID, "INTELLECT DEVOURER")) { nPoly = 215; nHD = 6; } else if(ComparePolyStr(sFormID, "TROLL")) { nPoly = 175; nHD = 6; } else if(ComparePolyStr(sFormID, "YUAN-TI")) { nPoly = 171; nHD = 6; } else if(ComparePolyStr(sFormID, "MINOTAUR")) { nPoly = 172; nHD = 6; } else if(ComparePolyStr(sFormID, "MEDUSA")) { nPoly = 167; nHD = 6; } else if(ComparePolyStr(sFormID, "BASILISK")) { nPoly = 197; nHD = 6; } else if(ComparePolyStr(sFormID, "MANTICORE")) { nPoly = 195; nHD = 6; } else if(ComparePolyStr(sFormID, "WYRMLING BLUE DRAGON")) { nPoly = 227; nHD = 6; } else if(ComparePolyStr(sFormID, "WYRMLING BRONZE DRAGON")) { nPoly = 229; nHD = 6; } else if(ComparePolyStr(sFormID, "BROWN BEAR")) { nPoly = 21; nHD = 6; } else if(ComparePolyStr(sFormID, "WINTER WOLF")) { nPoly = 257; nHD = 6; } else if(ComparePolyStr(sFormID, "DIRE WOLF")) { nPoly = 35; nHD = 6; } // HD 7 else if(ComparePolyStr(sFormID, "HARPY")) { nPoly = 173; nHD = 7; } else if(ComparePolyStr(sFormID, "STAG BEETLE")) { nPoly = 178; nHD = 7; } else if(ComparePolyStr(sFormID, "WYRMLING RED DRAGON")) { nPoly = 233; nHD = 7; } else if(ComparePolyStr(sFormID, "WYRMLING SILVER DRAGON")) { nPoly = 234; nHD = 7; } else if(ComparePolyStr(sFormID, "DIRE BOAR")) { nPoly = 36; nHD = 7; } // HD 8 else if(ComparePolyStr(sFormID, "MIND FLAYER")) { nPoly = 216; nHD = 8; } else if(ComparePolyStr(sFormID, "UMBER HULK")) { nPoly = 217; nHD = 8; } else if(ComparePolyStr(sFormID, "GORGON")) { nPoly = 192; nHD = 8; } else if(ComparePolyStr(sFormID, "SPHINX")) { nPoly = 193; nHD = 8; } else if(ComparePolyStr(sFormID, "WYRMLING GOLD DRAGON")) { nPoly = 231; nHD = 8; } else if(ComparePolyStr(sFormID, "POLAR BEAR")) { nPoly = 148; nHD = 8; } else if(ComparePolyStr(sFormID, "GRIZZLY BEAR")) { nPoly = 14; nHD = 8; } // HD 9 else if(ComparePolyStr(sFormID, "BATTLE DEVOURER")) { nPoly = 209; nHD = 9; } else if(ComparePolyStr(sFormID, "WILL O WISP")) { nPoly = 218; nHD = 9; } else if(ComparePolyStr(sFormID, "BULLETTE")) { nPoly = 313; nHD = 9; } // HD 10 else if(ComparePolyStr(sFormID, "ETTIN")) { nPoly = 187; nHD = 10; } else if(ComparePolyStr(sFormID, "GREY RENDER")) { nPoly = 221; nHD = 10; } else if(ComparePolyStr(sFormID, "DIRE SPIDER")) { nPoly = 188; nHD = 10; } // HD 11 else if(ComparePolyStr(sFormID, "BEHOLDER")) { nPoly = 210; nHD = 11; } // HD 12 else if(ComparePolyStr(sFormID, "HILL GIANT")) { nPoly = 222; nHD = 12; } else if(ComparePolyStr(sFormID, "DIRE BEAR")) { nPoly = 33; nHD = 12; } // HD 13 // HD 14 else if(ComparePolyStr(sFormID, "FROST GIANT")) { nPoly = 259; nHD = 14; } else if(ComparePolyStr(sFormID, "FROST GIANT FEMALE")) { nPoly = 308; nHD = 14; } // HD 15 else if(ComparePolyStr(sFormID, "FIRE GIANT")) { nPoly = 289; nHD = 14; } else if(ComparePolyStr(sFormID, "FIRE GIANT FEMALE")) { nPoly = 309; nHD = 15; } // Couldn't determine the form if (nPoly == 0) { SendMessageToPC(OBJECT_SELF, "Unknown form type. Check spelling."); // Default to chicken! nPoly = 40; } // Caster level not high enough for the form if (nHD > nCasterLevel) { SendMessageToPC(OBJECT_SELF, "Caster level is too low for this form."); // Default to chicken! nPoly = 40; } // Target hasn't enough HD for the form if (nHD > nTargetHD) { SendMessageToPC(OBJECT_SELF, "Target doesn't have enough HD for this form."); // Default to chicken! nPoly = 40; } ePoly = EffectPolymorph(nPoly); //Fire cast spell at event for the specified target SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, SPELL_POLYMORPH_SELF, FALSE)); //Apply the VFX impact and effects AssignCommand(oTarget, ClearAllActions()); // prevents an exploit ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget); ApplyEffectToObject(DURATION_TYPE_TEMPORARY, ePoly, oTarget, TurnsToSeconds(nDuration)); }
-
As lovely as transgender polymorphing is, the male/female options should probably just go off the players gender with a check under the "FIRE GIANT" "FROST GIANT" etc
-
I'm just a female Fire-Giant trapped in a male dwarf wizard's body.
-
Just keeping this here, need to covnert it to 2da later
Name Race Port NWep1 Nwep2 Nwep3 Hide Weap S/D/C AC Hp Pixie Fey po_pixie_ Claw1d2 *** *** Grig/Pixie porperties Dagger 7/18/11 1 *** Sahuagin Reptilian po_sahuagin_ Claw1d4 Claw1d4 Bite 1d4 *** Trident 14/13/12 5 2 Dryad Fey po_dryad_ *** *** *** *** Dagger 10/15/11 *** *** Ochre Jelly Ooze po_ochrejelly_ *** *** Ochre SlamMed Ochre Prop Med *** 15/3/15 *** 8 Nymph Fey po_nymph_ *** *** *** *** Dagger 10/13/10 *** *** Grey Ooze Ooze po_grayooze_ *** *** Gray ooze slam Gray ooze props *** 12/3/11 *** *** Blink Dog Magical Beast po_blinkdog_ *** *** Bite 1d6 *** *** 10/17/10 3 *** Satyr Fey po_satyr_ *** *** Slam 1d6 *** *** 10/13/12 4 5 Wyvern Dragon po_wyvern_ Claw 2d6 Bite 2d7 Wyvern Tail *** *** 22/12/16 10 36
-
Regarding the transgender thing - it only applies to level 14+ so far, so it can't matter much. If you want to add the gender control I suggest doing it like so:
else if(ComparePolyStr(sFormID, "FROST GIANT")) { nPoly = (nFemale?308:259); nHD = 14; } ```Just set nFemale at the start to either TRUE or FALSE.
-
324 POLYMORPH_TYPE_WS_PARROT 325 POLYMORPH_TYPE_WS_SEAGULL 326 POLYMORPH_TYPE_WS_HORSE 327 POLYMORPH_TYPE_WS_SNAKE 328 POLYMORPH_TYPE_PS_PIXIE 329 POLYMORPH_TYPE_WS_SAHUAGIN 330 POLYMORPH_TYPE_PS_DRYAD 331 POLYMORPH_TYPE_WS_OCHREJELLY 332 POLYMORPH_TYPE_PS_NYMPH 333 POLYMORPH_TYPE_WS_GREYOOZE 334 POLYMORPH_TYPE_WS_BLINKDOG 335 POLYMORPH_TYPE_PS_SATYR 336 POLYMORPH_TYPE_WS_WYVERN
Will be the numeric codes for the new ones
-
There are two chickens.
BoMbardier beetle has a typo.
Grizzly turns to water elemental. Check code. -
@omg:
There are two chickens.
BoMbardier beetle has a typo.
Grizzly turns to water elemental. Check code.'Adding my own botchups.
Pixie not working.
Wyvern not working
Satyr not working.
Grey Ooze not working
Ochre not working.
Parrot not working.
Seagull becomes a Satyr.
Horse becomes a wyvern.
Sahuaging becoming an emerald golem.
Snake makes a nightmare -
And the present iteration of code
#include "x2_inc_spellhook" // Returns true if sCreatureName starts with sFormID int ComparePolyStr(string sFormID, string sCreatureName) { return GetStringLeft(sCreatureName, GetStringLength(sFormID)) == sFormID; } void main() { /* Spellcast Hook Code Added 2003-06-23 by GeorgZ If you want to make changes to all spells, check x2_inc_spellhook.nss to find out more */ if (!X2PreSpellCastCode()) { // If code within the PreSpellCastHook (i.e. UMD) reports FALSE, do not run this spell return; } // End of Spell Cast Hook // No spell if already polymorphed. if (GetHasEffect(EFFECT_TYPE_POLYMORPH, OBJECT_SELF)) return; //Declare major variables object oTarget = GetSpellTargetObject(); effect eVis = EffectVisualEffect(VFX_IMP_POLYMORPH); effect ePoly; int nPoly = 0; int nHD = 0; string sFormID = GetStringUpperCase(GetLocalString(OBJECT_SELF, "sPolyFormID")); int nCasterLevel = GetCasterLevel(OBJECT_SELF); int nTargetHD = GetHitDice(oTarget); // Determine duration int nMetaMagic = GetMetaMagicFeat(); int nDuration = nCasterLevel; if (nMetaMagic == METAMAGIC_EXTEND) { nDuration = nDuration *2; //Duration is +100% } // -------------------------------- // --- Determine Polymorph type --- // HD 1 if(ComparePolyStr(sFormID, "EYEBALL")) { nPoly = 213; nHD = 1; } else if(ComparePolyStr(sFormID, "GOBLIN")) { nPoly = 157; nHD = 1; } else if(ComparePolyStr(sFormID, "HOBGOBLIN")) { nPoly = 163; nHD = 1; } else if(ComparePolyStr(sFormID, "KOBOLD")) { nPoly = 165; nHD = 1; } else if(ComparePolyStr(sFormID, "ORC")) { nPoly = 166; nHD = 1; } else if(ComparePolyStr(sFormID, "FIRE BEETLE")) { nPoly = 177; nHD = 1; } else if(ComparePolyStr(sFormID, "CHICKEN")) { nPoly = 40; nHD = 1; } else if(ComparePolyStr(sFormID, "FALCON")) { nPoly = 133; nHD = 1; } else if(ComparePolyStr(sFormID, "PENGUIN")) { nPoly = 26; nHD = 1; } else if(ComparePolyStr(sFormID, "RAVEN")) { nPoly = 134; nHD = 1; } else if(ComparePolyStr(sFormID, "RAT")) { nPoly = 144; nHD = 1; } else if(ComparePolyStr(sFormID, "OX")) { nPoly = 143; nHD = 1; } else if(ComparePolyStr(sFormID, "BADGER")) { nPoly = 25; nHD = 1; } else if(ComparePolyStr(sFormID, "BAT")) { nPoly = 140; nHD = 1; } else if(ComparePolyStr(sFormID, "COW")) { nPoly = 27; nHD = 1; } else if(ComparePolyStr(sFormID, "DEER")) { nPoly = 142; nHD = 1; } else if(ComparePolyStr(sFormID, "DIRE RAT")) { nPoly = 149; nHD = 1; } else if(ComparePolyStr(sFormID, "CHICKEN")) { nPoly = 40; nHD = 1; } else if(ComparePolyStr(sFormID, "WHITE STAG")) { nPoly = 145; nHD = 1; } else if(ComparePolyStr(sFormID, "PARROT")) { nPoly = 324; nHD = 1; } else if(ComparePolyStr(sFormID, "SEAGULL")) { nPoly = 325; nHD = 1; } else if(ComparePolyStr(sFormID, "HORSE")) { nPoly = 326; nHD = 1; } // HD 2 else if(ComparePolyStr(sFormID, "TROGLODYTE")) { nPoly = 312; nHD = 2; } else if(ComparePolyStr(sFormID, "LIZARDFOLK")) { nPoly = 170; nHD = 2; } else if(ComparePolyStr(sFormID, "GNOLL")) { nPoly = 158; nHD = 2; } else if(ComparePolyStr(sFormID, "DEEP ROTHE")) { nPoly = 190; nHD = 2; } else if(ComparePolyStr(sFormID, "KRENSHAR")) { nPoly = 194; nHD = 2; } else if(ComparePolyStr(sFormID, "BOMBADIER BEETLE")) { nPoly = 176; nHD = 2; } else if(ComparePolyStr(sFormID, "FAERIE DRAGON")) { nPoly = 224; nHD = 2; } else if(ComparePolyStr(sFormID, "PSEUDODRAGON")) { nPoly = 225; nHD = 2; } else if(ComparePolyStr(sFormID, "DOG")) { nPoly = 130; nHD = 2; } else if(ComparePolyStr(sFormID, "WOLF")) { nPoly = 23; nHD = 2; } else if(ComparePolyStr(sFormID, "SAHUAGIN")) { nPoly = 329; nHD = 2; } else if(ComparePolyStr(sFormID, "DRYAD")) { nPoly = 330; nHD = 2; } else if(ComparePolyStr(sFormID, "OCHRE JELLY")) { nPoly = 331; nHD = 2; } // HD 3 else if(ComparePolyStr(sFormID, "BUGBEAR")) { nPoly = 152; nHD = 3; } else if(ComparePolyStr(sFormID, "SEA HAG")) { nPoly = 168; nHD = 3; } else if(ComparePolyStr(sFormID, "STINK BEETLE")) { nPoly = 179; nHD = 3; } else if(ComparePolyStr(sFormID, "SWORD SPIDER")) { nPoly = 181; nHD = 3; } else if(ComparePolyStr(sFormID, "WYRMLING WHITE DRAGON")) { nPoly = 235; nHD = 3; } else if(ComparePolyStr(sFormID, "BLACK BEAR")) { nPoly = 131; nHD = 3; } else if(ComparePolyStr(sFormID, "COUGAR")) { nPoly = 135; nHD = 3; } else if(ComparePolyStr(sFormID, "CRAG CAT")) { nPoly = 136; nHD = 3; } else if(ComparePolyStr(sFormID, "LEOPARD")) { nPoly = 138; nHD = 3; } else if(ComparePolyStr(sFormID, "PANTHER")) { nPoly = 22; nHD = 3; } else if(ComparePolyStr(sFormID, "BOAR")) { nPoly = 24; nHD = 3; } else if(ComparePolyStr(sFormID, "DIRE BADGER")) { nPoly = 37; nHD = 3; } else if(ComparePolyStr(sFormID, "SNAKE")) { nPoly = 327; nHD = 3; } else if(ComparePolyStr(sFormID, "NYMPH")) { nPoly = 332; nHD = 3; } else if(ComparePolyStr(sFormID, "GRAY OOZE")) { nPoly = 333; nHD = 3; } // HD 4 else if(ComparePolyStr(sFormID, "OGRE")) { nPoly = 174; nHD = 4; } else if(ComparePolyStr(sFormID, "STINGER")) { nPoly = 169; nHD = 4; } else if(ComparePolyStr(sFormID, "GELATINOUS CUBE")) { nPoly = 208; nHD = 4; } else if(ComparePolyStr(sFormID, "GARGOYLE")) { nPoly = 191; nHD = 4; } else if(ComparePolyStr(sFormID, "GIANT SPIDER")) { nPoly = 180; nHD = 4; } else if(ComparePolyStr(sFormID, "WYRMLING BLACK DRAGON")) { nPoly = 226; nHD = 4; } else if(ComparePolyStr(sFormID, "WYRMLING BRASS DRAGON")) { nPoly = 228; nHD = 4; } else if(ComparePolyStr(sFormID, "WORG")) { nPoly = 258; nHD = 4; } else if(ComparePolyStr(sFormID, "BLINK DOG")) { nPoly = 334; nHD = 4; } // HD 5 else if(ComparePolyStr(sFormID, "ETTERCAP")) { nPoly = 212; nHD = 5; } else if(ComparePolyStr(sFormID, "HOOK HORROR")) { nPoly = 214; nHD = 5; } else if(ComparePolyStr(sFormID, "COCKATRICE")) { nPoly = 189; nHD = 5; } else if(ComparePolyStr(sFormID, "WYRMLING COPPER DRAGON")) { nPoly = 230; nHD = 5; } else if(ComparePolyStr(sFormID, "WYRMLING GREEN DRAGON")) { nPoly = 232; nHD = 5; } else if(ComparePolyStr(sFormID, "JAGUAR")) { nPoly = 137; nHD = 5; } else if(ComparePolyStr(sFormID, "LION")) { nPoly = 139; nHD = 5; } else if(ComparePolyStr(sFormID, "SATYR")) { nPoly = 335; nHD = 5; } // HD 6 else if(ComparePolyStr(sFormID, "DRIDER")) { nPoly = 211; nHD = 6; } else if(ComparePolyStr(sFormID, "FEMALE DRIDER")) { nPoly = 307; nHD = 6; } else if(ComparePolyStr(sFormID, "INTELLECT DEVOURER")) { nPoly = 215; nHD = 6; } else if(ComparePolyStr(sFormID, "TROLL")) { nPoly = 175; nHD = 6; } else if(ComparePolyStr(sFormID, "YUAN-TI")) { nPoly = 171; nHD = 6; } else if(ComparePolyStr(sFormID, "MINOTAUR")) { nPoly = 172; nHD = 6; } else if(ComparePolyStr(sFormID, "MEDUSA")) { nPoly = 167; nHD = 6; } else if(ComparePolyStr(sFormID, "BASILISK")) { nPoly = 197; nHD = 6; } else if(ComparePolyStr(sFormID, "MANTICORE")) { nPoly = 195; nHD = 6; } else if(ComparePolyStr(sFormID, "WYRMLING BLUE DRAGON")) { nPoly = 227; nHD = 6; } else if(ComparePolyStr(sFormID, "WYRMLING BRONZE DRAGON")) { nPoly = 229; nHD = 6; } else if(ComparePolyStr(sFormID, "BROWN BEAR")) { nPoly = 21; nHD = 6; } else if(ComparePolyStr(sFormID, "WINTER WOLF")) { nPoly = 257; nHD = 6; } else if(ComparePolyStr(sFormID, "DIRE WOLF")) { nPoly = 35; nHD = 6; } // HD 7 else if(ComparePolyStr(sFormID, "HARPY")) { nPoly = 173; nHD = 7; } else if(ComparePolyStr(sFormID, "STAG BEETLE")) { nPoly = 178; nHD = 7; } else if(ComparePolyStr(sFormID, "WYRMLING RED DRAGON")) { nPoly = 233; nHD = 7; } else if(ComparePolyStr(sFormID, "WYRMLING SILVER DRAGON")) { nPoly = 234; nHD = 7; } else if(ComparePolyStr(sFormID, "DIRE BOAR")) { nPoly = 36; nHD = 7; } // HD 8 else if(ComparePolyStr(sFormID, "MIND FLAYER")) { nPoly = 216; nHD = 8; } else if(ComparePolyStr(sFormID, "UMBER HULK")) { nPoly = 217; nHD = 8; } else if(ComparePolyStr(sFormID, "GORGON")) { nPoly = 192; nHD = 8; } else if(ComparePolyStr(sFormID, "SPHINX")) { nPoly = 193; nHD = 8; } else if(ComparePolyStr(sFormID, "WYRMLING GOLD DRAGON")) { nPoly = 231; nHD = 8; } else if(ComparePolyStr(sFormID, "POLAR BEAR")) { nPoly = 148; nHD = 8; } else if(ComparePolyStr(sFormID, "GRIZZLY BEAR")) { nPoly = 14; nHD = 8; } // HD 9 else if(ComparePolyStr(sFormID, "BATTLE DEVOURER")) { nPoly = 209; nHD = 9; } else if(ComparePolyStr(sFormID, "WILL O WISP")) { nPoly = 218; nHD = 9; } else if(ComparePolyStr(sFormID, "BULLETTE")) { nPoly = 313; nHD = 9; } // HD 10 else if(ComparePolyStr(sFormID, "ETTIN")) { nPoly = 187; nHD = 10; } else if(ComparePolyStr(sFormID, "GREY RENDER")) { nPoly = 221; nHD = 10; } else if(ComparePolyStr(sFormID, "DIRE SPIDER")) { nPoly = 188; nHD = 10; } // HD 11 else if(ComparePolyStr(sFormID, "BEHOLDER")) { nPoly = 210; nHD = 11; } // HD 12 else if(ComparePolyStr(sFormID, "HILL GIANT")) { nPoly = 222; nHD = 12; } else if(ComparePolyStr(sFormID, "DIRE BEAR")) { nPoly = 33; nHD = 12; } else if(ComparePolyStr(sFormID, "WYVERN")) { nPoly = 336; nHD = 12; } // HD 13 // HD 14 else if(ComparePolyStr(sFormID, "FROST GIANT")) { nPoly = 259; nHD = 14; } else if(ComparePolyStr(sFormID, "FROST GIANT FEMALE")) { nPoly = 308; nHD = 14; } // HD 15 else if(ComparePolyStr(sFormID, "FIRE GIANT")) { nPoly = 289; nHD = 14; } else if(ComparePolyStr(sFormID, "FIRE GIANT FEMALE")) { nPoly = 309; nHD = 15; } // Couldn't determine the form if (nPoly == 0) { SendMessageToPC(OBJECT_SELF, "Unknown form type. Check spelling."); // Default to chicken! nPoly = 40; } // Caster level not high enough for the form if (nHD > nCasterLevel) { SendMessageToPC(OBJECT_SELF, "Caster level is too low for this form."); // Default to chicken! nPoly = 40; } // Target hasn't enough HD for the form if (nHD > nTargetHD) { SendMessageToPC(OBJECT_SELF, "Target doesn't have enough HD for this form."); // Default to chicken! nPoly = 40; } ePoly = EffectPolymorph(nPoly); //Fire cast spell at event for the specified target SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, SPELL_POLYMORPH_SELF, FALSE)); //Apply the VFX impact and effects AssignCommand(oTarget, ClearAllActions()); // prevents an exploit ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, oTarget); ApplyEffectToObject(DURATION_TYPE_TEMPORARY, ePoly, oTarget, TurnsToSeconds(nDuration)); }
-
There are two chickens. - Fixed
BoMbardier beetle has a typo. - Fixed, was missing the first R
Grizzly turns to water elemental - Fixed, missing a 7 on the end
Pixie not working. - Heh, was missing from the code entirelySeagull becomes a Satyr. < it's the proper 325 in the script, but is registering as 335
Horse becomes a wyvern. <- again, jumping 10 spots higher.
Sahuaging becoming an emerald golem. <- 10 spots once more
Snake makes a nightmare < - and the sameWyvern not working
Satyr not working.
Grey Ooze not working
Ochre not working.
Parrot not working.