SOLVED Multiple anim spawn

dantedevil

Well-known member
It's any way to create a multiple anim spawn in the same enemy?

I mean,  something like:

anim spawn

anim spawn2

anim spawn3

Then you can spawn the same enemy with three different animations.

This way you no need create a new version of the same ememy to make a new anim spawn.
 
Solution
No. There are no multiple hard-coded anim spawns (like anim spawn2, anim spawn3, and so on) in OpenBOR. However, you can create multiple spawn animations by going with any anim follow you want, so no need to worry about using multiple anim spawns at all. You just need to script your follow animation in your character and in level for spawning if you intend to make multiple spawning animations.

Here, you can see the way the enemy will react for spawning:

Code:
anim	follow2
@script
    void self = getlocalvar("self");

    if(frame==0){ // bbox is inactive yet
      changeentityproperty(self, "Subject_to_Gravity", 0);
      changeentityproperty(self, "Subject_to_Wall", 0);
      changeentityproperty(self, "Subject_to_MinZ", 0);
     ...
Might be a way to add some animation change in spawn anim randomly or with conditions

1-Spawn anim with a script that select a follow anim

2a follow1
2b follow2
2c follow3

Just a suggestion.
I'm not the best for coding.
 
Without any scripted system :

Code:
spawn enemy
@script 
void main() {
	performattack(getlocalvar("self"), openborconstant("ANI_follow1"));
} @end_script
map 1
coords 600 300 0
at 0

I personally use a custom system for that and many other things used to specify enemies. The idea is to basically define a whole load of parameters in level files using entity alias.

Code:
spawn enemy
alias [faction=1;intro=follow1;evade=50;name=Jack]
map 1
coords 600 300 0
at 0

Then when entity spawn you just need to parse and process every key=value contained in alias and here you go. This kind of system let you have loads of new options to customize enemies in levels.

 
No. There are no multiple hard-coded anim spawns (like anim spawn2, anim spawn3, and so on) in OpenBOR. However, you can create multiple spawn animations by going with any anim follow you want, so no need to worry about using multiple anim spawns at all. You just need to script your follow animation in your character and in level for spawning if you intend to make multiple spawning animations.

Here, you can see the way the enemy will react for spawning:

Code:
anim	follow2
@script
    void self = getlocalvar("self");

    if(frame==0){ // bbox is inactive yet
      changeentityproperty(self, "Subject_to_Gravity", 0);
      changeentityproperty(self, "Subject_to_Wall", 0);
      changeentityproperty(self, "Subject_to_MinZ", 0);
      changeentityproperty(self, "Subject_to_MaxZ", 0);
    }
    if(frame==9){ // this when enemy's bbox is active
      changeentityproperty(self, "Subject_to_Wall", 1);
      changeentityproperty(self, "Subject_to_MinZ", 1);
      changeentityproperty(self, "Subject_to_MaxZ", 1);
      changeentityproperty(self, "Subject_to_Gravity", 1);
    }
	@end_script
	delay	14
	offset	23 62
	jumpframe	4 0 0 0.5
	frame	data/chars/Linda/34.png
	offset	23 61
	frame	data/chars/Linda/35.png
	offset	23 60
	frame	data/chars/Linda/36.png
	offset	23 61
	frame	data/chars/Linda/37.png
	@cmd	looper 0 3
	delay	14
	offset	18 65
	frame	data/chars/Linda/38.png
	offset	18 66
	frame	data/chars/Linda/39.png
	offset	17 65
	frame	data/chars/Linda/40.png
	offset	19 64
	frame	data/chars/Linda/41.png
	offset	27 63
	frame	data/chars/Linda/42.png
	offset	23 62
	frame	data/chars/Linda/34.png

In level, you spawn it like this:
Code:
spawn	Linda
@script
void main(){
void self = getlocalvar("self");
changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW2"));
}
@end_script
alias   Linda
map     8
item    whip2
coords	265 169
at	500

EDIT: It's really okay if your character's anim follow doesn't have script and it doesn't have to be, but you can make them spawn in whatever anim follow you want for spawning in level.
 
Solution
For my method I use a new entity to spawn any enemy.
For example, in my game there are many enemies (many diferent entities)
But I use just 1 spawn for any entity!

1) write a new entity.
2) write a spawn animation
3) write an animation script in that I get variables and I spawn the real enemy
4) set it to: type enemy hen load all entities you need:
    load enemy1
    load enemy etc..
    then set noaicontrol to 1 in this way:

Code:
onspawnscript	@script
void main () {
	changeentityproperty(getlocalvar("self"),"noaicontrol",1);
} 
@end_script

Here  my example:
Code:
name	spw_runjump
health	40
speed	8
height 40
type	enemy
#subtype	chase
aggression -4.0
attackthrottle 0.15 0.5
aimove chase
aimove wander
aimove normal
offscreenkill 7000
running  16 5.0 2 1 0

dust dust
paingrab 1
nolife 1
grabdistance 20
grabforce 10
throw	1.9 3
throwdamage	20
noquake 1
falldie 2
nodieblink 2
jumpmove	0 1
jumpspeed	7
blockodds 4
thold 10
bflash bflash #bflash aaa
summonkill 0
gfxshadow 0
bounce	1
jumpheight	4.7

risetime 100 -50 #This is for altering risetime (wait time for character while lying down after falling before rising). 

grabback 1 # serve a stare sempre dietro quando hai preso

score 5 -1

subject_to_platform 0
subject_to_obstacle 0
subject_to_wall 0
subject_to_hole 0
subject_to_gravity 0
no_adjust_base 1
subject_to_screen 0

hostile player npc
candamage player npc obstacle

palette data/chars/foot/alt0.gif

remap data/chars/foot/alt0.gif data/chars/foot/alt1.gif
remap data/chars/foot/alt0.gif data/chars/foot/alt2.gif
remap data/chars/foot/alt0.gif data/chars/foot/alt3.gif
remap data/chars/foot/alt0.gif data/chars/foot/alt4.gif
remap data/chars/foot/alt0.gif data/chars/foot/alt5.gif
remap data/chars/foot/alt0.gif data/chars/foot/alt6.gif
remap data/chars/foot/alt0.gif data/chars/foot/alt7.gif
remap data/chars/foot/alt0.gif data/chars/foot/alt8.gif
remap data/chars/foot/alt0.gif data/chars/foot/alt9.gif
remap data/chars/foot/alt0.gif data/chars/foot/alt10.gif
remap data/chars/foot/alt0.gif data/chars/foot/alt11.gif
remap data/chars/foot/alt0.gif data/chars/foot/alt12.gif
remap data/chars/foot/alt0.gif data/chars/foot/alt13.gif
remap data/chars/foot/alt0.gif data/chars/foot/alt14.gif

load	dust
load	boom_foot


load efoot_soldier

onspawnscript	@script
#include	"data/scripts/defines.c"
#import		"data/scripts/lib.c"

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

	changeentityproperty(self,"base",-1000);
	changeentityproperty(self,"noaicontrol",1);
} 
@end_script


script	@script
#include	"data/scripts/defines.c"
#import		"data/scripts/lib.c"

void main () {
	void self = getlocalvar("self");
	int anim_id = gep(self,"animationid");

	if ( anim_id == oc("ANI_SPAWN") ) {
		float tossv = gep(self,"tossv");
		float toss_fact = gev(self,"toss_fact");
	
		if ( toss_fact == NULL() ) toss_fact = 1.01;
		tossv /= toss_fact;

		cep(self,"velocity",NULL(),NULL(),tossv);
	}
} 
@end_script

