Aller au contenu

Photo

PC OnDamaged - is that possible?


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

#1
Alaster Wolf

Alaster Wolf
  • Members
  • 14 messages
Is it possible to have OnDamaged event script for the player? If not, are there any ideas on how to emulate that?

What I am trying to achieve is to determine when the player has been damaged and then run some actions on that PC. I was thinking to play around with the combat scripts on the NPC and I assume that it could be achieved somewhere in the OnCombatRoundEnd. However, this does not help with the damage caused by other means (triggers, traps, PVP attacks). Can anyone help me out, please?

#2
ffbj

ffbj
  • Members
  • 593 messages
There has been some work done in this area. I remember some discussions and even worked some scripts myself. So really the only way I know is to use the hb transversal to compare the PC's current hitpoints with their maximum and then reset them to being the current maximum, something along those lines.

#3
ffbj

ffbj
  • Members
  • 593 messages
This may be of use to help you with some parts of what you are trying to achieve:
http://nwvault.ign.c....detail&id=2692

#4
Shadooow

Shadooow
  • Members
  • 4 470 messages

Alaster Wolf wrote...

Is it possible to have OnDamaged event script for the player? If not, are there any ideas on how to emulate that?

What I am trying to achieve is to determine when the player has been damaged and then run some actions on that PC. I was thinking to play around with the combat scripts on the NPC and I assume that it could be achieved somewhere in the OnCombatRoundEnd. However, this does not help with the damage caused by other means (triggers, traps, PVP attacks). Can anyone help me out, please?

easy to do via OnHitCastSpell on armor (and skin when no armor is present) Im using this solution long time ago and already proposed it on these forums I think (try google search or maybe Omnibus if it was at old forums)

#5
Alaster Wolf

Alaster Wolf
  • Members
  • 14 messages
Thanks, guys!

For the moment, I am using the default script on the PC to compare their HPs.

I have been thinking before about the OnHitCastSpell, but dropped the idea. Now, a new thing for me here is that you can have it on the skin! I will look into this solution again.

#6
Alaster Wolf

Alaster Wolf
  • Members
  • 14 messages
BTW - I was hoping there would be a way to mess around with the default combat sequence (the initiative roll - attack roll - damage). But, it seems to be hardcoded?

#7
Alaster Wolf

Alaster Wolf
  • Members
  • 14 messages
@ffbj - Thanks for the link. I will check it out.

#8
WhiZard

WhiZard
  • Members
  • 1 204 messages

Alaster Wolf wrote...

BTW - I was hoping there would be a way to mess around with the default combat sequence (the initiative roll - attack roll - damage). But, it seems to be hardcoded?


Yes, it is hardcoded.  What is difficult about on-hit cast spell is that it doesn't tell the damage produced, and when you delay a script to check afterward, the damage for all blows in the flurry has already been dealt (since the damage is in reverse order of the attack rolls, GetDamageDealtByType() will only give the damage of the first hit in the flurry).

Nevertheless, I have come up with interesting results in having armor and weapons wear down by this event when placed on the skin through checking the material types and quality of both the weapon and the armor (I decrement the quality as a counter decreases).  If all you want to do is replicate the impact of the blow, then the damage does not matter as much as the strength of the attacker and the material and quality of the weapon and armor.

#9
Alaster Wolf

Alaster Wolf
  • Members
  • 14 messages

WhiZard wrote...

What is difficult about on-hit cast spell is that it doesn't tell the damage produced
...


Ah, yes. I have just tested it and as I came back to talk about that issue then I saw your message.

WhiZard wrote...
Nevertheless, I have come up with interesting results in having armor and weapons wear down by this event when placed on the skin through checking the material types and quality of both the weapon and the armor (I decrement the quality as a counter decreases).  If all you want to do is replicate the impact of the blow, then the damage does not matter as much as the strength of the attacker and the material and quality of the weapon and armor.


Interesting! Thanks. I am actually trying to do something similar, but more complex. As it sounds, it may be outside the NWN scripting limits.

Since the topic has expanded now, then let me explain what I had in mind. I am trying to ignore the HP as a feature and instead to track only the particular damage on creatures. So, when PC attacks someone the blow is countered by the armor/shield that wears down and the damage above the resistance of the armor/shield is done to a specific body part (limbs, torso, head). Damage to the body parts will either be minor (ignored), extensive (bleeding) or severe (for example - the victim loses their left arm and drops the shield). I would be tracking the Stamina scale so that every attack spends the stamina points of the attacker. Any bleeding also goes to the stamina scale until it is stopped.

