Author Topic: Merging equiped weapons into unarmed shapes claws...  (Read 512 times)

Legacy_Lazarus Magni

  • Hero Member
  • *****
  • Posts: 1837
  • Karma: +0/-0
Merging equiped weapons into unarmed shapes claws...
« on: July 06, 2011, 04:25:37 am »


               I have already altered the 2da to allow merge all, and I have found a script that the PW uses to acomplish the weapon merger into unarmed shapes claws, but it doesn't appear to be functioning. I am wondering if I need to include it in one of the original polymorph scripts (and if so which one)? Or if anyone else has an alternative idea on how to achieve this?
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Merging equiped weapons into unarmed shapes claws...
« Reply #1 on: July 06, 2011, 04:34:57 am »


               I am not sure what you are asking.
               
               

               
            

Legacy_Lazarus Magni

  • Hero Member
  • *****
  • Posts: 1837
  • Karma: +0/-0
Merging equiped weapons into unarmed shapes claws...
« Reply #2 on: July 06, 2011, 05:01:07 am »


               I am trying to get an equiped weapon to merge into the claws for unarmed shapes for druids and shifters. Does that make sense?
               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Merging equiped weapons into unarmed shapes claws...
« Reply #3 on: July 06, 2011, 06:31:22 am »


               Yes, you have to edit your shifter scripts. Fair warning: this is among the more complicated things to code, because it has a lot of moving parts. We ran into serious crash bug issues when adding invisible helms code, because of the way the various onacquire, onunacquire, onequip, and onunequip scripts interacted with shifter code.

Your target scripts are nw_s2_elemshape, nw_s2_wildshsape, and x2_s2_gwildshp. Here are our versions of those, plus the original include by Iznoghoud, likely the same one you found, which we still use some parts of:
Shfter Scripts

They won't compile without me ripping out substantial chunks of our mod for you, but they'll set you on the right track.

For those of you still wondering what the heck we're talking about, here's a small blurb from our shifter edits documentation:

Equipment Merging
- All equipment merges when you shift, with the exception of Shield AC. The attributes of your primary weapon will be applied to all weaponswhen you shift. The only weapon buffs that will transfer are keen and enchantment bonuses. Spells like Darkfire or Flame Weapon will not transfer between forms, but if cast on an armed form will remain until the shifter changes shape.

It basically means that if you're wearing a ring of resistance and slinging a longsword +1 flametongue, you'll still have all those properties on you when you shift. This is increasingly important to class balancing, the more magic you have in your module.

Funky
               
               

               


                     Modifié par FunkySwerve, 06 juillet 2011 - 05:31 .
                     
                  


            

Legacy_Lazarus Magni

  • Hero Member
  • *****
  • Posts: 1837
  • Karma: +0/-0
Merging equiped weapons into unarmed shapes claws...
« Reply #4 on: July 06, 2011, 08:10:59 am »


               Indeed Funky you hit the nail on the head. However the weird thing is we already have the ws_inc_shifter script, and it appears to be set up correctly. Also I suspect we also have the modified druid polymorph scripts you mentioned (although I have not looked yet). The weird thing is, the merging of weapon properties into unarmed shapes claws used to work. Somehow now it isn't functioning. I am wondering if there is some core (default) nwn script I need to add an include to, or why they are not working now?
               
               

               


                     Modifié par Lazarus Magni, 06 juillet 2011 - 07:12 .
                     
                  


            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Merging equiped weapons into unarmed shapes claws...
« Reply #5 on: July 06, 2011, 04:56:23 pm »


               It's impossible to say, without having seen the scripts. Iznoghoud's was somewhat buggy to begin with (though it did work, more or less, when properly set up), and we've reimplemented merging our own (albeit similar) way. Any number of edits could've interfered with its proper operation, unfortunately - there are a lot of events firing when a shifter shifts.

Debug code is your friend. One thing that helps is putting item event debugging in on your item events, which fires when a variabe is set on the PC. If you're using SIMTools or a similar system, you can then set and deset the var as you like to turn debugging on and off. If nothing else, it'll help you understand the order shifter events are firing in. Of course, if memory serves, they are not 100% consistent in the ordering, which can lead to some gnarly-looking code.

Here's some sample general item event debugging. I'm leaving in the very top of the script, so you can see something else we did. We wrappered all shift and polymorph effects in the mod to use a custom function that sets a variable at the beginning of the poly, and deletes it at the end. We then abort onequip if that var is set. For us, this was a part of the invisible helms/shifting crash fix, but being able to effectively go GetIsMidPolymorph has wider usefulness:


void main() {
    object oPC = GetPCItemLastEquippedBy();

    if (GetLocalInt(oPC, "MidPolymorph") || (ScanForPolymorphEffect(oPC) > -2))
        return;
    if (!GetIsPC(oPC) || GetIsDM(oPC))
        return;

    object oItem = GetPCItemLastEquipped();
    object oArea = GetArea(oPC);
    string sItemName = GetName(oItem);

    if (GetLocalInt(oPC, "DebugItemEvents")) {
        SendMessageToPC(oPC, COLOR_WHITE + "Item Event: Equip" +
            ", Owner: " + GetName(oPC) + " (" + GetObjectString(oPC) +
            "), Area: " + GetName(oArea) + " (" + GetObjectString(oArea) +
            "), Item: " + sItemName + " (" + GetObjectString(oItem) +
            ") [x" + IntToString(GetItemStackSize(oItem)) + "]" + COLOR_END);
    }

Here's that custom polymorph function, by the way:


void ApplyPolymorphEffect (int nDurType, effect ePoly, object oTarget, float fDur=0.0) {
    if (GetLocalInt(oTarget, "NoPoly"))
        return;

    SetLocalInt(oTarget, "MidPolymorph", TRUE);
    ApplyEffectToObject(nDurType, ePoly, oTarget, fDur);
    DeleteLocalInt(oTarget, "MidPolymorph");
}

Funky
               
               

               
            

Legacy_Lazarus Magni

  • Hero Member
  • *****
  • Posts: 1837
  • Karma: +0/-0
Merging equiped weapons into unarmed shapes claws...
« Reply #6 on: July 06, 2011, 10:54:23 pm »


               Well this is out current ws_inc_shifter:

//:://////////////////////////////
//:: Created By: Iznoghoud
//:: Last modified: January 19 2004
/*
What this script changes:
- Melee Weapon properties now carry over to the unarmed forms' claws and bite
attacks.
1) Now, items with an AC bonus (or penalty) carry over to the shifted form as
the correct type. This means if you wear an amulet of natural armor +4, and a
cloak of protection +5, and you shift to a form that gets all item properties
carried over, you will have the +4 natural armor bonus from the ammy, as well as
the +5 deflection bonus from the cloak. No longer will the highest one override
all the other AC bonuses even if they are a different type.
2) Other "stackable" item properties, like ability bonuses, skill bonuses and
saving throw bonuses, now correctly add up in shifted form. This means if you
have a ring that gives +2 strength, and a ring with +3 strength, and you shift
into a drow warrior, you get +5 strength in shifted form, where you used to get
only +3. (the highest)


This file contains the code that handles stacking item properties for the improved
Shifter and Druid wildshape scripts.
1 February 2004:
Added an option to allow or disallow AC stacking of different types.
*/
//:://////////////////////////////

//******** Begin Options *********

//***************** GENERAL OPTIONS *********************

// Set this to TRUE to allow differing types of AC bonuses on items to stack.
// (ie armor, deflection, natural) Warning: This can give shifters who multiclass
// with monk a godly AC depending on your module.
// With FALSE, AC will transfer as it did with the default Bioware shifter script.
const int GW_ALLOW_AC_STACKING = TRUE;

//***************** FOR SHIFTER SHAPES ******************

// Set this to TRUE to merge properties of boots/rings/ammy/cloak/bracers regardless
// of what polymorph.2da indicates.
// FALSE uses the polymorph.2da to decide whether to copy
const int GW_ALWAYS_COPY_ITEM_PROPS = TRUE;//FALSE;

// Set this to TRUE to merge armor/helmet properties regardless of what polymorph.2da indicates.
// FALSE uses the polymorph.2da to decide whether to copy
const int GW_ALWAYS_COPY_ARMOR_PROPS = TRUE;

// - Set this to 1 to copy over weapon properties to claw/bite attacks.
// - Set this to 2 to copy over glove properties to claw/bite attacks.
// - Set this to 3 to copy over from either weapon or gloves depending on whether a
//   weapon was worn at the time of shifting.
// - Set this to any other value ( eg 0 ) to not copy over anything to claw/bite attacks.
const int GW_COPY_WEAPON_PROPS_TO_UNARMED = 1;


//***************** FOR DRUID SHAPES ********************
// These options do nothing if you have not imported the improved Druid wild-
// and elemental shape scripts

// Set this to TRUE to merge properties of boots/rings/ammy/cloak/bracers regardless
// of what polymorph.2da indicates.
// FALSE uses the polymorph.2da to decide whether to copy
const int WS_ALWAYS_COPY_ITEM_PROPS = TRUE;//FALSE;

// Set this to TRUE to merge armor/helmet properties regardless of what polymorph.2da indicates.
// FALSE uses the polymorph.2da to decide whether to copy
const int WS_ALWAYS_COPY_ARMOR_PROPS = TRUE;

// - Set this to 1 to copy over weapon properties to claw/bite attacks.
// - Set this to 2 to copy over glove properties to claw/bite attacks.
// - Set this to 3 to copy over from either weapon or gloves depending on whether a
//   weapon was worn at the time of shifting.
// - Set this to any other value ( eg 0 ) to not copy over anything to claw/bite attacks.
const int WS_COPY_WEAPON_PROPS_TO_UNARMED = 1;

//******** End Options ***********

// Includes for various shifter and item related functions
#include "x2_inc_itemprop"
#include "x2_inc_shifter"

// **** Begin Function prototypes ****
// Copies oOld's Properties to oNew, but only properties that do not stack
// with properties of the same type. If oOld is a weapon, then bWeapon must be TRUE.
void WildshapeCopyNonStackProperties(object oOld, object oNew, int bWeapon = FALSE);
// Returns TRUE if ip is an item property that will stack with other properties
// of the same type: Ability, AC, Saves, Skills.
int GetIsStackingProperty(itemproperty ip);
// Returns the AC bonus type of oItem: AC_*_BONUS
int GetItemACType(object oItem);
// Looks for Stackable Properties on oItem, and sets local variables to count the total bonus.
// Also links any found AC bonuses/penalties to ePoly.
effect ExamineStackableProperties (object oPC, effect ePoly, object oItem );
// if bItems is TRUE, Adds the stackable properties on all the objects given to ePoly.
// if bArmor is TRUE, Adds the stackable properties on armor and helmet to ePoly.
effect AddStackablePropertiesToPoly ( object oPC, effect ePoly, int bWeapon, int bItems, int bArmor, object oArmorOld, object oRing1Old,
                                     object oRing2Old, object oAmuletOld, object oCloakOld, object oBracerOld,
                                     object oBootsOld, object oBeltOld, object oHelmetOld, object oShield, object oWeapon, object oHideOld);
// Returns the spell that applied a Polymorph Effect currently on the player.
// -1 if it was no spell, -2 if no polymorph effect found.
int ScanForPolymorphEffect(object oPC);

// Converts a number from iprp_damagetype.2da to the corresponding
// DAMAGE_TYPE_* constants.
int ConvertNumToDamTypeConstant ( int iItemDamType );

// Converts a number from iprp_immuncost.2da to the corresponding percentage of immunity
int ConvertNumToImmunePercentage ( int iImmuneCost );

// Special function to copy over weapon properties, which deals with copying
// over ranged weapons correctly.
void WildshapeCopyWeaponProperties(object oPC, object oOld, object oNew);

// Returns TRUE if oItem is a creature claw or bite.
int GetIsCreatureWeapon( object oItem );

// **** End Function prototypes ****

// **** Begin Functions, added by Iznoghoud ****
// Copies oOld's Properties to oNew, but only properties that do not stack
// with properties of the same type. If oOld is a weapon, then bWeapon must be TRUE.
void WildshapeCopyNonStackProperties(object oOld, object oNew, int bWeapon = FALSE) {

   if (GetIsObjectValid(oOld) && GetIsObjectValid(oNew))
   {
       itemproperty ip = GetFirstItemProperty(oOld);
       while (GetIsItemPropertyValid(ip)) // Loop through all the item properties.
       {
           if (bWeapon) // If a weapon, then we must make sure not to transfer between ranged and non-ranged weapons!
           {
               if (GetWeaponRanged(oOld) == GetWeaponRanged(oNew) )
               {
                   AddItemProperty(DURATION_TYPE_PERMANENT,ip,oNew);
               }
           }
           else
           {
               // If not a stacking property, copy over the property.
               // Dont copy on hit cast spell property unless the target is a claw/bite.
               if ( !GetIsStackingProperty(ip) && ( !(GetItemPropertyType(ip) == ITEM_PROPERTY_ONHITCASTSPELL) || GetIsCreatureWeapon(oNew) ) )
                   AddItemProperty(DURATION_TYPE_PERMANENT,ip,oNew);
           }
           ip = GetNextItemProperty(oOld); // Get next property
       }
   }
}
// Returns TRUE if ip is an item property that will stack with other properties
// of the same type: Ability, AC, Saves, Skills.
int GetIsStackingProperty(itemproperty ip) {
   int iType = GetItemPropertyType(ip);
   if ( iType == 0 || ( GW_ALLOW_AC_STACKING && (iType == 1) ) ||     // Bonus to Ability, AC
        iType == 27 || ( GW_ALLOW_AC_STACKING && (iType == 28) ) ||   // Penalty to Ability, AC
          iType == 40 || iType == 41 || // Bonus to saves (against element/universal, or fort/reflex/will)
          iType == 49 || iType == 50 || // Penalty to saves (against element/universal, or fort/reflex/will)
          iType == 52 || iType == 29 || // Skill Bonus, Penalty
          iType == 51 ||                // Regeneration
          iType == 20 || iType == 24    // Damage Immunity and Vulnerability
      )
       return TRUE;
   else
       return FALSE;
}
// Returns the AC bonus type of oItem: AC_*_BONUS
int GetItemACType(object oItem) {
   switch(GetBaseItemType(oItem)) {
   case BASE_ITEM_ARMOR: // These item types always get an armor ac bonus
   case BASE_ITEM_BRACER:
       return AC_ARMOUR_ENCHANTMENT_BONUS;
       break;
   case BASE_ITEM_BELT: // These item types always get a deflection ac bonus.
   case BASE_ITEM_CLOAK:
   case BASE_ITEM_GLOVES: // Note that gloves and bracers equip in the same inventory slot,
   case BASE_ITEM_HELMET: // but do not give the same AC bonus type!!!
   case BASE_ITEM_RING:
   case BASE_ITEM_TORCH:
       return AC_DEFLECTION_BONUS;
       break;
   case BASE_ITEM_BOOTS: // Only boots give a dodge ac bonus
       return AC_DODGE_BONUS;
       break;
   case BASE_ITEM_AMULET: // Only amulets give a natural AC bonus
       return AC_NATURAL_BONUS;
       break;
   case BASE_ITEM_LARGESHIELD: // Shields give a shield AC bonus
   case BASE_ITEM_SMALLSHIELD:
   case BASE_ITEM_TOWERSHIELD:
       return AC_SHIELD_ENCHANTMENT_BONUS;
       break;
   default: // It was a weapon, or a non default item, safest to default to deflection
       return AC_DEFLECTION_BONUS;
       break;
   };
   return AC_DEFLECTION_BONUS; // This one would seem unneccesary but it won't compile otherwise.
}
// Looks for Stackable Properties on oItem, and sets local variables to count the total bonus.
// Also links any found AC bonuses/penalties to ePoly.
effect ExamineStackableProperties ( object oPC, effect ePoly, object oItem )
{
   if ( !GetIsObjectValid(oItem) ) // If not valid, dont do any unneccesary work.
       return ePoly;
   itemproperty ip = GetFirstItemProperty(oItem);
   int iSubType;
   effect eTemp;
   while ( GetIsItemPropertyValid(ip) ) // Loop through all the item properties
   {
       if ( GetIsStackingProperty(ip) ) // See if it's a stacking property
       {
           iSubType = GetItemPropertySubType(ip); // Get the item property subtype for later use.
                                           // This contains whether a bonus is str, dex,
                                           // concentration skill, universal saving throws, etc.
           switch ( GetItemPropertyType(ip) ) // Which type of property is it?
           {
               // In the case of AC modifiers, add it directly to the Polymorphing effect.
               // For the other cases, set local variables on the player to
               // make a sum of all the bonuses/penalties. We use local
               // variables here because there are no arrays in NWScript, and
               // declaring a variable for every skill, ability type and saving
               // throw type in here is a little overboard.
               case 0: // Ability Bonus
                   SetLocalInt(oPC, "ws_ability_" + IntToString(iSubType), GetLocalInt(oPC, "ws_ability_" + IntToString(iSubType)) + GetItemPropertyCostTableValue(ip) );
                   break;
               case 1: // AC Bonus
                   ePoly = EffectLinkEffects(EffectACIncrease(GetItemPropertyCostTableValue(ip),GetItemACType(oItem)), ePoly);
                   break;
               case 27: // Ability Penalty
                   SetLocalInt(oPC, "ws_ability_" + IntToString(iSubType), GetLocalInt(oPC, "ws_ability_" + IntToString(iSubType)) - GetItemPropertyCostTableValue(ip) );
                   break;
               case 28: // AC penalty
                   ePoly = EffectLinkEffects(EffectACDecrease(GetItemPropertyCostTableValue(ip)), ePoly);
                   break;
               case 52: // Skill Bonus
                   SetLocalInt(oPC, "ws_skill_" + IntToString(iSubType), GetLocalInt(oPC, "ws_skill_" + IntToString(iSubType)) + GetItemPropertyCostTableValue(ip) );
                   break;
               case 29: // Skill Penalty
                   SetLocalInt(oPC, "ws_skill_" + IntToString(iSubType), GetLocalInt(oPC, "ws_skill_" + IntToString(iSubType)) - GetItemPropertyCostTableValue(ip) );
                   break;
               case 40: // Saving Throw Bonus vs Element(or universal)
                   SetLocalInt(oPC, "ws_save_elem_" + IntToString(iSubType), GetLocalInt(oPC, "ws_save_elem_" + IntToString(iSubType)) + GetItemPropertyCostTableValue(ip) );
                   break;
               case 41: // Saving Throw Bonus specific (fort/reflex/will)
                   SetLocalInt(oPC, "ws_save_spec_" + IntToString(iSubType), GetLocalInt(oPC, "ws_save_spec_" + IntToString(iSubType)) + GetItemPropertyCostTableValue(ip) );
                   break;
               case 49: // Saving Throw Penalty vs Element(or universal)
                   SetLocalInt(oPC, "ws_save_elem_" + IntToString(iSubType), GetLocalInt(oPC, "ws_save_elem_" + IntToString(iSubType)) - GetItemPropertyCostTableValue(ip) );
                   break;
               case 50: // Saving Throw Penalty specific (fort/reflex/will)
                   SetLocalInt(oPC, "ws_save_spec_" + IntToString(iSubType), GetLocalInt(oPC, "ws_save_spec_" + IntToString(iSubType)) - GetItemPropertyCostTableValue(ip) );
                   break;
               case 51: // Regeneration
                   SetLocalInt(oPC, "ws_regen", GetLocalInt(OBJECT_SELF, "ws_regen") + GetItemPropertyCostTableValue(ip) );
                   break;
               case 20: // Damage Immunity
                   SetLocalInt(oPC, "ws_dam_immun_" + IntToString(iSubType), GetLocalInt(oPC, "ws_dam_immun_" + IntToString(iSubType)) + ConvertNumToImmunePercentage(GetItemPropertyCostTableValue(ip)) );
                   break;
               case 24: // Damage Vulnerability
                   SetLocalInt(oPC, "ws_dam_immun_" + IntToString(iSubType), GetLocalInt(oPC, "ws_dam_immun_" + IntToString(iSubType)) - ConvertNumToImmunePercentage(GetItemPropertyCostTableValue(ip)) );
                   break;
           };
       }
       ip = GetNextItemProperty(oItem);
   }
   return ePoly;
}
// if bItems is TRUE, Adds all the stackable properties on all the objects given to ePoly.
// if bItems is FALSE, Adds only the stackable properties on armor and helmet to ePoly.
effect AddStackablePropertiesToPoly ( object oPC, effect ePoly, int bWeapon, int bItems, int bArmor, object oArmorOld, object oRing1Old,
                                     object oRing2Old, object oAmuletOld, object oCloakOld, object oBracerOld,
                                     object oBootsOld, object oBeltOld, object oHelmetOld, object oShield, object oWeapon, object oHideOld)
{
   if (bArmor ) // Armor properties get carried over
   {
       ePoly = ExamineStackableProperties ( oPC, ePoly, oArmorOld );
       ePoly = ExamineStackableProperties ( oPC, ePoly, oHelmetOld );
       ePoly = ExamineStackableProperties ( oPC, ePoly, oShield );
       ePoly = ExamineStackableProperties ( oPC, ePoly, oHideOld );
   }
   if ( bItems ) // Item properties get carried over
   {
       ePoly = ExamineStackableProperties ( oPC, ePoly, oRing1Old );
       ePoly = ExamineStackableProperties ( oPC, ePoly, oRing2Old );
       ePoly = ExamineStackableProperties ( oPC, ePoly, oAmuletOld );
       ePoly = ExamineStackableProperties ( oPC, ePoly, oCloakOld );
       ePoly = ExamineStackableProperties ( oPC, ePoly, oBootsOld );
       ePoly = ExamineStackableProperties ( oPC, ePoly, oBeltOld );
       ePoly = ExamineStackableProperties ( oPC, ePoly, oBracerOld );
   }
   // AC bonuses are attached to ePoly inside ExamineStackableProperties
   int i; // This will loop over all the different ability subtypes (eg str, dex, con, etc)
   int j; // This will contain the sum of the stackable bonus type we're looking at
   for ( i = 0; i <= 5; i++ ) // **** Handle Ability Bonuses ****
   {
       j = GetLocalInt(oPC, "ws_ability_" + IntToString(i));
       // Add the sum of this ability bonus to the polymorph effect.
       if ( j > 0 ) // Sum was Positive
           ePoly = EffectLinkEffects(EffectAbilityIncrease(i, j), ePoly);
       else if ( j < 0 ) // Sum was Negative
           ePoly = EffectLinkEffects(EffectAbilityDecrease(i, -j), ePoly);
       DeleteLocalInt(oPC, "ws_ability_" + IntToString(i));
   }
   for ( i = 0; i <= 26; i++ ) // **** Handle Skill Bonuses ****
   {
       j = GetLocalInt(oPC, "ws_skill_" + IntToString(i));
       // Add the sum of this skill bonus to the polymorph effect.
       if ( j > 0 ) // Sum was Positive
           ePoly = EffectLinkEffects(EffectSkillIncrease(i, j), ePoly);
       else if ( j < 0 ) // Sum was Negative
           ePoly = EffectLinkEffects(EffectSkillDecrease(i, -j), ePoly);
       DeleteLocalInt(oPC, "ws_skill_" + IntToString(i));
   }
   for ( i = 0; i <= 21; i++ ) // **** Handle Saving Throw vs element Bonuses ****
   {
       j = GetLocalInt(oPC, "ws_save_elem_" + IntToString(i));
       // Add the sum of this saving throw bonus to the polymorph effect.
       if ( j > 0 ) // Sum was Positive
           ePoly = EffectLinkEffects(EffectSavingThrowIncrease(SAVING_THROW_ALL, j, i), ePoly);
       else if ( j < 0 ) // Sum was Negative
           ePoly = EffectLinkEffects(EffectSavingThrowDecrease(SAVING_THROW_ALL, -j, i), ePoly);
       DeleteLocalInt(oPC, "ws_save_elem_" + IntToString(i));
   }
   for ( i = 0; i <= 3; i++ ) // **** Handle Saving Throw specific Bonuses ****
   {
       j = GetLocalInt(oPC, "ws_save_spec_" + IntToString(i));
       // Add the sum of this saving throw bonus to the polymorph effect.
       if ( j > 0 ) // Sum was Positive
           ePoly = EffectLinkEffects(EffectSavingThrowIncrease(i, j), ePoly);
       else if ( j < 0 ) // Sum was Negative
           ePoly = EffectLinkEffects(EffectSavingThrowDecrease(i, -j), ePoly);
       DeleteLocalInt(oPC, "ws_save_spec_" + IntToString(i));
   }
   j = GetLocalInt(oPC, "ws_regen");
   if ( j > 0 )
   {
       ePoly = EffectLinkEffects(EffectRegenerate(j, 6.0), ePoly);
       DeleteLocalInt(oPC, "ws_regen" );
   }
   for ( i = 0; i <= 13; i++ ) // **** Handle Damage Immunity and Vulnerability ****
   {
       j = GetLocalInt(oPC, "ws_dam_immun_" + IntToString(i));
       // Add the sum of this Damage Immunity/Vulnerability to the polymorph effect.
       if ( j > 0 ) // Sum was Positive
           ePoly = EffectLinkEffects(EffectDamageImmunityIncrease(ConvertNumToDamTypeConstant ( i ), j), ePoly);
       else if ( j < 0 ) // Sum was Negative
           ePoly = EffectLinkEffects(EffectDamageImmunityDecrease(ConvertNumToDamTypeConstant ( i ), -j), ePoly);
       DeleteLocalInt(oPC, "ws_dam_immun_" + IntToString(i));
   }

   return ePoly; // Finally, we have the entire (possibly huge '<img'>  ) effect to be applied to the shifter.
}

// Returns the spell that applied a Polymorph Effect currently on the player.
// -1 if it was no spell, -2 if no polymorph effect found.
int ScanForPolymorphEffect(object oPC)
{
   effect eEffect = GetFirstEffect(oPC);
   while ( GetIsEffectValid(eEffect) )
   {
       if ( GetEffectType( eEffect ) == EFFECT_TYPE_POLYMORPH )
       {
           return GetEffectSpellId(eEffect);
       }
       eEffect = GetNextEffect(oPC);
   }
   return -2;
}

// Converts a number from iprp_damagetype.2da to the corresponding
// DAMAGE_TYPE_* constants.
int ConvertNumToDamTypeConstant ( int iItemDamType )
{
   switch ( iItemDamType )
   {
       case 0:
           return DAMAGE_TYPE_BLUDGEONING;
           break;
       case 1:
           return DAMAGE_TYPE_PIERCING;
           break;
       case 2:
           return DAMAGE_TYPE_SLASHING;
           break;
       case 5:
           return DAMAGE_TYPE_MAGICAL;
           break;
       case 6:
           return DAMAGE_TYPE_ACID;
           break;
       case 7:
           return DAMAGE_TYPE_COLD;
           break;
       case 8:
           return DAMAGE_TYPE_DIVINE;
           break;
       case 9:
           return DAMAGE_TYPE_ELECTRICAL;
           break;
       case 10:
           return DAMAGE_TYPE_FIRE;
           break;
       case 11:
           return DAMAGE_TYPE_NEGATIVE;
           break;
       case 12:
           return DAMAGE_TYPE_POSITIVE;
           break;
       case 13:
           return DAMAGE_TYPE_SONIC;
           break;
       default:
           return DAMAGE_TYPE_POSITIVE;
           break;
   };
   // This one might seem unneccesary but it wont compile otherwise
   return DAMAGE_TYPE_POSITIVE;
}

// Converts a number from iprp_immuncost.2da to the corresponding percentage of immunity
int ConvertNumToImmunePercentage ( int iImmuneCost )
{
   switch ( iImmuneCost )
   {
       case 1:
           return 5;
           break;
       case 2:
           return 10;
           break;
       case 3:
           return 25;
           break;
       case 4:
           return 50;
           break;
       case 5:
           return 75;
           break;
       case 6:
           return 90;
           break;
       case 7:
           return 100;
           break;
       default:
           return 0;
           break;
   };
   return 0;
}

void WildshapeCopyWeaponProperties(object oPC, object oOld, object oNew)
{
   if (GetIsObjectValid(oOld) && GetIsObjectValid(oNew))
   {
       itemproperty ip = GetFirstItemProperty(oOld);
       // If both are Melee Weapons
       if ( !GetWeaponRanged(oOld) && !GetWeaponRanged(oNew) )
       {
           while (GetIsItemPropertyValid(ip))
           {
               AddItemProperty(DURATION_TYPE_PERMANENT,ip,oNew);
               ip = GetNextItemProperty(oOld);
           }// while
       }

       // If both are Ranged Weapons
       else if ( GetWeaponRanged(oOld) && GetWeaponRanged(oNew) )
       {
           int bUnlimitedAmmoFound = FALSE;
           itemproperty ipNew;
           int iOldMightyValue = 0;
           object oAmmo;
           while (GetIsItemPropertyValid(ip))
           {
               if ( GetItemPropertyType(ip) == 61 ) // 61 = Unlimited Ammo
               {
                   // For some reason, when removing/replacing an unlimited
                   // ammo property, the corresponding missile type will get
                   // dropped in the player's inventory, so we have to remove
                   // that missile again to prevent abuse.
                   bUnlimitedAmmoFound = TRUE;
                   oAmmo = GetItemInSlot(INVENTORY_SLOT_ARROWS, oPC);
                   if ( !GetIsObjectValid( oAmmo ) )
                       oAmmo = GetItemInSlot(INVENTORY_SLOT_BOLTS, oPC);
                   if ( !GetIsObjectValid( oAmmo ) )
                       oAmmo = GetItemInSlot(INVENTORY_SLOT_BULLETS, oPC);
                   IPRemoveMatchingItemProperties(oNew, ITEM_PROPERTY_UNLIMITED_AMMUNITION, DURATION_TYPE_PERMANENT );
                   AddItemProperty(DURATION_TYPE_PERMANENT,ip,oNew);
                   DestroyObject(oAmmo);
               }
               else if ( GetItemPropertyType(ip) == 45 ) // 45 = Mighty
               {
                   ipNew = GetFirstItemProperty(oNew);
                   // Find the mighty value of the Polymorph's weapon
                   while ( GetIsItemPropertyValid(ipNew) )
                   {
                       if ( GetItemPropertyType( ipNew ) == 45 )
                       {
                           iOldMightyValue = GetItemPropertyCostTableValue( ipNew );
                           break;
                       }
                       ipNew = GetNextItemProperty(oNew);
                   } // while
                   // If new mighty value bigger, remove old one and add new one.
                   if ( GetItemPropertyCostTableValue(ip) > iOldMightyValue )
                   {
                       RemoveItemProperty(oNew, ipNew);
                       AddItemProperty(DURATION_TYPE_PERMANENT,ip,oNew);
                   }
               }
               else
                   AddItemProperty(DURATION_TYPE_PERMANENT,ip,oNew);

               ip = GetNextItemProperty(oOld);
           } // while
           // Add basic unlimited ammo if neccesary
           if ( bUnlimitedAmmoFound == FALSE && !GetItemHasItemProperty(oNew, ITEM_PROPERTY_UNLIMITED_AMMUNITION ) )
               AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyUnlimitedAmmo(), oNew);
       }
   }
   else if ( GetWeaponRanged(oNew) )
   {
       // Add basic unlimited ammo if neccesary
       if ( !GetItemHasItemProperty(oNew, ITEM_PROPERTY_UNLIMITED_AMMUNITION ) )
           AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyUnlimitedAmmo(), oNew);
   }
}