anim	SPAWN
	@script
		void self = getlocalvar("self");
		int frame = getlocalvar("frame");
		int dir = getentityproperty(self, "direction");
		float x = getentityproperty(self, "x");
		float z = getentityproperty(self, "z");
		float a = getentityproperty(self, "y");
		float base = getentityproperty(self, "base");
		int dir = getentityproperty(self, "direction");
		int maxhealth = getentityproperty(self, "maxhealth");
		int time = openborvariant("elapsed_time");
		int game_speed = openborvariant("game_speed");
		int start_frame = 2, last_frame = 12;
		float t_alt = 35, t_base = 1.0;
		float jump_y = getentityvar(self,"jump_y");
		float jump_x = getentityvar(self,"jump_x");
		float jump_z = getentityvar(self,"jump_z");
		float spawn_time = getentityvar(self,"spawn_time");

    		setentityvar(self,10,getentityproperty(self, "nograb"));

		if ( jump_y == NULL() ) jump_y = 4.0;
		if ( jump_x == NULL() ) jump_x = -1.7;
		if ( jump_z == NULL() ) jump_z = 0;
		if ( spawn_time == NULL() ) spawn_time = 0;
		else {
    			int sign = 1;

			spawn_time *= game_speed;
    			if ( spawn_time < 0 ) {
        			sign = -1;
        			spawn_time *= -1;
    			}
    			spawn_time = spawn_time%(spawn_time+1);
    			spawn_time *= sign;
		}

		if ( getlocalvar("mem_time") == NULL() ) setlocalvar("mem_time",time);
		else {
			if ( time-getlocalvar("mem_time") <= spawn_time ) {
				if ( frame != 0 ) changeentityproperty(self,"animpos",0);
				//drawstring(10,50,0,"aaaaaaaa");
			}
		}


		if ( frame <= 0 ) {
			changeentityproperty(self, "velocity", 0, 0, 0);
		}

		if ( frame == start_frame ) {
			changeentityproperty(self,"base",a);
			changeentityproperty(self, "no_adjust_base", 0);
			changeentityproperty(self, "subject_to_gravity", 1);
			changeentityproperty(self, "gfxshadow", 1);
			tossentity(self, jump_y, jump_x, jump_z);
		}

		if ( getlocalvar("started") == NULL() ) {
			if ( frame >= start_frame+9 ) changeentityproperty(self,"animpos",start_frame+5);
			if ( frame >= start_frame && frame <= start_frame+9 && checkwall(x,z) <= a ) {
				changeentityproperty(self, "subject_to_wall", 1);
				changeentityproperty(self, "subject_to_platform", 1);
				setlocalvar("started",1);
			}
		}

		if ( getlocalvar("started") > 0 && getlocalvar("started") <= 1 ) {
			if ( a-base >= 0 && a-base <= t_alt && frame >= last_frame-6 && frame <= last_frame-2 ) {
				changeentityproperty(self,"animpos",last_frame-2); // stai per atterrare
				setlocalvar("started",2);
			}
			if ( a > base && frame >= last_frame-2 ) {
				changeentityproperty(self,"animpos",last_frame-6); // mantieni il jumpframe
			}
		}

		if ( getlocalvar("started") == 2 ) {
			if ( a-base >= 0 && a-base <= t_alt && frame >= last_frame-2 ) {
				changeentityproperty(self,"animpos",last_frame-2); // stai per atterrare
			}
			if ( a <= base+t_base ) {
				changeentityproperty(self,"animpos",last_frame-1); // landframe
				setlocalvar("started",3);
			}
		}


		if ( getlocalvar("started") > 0 && a <= base+t_base && frame >= last_frame ) {
			void ent;
			int health = getentityproperty(self,"health");
			int map = getentityproperty(self,"map");

			changeentityproperty(self, "velocity", 0, 0, 0);
			clearspawnentry();
			setspawnentry("name", "efoot_soldier");
			ent = spawn();
			changeentityproperty(ent, "position", x, z, a);
			changeentityproperty(ent, "base", base);
			changeentityproperty(ent, "health", health);
			changeentityproperty(ent, "map", map);
			changeentityproperty(ent, "direction", dir);
			killentity(self);
		}
	@end_script

	loop 0
	#jumpframe 8 4.0 0 1.0
	#dropframe 9
	landframe 11

	bbox	0

	delay	10
		offset  30  57
	frame	data/chars/misc/empty.gif
	frame	data/chars/misc/empty.gif

	delay	7
	frame	data/chars/foot/z2.gif
	frame	data/chars/foot/z3.gif
	frame	data/chars/foot/z4.gif
	frame	data/chars/foot/z1.gif

	frame	data/chars/foot/z2.gif
	frame	data/chars/foot/z3.gif
	frame	data/chars/foot/z4.gif
	frame	data/chars/foot/z1.gif

	delay	10
		offset  17  80
	frame	data/chars/foot/za3.gif
	delay	10
		offset  17  86
	frame	data/chars/foot/za4.gif
	delay	100
	frame	data/chars/foot/za4.gif