This idea is in its early phase, so there may be some changes to it.

Modifié par Alaster Wolf, 20 mars 2013 - 06:25 .


#10
WhiZard

WhiZard
  • Members
  • 1 204 messages

Alaster Wolf wrote...
So, when PC attacks someone the blow is countered by the armor/shield that wears down and the damage above the resistance of the armor/shield is done to a specific body part (limbs, torso, head). Damage to the body parts will either be minor (ignored), extensive (bleeding) or severe (for example - the victim loses their left arm and drops the shield).


Here is an include file (won't run by itself and requires other includes that I created) which shows a lot of the circumstances I was factoring in when working on my system.


#include "dd_inc_craft"

// Returns the material element of the item
// Returns 0 if item is not elemental
int GetElement(object oItem);
// Gets the highest attack bonus property value
int GetHighAB(object oItem);
// Gets the highest DR enhancement value
int GetHighDR(object oItem);
// Returns FALSE if armed with non-creature weapon
// Returns TRUE if fighting unarmed
int GetIsUnarmed(object oAttacker);
// This is the main combat function for the gradual ruining of items.
// Called Shot and Disarm feats adjust the affected items to be ruined.
// Fists without gloves cause the attacker to become stunned for a flurry.
void OnHitWeaponVsArmor(object oAttacker, object oDefender = OBJECT_SELF);
// Resets quality of item when it is damaged
void ResetQualityByDamage(object oItem, int nQuality, itemproperty ipCurrentQuality);

int GetElement(object oItem)
  {
  int nElement = 51; //For comparative reasons only
  int nPossible = 0;
  itemproperty ipElement = GetFirstItemProperty(oItem);
  while(GetIsItemPropertyValid(ipElement))
    {
    if(GetItemPropertyType(ipElement) == ITEM_PROPERTY_MATERIAL)
      {
      nPossible = GetItemPropertyParam1(ipElement);
      if((nPossible > 45) && (nPossible < 51)) // Checks for element
        {
        if(nElement > nPossible) nElement = nPossible;
        }
      }
    }
  if(nElement != 51) return nElement;
  else return 0;
  }

int GetHighAB(object oItem)
  {
  int nAB = 0;
  int nPossible = 0;
  int nType = 0;
  itemproperty ipAB = GetFirstItemProperty(oItem);
  while(GetIsItemPropertyValid(ipAB))
    {
    nType = GetItemPropertyType(ipAB);
    if(nType == ITEM_PROPERTY_ATTACK_BONUS || nType == ITEM_PROPERTY_ENHANCEMENT_BONUS)
      {
      nPossible = GetItemPropertyParam1(ipAB);
      if(nAB < nPossible) nAB = nPossible;
      }
    ipAB = GetNextItemProperty(oItem);
    }
  return nAB;
  }

int GetHighDR(object oItem)
  {
  int nDR = 0;
  int nPossible = 0;
  itemproperty ipDR = GetFirstItemProperty(oItem);
  while(GetIsItemPropertyValid(ipDR))
    {
    if(GetItemPropertyType(ipDR) == ITEM_PROPERTY_DAMAGE_REDUCTION)
      {
      nPossible = GetItemPropertySubType(ipDR) + 1;
      if(nDR < nPossible) nDR = nPossible;
      }
    ipDR = GetNextItemProperty(oItem);
    }
  return nDR;
  }

int GetIsUnarmed(object oAttacker)
  {
  //Does not check for last use of throwing item
  if(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oAttacker) == OBJECT_INVALID)
    return TRUE;
  return FALSE;
  }

