White Dragon
New member
WATER PUDDLE EFFECT (with ripple and splash effect) v1.61
********This is an old post.********
Latest version is here: http://www.chronocrash.com/forum/index.php?topic=2549.0
TODO LIST:
1) Get a splash sound and put it into "data/sounds/water_splash01.wav" path.
2) Make a water splash entity named water_splash like:
3) Make a ripple entity like:
divide it in 2 parts frontal and back. Back part is disblayable at the back of the character,
frontal part is in front of the character.
- name frontal ripple entity as water_ripple_front
- name back ripple entity as water_ripple_back
make them like:
FRONTAL: BACK:
Use these features for ripple/splash:
4) Make a water puddle empty entity like (changing width/depth/height params if you want):
5) In ondrawscript event of your character entity write (example ondrawscript water_puddle_script.c):
6) save your water puddle library in a c file named lib_water_puddle.c
I hope I've not forgotten anything!
Enjoy!
Ps. Don't forget to spawn water_puddle empty entity in your level.txt
Example:
and remember to load all entities (ex. load splash and ripple entities in water_puddle_test entity)!
[attachment deleted by admin]
********This is an old post.********
Latest version is here: http://www.chronocrash.com/forum/index.php?topic=2549.0
TODO LIST:
1) Get a splash sound and put it into "data/sounds/water_splash01.wav" path.
2) Make a water splash entity named water_splash like:
3) Make a ripple entity like:
divide it in 2 parts frontal and back. Back part is disblayable at the back of the character,
frontal part is in front of the character.
- name frontal ripple entity as water_ripple_front
- name back ripple entity as water_ripple_back
make them like:
FRONTAL: BACK:
Use these features for ripple/splash:
Code:
name WHAT-YOU-WANT
type none
toflip 1
nomove 1 0
subject_to_wall 0
subject_to_obstacle 0
subject_to_platform 0
subject_to_gravity 0
no_adjust_base 1
4) Make a water puddle empty entity like (changing width/depth/height params if you want):
Code:
name water_puddle_test
type none
health 1
nomove 1 0
facing 1
nodieblink 2
nodrop 1
nolife 1
gfxshadow 1
height 20
subject_to_platform 0
subject_to_obstacle 0
subject_to_wall 0
subject_to_hole 0
subject_to_gravity 0
no_adjust_base 1
load water_splash
load water_ripple_front
load water_ripple_back
onspawnscript @script
void main() {
void self = getlocalvar("self");
setentityvar(self, 0, "water_puddle"); // name/type
setentityvar(self, 1, 1024); // width
setentityvar(self, 2, 20); // height
setentityvar(self, 3, 180); // depth
setentityvar(self, "map", 0); // ripple/splash map
setentityvar(self, "transp", 30); // alpha transp value
}
@end_script
anim IDLE
loop 1
bbox 0
delay 1
offset 0 0
frame data/chars/misc/empty.gif
5) In ondrawscript event of your character entity write (example ondrawscript water_puddle_script.c):
Code:
#import "data/scripts/lib_water_puddle.c"
void main() {
void self = getlocalvar("self");
// ENTITIES COUNT FUNCS
check_entities(self);
if ( getlocalvar("water_puddle_found") == 1 ) check_ripple(self);
}
int check_entities(void self) {
int i = 0;
int water_puddle_found_flag = 0, water_puddle_is_on = 0;
if ( openborvariant("in_level") ) {
if ( getlevelproperty("type") != 2 ) {
for (i = 0; i < openborvariant("count_entities"); ++i) { // openborconstant("MAX_ENTS")
void ent = getentity(i);
if ( getentityproperty(ent, "exists") ) {
/// WATER PUDDLE ///
if ( getentityvar(ent, 0) == "water_puddle" ) {
int anim_id = getentityproperty(self,"animationid");
int water_puddle_flag = 0;
water_puddle_found_flag = 1;
if ( anim_id == openborconstant("ANI_SPAWN") || anim_id == openborconstant("ANI_RESPAWN") ) {
int anim_pos = getentityproperty(self,"animpos");
if ( anim_pos <= 1 ) water_puddle_flag = 1;
}
if ( !water_puddle_flag && !water_puddle_is_on ) water_puddle_is_on = check_water_puddle(self, ent);
if ( !water_puddle_is_on && getlocalvar("water_puddle_found") != 1 ) setlocalvar("water_puddle_found",1);
}
} // fine if exists
} // fine for all_ents
/// WATER PUDDLE RESET ///
if ( !water_puddle_found_flag || water_puddle_is_on <= 0 ) {
reset_water_puddle(self);
}
} // fine if level prop
}
}
6) save your water puddle library in a c file named lib_water_puddle.c
Code:
#define gpp getplayerproperty
#define cpp changeplayerproperty
#define gep getentityproperty
#define cep changeentityproperty
#define ov openborvariant
#define cv changeopenborvariant
#define oc openborconstant
#define clp changelayerproperty
#define glv getlocalvar
#define slv setlocalvar
#define sev setentityvar
#define gev getentityvar
#define sgv setglobalvar
#define ggv getglobalvar
#define SPLASH_SOUNDFX "data/sounds/water_splash01.wav"
#define ENT_WATER_SPLASH "water_splash"
#define ENT_RIPPLE_FRONT "water_ripple_front"
#define ENT_RIPPLE_BACK "water_ripple_back"
#define RIPPLE_SPAWNING_FRAMES_PAUSE 2
#define SPLASH_DOWN_START_FRAME 2
#define RIPPLE_XSHIFT 3
#define RIPPLE_ASHIFT 0
#define WATER_H_FIX 0
int check_ripple(void self) {
int is_on_puddle;
int is_on_base;
int was_on_puddle = glv("was_on_puddle");
int was_on_base = glv("was_on_base");
void ripple = glv("ripple");
void splash = glv("splash");
int ripple_frame = RIPPLE_SPAWNING_FRAMES_PAUSE;
is_on_puddle = is_on_puddle(self); // check if this ent is on puddle (like stairs)
is_on_base = is_on_base(self); // or is in "y" of puddle
// CHECK EXISTENCE
if ( !is_name(ripple,"defaultmodel",ENT_RIPPLE_FRONT) || !is_for(ripple,self) ) { slv("ripple",NULL()); ripple = glv("ripple"); }
if ( !is_name(splash,"defaultmodel",ENT_WATER_SPLASH) || !is_for(splash,self) ) { slv("splash",NULL()); splash = glv("splash"); }
if ( is_on_puddle ) {
if ( is_on_base ) {
if ( is_stopped(self) ) { // Se il pg è fermo crea un ripple per volta
if ( ripple == NULL() || !gep(ripple,"exists") ) ripple = ripple_spawn(self,"ripple_front","ripple_back",ENT_RIPPLE_FRONT,ENT_RIPPLE_BACK,get_water_map()); // spawn ent if not exists (mem ripple in a localvar)
} else {
// Se il pg è in movimento crea nuovi ripple dopo il frame X
if ( ripple == NULL() || !gep(ripple,"exists") ) ripple = ripple_spawn(self,"ripple_front","ripple_back",ENT_RIPPLE_FRONT,ENT_RIPPLE_BACK,get_water_map());
else {
if ( ripple != NULL() ) {
if ( gep(ripple,"animpos") >= ripple_frame ) ripple = ripple_spawn(self,"ripple_front","ripple_back",ENT_RIPPLE_FRONT,ENT_RIPPLE_BACK,get_water_map());
}
} // fine if ripple exists
} // fine if is_in_movement
} // fine if is_on_base
if ( !was_on_puddle && !was_on_base ) {
slv("splash",spawn_splash(self,ENT_WATER_SPLASH,SPLASH_SOUNDFX,SPLASH_DOWN_START_FRAME)); // splash down
splash = glv("splash");
}
// adjust splash position for speedy moves
if ( !check_splash_pos(self,glv("splash"),ENT_WATER_SPLASH) ) slv("splash",NULL());
} else {
if ( is_stopped(self) ) {
delete_ripple(self,"ripple_front","ripple_back",ENT_RIPPLE_FRONT,ENT_RIPPLE_BACK);
slv("ripple",NULL());
ripple == glv("ripple");
}
}
if ( was_on_puddle && !is_on_base && was_on_base ) {
slv("splash",spawn_splash(self,ENT_WATER_SPLASH,SPLASH_SOUNDFX,get_water_map())); // splash up
splash = glv("splash");
}
slv("was_on_puddle",is_on_puddle);
slv("was_on_base",is_on_base);
slv("ripple",ripple);
slv("splash",splash);
}
int is_on_puddle(void self) {
if ( getlocalvar("is_on_water_puddle") > 0 ) return 1;
else return 0;
}
void ripple_spawn(void self, char ripple_front, char ripple_back, char front_ripple_name, char back_ripple_name, int map) {
if ( map == NULL() ) map = 0;
slv(ripple_front,spawnsubentity_relative(front_ripple_name,RIPPLE_XSHIFT,0.1,RIPPLE_ASHIFT+get_water_height()-WATER_H_FIX,self));
slv(ripple_back,spawnsubentity_relative(back_ripple_name,0,-1.0,0,glv(ripple_front)));
//changeentityproperty(glv(ripple_front),"parent",self);
changeentityproperty(glv(ripple_back),"parent",self);
changeentityproperty(glv(ripple_front),"map",map);
changeentityproperty(glv(ripple_back),"map",map);
return glv(ripple_front);
}
int delete_ripple(void self, char ripple_front, char ripple_back, char front_ripple_name, char back_ripple_name) {
if ( gep(glv(ripple_front),"exists") ) {
if ( is_name(glv(ripple_front),"defaultmodel",front_ripple_name) && is_for(glv(ripple_front),self) ) { killentity(glv(ripple_front)); }
}
slv(ripple_front,NULL());
if ( gep(glv(ripple_back),"exists") ) {
if ( is_name(glv(ripple_back),"defaultmodel",back_ripple_name) && is_for(glv(ripple_back),self) ) { killentity(glv(ripple_back)); }
}
slv(ripple_back,NULL());
return 1;
}
void spawn_splash(void self, char water_splash_name, char splash_sound_name, int frame, int map) {
void splash;
float base = gep(self,"base");
if ( map == NULL() ) map = 0;
splash = spawnsubentity_relative(water_splash_name,RIPPLE_XSHIFT,1,NULL(),self);
changeentityproperty(splash,"position",NULL(),NULL(),base+RIPPLE_ASHIFT+get_water_height()-WATER_H_FIX);
changeentityproperty(splash,"parent",self);
changeentityproperty(splash,"map",map);
if ( frame != NULL() ) {
changeentityproperty(splash,"animpos",frame);
playsample(loadsample(splash_sound_name));
}
return splash;
}
// return 0 if it doesn't exists
int check_splash_pos(void self, void splash, char model_name) {
if ( gep(splash,"exists") ) {
int anim_pos = gep(splash,"animpos");
if ( !is_name(splash,"defaultmodel",model_name) || !is_for(splash,self) ) return 0;
if ( anim_pos <= SPLASH_DOWN_START_FRAME ) {
float x = gep(self,"x");
float z = gep(self,"z");
float a = gep(self,"y");
float base = gep(self,"base");
int dir = gep(self,"direction");
float ex = gep(splash,"x");
float xshift = RIPPLE_XSHIFT;
if ( !dir ) xshift *= -1;
if ( ex != x+xshift ) {
cep(splash,"position",x+xshift,z+1,base+RIPPLE_ASHIFT+get_water_height()-WATER_H_FIX);
}
} // fine if animpos
return 1;
} else return 0; // fine if exists
}
int get_water_map() {
return glv("water_map");
}
int set_water_map(int value) {
return slv("water_map",value);
}
int get_water_height() {
return glv("water_height");
}
int set_water_height(float value) {
slv("water_height",value);
}
int check_puddle(void self, int no_a_flag) {
int i;
if ( getglobalvar("in_menu") != 1 && getlevelproperty("type") != 2 ) {
for (i = 0; i < openborvariant("count_entities"); ++i) { // openborconstant("MAX_ENTS")
void ent = getentity(i);
if ( getentityproperty(ent, "exists") ) {
if ( getentityvar(ent, 0) == "water_puddle" ) {
if ( no_a_flag && no_a_flag != NULL() ) return check_water_puddle_no_a(self, ent);
else return check_water_puddle(self, ent, 1);
}
} // fine if exists
} // fine for all_ents
return 0;
}
}
int check_water_puddle(void self, void ent, int check_only_flag) {
int p = getentityproperty(self, "playerindex");
float x = getentityproperty(self, "x");
float z = getentityproperty(self, "z");
float a = getentityproperty(self, "y");
float base = getentityproperty(self, "base");
float ex = getentityproperty(ent, "x");
float ez = getentityproperty(ent, "z");
float ea = getentityproperty(ent, "y");
float ebase = getentityproperty(ent, "base");
float height = getentityvar(ent, 2);
float width = getentityvar(ent, 1);
float depth = getentityvar(ent, 3);
float new_base, ezhift, exhift;
if ( height == NULL() ) height = getentityproperty(ent, "height");
if ( height == NULL() ) height = 0;
set_water_height(height);
set_water_map(getentityvar(ent,"map"));
if (x > ex) exhift = x-ex;
else exhift = ex-x;
if ( getentityvar(ent, 0) == "water_puddle" ) {
if ( x <= ex+width && x >= ex && z <= ez+2+depth/2 && z >= ez-depth/2 && a <= ebase+2+height && a >= ebase-2 ) {
if ( !check_only_flag || check_only_flag == NULL() ) {
draw_clipping_transp(self, 140, height, getentityvar(ent,"transp"));
clip_character(self, -190, height);
setlocalvar("is_on_water_puddle", 1);
} else return 1;
} else {
if ( !check_only_flag || check_only_flag == NULL() ) {
if ( getlocalvar("is_on_water_puddle") == 1 ) {
reset_water_puddle_clipping(self);
setlocalvar("is_on_water_puddle", NULL());
}
} else return 0;
} // fine if coords
}
}
int check_water_puddle_no_a(void self, void ent) {
float x = getentityproperty(self, "x");
float z = getentityproperty(self, "z");
float a = getentityproperty(self, "y");
float ex = getentityproperty(ent, "x");
float ez = getentityproperty(ent, "z");
float ea = getentityproperty(ent, "y");
float width = getentityvar(ent, 1);
float depth = getentityvar(ent, 3);
if ( getentityvar(ent, 0) == "water_puddle" ) {
if ( x <= ex+width && x >= ex && z <= ez+2+depth/2 && z >= ez-depth/2 ) {
return 1;
} else {
return 0;
} // fine if coords
}
}
int reset_water_puddle_clipping(void self, int shadow_flag) {
changedrawmethod(NULL(), "enabled", 0);
changedrawmethod(NULL(), "reset", 1);
setdrawmethod(NULL(), 0);
changedrawmethod(self, "enabled", 0);
changedrawmethod(self, "reset", 1);
setdrawmethod(self, 0);
if ( !shadow_flag || shadow_flag == NULL() ) {
if ( !getentityproperty(self,"gfxshadow") ) changeentityproperty(self,"gfxshadow",1);
}
}
int reset_water_puddle(void self) {
if ( glv("was_on_puddle") != NULL() || glv("was_on_base") != NULL() || glv("is_on_water_puddle") != NULL() ) {
reset_water_puddle_clipping(self);
setlocalvar("water_puddle_found",NULL());
slv("was_on_puddle",NULL());
slv("was_on_base",NULL());
slv("is_on_water_puddle",NULL());
}
}
int clip_character(void self, float clipx, float clipy) {
if ( openborvariant("in_level") ) {
float x = getentityproperty(self, "x");
float z = getentityproperty(self, "z");
float a = getentityproperty(self, "y");
float base = getentityproperty(self, "base");
int layer = getentityproperty(self, "setlayer");
float xpos = openborvariant("xpos");
float ypos = openborvariant("ypos");
int colourmap = getentityproperty(self, "colourmap");
changedrawmethod(NULL(), "enabled", 1);
changedrawmethod(NULL(), "reset", 1);
if ( getentityproperty(self,"gfxshadow") ) changeentityproperty(self,"gfxshadow",0);
changedrawmethod(self, "cliph", 256);
changedrawmethod(self, "clipw", 512);
changedrawmethod(self, "clipx", clipx);
changedrawmethod(self, "clipy", -256-clipy+a-base);
setdrawmethod(self, 1, 256, 256, 0, 0, 0, 0, 1, 0, 0, 0, 0, colourmap);
changedrawmethod(NULL(), "enabled", 0);
changedrawmethod(NULL(), "reset", 1);
setdrawmethod(NULL(), 0);
}
}
int draw_clipping_transp(void self, float clipx, float clipy, int transp) {
if ( openborvariant("in_level") ) {
void spr = getentityproperty(self, "sprite");
float x = getentityvar(self, "x");
float z = getentityvar(self, "z");
float a = getentityvar(self, "y");
float base = getentityvar(self, "base");
int facing = getentityvar(self, "direction");
int layer = getentityproperty(self, "setlayer");
float xpos = openborvariant("xpos");
float ypos = openborvariant("ypos");
int colourmap = getentityproperty(self, "colourmap");
if ( x == NULL() ) x = getentityproperty(self, "x");
if ( z == NULL() ) z = getentityproperty(self, "z");
if ( a == NULL() ) a = getentityproperty(self, "y");
if ( base == NULL() ) base = getentityproperty(self, "base");
if ( facing == NULL() ) facing = getentityproperty(self, "direction");
if ( transp == NULL() ) transp = 0;
if ( spr != NULL() ) {
if (facing == 1) facing = 0;
else facing = 1;
changedrawmethod(NULL(), "enabled", 1);
changedrawmethod(NULL(), "reset", 1);
changedrawmethod(NULL(), "cliph", 356);
changedrawmethod(NULL(), "clipw", 512);
changedrawmethod(NULL(), "clipx", x-xpos-clipx);
changedrawmethod(NULL(), "clipy", z-a-ypos-4-clipy);
changedrawmethod(NULL(), "channelg", transp);
changedrawmethod(NULL(), "channelr", transp);
changedrawmethod(NULL(), "channelb", transp);
// (entity, int flag, int scalex, int scaley, int flipx, int flipy, int shiftx, int alpha, int remap, int fillcolor, int rotate, int fliprotate, int transparencybg, void* colourmap, int centerx, int centery);
setdrawmethod(NULL(), 1, 256, 256, facing, 0, 0, 6, 1, 0, 0, 0, 0, colourmap); // map: -1 = Use entity's colormap.
drawsprite(spr, x-xpos, z-a-ypos-4, z+2, layer);
changedrawmethod(NULL(), "enabled", 0);
changedrawmethod(NULL(), "reset", 1);
setdrawmethod(NULL(), 0);
}
}
}
I hope I've not forgotten anything!
Enjoy!
Ps. Don't forget to spawn water_puddle empty entity in your level.txt
Example:
Code:
spawn water_puddle_test 1
@script
void main() {
void self = getlocalvar("self");
setentityvar(self, 1, 1024); // width
setentityvar(self, 2, 20); // height
setentityvar(self, 3, 180); // depth
setentityvar(self, "map", 0); // ripple/splash map
setentityvar(self, "transp", 30); // alpha transp value
}
@end_script
coords 0 180 0
at 0
and remember to load all entities (ex. load splash and ripple entities in water_puddle_test entity)!
[attachment deleted by admin]