anim	IDLE
	loop	0

	offset	26 60
	bbox	0
	delay	4
	frame	data/chars/foot/idle01.gif

and I can use this spawn_enemy in this way (in #level.txt):
Code:
spawn spw_runjump 1
health 40
@script
void main() {
    void self = getlocalvar("self");
    setentityvar(self,"jump_y",4.0);
    setentityvar(self,"jump_x",-2.0);
    setentityvar(self,"jump_z",0);
    setentityvar(self,"spawn_time",2.0);
    setentityvar(self,"toss_fact",1.02);
}
@end_script
coords 390 740 450
at 0

Note how I can set my params!!  ;)
 
Thanks to all my friends!
Now I see every method.

Piccolo can you explain me some settings of this line:

Code:
[faction=1;intro=follow1;evade=50;name=Jack]

Faction?
Intro= I see is the the follow to spawn the entity.
Evade?
Name= name of the entity.
 
dantedevil said:
Piccolo can you explain me some settings of this line:

Code:
[faction=1;intro=follow1;evade=50;name=Jack]

Faction?
Intro= I see is the the follow to spawn the entity.
Evade?
Name= name of the entity.

Those are settings that can be processed by the script I mentionned.

- faction is for setting entity faction ID, allowing to have multiple enemy factions that'll fight each other.
- intro is the "spawn" animation that entity will use yes.
- evade is the base evade rate of this entity (here 50 %). Also requires a scripted evade system.
 
Piccolo said:
I personally use a custom system for that and many other things used to specify enemies. The idea is to basically define a whole load of parameters in level files using entity alias.

Code:
spawn enemy
alias [faction=1;intro=follow1;evade=50;name=Jack]
map 1
coords 600 300 0
at 0

Then when entity spawn you just need to parse and process every key=value contained in alias and here you go. This kind of system let you have loads of new options to customize enemies in levels.

This is one of the coolest things I've seen done with OpenBOR.
 
- faction is for setting entity faction ID, allowing to have multiple enemy factions that'll fight each other.
- intro is the "spawn" animation that entity will use yes.
- evade is the base evade rate of this entity (here 50 %). Also requires a scripted evade system.

So if I don't have faction or evade scripts,  this script not work for me?
 
dantedevil said:
So if I don't have faction or evade scripts,  this script not work for me?

Well here in a level definition it's not even a script, just an entity alias. So yes without a script to process aliases they'll just be aliases and nothing more. I'll try to post a how-to about this method later, for it is quite practical to specify more entity properties in level files.
 
Thanks to all my friends!
I really appreciate all the help they have given me.
With all your collaborations I've created a variety of ANIM SPAWN for each enemy, and some some special ANIM SPAWN in certain levels.

The new spawn look great in every level.

Thanks again!
 
@ Piccolo : Can I see the script to read that alias? I want to know how to extract different parameters from that alias :)

BTW last time I tried, factions don't work so did you get them to work in your end?
 