void OnHitWeaponVsArmor(object oAttacker, object oDefender = OBJECT_SELF)
  {
  //Plot Flag needed to take into account creatures like Black Blade of Disaster
  int bAttackerPlot = GetPlotFlag(oAttacker);
  int bDefenderPlot = GetPlotFlag(oDefender);
  int nExtreme = (EXTREME_CHANCE - 1 + d100())/ 100; //20% chance of extreme hit
  int nAttackType = GetLastAttackType(oAttacker);
  object oAttackWeapon = GetLastWeaponUsed(oAttacker);
  if(oAttackWeapon == OBJECT_INVALID)
    {
    ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectStunned(), oAttacker, 2.0);
    oAttackWeapon = GetItemInSlot(INVENTORY_SLOT_CARMOUR);
    }
  struct object_struct stAttackWeapon = SetObjectUsed(oAttackWeapon);
  int nAType = stAttackWeapon.nType;
  int bARanged = stAttackWeapon.bRanged;
  object oDefendItem = OBJECT_INVALID;
  int nDefendItemType = 0;
  object oProjectile = OBJECT_INVALID;
  //Throwing and projectile weapons are treated differently
  if(bARanged)
    {
    if(nAType == BASE_ITEM_SHORTBOW || nAType == BASE_ITEM_LONGBOW)
      oProjectile = GetItemInSlot(INVENTORY_SLOT_ARROWS);
    else if (nAType == BASE_ITEM_LIGHTCROSSBOW || nAType == BASE_ITEM_HEAVYCROSSBOW)
      oProjectile = GetItemInSlot(INVENTORY_SLOT_BOLTS);
    else if (nAType == BASE_ITEM_SLING)
      oProjectile = GetItemInSlot(INVENTORY_SLOT_BULLETS);
    }
  if(nAttackType == SPECIAL_ATTACK_DISARM || nAttackType == SPECIAL_ATTACK_IMPROVED_DISARM)
    {
    if(nExtreme == 1)
      {
      oDefendItem = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oDefender);
      nDefendItemType = GetBaseItemType(oDefendItem);
      if(nDefendItemType == BASE_ITEM_SMALLSHIELD || nDefendItemType == BASE_ITEM_LARGESHIELD || nDefendItemType == BASE_ITEM_TOWERSHIELD)
        oDefendItem = OBJECT_INVALID;
      if(oDefendItem == OBJECT_INVALID)
        oDefendItem = GetItemInSlot(INVENTORY_SLOT_CWEAPON_L);
      if(oDefendItem == OBJECT_INVALID)
        nExtreme = 0;
      }
    if(nExtreme == 0)
      {
      oDefendItem = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oDefender);
      if(oDefendItem == OBJECT_INVALID)
        oDefendItem = GetItemInSlot(INVENTORY_SLOT_CWEAPON_R, oDefender);
      if(oDefendItem == OBJECT_INVALID)
        oDefendItem = GetItemInSlot(INVENTORY_SLOT_CARMOUR, oDefender);
      }
    }
  else if(nAttackType == SPECIAL_ATTACK_CALLED_SHOT_ARM)
    {
    if(nExtreme == 0)
      {
      oDefendItem = GetItemInSlot(INVENTORY_SLOT_CHEST, oDefender);
      if(oDefendItem == OBJECT_INVALID) nExtreme = 1;
      }
    if(nExtreme == 1)
      {
      oDefendItem = GetItemInSlot(INVENTORY_SLOT_ARMS, oDefender);
      if(GetBaseItemType(oDefendItem) == BASE_ITEM_GLOVES || oDefendItem == OBJECT_INVALID)
         oDefendItem = GetItemInSlot(INVENTORY_SLOT_CARMOUR, oDefender);
      }
    }
  else if(nAttackType == SPECIAL_ATTACK_CALLED_SHOT_LEG)
    {
    if(nExtreme == 0)
      {
      oDefendItem = GetItemInSlot(INVENTORY_SLOT_CHEST, oDefender);
      if(oDefendItem == OBJECT_INVALID) nExtreme = 1;
      }
    if(nExtreme == 1)
      {
      oDefendItem = GetItemInSlot(INVENTORY_SLOT_BOOTS, oDefender);
      if(oDefendItem == OBJECT_INVALID)
        oDefendItem = GetItemInSlot(INVENTORY_SLOT_CARMOUR, oDefender);
      }
    }
  else
    {
    if(nExtreme == 0)
       {
       oDefendItem = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oDefender);
       nDefendItemType = GetBaseItemType(oDefendItem);
       if(nDefendItemType != BASE_ITEM_SMALLSHIELD && nDefendItemType != BASE_ITEM_LARGESHIELD && nDefendItemType != BASE_ITEM_TOWERSHIELD)
         oDefendItem = OBJECT_INVALID;
       if(oDefendItem == OBJECT_INVALID)
         oDefendItem = GetItemInSlot(INVENTORY_SLOT_CHEST, oDefender);
       if(oDefendItem == OBJECT_INVALID)
         oDefendItem = GetItemInSlot(INVENTORY_SLOT_CARMOUR, oDefender);
       }
    else
      {
      oDefendItem = GetItemInSlot(INVENTORY_SLOT_HEAD, oDefender);
      if(oDefendItem == OBJECT_INVALID)
        oDefendItem = GetItemInSlot(INVENTORY_SLOT_CWEAPON_B, oDefender);
      if(oDefendItem == OBJECT_INVALID)
        oDefendItem = GetItemInSlot(INVENTORY_SLOT_CARMOUR);
      }
    }
  struct object_struct stDefendItem = SetObjectUsed(oDefendItem);
  int nAElemental = stAttackWeapon.nElemental;
  int nDElemental = stDefendItem.nElemental;
  int nAttackRoll = 0;
  int bDamage = FALSE;
  struct object_struct stProjectile = SetObjectUsed(oProjectile);
  if(bAttackerPlot)
    {
    nAElemental = 46;
    bDamage = TRUE;
    }
  if(bDefenderPlot)
    {
    nDElemental = 46;
    bDamage = TRUE;
    }
  object oATorch = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oAttacker);
  object oDTorch = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oDefender);
  if(nAElemental == 47 && nDElemental == 48) bDamage = TRUE;
  if(nAElemental == 48 && nDElemental == 47) bDamage = TRUE;
  if(nAElemental == 49 && nDElemental == 50) bDamage = TRUE;
  if(nAElemental == 50 && nDElemental == 49) bDamage = TRUE;
  if(nAElemental == 0 && nDElemental == 0) bDamage = TRUE;
  if(nAElemental != 49 && nAElemental != 46 && nDElemental == 50 && GetBaseItemType(oATorch) == BASE_ITEM_TORCH && bARanged == FALSE)
    {
    bDamage = TRUE;
    stAttackWeapon = SetObjectUsed(oATorch);
    }
  else if(nAElemental == 50 && nDElemental != 49 && nDElemental != 46 && GetBaseItemType(oDTorch) == BASE_ITEM_TORCH)
    {
    bDamage = TRUE;
    if(oDefendItem != oDTorch)
      stDefendItem = SetObjectUsed(oDTorch);
    }
  oAttackWeapon = stAttackWeapon.oObject;
  nAType = stAttackWeapon.nType;
  int bRanged = stAttackWeapon.bRanged;
  int nAMaterialValue = stAttackWeapon.nHMaterialValue;
  int nAQualityValue = stAttackWeapon.nHQuality;
  int nAttackElement = nAElemental;
  itemproperty ipAQuality = stAttackWeapon.ipHQuality;
  int nABValue = stAttackWeapon.nHABValue;
  int nPMaterialValue = stProjectile.nHMaterialValue;
  int nPQualityValue = stProjectile.nHQuality;
  oDefendItem = stDefendItem.oObject;
  int nDType = stDefendItem.nType;
  int nDMaterialValue = stDefendItem.nHMaterialValue;
  int nDQualityValue = stDefendItem.nHQuality;
  int nDefendElement = nDElemental;
  itemproperty ipDQuality = stDefendItem.ipHQuality;
  int nDRValue = stDefendItem.nHDRValue;
  int nMaterialValue, nQualityValue;
  int nAttackItemPoints = GetLocalInt(oAttackWeapon, "ItemPoints");
  int nDefenseItemPoints = GetLocalInt(oDefendItem, "ItemPoints");
  int nStrengthMod = GetAbilityModifier(ABILITY_STRENGTH, oAttacker);
  int bArmor = FALSE;
  if(nStrengthMod < 1) nStrengthMod = 1;
  int nAttackDamage, nDefendDamage, nPossible, nTough;
  if(bDamage)
    {
    if(nAttackElement == 0 && nDefendElement == 0)
      //AttackRoll
      {
      if(bRanged)
        {
        if(oProjectile != OBJECT_INVALID)
          {
          nMaterialValue = nPMaterialValue;
          nQualityValue = nPQualityValue - 1;
          }
         //Material is of projectile, Quality comes from both
        else nMaterialValue = nDMaterialValue;
        nQualityValue += nDQualityValue - 1;
        //Arcane Archer Enchant feats add one per feat
        if(nAType == BASE_ITEM_LONGBOW || nAType == BASE_ITEM_SHORTBOW)
          {
          int nFeat = 1059;
          int bOnlyOne = FALSE;
          while(nFeat > 1044 && bOnlyOne == FALSE)
            {
            if(GetHasFeat(nFeat, oAttacker))
              {
              nAttackRoll += (nFeat - 1039);
              bOnlyOne == TRUE;
              }
            nFeat -= 1;
            }
          nFeat = 449;
          while(nFeat > 444 && bOnlyOne == FALSE)
            {
            if(GetHasFeat(nFeat, oAttacker))
              {
              nAttackRoll += (nFeat - 444);
              bOnlyOne == TRUE;
              }
            nFeat -= 1;
            }
          }
        }
      else
        {
        int bUnarmed = GetIsUnarmed(oAttacker);

        if(bUnarmed)
          {
          if(GetHasFeat(FEAT_EPIC_IMPROVED_KI_STRIKE_5, oAttacker))
            nAttackRoll += 100;
          else if(GetHasFeat(FEAT_EPIC_IMPROVED_KI_STRIKE_4, oAttacker))
            nAttackRoll += 80;
          else if(GetHasFeat(344, oAttacker)) //Ki Strike +3
            nAttackRoll += 60;
          else if(GetHasFeat(343, oAttacker)) //Ki Strike +2
            nAttackRoll += 40;
          else if(GetHasFeat(FEAT_KI_STRIKE, oAttacker))
            nAttackRoll += 20;
          }
        nMaterialValue = nAMaterialValue;
        nQualityValue = nAQualityValue - 1;
        }
      nAttackRoll += (nMaterialValue + nQualityValue + nABValue);
      nMaterialValue = nDMaterialValue;
      nQualityValue = nDQualityValue - 1;
      nAttackRoll -= (nMaterialValue + nQualityValue + nDRValue);
      }
    //ApplyItemDamage
    if(nAttackElement == 0 && nDefendElement == 0)
      {
      if(nAttackRoll > -1)
        {
        nDefendDamage = nStrengthMod * (1 + nAttackRoll);
        nAttackDamage = nStrengthMod/(1 + nAttackRoll);
        }
      else
        {
        nDefendDamage = nStrengthMod/(1 - nAttackRoll);
        nAttackDamage = nStrengthMod *(1 - nAttackRoll);
        }
      }
    else
      {
      if(nAttackElement != 46 && nDefendElement != 0)
        nAttackDamage = nStrengthMod;
      if(nDefendElement != 46 && nAttackElement != 0)
        nDefendDamage = nStrengthMod;
      }
    if(bRanged) nDefendDamage = 0;
    nTough = WEAPON_TOUGHNESS;
    nPossible = ((nAttackItemPoints - nAttackDamage - 1) / nTough);
    if(nPossible < 0)
      {
      if(nAType == BASE_ITEM_CREATUREITEM)
        {
        AssignCommand(oDefender, ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectDeath(TRUE), oAttacker));
        if(GetIsPC(oAttacker)) SendMessageToPC(oAttacker, "Your body tears to shreds as you strike your opponent");
        if(GetIsPC(oDefender)) SendMessageToPC(oDefender, "You feel an opponent's body tearing on your armor");
        }
      else
        {
        DestroyObject(oAttackWeapon);
        if(GetIsPC(oAttacker)) SendMessageToPC(oAttacker, "Your weapon broke when striking your opponent");
        if(GetIsPC(oDefender)) SendMessageToPC(oDefender, "A weapon broke when striking your armor");
        }
      }
    else
      {
      if((nAttackItemPoints - 1)/ nTough > nPossible)
        ResetQualityByDamage(oAttackWeapon, (nPossible + 1), ipAQuality);
      SetLocalInt(oAttackWeapon, "ItemPoints", (nAttackItemPoints - nAttackDamage));
      }
    bArmor = GetIsArmor(nDType);
    if(bArmor)
      nTough = 10 * ARMOR_TOUGHNESS;
    else nTough = 10 * WEAPON_TOUGHNESS;
    nPossible = ((nDefenseItemPoints - nDefendDamage - 1)/nTough);
    if(nPossible < 0)
      {
      if(nDType == BASE_ITEM_CREATUREITEM)
        {
        AssignCommand(oAttacker, ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectDeath(TRUE), oDefender));
        if(GetIsPC(oAttacker)) SendMessageToPC(oAttacker, "Your blow tatters your opponent");
        if(GetIsPC(oDefender)) SendMessageToPC(oDefender, "Your body is tattered from one too many blows");
        }
      else
        {
        DestroyObject(oDefendItem);
        if(GetIsPC(oAttacker)) SendMessageToPC(oAttacker, "You have broken an item of your opponent");
        if(GetIsPC(oDefender)) SendMessageToPC(oDefender, "Something broke from that last blow");
        }
      }
    else
      {
      if((nDefenseItemPoints - 1)/nTough > nPossible)
        ResetQualityByDamage(oDefendItem, (nPossible + 1), ipDQuality);
      SetLocalInt(oDefendItem, "ItemPoints", (nDefenseItemPoints - nDefendDamage));
      }
    }
  }