// Returns TRUE if oItem is a creature claw or bite.
int GetIsCreatureWeapon( object oItem )
{
   int iBaseItemType = GetBaseItemType(oItem);
   switch ( iBaseItemType )
   {
       case BASE_ITEM_CBLUDGWEAPON:
       case BASE_ITEM_CPIERCWEAPON:
       case BASE_ITEM_CSLASHWEAPON:
       case BASE_ITEM_CSLSHPRCWEAP:
           return TRUE;
       default:
           return FALSE;
   };
   return FALSE;
}

// **** End Functions, added by Iznoghoud ****

I also tried changing the:
const int GW_COPY_WEAPON_PROPS_TO_UNARMED = 1;

to 3, as well as the one for druid shapes, but it had no effect.

Also I don't appear to have nw_s2_wildshsape, so I assume you mean x2_s2_wildshsape? This system has worked in the past, and I am not sure why now it is not functioning (or fully anyways, as weapons are getting merged for the armed shapes.)
               
               

               
            

Legacy_Terrorble

  • Sr. Member
  • ****
  • Posts: 370
  • Karma: +0/-0
Merging equiped weapons into unarmed shapes claws...
« Reply #7 on: July 08, 2011, 04:28:19 am »


               In your polymorph.2da, MergeW column, change a few of the unarmed shapes back to 0 and test them. Also, your custom polymorph.2da is in your override folder (just checking)?

