turtles manhole

kmilloz

Member
Would like some help to make the animation turtles falling in manhole ... I created an entity with attack (x) and players with pain (x), but I wish they would fall always in the middle of the hole ... sometimes they get were the hole ... Thanks

Gostaria de alguma ajuda para fazer a animação das tartarugas caindo no bueiro... Criei uma entidade com ataque (x) e os jogadores com pain (x), mas gostaria que eles sempre caissem no meio do buraco... as vezes eles ficam foram do buraco... Obrigado

 
So the bbox of players are hard to hit, players can go through the hole, time ...
Assim os bbox dos jogadores ficam difíceis de serem atingidos, os jogadores conseguem passar pelo buraco, as vezes...
 
My suggestion is to use followup for manhole's attack. In the follow1 (for instance) animation, manhole puts turtle at its coords with script

Just a minute, I need to trial n error the script :)

[couple minutes later]

Ah that took more than a minute but anyways :D

I assume the manhole is trap type. This script is applied to trap type entity.
As mentioned above, set followup system for manhole's attack then set this script in its follow animation (I use FOLLOW1 as example):

anim follow1
@script
    void self = getlocalvar("self");
    int Opp = getentityproperty(self, "opponent");

    if(Opp && frame==0){
      float x = getentityproperty(self, "x");
      float z = getentityproperty(self, "z");

      changeentityproperty(Opp, "position", x, z);
    }
    if(frame==8){
      setidle(self, openborconstant("ANI_IDLE"));
    }
@end_script
...

This script find manhole's last entity it just hit then moves it to manhole's coordinate.
I also added another function to be run at 9th frame to revert manhole to IDLE animation after FOLLOW1 animation ends. You should change 8 to proper value :)
 
In that code I see a bug when 2 or more entities are damaged consecutively and another bug when the player dies. Not tested.I can post you my script on script event based. However I can work on an improvement of the script based on didhitscript event and a script event just to clear an array list
 
White Dragon said:
In that code I see a bug when 2 or more entities are damaged consecutively and another bug when the player dies. Not tested.I can post you my script on script event based. However I can work on an improvement of the script based on didhitscript event and a script event just to clear an array list

thanks guys! all help is welcome!
 
Bloodbane said:
My suggestion is to use followup for manhole's attack. In the follow1 (for instance) animation, manhole puts turtle at its coords with script

Just a minute, I need to trial n error the script :)

[couple minutes later]

Ah that took more than a minute but anyways :D

I assume the manhole is trap type. This script is applied to trap type entity.
As mentioned above, set followup system for manhole's attack then set this script in its follow animation (I use FOLLOW1 as example):

anim follow1
@script
    void self = getlocalvar("self");
    int Opp = getentityproperty(self, "opponent");

    if(Opp && frame==0){
      float x = getentityproperty(self, "x");
      float z = getentityproperty(self, "z");

      changeentityproperty(Opp, "position", x, z);
    }
    if(frame==8){
      setidle(self, openborconstant("ANI_IDLE"));
    }
@end_script
...

This script find manhole's last entity it just hit then moves it to manhole's coordinate.
I also added another function to be run at 9th frame to revert manhole to IDLE animation after FOLLOW1 animation ends. You should change 8 to proper value :)

thanks guy!
 
O Ilusionista said:

But what's happen if 4 players walk on it concurrently?

However I post my solution (animations == PAIN24, DEATH24):

Entity
Code:
name	 manhole
type	none
nolife 1
facing 1
setlayer -1

subject_to_wall 1
subject_to_obstacle 0
subject_to_platform 1
subject_to_gravity 1
no_adjust_base 0

script data/scripts/manhole_script.c
didhitscript data/scripts/manhole_didhit.c

palette	data/bgs/debug/manhole/manhole.gif

anim	IDLE
	loop	1
	fastattack 1
	range -50 50
	rangez -30 30

	offset	22 25
	delay	1
	bbox  0
		noreflect 1
		attack  2  -4  39  27  0  0  1  0  0  20
	frame	data/chars/misc/empty.gif

script event:
Code:
#import "data/scripts/lib.c"

void main() {
    void self = getlocalvar("self");

    setlocalvar("opp_list",clear_hitbyid_list(self,"opp_list"));
    //drawstring(10,100,0,getlocalvar("opp_list"));
}

