Change health spawn enemy with weapon

dantedevil

Well-known member
I just realized that when you spawn an enemy with a weapon, the system not take into account the health that you put and always leave the one you have in the header of their txt.

Here enemy header txt:
Code:
name	SLICER
health	60
speed	10
type	enemy
risetime -200 -200 
gfxshadow  1
aggression -30
falldie 2
projectilehit   enemy obstacle
hmap 1 5
fmap 2
noquake 1

aimove Avoidz

weapons  none SLICER2 SLICER 

icon	data/chars/gang1/slicer/icon.png 1
animationscript data/scripts/escript.h 

palette data/chars/gang1/slicer/idle0.png
alternatepal data/chars/gang1/slicer/map.png
alternatepal data/chars/gang1/slicer/map2.png 
alternatepal data/chars/gang1/slicer/map3.png 
alternatepal data/chars/gang1/slicer/map4.png 
alternatepal data/chars/gang1/slicer/map5.png 
alternatepal data/chars/gang1/slicer/map6.png 
alternatepal data/chars/gang1/slicer/map7.png

Here enemy weapon header txt:
Code:
name	SLICER2
health	60
speed	10
type	none
risetime -200 -200 
gfxshadow  1
aggression -30
dust		dust
hmap 1 5
fmap 2
aimove avoid

load knife2

typeshot      0
weaploss      0 
modelflag     1

icon	data/chars/gang1/slicer/icon.png 1

animationscript data/scripts/escript.h 

palette data/chars/gang1/slicer/idle0.png
alternatepal data/chars/gang1/slicer/map.png
alternatepal data/chars/gang1/slicer/map2.png 
alternatepal data/chars/gang1/slicer/map3.png 
alternatepal data/chars/gang1/slicer/map4.png 
alternatepal data/chars/gang1/slicer/map5.png 
alternatepal data/chars/gang1/slicer/map6.png 
alternatepal data/chars/gang1/slicer/map7.png

In their Slicer txt have health  60, and always spawn with this health, when spawn the weapon.
Is this true or is it a bug?
And if so, is there a way to allocate more health?

Here in the example I put health 200, but always spawn with 60 health, as it is designated in the header txt. It would be important to find the solution to be able to manually designate the energy for 1p, 2p or 3p, as we normally do.

Code:
spawn  slicer
health   200
2phealth 230
3phealth 260
weapon knife
coords  362 242 0
at      0