Code:
void processAliasInit(){
	void vSelf = getlocalvar("self");
	void alias = getentityproperty(vSelf, "name");
	
	
	if(strleft(alias, 1) != "[") return;
	
	// Revert entity name to model default name
	changeentityproperty(vSelf, "name", getentityproperty(vSelf, "model"));
	
	void fullStr = strright(alias, 1);
	void remainder = strinfirst(fullStr, ";");
	void currentParam;
	
	if(remainder == NULL() || remainder == "" || remainder == -1) return;
	
	
	while(remainder != NULL() && remainder != "]" && remainder != "" && remainder != -1){
		int pos = strlength(fullStr) - strlength(remainder);
		currentParam = strleft(fullStr, pos);
		processParam(currentParam);	

		fullStr = strright(remainder, 1);
		remainder = strinfirst(fullStr, ";");
		
	}
	
	
}

void setFaction(char value){
	void vSelf = getlocalvar("self");
	
	int hostile = openborconstant("TYPE_PLAYER") + 65536; // openborconstant("TYPE_NPC");
// 	65536 = "ally to player" NPC faction. Used to distingish NPC that are both allied to players & enemies
	
	switch(value){
		case "0": // No faction, just an enemy
			changeentityproperty(vSelf, "type", openborconstant("TYPE_ENEMY"));
			break;
			
		case "1": // Enemy faction 1
			changeentityproperty(vSelf, "type", openborconstant("TYPE_ENEMY") + openborconstant("TYPE_NPC") + 2048);
			hostile += 4096 + 8192;
			
			break;
		case "2": // Enemy faction 2
			changeentityproperty(vSelf, "type", openborconstant("TYPE_ENEMY") + 4096);
			hostile += 2048 + 8192;
			break;
		case "3":
			changeentityproperty(vSelf, "type", openborconstant("TYPE_ENEMY") + 8192);
			hostile += 2048 + 4096;
			break;
			
			
		case "4": // The following factions are used for particular cases
			changeentityproperty(vSelf, "type", openborconstant("TYPE_ENEMY") + 16384);
			hostile += 2048 + 4096;
			break;
		case "5":
			changeentityproperty(vSelf, "type", openborconstant("TYPE_ENEMY") + 32768);
			hostile += 2048 + 4096;
			break;
		case "6": // 65536 = ally NPC faction. Used to distingish NPC that are both allied to players & enemies
			changeentityproperty(vSelf, "type", openborconstant("TYPE_ENEMY") + 65536);
			hostile += 2048 + 4096;
			break;
		default:
// 			changeentityproperty(vSelf, "type", getindexedvar("faction"+value"+Type"));
// 			changeentityproperty(vSelf, "hostile", getindexedvar("faction"+value"+Hostile"));
			break;
			
	}
	changeentityproperty(vSelf, "hostile",  hostile);
	changeentityproperty(vSelf, "candamage",  hostile + openborconstant("TYPE_OBSTACLE"));
}

void processParam(char param){
	void vSelf = getlocalvar("self");
	void remainder = strinfirst(param, "=");
	
	int pos = strlength(param) - strlength(remainder);
	char key = strleft(param, pos);
	char value = strright(remainder, 1);
	
// 	log("\nkey : " + key + " = " + value);
	
	switch(key){
		case "alias":
		case "name":
		case "n":
			changeentityproperty(vSelf, "name", value);
			break;
			
			
		case "antigrab":
			if(value == "0") changeentityproperty(vSelf, "antigrab", 0);
			else if(value == "1") changeentityproperty(vSelf, "antigrab", 1);
			break;
			
		case "breakout":
		case "b":
			if(value == "0") setentityvar(vSelf, "breakoutAniID", NULL());
			else {
				value = convertVar(value, "float");
				setentityvar(vSelf, "breakoutChance", value);
			}
			break;
			
		case "evade":
		case "e":
			if(value == "0") setentityvar(vSelf, "evadeAniID", NULL());
			else {
				value = convertVar(value, "float");
				setentityvar(vSelf, "evadeChance", value);
			}
			break;
			
		case "faction":
		case "f":
			setFaction(value);
			break;
			
		case "intro":
		case "i":
			performattack(vSelf, openborconstant("ANI_" + value));
			break;
			
		case "layer":
		case "l":
			changeentityproperty(vSelf, "setlayer", convertVar(value, "int"));
			break;
			
		case "nomove":
			changeentityproperty(vSelf, "aimove", openborconstant("AIMOVE1_NOMOVE"));
			break;
		
			
		case "type":
		case "t":
			setentityvar(vSelf, "type", convertVar(value, "int"));
			break;
			
		case "x":
			changeentityproperty(vSelf, "x", convertVar(value, "int"));
			break;

	}
	
	
}