void ResetQualityByDamage(object oItem, int nQuality, itemproperty ipCurrentQuality)
  {
  RemoveItemProperty(oItem, ipCurrentQuality);
  AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyQuality(nQuality), oItem);
  if(nQuality = 1)
    AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyNoDamage(), oItem);
  }

#11
MagicalMaster

MagicalMaster
  • Members
  • 2 000 messages
You might find this useful for creating your system: http://social.biowar.../index/16271409

Basically runs a psuedo-heartbeat on a creature - except you'd be running it on PCs. You can check the HP at the previous call and the HP at the current call to see how much damage was taken in that time-frame.

It's not perfect (theoretically you could take 100 damage and be healed for 100 damage between psuedo-heartbeats) for what you're trying to do, but it wouldn't be too hard to adapt. The system can already track a "hpbonus" value which you could swap to your "stamina" concept.

#12
Alaster Wolf

Alaster Wolf
  • Members
  • 14 messages
Guys - thank you so much! You gave me much more material than I expected! I will need some time to process all this. I'll come back to showcase the system if I get it done!

Actually, I am so happy that this community is still very alive. I have been playing around with NWN for the past 10 years and it still gives me much pleasure. I was thinking to suggest an open project to create a new rpg engine based on the experience with NWN. I am not sure if that would be a forbidden topic in these forums?