I try this script by O Ilusionista (http://www.chronocrash.com/forum/index.php?topic=3980.msg55051#msg55051)
, but not work:
Code:
spawn  slicer
@script void main() {
void self = getlocalvar("self"); // get caller
int iLife = 300;
changeentityproperty(self, "maxhealth",iLife );
changeentityproperty(self, "health",iLife );
} @end_script
weapon knife 0
coords  362 242 0
at      0
 
I need time to test, but on that script the weapon declaration comes after the script, it will get overwritten.
I can't remember if you can retrieve the health set into level spawn by script, it would be easy to do so.

Maybe, you can set a local variable for this. I can think in some ways to fix this, but I would need time to do it.
Maybe we are overdoing it.

 
O Ilusionista said:
I need time to test, but on that script the weapon declaration comes after the script, it will get overwritten.
I can't remember if you can retrieve the health set into level spawn by script, it would be easy to do so.

Maybe, you can set a local variable for this. I can think in some ways to fix this, but I would need time to do it.
Maybe we are overdoing it.
Take your time my friend.
It is incredible that nobody has detected this problem before, but without a doubt the solution will be useful for everyone.

Thanks for all your help my friend!
 
dantedevil said:
It is incredible that nobody has detected this problem before,..

That's not true at all. Me, Bloodbane and other guys have already discussed this a few times here in the forum. You just have missed the party  ;D
 
Dante, I noticed something:

name SLICER
health 60
speed 10
type enemy
risetime -200 -200
gfxshadow  1
aggression -30
falldie 2
projectilehit  enemy obstacle
hmap 1 5
fmap 2
noquake 1

aimove Avoidz

weapons  none SLICER2

This is wrong. The last weapon should be the normal model, not the alternate mode (weapon). Like this:

name  Spider-Woman
health  200
mp 120
speed  14
type   player
weapons  a_SWNave a_SWNave2 Spider-Woman

 
I came up with an idea to solve this.

Set this in level:
Code:
spawn  slicer
@script
void main()
{
    void self = getlocalvar("self");
    changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW1"));
}
@end_script
weapon knife
coords  362 242 0
at      0

Then, in the enemy weapon (slicer2):
anim follow1
              loop  0
              offset 82 177
              delay  1
              data/chars/gang1/idle0.png. png
(Here place a Script to add more health, depending on whether there is 1P, 2P, 3P)
            data/chars/gang1/idle0.png. png

Maybe it works, but I can not prove it, since I do not know what the Script would be like.
 
While thinking what script to solve this issue, I discovered that enemies with weapon on spawn DO take defined health in level text. However due health adjustment on weapon change, they lost the defined health and use maximum health defined on default weapon (after weapon change)

IOW when spawned like in this example:
Code:
spawn  slicer
health   200
2phealth 230
3phealth 260
weapon knife
coords  362 242 0
at      0

Slicer DOES start with 200 HP, however when he/she is beaten, his/her HP restarts from 60 HP (original max HP) and takes damage from there

However, if Slicer and Slicer2's health (max health) are say 1000, he/she starts with 200 HP and can retain that HP when beaten since original max HP is larger than 200 HP

I haven't figured out script solution for this, but non script solution I could offer right now is to set large health in enemy's text and set health for all respective enemy's spawn in level texts

OTOH maybe this is an engine bug which should be fixed
 
Well my friend, at least it is a solution to the problem and easy to apply.

But when using this, it generates a new problem:

There are several situations in which one enemy spawn another, such as when a motorcycle comes with a companion mounted behind and it jumps, or when a boss comes calling reinforcements. In these cases the enemies use a custom animation to enter and take the health they have by default.
So these cases we need a script to adjust the health depending how many players are playing.


Example:

Here the spawn animation of one of the bikers, as you see spawn SLICER:
Code:
anim spawn
	loop	0
	offset	88 130
	delay   5
        sound	data/chars/biker/bike.wav
	frame	data/chars/biker/bike_bd300.png
	frame	data/chars/biker/bike_bd300b.png
	frame	data/chars/biker/bike_bd300.png
	frame	data/chars/biker/bike_bd300b.png
	frame	data/chars/biker/bike_bd300.png
	frame	data/chars/biker/bike_bd300b.png
	frame	data/chars/biker/bike_bd300.png
	frame	data/chars/biker/bike_bd300b.png
	frame	data/chars/biker/bike_bd300.png
	frame	data/chars/biker/bike_bd300b.png
	frame	data/chars/biker/bike_bd300.png
	frame	data/chars/biker/bike_bd300b.png
	frame	data/chars/biker/bike_bd300.png
	frame	data/chars/biker/bike_bd300b.png
	frame	data/chars/biker/bike_bd300.png
	frame	data/chars/biker/bike_bd300b.png
	frame	data/chars/biker/bike_bd300.png
	frame	data/chars/biker/bike_bd300b.png
	frame	data/chars/biker/bike_bd300.png
	@script
		if(frame == 20){
			void ent = spawn01("slicer", -55, 25, 1);
			performattack(ent, openborconstant("ANI_follow13"), 1);

		}
	@end_script
	frame	data/chars/biker/bike_bd300b.png
	offset	88 103
	frame	data/chars/biker/bike00.png

So here in the anim follow13 of SLICER, need add a script to adjust the health depending how many players are playing.
Code:
anim follow13
	loop	0
	delay	6
	offset	82 177
        jumpframe 1 1 -0.7
        @cmd    manUsa1
        @cmd    defenseAtk4 1
	frame	data/chars/gang1/slicer/rise3.png
	offset	82 155
	frame	data/chars/gang1/slicer/j2.png
	frame	data/chars/gang1/slicer/j2.png
	frame	data/chars/gang1/slicer/j2.png
	frame	data/chars/gang1/slicer/j1.png
	frame	data/chars/gang1/slicer/j1.png
	offset	82 177
	frame	data/chars/gang1/slicer/w1.png
 
I don't have enemies with weapons on my game, so I can't recreate it.

Anyway, I tested my own code and it doesn't works - which is strange, since I can swear I saw uTunnels using something like that (btw, it should not have that main(), i forgot that).
Then I reminded that spawnscripts are persistent and tried this:

Save this file as lifespawn.c
Code:
void main() {
void self = getlocalvar("self"); // get caller
int iLife = 300;
changeentityproperty(self, "maxhealth",iLife );
changeentityproperty(self, "health",iLife );
}

And set it on the character spawn in level
spawn Dummy
coords 200 180
health 20
spawnscript data/scripts/lifespawn.c
at 0

OR]

you can set the script AFTER the health setting

spawn Dummy
coords 200 180
health 20
@script void main() {
void self = getlocalvar("self"); // get caller
int iLife = 300;
changeentityproperty(self, "maxhealth",iLife );
changeentityproperty(self, "health",iLife );
} @end_script
at 0

If you want, PM me your mod.
 
Well my friend, none of the 2 systems worked.

I'm going to stay with the alternative of Bloodbane and put more health by default, and then assign less in the spawn level.

Now only need add a script in specific spawn animations, to adjust the health depending how many players are playing.
 
After many tests, I found the best solution using all the help they have given me.