void ondestroy() {
    destroy_hitbyid_list("opp_list");
}

didhitscript event:
Code:
#import "data/scripts/lib.c"

void main() {
    void self = getlocalvar("self");
    int damage = getlocalvar("damage");
    int drop = getlocalvar("drop");
    int attacktype = getlocalvar("attacktype");
    void damagetaker = getlocalvar("damagetaker");

    /*
    self: Caller.
    damagetaker: Recipient of attack or item.
    damage: attack damage. "
    drop: knockdown power.
    attacktype: attack type, see 'openborconstant'.
    noblock: block break force of attack.
    guardcost: Guardcost of attack.
    jugglecost: Jugglecost of attack.
    pauseadd: Pause value of attack.
    blocked: Receiving entity did (1) or did not (0) block attack.
    */

    add_hitbyid_list(self,"opp_list",damagetaker);
    get_object(self,damagetaker);
}

int get_object(void self, void player) {
            //drawstring( 20,180,0,"Manhole1:  "+"   x:  "+x+"   z:  "+z+ "   a:  "+a );
            float x = getentityproperty(self, "x");
            float z = getentityproperty(self, "z");
            float a = getentityproperty(self, "y");
            float xp, zp, ap;

            xp = getentityproperty(player, "x");
            zp = getentityproperty(player, "z");
            ap = getentityproperty(player, "y");

            // ATTENZIONE A QUESTO "y" == 0 SE SI VOGLIONO BUCHI IN ALTO!!
            if ( xp > x-30 && xp < x+30 && zp > z-20 && zp < z+20 && ap == a ) {
                int anim_id = getentityproperty(player, "animationid");

                if ( getentityproperty(player, "invincible") == 0 && getentityproperty(player, "vulnerable") != 0 && anim_id != openborconstant("ANI_PAIN24") && anim_id != openborconstant("ANI_DIE24") ) {
                    if ( !is_in_pain(player) ) {
                        void defaultmodel = getentityproperty(self, "defaultmodel");
                        int health = getentityproperty(player,"health");
                        int damage = 20;

                            // IMPORTANTISSIMO: noaicontrol + cambio d'animazione funziona solo se lo script viene ripetuto a ciclo ad ogni frame!!
                            //changeentityproperty(player, "noaicontrol", 1); // lo facciamo perchè con qualche mossa speciale altrimenti può evitare di cadere

                            changeentityproperty(player, "position", x+0, z-7, ap+0);
                            changeentityproperty(player, "base", ap+0);

                            // SUPER IMPORTANTISSIMO: Se non imposti la velocity a 0 su tutti i parametri, il player continuerà a camminare anche dopo noaicontrol impostato a vero!!
                            changeentityproperty(player, "velocity", 0, 0, 0);
                            changeentityproperty(player, "aiflag", "jumping", 0);
                            changeentityproperty(player, "aiflag", "running", 0);
                            if ( defaultmodel == "manhole_sx" ) changeentityproperty(player, "direction", 0); // <-------- FORCE DIRECTION!!
                            else if ( defaultmodel == "manhole_dx" ) changeentityproperty(player, "direction", 1);

                            // Con il seguente metodo dato dalle seguenti 2 funzioni, ci assicuriamo di far perdere una somma COSTANTE di HP al player...
                            //changeentityproperty( player,"health",getentityproperty(player,"health")-20 );
                            damageentity(player,self,damage,0,openborconstant("ATK_NORMAL24"));
                            changeentityproperty(player, "hitbyid", 0);
                            //if ( getentityproperty(player,"health") <= 0 ) changeentityproperty(player, "animation", openborconstant("ANI_FOLLOW21"));
                            //else performattack(player, openborconstant("ANI_FOLLOW20"), 1);

                            playsample(loadsample("data/sounds/falling_cave.wav"));
                    } // fine if dead/pain/fall
                } // fine if invincible
            } // fine if coords
}