P.S.  Props to Iznoghoud for this script set - it has really worked well for us and added a lot of fun to our mod for years.
               
               

               


                     Modifié par Terrorble, 08 juillet 2011 - 03:31 .
                     
                  


            

Legacy_Lazarus Magni

  • Hero Member
  • *****
  • Posts: 1837
  • Karma: +0/-0
Merging equiped weapons into unarmed shapes claws...
« Reply #8 on: July 08, 2011, 09:55:03 pm »


               Thank you Terrorble!!! That didn't quite work for me, but got me on a path that did. Turns out if I have W set to 1, and then copy the resref for the creature's claw into the equiped colum field, it works. Don't ask me why, but it does. Just need to do it for all of the unarmed now, and upload. (And yep, I do have it in the override folder.)

Thank you everyone for the input!
Laz
               
               

               


                     Modifié par Lazarus Magni, 08 juillet 2011 - 08:56 .
                     
                  


            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Merging equiped weapons into unarmed shapes claws...
« Reply #9 on: July 08, 2011, 11:29:03 pm »


               There is a bug in the 
 int ConvertNumToDamTypeConstant ( int iItemDamType )
function above.  

...

case 12:
return DAMAGE_TYPE_POSITIVE;
break;
case 13:
return DAMAGE_TYPE_SONIC;
break;
...