#13
Alaster Wolf

Alaster Wolf
  • Members
  • 14 messages

WhiZard wrote...

Here is an include file (won't run by itself and requires other includes that I created) which shows a lot of the circumstances I was factoring in when working on my system.


Thanks! Your extensive script is a gold!

Modifié par Alaster Wolf, 20 mars 2013 - 09:08 .


#14
Alaster Wolf

Alaster Wolf
  • Members
  • 14 messages

WhiZard wrote...
Here is an include file (won't run by itself and requires other includes that I created) which shows a lot of the circumstances I was factoring in when working on my system.


I find your script to be very interesting so I was wondering if you could publish your system?

I have tried to determine the parts that were missing in order to compile your script:

const int EXTREME_CHANCE = 0;
const int WEAPON_TOUGHNESS = 0;
const int ARMOR_TOUGHNESS = 0;

struct object_struct
{
    int nType;
    int bRanged;
    int nElemental;
    object oObject;
    int nHMaterialValue;
    int nHDRValue;
    int nHQuality;
    itemproperty ipHQuality;
    int nHABValue;
};
struct object_struct SetObjectUsed( object oObject ){
    struct object_struct stReturn;
    return stReturn;
}
int GetIsArmor( int nType ){
    return FALSE;
}

#15
ffbj

ffbj
  • Members
  • 593 messages
Yeah, that's what I am talkin about really cool Whizard.
I did a little fatigue demo since it was mentioned above, I thought I would post that too.
 http://nwvault.ign.c....Detail&id=3730

Yeah you should also check out Magical Masters  massive  hp tracker demo/scripts they are fine.

Modifié par ffbj, 22 mars 2013 - 12:19 .


#16
Alaster Wolf

Alaster Wolf
  • Members
  • 14 messages

ffbj wrote...
I did a little fatigue demo since it was mentioned above, I thought I would post that too.
 http://nwvault.ign.c....Detail&id=3730


Wow, really cool demo! I have not run it yet but the description of it is exactly what I was doing in my script. It will really come useful! Thanks ffbj!

#17
Pstemarie

Pstemarie
  • Members
  • 2 745 messages
All PCs run the same script for their events - its called "default" - and if you open some of the character bics you'll see it listed. You can use this script to run specific effects/routines on the PC whenever an event is fired for a particular PC. OldMansBeard has some excellent use of this method in his OHS System.

What's nice about using the "default" script is that it doesn't rely upon a heartbeat that has to check every single PC each time it fires, it fires only for a PC whenever the need arises. Therefore you could link an effect to the OnDamaged event in the "default" script and it will only fire for a PC whenever their OnDamaged event fires - no need for heartbeat checks.

I'll admit I might be a little off as its been several years since I've played with a "default" script so I'll defer to OMB and the OHS. Furthermore, I do recall something about not all events firing reliably but I can't remember which ones - OHS will have notes on this anyway.

Just for the record. The "default" script does not actually exist. It is a marker script placed into character bics so that PC behavior could be overridden by the Community. 

Modifié par Pstemarie, 22 mars 2013 - 11:09 .


#18
Shadooow

Shadooow
  • Members
  • 4 470 messages
default script doesnt run for all events Pstemarie, merely a few and OnDamaged isnt among them

also due to my recent discovery, that traps created by scripts run default as heartbeat, I can't recommend using default script any further, unless you dont spawn traps (or you use NWNX to set PC's heartbeat as I do) pseudo-hb is better option

#19
Pstemarie

Pstemarie
  • Members
  • 2 745 messages
Thanks Shadoow, I knew there was more with that default script but couldn't recall. Wondering though if just putting a flag to identify the caller as a PC would be enough to bypass traps. However, for this thread its moot since OnDamaged doesn't fire properly.

Modifié par Pstemarie, 22 mars 2013 - 11:36 .


#20
Shadooow

Shadooow
  • Members
  • 4 470 messages

Pstemarie wrote...

Thanks Shadoow, I knew there was more with that default script but couldn't recall. Wondering though if just putting a flag to identify the caller as a PC would be enough to bypass traps. However, for this thread its moot since OnDamaged doesn't fire properly.

It is, but the problem is that the default script will still fire each 6seconds for each trap created by script.

As long as you care about efficiency pseudo-hb is better choice. If you aren't concerned about efficiency it doesn't matter of course.

Modifié par ShaDoOoW, 22 mars 2013 - 12:07 .


#21
Pstemarie

Pstemarie
  • Members
  • 2 745 messages
That makes sense - hadn't thought of it that way.

#22
WhiZard

WhiZard
  • Members
  • 1 204 messages
I named a script "default" and the only time it ran was for the HeartBeat and Death events. All other instances in the bic (including Rested, OnNotice, Endround, Attacked, Damaged, etc.) the script didn't fire for even though the bic listed default there. Also it seems "default" is a patched implementation (likely 1.69) as older character files don't seem to have it listed even though they respect it.

Given module level support already deals with these events (module heartbeat can just loop through the PCs), it doesn't seem worthwhile to create a "default" script.

#23
ffbj

ffbj
  • Members
  • 593 messages
True I just the default hb transversal for my fatigue script for instance it checks if the PC is in combat and then executes if that returns true.
In regard to traps, I have all traps designated by giving them the owners name on acquired. So wether by construction, purchase, or recovery it will have the aforesaid PC's name on it. Then you can get the last damager or last killer indirectly. So no anonymous trap killing in my campaign.
My rp justification for this is it is an imperial edict. Anyone who carries an unbranded trap is in violation, and you really don't want to annoy the empire.

Modifié par ffbj, 22 mars 2013 - 08:43 .


#24
Pstemarie

Pstemarie
  • Members
  • 2 745 messages
Good stuff to know Whizard. Like I said in my op I knew there were limitations, just didn't know what they were. My guess would be that at some point BioWare intended the default to do more, but they never got around to implementing it.

#25
WhiZard

WhiZard
  • Members
  • 1 204 messages
I accidentally ran into a weird situation with the "default" script. Whenever a negative mind-effect was removed (reverting the character back to GUI control) the script would fire. This does not apply to the removal of other effects. I have not found any useful implementation for this, especially since the removed effect cannot be obtained, and the script is shared with heartbeat and death.