/*
 *  Might exists a far less tricky way to do this
 * 
 */
void convertVar(void var, char type){
	
	if(! (type == "int" || type == "str" || type == "float")) return NULL();
	
	void fileIndex = createfilestream();
// 	void fileIndex = openfilestream("data/scripts/tmp.xt");
	filestreamappend(fileIndex, var);
	
	void convertedVar = getfilestreamargument(fileIndex ,0, type);
	
	closefilestream(fileIndex);
	
	return convertedVar;
	
	
}

It's in the first function (which I call in entity spawnscript).

Be warned though that aliases are limited in length, so if you want to pack lots of parameters you'll have to use very short keys (~ letters).

And yes factions works great for me. I left the function I use for generic faction definition in the code above. But you can create more precise faction settings for some individuals in their own spawn script.
 
Piccolo I notice that you use a file handling to convert a type.
I want to propose my version for your alias.

write a lib.c file in data/scripts/ directory:
Code:
#define gpp getplayerproperty
#define cpp changeplayerproperty
#define gep getentityproperty
#define cep changeentityproperty
#define ov  openborvariant
#define cv  changeopenborvariant
#define oc  openborconstant
#define glv getlocalvar
#define slv setlocalvar
#define sev setentityvar
#define gev getentityvar
#define sgv setglobalvar
#define ggv getglobalvar
#define glvp getlevelproperty
#define clvp changelevelproperty
#define glp getlayerproperty
#define clp changelayerproperty
#define si setidle
#define pa performattack

int trunc(int num) {
    int sign = 1;

    if ( num < 0 ) {
        sign = -1;
        num *= -1;
    }

    num = num%(num+1);
    num *= sign;

    return num;
}

float abs(float num) {
    if (num < 0) num *= -1;

    return num;
}

int exp(int base, int exp) {
    int i = 0;
    int result;
    int sign = 1;

    if ( base < 0 ) sign = -1;
    base = abs(base);
    exp = abs(exp);
    result = base;

    if ( exp == 0 ) return 1;
    for ( i = 0; i < exp-1; ++i ) {
        result *= base;
    }
    result *= sign;

    return result;
}

char getchar(char str, int index) {

    if ( index >= strlength(str) ) index = strlength(str)-1;
    else if ( index < 0 ) index = 0;

    if ( strlength(str) > 0 ) {
        str = strright(str, index);

        if ( strlength(str) > 1 ) {
            index = 1;
            str = strleft(str, index);
        }
    }

    return str;
}

char substr(char str, int start_index, int length) {
    if ( start_index+length > strlength(str) ) return NULL();
    if ( start_index < 0 || strlength(str) <= 0 ) return NULL();

    str = strright(str, start_index);
    str = strleft(str, length);

    return str;
}

char search_str(char str, char sub, int case_flag) {
    char substr;

    if ( str == NULL() || sub == NULL() ) return -1;
    if ( case_flag == NULL() ) case_flag = 0;

    if ( case_flag ) substr = strinfirst(lowercase(str), lowercase(sub));
    else substr = strinfirst(str, sub);

    return substr;
}