Case 12 and 13 are reverced  DAMAGE_TYPE_SONIC should be case 12 and POSTIVE should be case 13. 

Or you could just reduce the entire function to: 

int ConvertNumToDamTypeConstant ( int iItemDamType )
{
   reutrn 1<<iItemDamType;
}

 

It would return the same values.
               
               

               


                     Modifié par Lightfoot8, 09 juillet 2011 - 01:05 .
                     
                  


            

Legacy_Lazarus Magni

  • Hero Member
  • *****
  • Posts: 1837
  • Karma: +0/-0
Merging equiped weapons into unarmed shapes claws...
« Reply #10 on: July 09, 2011, 12:48:17 am »


               Hmm thank you Lightfoot8 I might try that.
               
               

               
            

Legacy_Lazarus Magni

  • Hero Member
  • *****
  • Posts: 1837
  • Karma: +0/-0
Merging equiped weapons into unarmed shapes claws...
« Reply #11 on: July 09, 2011, 09:50:05 am »


               Well it turns out my solution was not perfect, although could be usefull under certain circumstances... It looks like base weapons are merging now, however for shiftey/monk hybrids they are losing their ability to flury, sf, qp, as well as the extra unarmed attacks. This may be usefull as I mentioned in some capacity to make it so not all unarmed shapes get those monk bonuses, however I would still like to retain those bonuses for at least one shape in each form type (except perhaps the humanoid since all of them are armed... although that would be easy to change.) So anyways, although this is a decent tempory solution, I am still seeking ideas for a more flexible permanent one to restore the monk unarmed attack bonuses to some of the shapes, other than giving unarmed shapes kamas and improved 2 weap feats (which doesn't make alot of sense for the druid animal shapes)... Anyone got any ideas?
               
               

               


                     Modifié par Lazarus Magni, 09 juillet 2011 - 08:57 .