Starting with the Bloodbane solution, I assign the enemy and the enemy weapon (slicer and slicer2) a high health value for defaut, in this case 120, which is the health it would have if there are 3 players.
Ex:
1P 60
2P 90
3P 120.

But using only the Bloodbane method, when spawning the enemy by designating a lower health for 1P and 2P, the enemy appears with a health bar that is not full..
Ex: Max default is 120, for 1P it is 60, this way it appears with half health bar.
Code:
spawn  slicer
health   60
2phealth 90
3phealth 120
weapon knife
coords  362 242 0
at      0

To avoid this detail and for the enemy to appear with the health bar full, regardless of the health that is designated, we use the method of O Ilusionista.
After assign the enemy and the enemy weapon (slicer and slicer2) a high health value for defaut, in this case 120, which is the health it would have if there are 3 players,
then we use the script to assign the desired default health for spawn the enemy.
Ex: Here we go to spawn the enemy with 60 health (1 P)

Code:
spawn  slicer
weapon knife
@script void main() {
void self = getlocalvar("self"); // get caller
int iLife = 60;
changeentityproperty(self, "maxhealth",iLife );
changeentityproperty(self, "health",iLife );
} @end_script
coords  362 242 0
at      0

In this way the enemy appears with the health we want and with the health bar full.

Now the only thing that would be missing would be to modify this script so that it assigns the health by default, depending how many players are playing.

Something like:
@script
void self = getlocalvar("self"); // get caller
int iLife = 60;// 60 P1, 90 P2, 120 P3 assigning the 3 values to the script
changeentityproperty(self, "maxhealth",iLife );
changeentityproperty(self, "health",iLife );
@end_script
(fix the script, thanks for Ilu's)

Sorry but I don't know how modify the script.

Thanks for all the help my friends.
 
I said I made a typo on that script. It should be

Code:
@script
void self = getlocalvar("self"); // get caller
int iLife = 60;// 60 P1, 90 P2, 120 P3 assigning the 3 values to the script
changeentityproperty(self, "maxhealth",iLife );
changeentityproperty(self, "health",iLife );
@end_script
 
O Ilusionista said:
I said I made a typo on that script. It should be

Code:
@script
void self = getlocalvar("self"); // get caller
int iLife = 60;// 60 P1, 90 P2, 120 P3 assigning the 3 values to the script
changeentityproperty(self, "maxhealth",iLife );
changeentityproperty(self, "health",iLife );
@end_script

Ups sorry, my bad. I copy the wrong script, but in the level is ok.
Thanks for tell me.
 
After some trial n errors, I managed to script something to solve this. This script system requires scripts to be declared in multiple texts.
First enemies need this takedamagescript:
Storing.c
Code:
void main()
{// Preserves maximum health and health during weapon model change
// Also stores received damage
    void self = getlocalvar("self");
    int Damage = getlocalvar("damage"); //Get received damage
    int RilMHP = getentityvar(self, 8);
    int Dams = getentityvar(self, 9);

    if(RilMHP==NULL()){
      RilMHP = getentityproperty(self, "maxhealth");
      setentityvar(self, 8, RilMHP);
    }

    if(Dams==NULL()){
      Dams = 0;
    }

    changeentityproperty(self, "maxhealth", RilMHP);
    changeentityproperty(self, "health", RilMHP - Dams - Damage);

    setentityvar(self, 9, Dams+Damage);
}

then declare it in enemy's text with this:
Code:
takedamagescript data/scripts/storing.c

That should be declared in main model and all weapon models enemy has

In enemy's GET animation, declare this script:
Code:
anim	get
@script
    if(frame==1){
      void self = getlocalvar("self");
      int RilMHP = getentityvar(self, 8);
      int Dams = getentityvar(self, 9);

      changeentityproperty(self, "maxhealth", RilMHP);
      changeentityproperty(self, "health", RilMHP - Dams);
    }
@end_script
...

Last, when enemy is spawned, his/her entity variable must be set like this:
Code:
spawn	Williams
@script
void main()
{
    void self = getlocalvar("self");
    setentityvar(self, 8, 130); // defines maximum's health
}
@end_script
health	130
map	5
weapon	KnifeW 0
coords	400 225
at	100

The script system works like this, when enemy takes damage, the damage is stored in an enemy's entity variable. At the same time, enemy's HP (which is resetted during weapon model change) is reverted to desired health i.e defined maximum health - taken damage. As result, enemy's HP after the damage is as it should be
The script in GET works same way except without damage storing
The script in enemy's spawn in level text, is for defining enemy's starting health.
I use entity variables 8 and 9 cause enemies in demo I'm using already are using entity variables from 1 to 7

I've tested this system and it works :D
[couple minutes later]

Ok,made small fix
 
Back
Top Bottom