About spawning a shield

Hi All,

This question has been addressed here and there, but I can't seem to get it to work the way I want it. I have an enemy who occasionally spawns a shield, and that shield should absorb all the hits until it dies. I've repurposed some scripts I found in the DnD Rise of Warduke game (masterpiece, that one), and have it mostly working except that the parent still takes damage as usual. Upon summoning, I've tried this:

Code:
anim follow2

@script
    if(frame==8){
      void self = getlocalvar("self");
      changeentityproperty(self, "defense", openborconstant("ATK_NORMAL"), 0, 500);
      changeentityproperty(self, "defense", openborconstant("ATK_NORMAL1"), 0, 500);
      changeentityproperty(self, "defense", openborconstant("ATK_NORMAL2"), 0, 500);
      changeentityproperty(self, "defense", openborconstant("ATK_NORMAL3"), 0, 500);
      changeentityproperty(self, "defense", openborconstant("ATK_NORMAL4"), 0, 500);
      changeentityproperty(self, "defense", openborconstant("ATK_NORMAL5"), 0, 500);
      changeentityproperty(self, "defense", openborconstant("ATK_NORMAL6"), 0, 500);
      changeentityproperty(self, "defense", openborconstant("ATK_NORMAL7"), 0, 500);
      changeentityproperty(self, "defense", openborconstant("ATK_NORMAL8"), 0, 500);
      changeentityproperty(self, "defense", openborconstant("ATK_NORMAL9"), 0, 500);
      changeentityproperty(self, "defense", openborconstant("ATK_NORMAL10"), 0, 500);
      changeentityproperty(self, "defense", openborconstant("ATK_NORMAL13"), 0, 500);
      changeentityproperty(self, "defense", openborconstant("ATK_BURN"), 0, 500);
      changeentityproperty(self, "defense", openborconstant("ATK_SHOCK"), 0, 500);
    }
@end_script

Which works, and when the shield is destroyed, I use this in the shield script:

Code:
anim death
@script
    if(frame==2){
      void self = getlocalvar("self");
      void Parent = getentityvar(self, 0);

      if(Parent){
        changeentityproperty(Parent, "defense", openborconstant("ATK_NORMAL"), 1, 1);
        changeentityproperty(Parent, "defense", openborconstant("ATK_NORMAL1"), 1, 1);
        changeentityproperty(Parent, "defense", openborconstant("ATK_NORMAL2"), 1, 1);
    changeentityproperty(Parent, "defense", openborconstant("ATK_NORMAL3"), 1, 1);
        changeentityproperty(Parent, "defense", openborconstant("ATK_NORMAL4"), 1, 1);
        changeentityproperty(Parent, "defense", openborconstant("ATK_NORMAL5"), 1, 1);
        changeentityproperty(Parent, "defense", openborconstant("ATK_NORMAL6"), 1, 1);
        changeentityproperty(Parent, "defense", openborconstant("ATK_NORMAL7"), 1, 1);
        changeentityproperty(Parent, "defense", openborconstant("ATK_NORMAL8"), 1, 1);
        changeentityproperty(Parent, "defense", openborconstant("ATK_NORMAL9"), 1, 1);
        changeentityproperty(Parent, "defense", openborconstant("ATK_NORMAL10"), 1, 1);
        changeentityproperty(Parent, "defense", openborconstant("ATK_NORMAL13"), 1, 1);
        changeentityproperty(Parent, "defense", openborconstant("ATK_BURN"), 0.4, 1);
        changeentityproperty(Parent, "defense", openborconstant("ATK_SHOCK"), 0.4, 1);
        setentityvar(Parent, 0, NULL());
      }

      killentity(self); //Suicide!
    }
@end_script

In theory, this should make the parent immune to all forms of attacks, and revert it when the shield is destroyed no? Am I missing something?
The spawning script is:
@cmd spawnShield

Code:
void spawnShield(void Name, float dx, float dy, float dz, int Health)
{ // Spawn Shield entity, bind it, store it and set health
   void Spawn;
   Spawn = spawnBind2(Name, dx, dy, dz, 0, 0, 0);                 
   changeentityproperty(Spawn, "maxhealth", Health);
   changeentityproperty(Spawn, "health", Health);
}
void spawnBind2(void Name, float dx, float dy, float dz, int Dir, int Flag, int Num)
{ // Spawn entity, bind it and store each other
   void self = getlocalvar("self");
   void Spawn;
   Spawn = spawn01(Name, dx, dy, dz);
   bindentity(Spawn, self, dx, dz, dy, Dir, Flag);
   setentityvar(self, Num, Spawn);
   setentityvar(Spawn, Num, self);
   return Spawn; //Return spawn
}
 