lib.c
Code:
void add_hitbyid_list(void self, void entityvar, void opp) {
    int i = 0;
    void opp_list = getentityvar(self,entityvar);

    if ( opp != NULL() && getentityproperty(opp,"exists") ) {
        if ( opp_list == NULL() ) {
            setentityvar(self,entityvar,array(1));
            opp_list = getentityvar(self,entityvar);
        }
        i = size(opp_list)-1;
        set(opp_list,i++,opp);
        //setentityvar(self,entityvar,opp_list);
    }

    return opp_list;
}

void clear_hitbyid_list(void self, void entityvar) {
    int i = 0;
    void opp_list = getentityvar(self,entityvar);

    if ( opp_list != NULL() ) {
        //drawstring(10,100,0,opp_list);
        for ( i = size(opp_list)-1; i >= 0; i-- ) {
            void opp = get(opp_list,i);

            if ( opp != NULL() && getentityproperty(opp,"exists") ) {
                changeentityproperty(opp,"hitbyid",0);
                set(opp_list,i,NULL());
            } else set(opp_list,i,NULL());
        }
        free(opp_list);
        setentityvar(self,entityvar,NULL());
        opp_list = getentityvar(self,entityvar);
    }

    return opp_list;
}

void destroy_hitbyid_list(char localvar_name) {
    int i = 0;
    void opp_list = getlocalvar(localvar_name);

    if ( opp_list != NULL() ) {
        for ( i = size(opp_list)-1; i >= 0; i-- ) {
            set(opp_list,i,NULL());
        }
        free(opp_list);
        setlocalvar(localvar_name,NULL());
        opp_list = getlocalvar(localvar_name);
    }

    return opp_list;
}
 
naturally in pain24 animation or pain# animation put invincible flag or change position from the hole
here my anims:
Code:
anim	PAIN24 # Tombino (MANHOLE4)
	loop	0

	@script
		void self = getlocalvar("self");
		//drawstring( 20,170,0,"animpos:  "+getentityproperty(self, "animpos") );
		if ( getentityproperty(self, "animpos") == 10 ) {
    			changeentityproperty(self, "invincible", 1);
    			changeentityproperty(self, "invinctime", openborvariant("elapsed_time") + (openborvariant("game_speed")*1)); //makes entity invincible for 1.5 seconds, change decimal number to change time length
		}
		if ( getentityproperty(self, "animpos") == 18 ) {
			// ATTENZIONE: L'opponent poi muore. quindi conviene prendere le coordinate da se stesso...
			float x = getentityproperty(self, "x");
			float z = getentityproperty(self, "z");
			float a = getentityproperty(self, "y");
			if ( getentityproperty(self, "direction") == 1 ) changeentityproperty(self, "position", x+40, z+16, a);
			else changeentityproperty(self, "position", x-40, z+16, a);
		}
	@end_script

	fshadow 0
	offset	52 69
	delay	7
	#sound	data/sounds/cave.wav
		bbox  0
	frame	data/chars/don/falling01.gif
	offset  55  69
	frame	data/chars/don/falling02.gif
	frame	data/chars/don/falling03.gif
	frame	data/chars/don/falling04.gif
	delay	10
	frame	data/chars/don/falling05.gif
	offset  55  60
	frame	data/chars/don/falling05.gif
	offset  55  52
	frame	data/chars/don/falling05.gif
	custknife say_cave
        throwframe	7 10
	delay	170
		bbox  0
	frame	data/chars/don/empty.gif
	offset  58  69
	delay	7
	frame	data/chars/don/falling06.gif
	frame	data/chars/don/falling07.gif
	offset  55  64
	frame	data/chars/don/falling08.gif
	frame	data/chars/don/falling09.gif
	frame	data/chars/don/falling10.gif
	fshadow 1
	frame	data/chars/don/falling11.gif
	frame	data/chars/don/falling12.gif
	offset  55  80
		attack  0
	frame	data/chars/don/falling13.gif
	offset  55  64
	frame	data/chars/don/falling14.gif
	frame	data/chars/don/falling15.gif
	offset  75  64
	frame	data/chars/don/falling16.gif
	#riseinv {int} {bl} 
	delay 20
	@cmd changeentityproperty getlocalvar("self") "noaicontrol" 0
	offset  28  59
	frame	data/chars/don/001.gif