char replace_str(char txt, char pat, char rep) {
    char str_left = "", str_right = "";
    int len = strlength(pat);

    str_left = strinfirst(txt,pat);
    if ( str_left == -1 ) return -1;
    str_left = substr(txt,0,strlength(txt)-strlength(str_left));

    str_right = strinfirst(txt,pat);
    str_right = substr(str_right,len,strlength(str_right)-len);

    return ( str_left+rep+str_right );
}

int searchstr_index(char txt, char pat, int reverse_flag) {
    char tmp = "";

        tmp = strinfirst(txt,pat);
        if ( tmp == -1 ) return -1;
        else return ( strlength(txt)-strlength(tmp) );

}

int parse_vars() {
    void self = glv("self");
    char name = gep(self,"name");
    char model = gep(self,"model");
    char str = name, tmp_str = "", param = "";
    char value = "";
    int i = 0, si = 0;

    tmp_str = "";
    while( tmp_str != -1 ) {
        tmp_str = replace_str(str," ","");
        if ( tmp_str != -1 ) str = tmp_str;
    }
    tmp_str = "";
    while( tmp_str != -1 ) {
        tmp_str = replace_str(str," ","");
        if ( tmp_str != -1 ) str = tmp_str;
    }

    tmp_str = "";
    tmp_str = replace_str(str,"[","");
    if ( tmp_str == -1 ) return 0;
    else str = tmp_str;

    tmp_str = "";
    tmp_str = replace_str(str,"]","");
    if ( tmp_str == -1 ) return 0;
    else str = tmp_str;

    si = 0;
    while( si != -1 ) {
        si = searchstr_index(str,"=");
        if ( si == -1 ) break; // no more params

        // get substring
        si = searchstr_index(str,";");
        if ( si != -1 ) param = substr(str,0,si+1);
        else param = str;

        // update string - param
        str = substr(str,strlength(param),strlength(str)-strlength(param));

        // remove all ";"
        tmp_str = "";
        while( tmp_str != -1 ) {
            tmp_str = replace_str(param,";","");
            if ( tmp_str != -1 ) param = tmp_str;
        }

        // parse param and value
        si = searchstr_index(param,"=");
        value = param;
        param = substr(param,0,si);
        value = substr(value,si+1,strlength(value)-si-1);

        if ( is_float(value) ) sev(self,param,to_float(value));
        else sev(self,param,value);
    }

    if ( gev(self,"name") == NULL() ) {
        cep(self,"name",model);
    } else cep(self,"name",gev(self,"name"));

    //drawstring(10,50,0,"alias: "+gev(self,"name"));

    return 1;
}

float to_float(char num) {
    char str_decimal = "", str_mantix = "", str_digit = "", tmp = "";
    int decimal = 0, sign = 1, sign_flag = 0;
    float digit = 0;
    int i = 0;
    float float_num = 0, mantix = 0;

    i = searchstr_index(num,".");
    if ( i != -1 ) {
        str_decimal = substr(num,0,i);
        str_mantix = substr(num,i+1,strlength(num)-i-1);
    } else {
        str_decimal = num;
        str_mantix = "";
    }

    tmp = getchar(str_decimal,0);
         if ( tmp == "+" ) { sign =  1; sign_flag = 1; }
    else if ( tmp == "-" ) { sign = -1; sign_flag = 1; }
    if ( sign_flag ) str_decimal = substr(str_decimal,1,strlength(str_decimal)-1);

    // get decimal part
    for ( i = strlength(str_decimal)-1; i >= 0; --i ) {
        str_digit = getchar(str_decimal,i);

             if ( str_digit == "0" ) digit = 0;
        else if ( str_digit == "1" ) digit = 1;
        else if ( str_digit == "2" ) digit = 2;
        else if ( str_digit == "3" ) digit = 3;
        else if ( str_digit == "4" ) digit = 4;
        else if ( str_digit == "5" ) digit = 5;
        else if ( str_digit == "6" ) digit = 6;
        else if ( str_digit == "7" ) digit = 7;
        else if ( str_digit == "8" ) digit = 8;
        else if ( str_digit == "9" ) digit = 9;
        else continue;

        digit *= exp(10,strlength(str_decimal)-1-i);
        decimal += digit;
    }

    // get mantix part
    for ( i = 0; i < strlength(str_mantix); ++i ) {
        int div = 0;

        str_digit = getchar(str_mantix,i);

             if ( str_digit == "0" ) digit = 0;
        else if ( str_digit == "1" ) digit = 1;
        else if ( str_digit == "2" ) digit = 2;
        else if ( str_digit == "3" ) digit = 3;
        else if ( str_digit == "4" ) digit = 4;
        else if ( str_digit == "5" ) digit = 5;
        else if ( str_digit == "6" ) digit = 6;
        else if ( str_digit == "7" ) digit = 7;
        else if ( str_digit == "8" ) digit = 8;
        else if ( str_digit == "9" ) digit = 9;
        else continue;

        div = exp(10,i+1);
        digit = (digit*1.0)/div; // *1.0 to normalize to float
        mantix += digit;
    }

    float_num = (sign*(decimal+mantix));

    return float_num;
}