Instead of changing the defense to all type of attacks, its way better to use ondoattack, as it will fully nuliffy the attack - as the ondoattack happens before of all the hit routines, it can simply not confirm the hit


 
Can I see the whole FOLLOW2 of the shield spawner?
Code:
anim    follow2
@script
    if(frame==8){
      void self = getlocalvar("self");
      changeentityproperty(self, "defense", openborconstant("ATK_NORMAL"), 0, 500);
      changeentityproperty(self, "defense", openborconstant("ATK_NORMAL1"), 0, 500);
      changeentityproperty(self, "defense", openborconstant("ATK_NORMAL2"), 0, 500);
      changeentityproperty(self, "defense", openborconstant("ATK_NORMAL3"), 0, 500);
      changeentityproperty(self, "defense", openborconstant("ATK_NORMAL4"), 0, 500);
      changeentityproperty(self, "defense", openborconstant("ATK_NORMAL5"), 0, 500);
      changeentityproperty(self, "defense", openborconstant("ATK_NORMAL6"), 0, 500);
      changeentityproperty(self, "defense", openborconstant("ATK_NORMAL7"), 0, 500);
      changeentityproperty(self, "defense", openborconstant("ATK_NORMAL8"), 0, 500);
      changeentityproperty(self, "defense", openborconstant("ATK_NORMAL9"), 0, 500);
      changeentityproperty(self, "defense", openborconstant("ATK_NORMAL10"), 0, 500);
      changeentityproperty(self, "defense", openborconstant("ATK_NORMAL13"), 0, 500);
      changeentityproperty(self, "defense", openborconstant("ATK_BURN"), 0, 500);
      changeentityproperty(self, "defense", openborconstant("ATK_SHOCK"), 0, 500);
    }
@end_script

    seta    40
    offset  46 86
    delay  10
    Bbox    41 53 9 33
    frame  data/chars/doom/atk5_1.GIF
    frame  data/chars/doom/atk5_2.GIF
    frame  data/chars/doom/atk5_3.GIF
    frame  data/chars/doom/atk5_4.GIF
    frame  data/chars/doom/atk5_5.GIF
    frame  data/chars/doom/atk5_6.GIF
    frame  data/chars/doom/atk5_7.GIF
    @cmd    spawnShield "PerisaiSky" 0 30 2 60
    frame  data/chars/doom/atk5_8.GIF
    frame  data/chars/doom/atk5_9.GIF
    frame  data/chars/doom/atk5_9.GIF

The shield spawns correctly, and is destroyed after a number of hits, but the parent is still hit normally.
 
Instead of changing the defense to all type of attacks, its way better to use ondoattack, as it will fully nuliffy the attack - as the ondoattack happens before of all the hit routines, it can simply not confirm the hit


Interesting... I could try adding some logic to it. For instance, using this as a conditional:
Code:
      void self = getlocalvar("self");
      void Shield = getentityvar(self, 0);

      if(Shield != NULL()){
        changeopenborvariant("lasthitc",0);
      }
 
Last edited:
Also, as per this thread: Tutorial - DoAttack Event
It seems my version openbor also does not have a
openborconstant("EXCHANGE_RECIPIANT")
When I try running it that way, it crashes. If I try, as Ilusionista did, setting which == 0, the clause will somewhat randomly trigger, so that's not a fix...
 
Sorry for late reply, I haven't figured out what's wrong with your setting cause it works here.
So let me confirm this: after spawning shield, the spawner should be immune to any damage until shield is broken. Your issue is the spawner still takes damage despite having shield spawned right?
 
seems my version openbor also does not have a
openborconstant("EXCHANGE_RECIPIANT")
Which build are you using ? Ondoattack is on the engine for quite some time, so your build must be very old.

Also, this part will only really work inside ondoattack, because it happens before to hit detection routine:

changeopenborvariant("lasthitc",0)

Trying to use this in any other type of event won't have the same effect, because the hit was already registered.
 
Sorry for late reply, I haven't figured out what's wrong with your setting cause it works here.
So let me confirm this: after spawning shield, the spawner should be immune to any damage until shield is broken. Your issue is the spawner still takes damage despite having shield spawned right?
Correct. For clarity, in openborconstant("ATK_NORMAL1"), does ATK_NORMAL1 refer to the numbered enemy attack animation, or the type of enemy attack (i.e., attack4 0 0 0 0)?
 
Which build are you using ? Ondoattack is on the engine for quite some time, so your build must be very old.

Also, this part will only really work inside ondoattack, because it happens before to hit detection routine:

changeopenborvariant("lasthitc",0)

Trying to use this in any other type of event won't have the same effect, because the hit was already registered.
It's 3.0.0.0.

As for the use, I really am trying to use it almost exactly as is, except for the shield part.
I'm doing:
Code:
void main()
{
  void self;      // Entity running event
  int which;      // Attacker or defender event?
  int hit_by_id;  // Entity ID of entity attack hit.
  int attack_id;  // Entity ID of entity that performed attack.
  void Shield;
  self  = getlocalvar("self");
  which = getlocalvar("which");
  Shield = getentityvar(self, 0);
  if(which == openborconstant("EXCHANGE_RECIPIANT"))
  {
    hit_by_id   = getentityproperty(self, "hitbyid");
    attack_id   = getlocalvar("attackid");

    if(hit_by_id != attack_id)
    {
      
      if(Shield != NULL()){
        changeopenborvariant("lasthitc", 0);
      }
                    
    }
  }

  changeentityproperty(self, "hitbyid", hit_by_id);
}
 
Back
Top Bottom