anim	DEATH24 # Tombino + Death (MANHOLE4)
	loop	0

	@script
		void self = getlocalvar("self");
       		float x = getentityproperty(self, "x");
       		float z = getentityproperty(self, "z");
       		float a = getentityproperty(self, "y");
		void ent;
		//drawstring( 20,170,0,"animpos:  "+getentityproperty(self, "animpos") );
		if ( getentityproperty(self, "animpos") == 10 ) {
    			changeentityproperty(self, "invincible", 1);
    			changeentityproperty(self, "invinctime", openborvariant("elapsed_time") + (openborvariant("game_speed")*1)); //makes entity invincible for 1.5 seconds, change decimal number to change time length
		}
		else if ( getentityproperty(self, "animpos") == 18 ) {
			// ATTENZIONE: L'opponent poi muore. quindi conviene prendere le coordinate da se stesso...
			x = getentityproperty(self, "x");
			z = getentityproperty(self, "z");
			a = getentityproperty(self, "y");
			if ( getentityproperty(self, "direction") == 1 ) changeentityproperty(self, "position", x+40, z+16, a);
			else changeentityproperty(self, "position", x-40, z+16, a);
		}
     		else if ( getentityproperty(self, "animpos") == 22 ) {
			clearspawnentry();
			setspawnentry("name", "shellshock");
			ent = spawn();
			changeentityproperty(ent, "base", a+30);
			changeentityproperty(ent, "parent", self);
			changeentityproperty(ent, "map", 2);
			if ( getentityproperty(self, "direction") == 1 ) {
        			changeentityproperty(ent, "position", x+40, z, a+30);
				changeentityproperty(ent, "direction", 1);
			} else {
        			changeentityproperty(ent, "position", x-40, z, a+30);
				changeentityproperty(ent, "direction", 0);
			}
      		}
     		else if ( getentityproperty(self, "animpos") == 27 ) {
			clearspawnentry();
			setspawnentry("name", "death_stars");
			ent = spawn();
        		if ( getentityproperty(self, "direction") == 1 ) changeentityproperty(ent, "position", x+10, z, a+30);
			else  changeentityproperty(ent, "position", x-10, z, a+30);
			changeentityproperty(ent, "base", a+30);
			changeentityproperty(ent, "parent", self);
      		}
	@end_script

	fshadow 0
	offset	52 69
	delay	7
		bbox  0
	frame	data/chars/don/falling01.gif
	offset  55  69
	frame	data/chars/don/falling02.gif
	frame	data/chars/don/falling03.gif
	frame	data/chars/don/falling04.gif
	delay	10
	frame	data/chars/don/falling05.gif
	offset  55  60
	frame	data/chars/don/falling05.gif
	offset  55  52
	frame	data/chars/don/falling05.gif
	custknife say_cave
        throwframe	7 10
	delay	170
		bbox  0
	frame	data/chars/don/empty.gif
	offset  58  69
	delay	7
	frame	data/chars/don/falling06.gif
	frame	data/chars/don/falling07.gif
	offset  55  64
	frame	data/chars/don/falling08.gif
	frame	data/chars/don/falling09.gif
	frame	data/chars/don/falling10.gif
	fshadow 1
	frame	data/chars/don/falling11.gif
	frame	data/chars/don/falling12.gif
	offset  55  80
		attack  0
	frame	data/chars/don/falling13.gif
	offset  55  64
	frame	data/chars/don/falling14.gif
	frame	data/chars/don/falling15.gif
	offset  75  64
	frame	data/chars/don/falling16.gif

	delay	10
	offset	21 62
	frame	data/chars/don/164.gif
	frame	data/chars/don/165.gif
	offset	28 76
	frame	data/chars/don/155.gif
	@cmd	changeentityproperty getlocalvar("self") "velocity" 0 0 0
	offset	19 40
	frame	data/chars/don/death02.gif
	frame	data/chars/don/death01.gif
	frame	data/chars/don/death02.gif
	frame	data/chars/don/death03.gif
	delay	120
		offset  19  41
	frame	data/chars/don/death04.gif
	sound	data/sounds/death.wav
	delay	1
	frame	data/chars/don/death04.gif
 
I agree with White Dragon. I made that script for a crusher trap (goes up and down) which works differently than manhole so using suggested didhitscript is best way cause it allows manhole to 'attack' others at same time
 
Back
Top Bottom