int is_float(char num) {
    char str_decimal = "", str_mantix = "", str_digit = "", tmp = "";
    int sign_flag = 0;
    float digit = 0;
    int i = 0;

    i = searchstr_index(num,".");
    if ( i != -1 ) {
        str_decimal = substr(num,0,i);
        str_mantix = substr(num,i+1,strlength(num)-i-1);
    } else {
        str_decimal = num;
        str_mantix = "";
    }

    tmp = getchar(str_decimal,0);
         if ( tmp == "+" ) { sign_flag = 1; }
    else if ( tmp == "-" ) { sign_flag = 1; }
    if ( sign_flag ) str_decimal = substr(str_decimal,1,strlength(str_decimal)-1);

    // get decimal part
    for ( i = strlength(str_decimal)-1; i >= 0; --i ) {
        str_digit = getchar(str_decimal,i);

             if ( str_digit == "0" ) digit = 0;
        else if ( str_digit == "1" ) digit = 1;
        else if ( str_digit == "2" ) digit = 2;
        else if ( str_digit == "3" ) digit = 3;
        else if ( str_digit == "4" ) digit = 4;
        else if ( str_digit == "5" ) digit = 5;
        else if ( str_digit == "6" ) digit = 6;
        else if ( str_digit == "7" ) digit = 7;
        else if ( str_digit == "8" ) digit = 8;
        else if ( str_digit == "9" ) digit = 9;
        else return 0;
    }

    // get mantix part
    for ( i = 0; i < strlength(str_mantix); ++i ) {
        str_digit = getchar(str_mantix,i);

             if ( str_digit == "0" ) digit = 0;
        else if ( str_digit == "1" ) digit = 1;
        else if ( str_digit == "2" ) digit = 2;
        else if ( str_digit == "3" ) digit = 3;
        else if ( str_digit == "4" ) digit = 4;
        else if ( str_digit == "5" ) digit = 5;
        else if ( str_digit == "6" ) digit = 6;
        else if ( str_digit == "7" ) digit = 7;
        else if ( str_digit == "8" ) digit = 8;
        else if ( str_digit == "9" ) digit = 9;
        else return 0;
    }

    return 1;
}

void get_parsed_var(char label) {
    void self = glv("self");
    void value = gev(self,label);

    return value;
}

USAGE:

Spawn your enemy in #level.txt, and set your vars like:
Code:
spawn enemy001 1
alias [jumpx=-405.123;jumpz=6.3;name=test_alias]
map 0
coords 300 200
at 0

then in your enemy use this spawn script:
Code:
onspawnscript	@script
#import "data/scripts/lib.c"
void main() {
 parse_vars();
}
@end_script

then in any script event you can call a variable using:
float jumpx = get_parsed_var("jumpx");

With my script you can use any param you want (in this case "jumpx" but youcan use what-you-want param).
Note my type converter (to_float() and is_float() valid to int too)
 
Back
Top Bottom