Aller au contenu

Photo

Destroying items with fire resistance and/or immunity


  • Veuillez vous connecter pour répondre
8 réponses à ce sujet

#1
apunyfly

apunyfly
  • Members
  • 112 messages
The script I use fails with a 'too many instructions' when testing with a player possessing such items, although works fine for a level one character with non-magical items. Could be a simple logic error, (if that's the case, I apologise, I wrote this some time ago, although returned to it recently).  Haven't yet implemented it for the items in the player's hands.
If it is the object destruction which can't be handled, how can it be made more efficient ?


void main()
{
int nSlot;
object oPC = GetEnteringObject();
//object oItem = GetFirstItemInInventory(oPC);//
object oItemb;
float fDelay = 1.0f;
int nProperty = ITEM_PROPERTY_DAMAGE_RESISTANCE;
int nPropertyb =  ITEM_PROPERTY_IMMUNITY_DAMAGE_TYPE;

for( nSlot=0; nSlot<NUM_INVENTORY_SLOTS;nSlot++)
{
   itemproperty iProp =GetFirstItemProperty(oItemb);
   while(GetIsItemPropertyValid(iProp))
       {object oItemb =GetItemInSlot(nSlot,oPC);
       if(GetIsObjectValid(oItemb)==TRUE)
          {if((GetItemHasItemProperty(oItemb,nProperty)==TRUE||
         GetItemHasItemProperty(oItemb,nPropertyb))==TRUE)
               {if(GetItemPropertyType(iProp)==DAMAGE_TYPE_FIRE)
                    {if (GetPlotFlag(oItemb)==TRUE)
                    {SetPlotFlag(oItemb,FALSE);}
               DestroyObject(oItemb,fDelay);}
           else
          {itemproperty iProp = GetNextItemProperty(oItemb);}
}
}
}
}
}

#2
Shadooow

Shadooow
  • Members
  • 4 474 messages
This code is absolutely wrong and unreadable. You also still don't check the damage type.

half-working script - the script works except that the GetItemPropertySomething have to be changed to GetItemPropertySubType or CostTable etc. I dont know which one returns the damage type, you have to try printing all of them and compare to the item in question to find out the right one. It can even be different for damage_resistance and damage immunity itemproperty but hopefuly not.

void CheckIPs(object oItem)
{
itemproperty iProp = GetFirstItemProperty(oItem);
 while(GetIsItemPropertyValid(iProp))
 {
  switch(GetItemPropertyType(iProp))
  {
  case ITEM_PROPERTY_DAMAGE_RESISTANCE:
  case ITEM_PROPERTY_IMMUNITY_DAMAGE_TYPE:
   if(GetItemPropertySomething(iProp) == IP_CONST_DAMAGETYPE_FIRE)
   {
   DestroyObject(oItem);
   return;
   }
  break;
  }
 iProp = GetNextItemProperty(oItem);
 }
}

void main()
{
int nSlot;
object oPC = GetEnteringObject();
object oItem;

 for(;nSlot<NUM_INVENTORY_SLOTS;nSlot++)
 {
 oItem = GetItemInSlot(nSlot,oPC);
  if(GetIsObjectValid(oItem))
  {
  CheckIPs(oItem);
  }
 }
}



#3
The Amethyst Dragon

The Amethyst Dragon
  • Members
  • 1 882 messages
Maybe this will work for you.  It compiled for me just fine, but I haven't tested it in a running module.

// Returns TRUE if oItem has either Damage Resistance (fire) or
// Damage Immunity (fire) properties.
int CheckForWeakProps(object oItem);
int CheckForWeakProps(object oItem)
{
int nReturn = FALSE;
int nPropTypeA;
int nPropTypeB;
itemproperty ipPropTest = GetFirstItemProperty(oItem);
while(GetIsItemPropertyValid(ipPropTest) == TRUE)
   {
   nPropTypeA = GetItemPropertyType(ipPropTest);
   nPropTypeB = GetItemPropertySubType(ipPropTest);
   if (nPropTypeA == ITEM_PROPERTY_DAMAGE_RESISTANCE || nPropTypeA == ITEM_PROPERTY_IMMUNITY_DAMAGE_TYPE)
      {
      if (nPropTypeB == IP_CONST_DAMAGETYPE_FIRE)
         {
         return TRUE;
         }
      }
   ipPropTest = GetNextItemProperty(oItem);
   }
return nReturn;
}

void main()
{
object oPC = GetEnteringObject();
object oItemb;
int nSlot;
for (nSlot = 0; nSlot < NUM_INVENTORY_SLOTS; nSlot++)
   {
   oItemb = GetItemInSlot(nSlot, oPC);
   if (CheckForWeakProps(oItemb) == TRUE)
      {
      SetPlotFlag(oItemb, FALSE);
      DelayCommand(1.0, DestroyObject(oItemb));
      }
   }
}



#4
Kato -

Kato -
  • Members
  • 392 messages
void DestroyFireImmuneItems(object oPC)
{
    int nSlot = INVENTORY_SLOT_HEAD;
    object oItem;
    itemproperty ip;
    for(nSlot; nSlot < NUM_INVENTORY_SLOTS; Slot++)
    {
        oItem = GetItemInSlot(nSlot, oPC);
        if(oItem != OBJECT_INVALID)
        {
             ip = GetFirstItemProperty(oItem);
             while(GetIsItemPropertyValid(ip))
             {
                 switch(GetItemPropertyType(ip))
                 {
                     case ITEM_PROPERTY_DAMAGE_RESISTANCE:
                     case ITEM_PROPERTY_IMMUNITY_DAMAGE_TYPE:
                     if(GetItemPropertySubType(ip) == IP_CONST_DAMAGETYPE_FIRE) 
                     {
                         DestroyObject(oItem);
                         break;
                     }
                 } 
                 ip = GetNextItemProperty(oItem); 
             }
        }
    }
}

This should do it, rename the function if needed. (Fingers crossed, I sincerely hope ShaDoOoW won't tell me this is totally wrong and unreadable, except if it is lol) 

Kato

Modifié par Kato_Yang, 14 juillet 2012 - 06:33 .


#5
Failed.Bard

Failed.Bard
  • Members
  • 774 messages

void DestroyFireImmuneItems(object oPC)

maybe -- DestroyEquippedFireImmuneItems(object oPC) -- as the function name instead, so its use is that little more apparent. I didn't test it, but the logic flow in it looks good, Kato.

#6
Kato -

Kato -
  • Members
  • 392 messages
Thanks FB :)

#7
apunyfly

apunyfly
  • Members
  • 112 messages
Thank you for your replies everyone. I will try some of these scripts out.

Edit : The Amethyst Dragon's script works perfectly. Will try the others out too.

Modifié par apunyfly, 14 juillet 2012 - 08:40 .


#8
Shadooow

Shadooow
  • Members
  • 4 474 messages

Kato_Yang wrote...

void DestroyFireImmuneItems(object oPC)
{
    int nSlot = INVENTORY_SLOT_HEAD;
    object oItem;
    itemproperty ip;
    for(nSlot; nSlot < NUM_INVENTORY_SLOTS; Slot++)
    {
        oItem = GetItemInSlot(nSlot, oPC);
        if(oItem != OBJECT_INVALID)
        {
             ip = GetFirstItemProperty(oItem);
             while(GetIsItemPropertyValid(ip))
             {
                 switch(GetItemPropertyType(ip))
                 {
                     case ITEM_PROPERTY_DAMAGE_RESISTANCE:
                     case ITEM_PROPERTY_IMMUNITY_DAMAGE_TYPE:
                     if(GetItemPropertySubType(ip) == IP_CONST_DAMAGETYPE_FIRE) 
                     {
                         DestroyObject(oItem);
                         break;
                     }
                 } 
                 ip = GetNextItemProperty(oItem); 
             }
        }
    }
}

This should do it, rename the function if needed. (Fingers crossed, I sincerely hope ShaDoOoW won't tell me this is totally wrong and unreadable, except if it is lol) 

Kato

its readable perfectly, and its corrent

though there was a reason why i splitted the script into its own function, doing two loops inside it dangerous and if you destroy the item, you want to exit the current loop in order not to loop any other ips (since item is destroyed later, script will still loop ips I suppose). However break statement will in your script break only switch and not while loop so the script might take more instruction than needed.

EDIT: using if instead of switch will work this way without need for new function, though switch saves variable... your call

Modifié par ShaDoOoW, 14 juillet 2012 - 06:42 .


#9
Kato -

Kato -
  • Members
  • 392 messages
Indeed, thanks for that precision ShaDoOoW. Also, as an info for the OP, there is a typo in the for statement, Slot++ should be replaced by nSlot++, of course...

Kato