Antiwall

O Ilusionista

Captain 80K
Hi there.
After some months of study, I am confortable with OpenBOR script and managed to reach my goal in many of my attempts (with help of others, for sure). But there is something which is still bothering me - Antiwall code, on a specific case.

This is the antiwall code I use:

Code:
void antiwall(int Dist, int Move, int Distz)
{// Checks if there is wall at defined distance
// If there is wall, entity will be moved away with defined movement
   void self = getlocalvar("self");
   int Direction = getentityproperty(self, "direction");
   int x = getentityproperty(self, "x");
   int z = getentityproperty(self, "z");
   float H;
   float Hz;

   if (Direction == 0){ //Is entity facing left?                  
      Dist = -Dist; //Reverse Dist to match facing
      Move = -Move; //Reverse Move to match facing
   }

   H = checkwall(x+Dist,z);
   Hz = checkwall(x+Dist,z+Distz);

   if(Hz > 0)
   {
     changeentityproperty(self, "position", x, z-Distz);
   }

   if(H > 0)
   {
     changeentityproperty(self, "position", x+Move);
   }
}

It works great, and I made many variations of it (detect wall colisions, bounce on the wall, change animation upon wall detect, etc). But I need to check if my char is OVER a wall, like when we use walls as platform.

How I can do that? by checking the if the "a" position is different than "base" position?
 
The simplest way is to check wall at entity's standing coordinate.

H = checkwall(x,z);

checkwall function will return height of the wall. Compare this result with entity's current altitude to see if entity is over wall or not
 
I realize that this won't work. I need to check if there is a wall so I don't release the target, after a scripted slam, INTO a wall (because it gets killed). But if I use this code when I am OVER a wall (on top), even not being close to a wall, the code takes effect.

So, I need the code to check if there is a wall near IF YOU NOT OVER A WALL. If you are over a wall, the code should just take effect if there is wall NEAR, not UNDER you.

its possible?
 
My version of wall checking is old and frankly the code is an embarrassment to me these days, but it does account for standing on walls and won't shunt you out if you start out on top of it.

This is because checkwall() actually returns wall height at the designated coordinates, not a Boolean "is there a wall". All you need to do is add in a variant for current height instead of just the base. Compare that to the checkwall() result, and you will know if you are over a wall or in it.

DC

Code:
void wall_bound(void vEnt, void vBound){
	
	/*
	wall_bound
	Damon Vaughn Caskey
	2010_05_15
	~2011_07_22

	Shunt self away from wall if bound entity is inside of it (wall). Prevents getting 
	a bound entity stuck within areas meant to be inaccesable or bounced to infinity
	by wall functions.

    vEnt:	Anchor entity.
	vBound:	Bound entity.
	iX/Y/Z:	Anchor location
	*/

    int	iOX, iOZ, iOB;														//Bound offset and Base.
	int	iX		= getentityproperty(vEnt, "x");								//Get self X location.
    int iY		= getentityproperty(vEnt, "a");								//Get self Y location.
    int iZ		= getentityproperty(vEnt, "z");								//Get self Z location.
	

	if (vBound)                                                             //Anything there?
    {            
        iOX = getentityproperty(vBound, "x");								//Get X bind offset.
        iOZ = getentityproperty(vBound, "z");								//Get Z bind offset.
		iOB = getentityproperty(vBound, "base");							//Get bound base.

		if (iOX > iX)														//Bound to right of anchor?
		{			
			iX++;															//Increment once.
			iOX++;															//Increment once.

			do																//Start loop.
			{					
				iX--;														//Decrement anchor location.
				iOX--;														//Decrement bound location.
			}
			while(checkwall(iOX+15, iOZ)>iOB && !checkhole(iOX+15, iOZ));	//Continue until outside of wall or in a pit.
		}
		else																//Bound left of anchor.
		{
			if(!checkwall(iOX-15, iOZ)>iOB) return;

			iX--;															//Decrement once.
			iOX--;															//Decrement once.

			do																//Start loop.
			{					
				iX++;														//Increment anchor location.
				iOX++;														//Increment bound location.
			}
			while(checkwall(iOX-15, iOZ)>iOB && !checkhole(iOX-15, iOZ));	//Continue until outside of wall or in a pit.
		}
			
		changeentityproperty(vEnt, "position", iX, iZ, iY);					//Apply location to anchor.
	}
}
 
Sorry for the late reply, I think I understand the problem here. Antiwall function was designed in a mod without walls as platforms.
For mods with such walls, you need to use updated version:

Code:
void antiwall(int Dist, int Move, int Distz)
{// Checks if there is wall at defined distance
// If there is wall, entity will be moved away with defined movement
   void self = getlocalvar("self");
   int Direction = getentityproperty(self, "direction");
   int x = getentityproperty(self, "x");
   int y = getentityproperty(self, "a");
   int z = getentityproperty(self, "z");
   float H;
   float Hz;

   if(Direction == 0){ //Is entity facing left?                  
      Dist = -Dist; //Reverse Dist to match facing
      Move = -Move; //Reverse Move to match facing
   }

   H = checkwall(x+Dist,z);
   Hz = checkwall(x+Dist,z+Distz);

   if(Hz > y)
   {
     changeentityproperty(self, "position", x, z-Distz);
   }

   if(H > y)
   {
     changeentityproperty(self, "position", x+Move);
   }
}
 
Im posting this for myself and others , when entity will be close to the wall they will turn around and walk opposite way using their own speed as velocity , so you can make enemies like in super mario,iIt just requires one animation.
I could not find such script on forums.

Code:
@script
    void self = getlocalvar("self");
    int x = getentityproperty(self, "x");
    int z = getentityproperty(self, "z");
    int Dir = getentityproperty(self, "direction");
	int sped = getentityproperty(self, "speed");
    int Sx = 1;
if(Dir==0){
     Sx = -Sx;
	 changeentityproperty(self, "velocity", 0-sped );
    }
if(Dir==1){
	 changeentityproperty(self, "velocity", sped );
    }
    void Plat = checkwall(x+Sx, z);
if( Dir == 0 && frame > 0 && x-(x-Plat) > 20 ){ 
     changeentityproperty(self, "direction", 1 );
    }
if( Dir == 1 && frame > 0 && x-(x-Plat) > 20 ){ 
    changeentityproperty(self, "direction", 0 );
     }
@end_script
 
Thanks bWWd this is really great, I'm thinking about using it to make a projectile bounce off a wall
 
Cool, im trying to figure out identical script but for character /enemy that walks on platform in his fake walk( follow or spawn anim) and script takes care of changing direction and velocity when enemy is reaching the end of the platform from both sides but so far im not succesfull.I tried with walkoff animation but somehow velocity is not working once walkoff gets activated,  also when checked base while on platform then its "1" and when checked when walkoff is activated then its suddenly 100000 or something, i can only turn him around and velocities wont work, does anyone know why this happens ? Ive seen this happen in some occasions too, where velocity change would not work unless i gave it a bit of "lift" with Y velocity upwards, its strange.
Does anyone have this kind of  working script ?

This is what i had so far :
Code:
anim	walkoff
	loop	1
	delay	5
@script
void self = getlocalvar("self"); //Get calling entity.
int y = getentityproperty(self,"a"); //get y
int x = getentityproperty(self,"x"); //get x
    int Dir = getentityproperty(self, "direction");
	int sped = getentityproperty(self, "speed");
	int base = getentityproperty(self, "base");
 setlocalvar("wys" , base );
	 settextobj(1, 250 , 100 , 1, 1, base , openborvariant("elapsed_time")+2000);	 
if( Dir == 0 && frame > 0 ){ 
  changeentityproperty(self, "antigravity", 1 );
  changeentityproperty(self, "direction", 1 );
   
    changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW2"));
}
if( Dir == 1 && frame > 0 ){ 
 changeentityproperty(self, "antigravity", 1 );
  changeentityproperty(self, "direction",0 );

 changeentityproperty(self, "animation", openborconstant("ANI_FOLLOW2"));
}
	@end_script	
		@cmd	settextobj 4 ((openborvariant("hResolution"))/2 -(strwidth("CANCEL" 1))/2  280 0  -1 "walkoff"
	
	offset	19 85
	seta   1
	sound data/sounds/beep.wav
	frame	data/sprites/bug1.gif

	frame	data/sprites/bug1.gif
	frame	data/sprites/bug1.gif
	frame	data/sprites/bug1.gif
	frame	data/sprites/bug1.gif
	frame	data/sprites/bug1.gif
	frame	data/sprites/bug1.gif
	frame	data/sprites/bug1.gif
								


	anim	follow2
	loop	1
	offset	19 85
	bbox	4 10 36 25
	delay	3
@script
    void self = getlocalvar("self");
    int x = getentityproperty(self, "x");
    int z = getentityproperty(self, "z");
	   int y = getentityproperty(self, "a");
    int Dir = getentityproperty(self, "direction");
	int sped = getentityproperty(self, "speed");
	int base = getentityproperty(self, "base");
	
	  changeentityproperty(self, "base", getglobalvar("base") );
	  settextobj(1, 250 , 100 , 1, 1, base, openborvariant("elapsed_time")+2000);	 
if(Dir==0){
  changeentityproperty(self, "velocity", -1  ,0,0);

    }
if(Dir==1){
  changeentityproperty(self, "velocity", 1  ,0,0);
 
    }
@end_script
	@cmd	settextobj 4 ((openborvariant("hResolution"))/2 -(strwidth("CANCEL" 1))/2  280 0  -1 "follow2"	
	sound	data/sounds/bee.wav
	seta  1
	frame	data/sprites/bug1.gif
	frame	data/sprites/bug2.gif
	frame	data/sprites/bug3.gif
	frame	data/sprites/bug2.gif
	frame	data/sprites/bug1.gif
	frame	data/sprites/bug2.gif
	frame	data/sprites/bug3.gif
	frame	data/sprites/bug2.gif
		frame	data/sprites/bug3.gif
	frame	data/sprites/bug2.gif
	frame	data/sprites/bug1.gif
	frame	data/sprites/bug2.gif
	frame	data/sprites/bug3.gif
	frame	data/sprites/bug2.gif

Can i cancel walkoff so base would say "1" again ?
 
when checked when walkoff is activated then its suddenly 100000 or something
This happens when you fall into a hole - the base is changed to -1000.

Byt the way, I do prefer to use onblockw and onblockP scripts in most of the times - we are reinventing the wheel when we do this type of code in animationscript, because the engine already does those checks.
 
I know about onblockpscript, the problem is , people are mentioning it but provide 0 examples and search brings nothing that i could use as a base, also i could be wrong but this script runs when you hit the platform when you are not on it, not when you are actually on it.
This was first thing i checked on forums and i could not find examples of it working and proper syntax to obtain and compare entity's position with platform position and its length.
Most of the time when im scripting im spending to actually find the right syntax to compare stuff, ive seen some bizarre things work on one line and not work on another line unless i did fresh check of property again and again.But anyway...
Im still looking for some solution.
 
bWWd ah take a look at my Wall Jump tutorial for reference: http://www.chronocrash.com/forum/index.php?topic=3767.0
You will see we don't have to do any wall check for that to work. And to make it work for platforms, just call the same script as onblockP.

I tried with onblockS and onblockO and both works too.
 
Got it working for platforms anyway, but i will take a look, i actually paxploded your mod looking for help but you use non typical naming for scripts
heres my code, use it in follow or spawn, it will automatically move entity and change direction when platform will end, and platform is 80 pixels wide so its 40 on both sides, adjust values for your needs:
Code:
	@script
    void self = getlocalvar("self");
    int x = getentityproperty(self, "x");
    int z = getentityproperty(self, "z");
	   int y = getentityproperty(self, "a");
    int Dir = getentityproperty(self, "direction");
	int sped = getentityproperty(self, "speed");
	int base = getentityproperty(self, "base");
	 changeentityproperty(self, "antigravity", 0 );
	 void  Plat = checkplatformbetween(x, z, 0, 1000);
	  settextobj(1, 250 , 100 , 1, 1, base, openborvariant("elapsed_time")+2000);	 
if(Dir==0){
  changeentityproperty(self, "velocity", -1  ,0,0);
   settextobj(1, 250 , 100 , 1, 1, "dir0", openborvariant("elapsed_time")+2000);	
 settextobj(2, 250 , 120 , 1, 1,  getentityproperty(Plat, "x"), openborvariant("elapsed_time")+2000);	   
    settextobj(3, 250 , 140 , 1, 1,"muchax   "+x, openborvariant("elapsed_time")+2000);	

    }
if(Dir==1){
  changeentityproperty(self, "velocity", 1  ,0,0);
   settextobj(1, 250 , 100 , 1, 1, "dir1" , openborvariant("elapsed_time")+2000);	 
 
    }
	
	if(Dir==0 && x+40 <= getentityproperty(Plat, "x")){
	  changeentityproperty(self, "direction", 1 );
  changeentityproperty(self, "velocity", 1  ,0,0);
   settextobj(1, 250 , 100 , 1, 1, "dirala0", openborvariant("elapsed_time")+2000);	 
 settextobj(2, 250 , 120 , 1, 1,  getentityproperty(Plat, "x"), openborvariant("elapsed_time")+2000);	 
  settextobj(4, 250 , 160 , 1, 1,  "zmiana0", openborvariant("elapsed_time")+2000);	 
    }
		if(Dir==1 && x-40 >= getentityproperty(Plat, "x")){
	  changeentityproperty(self, "direction", 0 );
  changeentityproperty(self, "velocity", -1  ,0,0);
   settextobj(1, 250 , 100 , 1, 1, "dirala0", openborvariant("elapsed_time")+2000);	 
 settextobj(2, 250 , 120 , 1, 1,  getentityproperty(Plat, "x"), openborvariant("elapsed_time")+2000);	 
  settextobj(4, 250 , 160 , 1, 1,  "zmiana1", openborvariant("elapsed_time")+2000);	 
    }
@end_script

Just remove text objects, they're there for debugging

--
Slimmed down:
Code:
	@script
    void self = getlocalvar("self");
    int x = getentityproperty(self, "x");
    int z = getentityproperty(self, "z");
    int y = getentityproperty(self, "a");
    int Dir = getentityproperty(self, "direction");
	int sped = getentityproperty(self, "speed");
	 void  Plat = checkplatformbetween(x, z, 0, 1000);
if(Dir==0){
  changeentityproperty(self, "velocity", -1  ,0,0);
    }
if(Dir==1){
  changeentityproperty(self, "velocity", 1  ,0,0);
    }
	if(Dir==0 && x+40 <= getentityproperty(Plat, "x")){
	  changeentityproperty(self, "direction", 1 );
    }
		if(Dir==1 && x-40 >= getentityproperty(Plat, "x")){
	  changeentityproperty(self, "direction", 0 );
    }
@end_script
Now i understand better how to change thing swhen on platforms so i might try to do some climbdown and climbup animations /mechanics.
--
Ok i detected when character is supposed to start climbing when hes under or climb down when hes on platform corner.
So i think this will work.
---
Ok heres platform climb up/down preparation code
Code:
	@script
    void self = getlocalvar("self");
    int x = getentityproperty(self, "x");
    int z = getentityproperty(self, "z");
	   int y = getentityproperty(self, "a");
    int Dir = getentityproperty(self, "direction");
	int sped = getentityproperty(self, "speed");
	int base = getentityproperty(self, "base");
	 changeentityproperty(self, "antigravity", 0 );
	 	 int Sx = 0;
		 int Sxa = 10;
		 if(Dir==0){
 Sx = -Sx;
  Sxa = -Sxa;
}
	 void  Plat = checkplatformbelow(x+Sx, z, y);
	 void  PlatA = checkplatformabove(x+Sxa, z, y);

	  settextobj(1, 150 , 100 , 1, 1, base, openborvariant("elapsed_time")+2000);	
if(Dir==0){
   settextobj(1, 150 , 100 , 1, 1, "dir0", openborvariant("elapsed_time")+2000);	
 settextobj(2, 150 , 120 , 1, 1,  getentityproperty(Plat, "x"), openborvariant("elapsed_time")+2000);	   
    settextobj(3, 150 , 140 , 1, 1,"muchax   "+x, openborvariant("elapsed_time")+2000);	

    }
if(Dir==1){
   settextobj(1, 150 , 100 , 1, 1, "dir1" , openborvariant("elapsed_time")+2000);	
  settextobj(2, 150 , 120 , 1, 1,  getentityproperty(Plat, "x"), openborvariant("elapsed_time")+2000);	   
    settextobj(3, 150 , 140 , 1, 1,"muchax   "+x, openborvariant("elapsed_time")+2000);	
    }
	
	if(Dir==1 && x-5 <= getentityproperty(PlatA, "x")){
   settextobj(1, 150 , 100 , 1, 1, "dirala0", openborvariant("elapsed_time")+2000);	
 settextobj(2, 150 , 120 , 1, 1,  getentityproperty(Plat, "x"), openborvariant("elapsed_time")+2000);	
  settextobj(4, 150 , 160 , 1, 1,  "climbup LEFT", openborvariant("elapsed_time")+100);	
    }
		if(Dir==0&& x-50 >= getentityproperty(PlatA, "x")){
	   settextobj(1, 150 , 100 , 1, 1, "dirala0", openborvariant("elapsed_time")+2000);	
 settextobj(2, 150 , 120 , 1, 1,  getentityproperty(Plat, "x"), openborvariant("elapsed_time")+2000);	
  settextobj(4, 150 , 160 , 1, 1,  "climbup_RIGHT", openborvariant("elapsed_time")+100);	
    }
		if(Dir==1 && x-40 >= getentityproperty(Plat, "x")&& y+50 >= getentityproperty(Plat, "y")){
   settextobj(1, 150 , 100 , 1, 1, "dirala0", openborvariant("elapsed_time")+2000);	
 settextobj(2, 150 , 120 , 1, 1,  getentityproperty(Plat, "x"), openborvariant("elapsed_time")+2000);	
  settextobj(4, 150 , 160 , 1, 1,  "climbdown RIGHT", openborvariant("elapsed_time")+100);	
    }
		if(Dir==0 && x-20 <= getentityproperty(Plat, "x")&& y+50 >= getentityproperty(Plat, "y")){
	   settextobj(1, 150 , 100 , 1, 1, "dirala0", openborvariant("elapsed_time")+2000);	
 settextobj(2, 150 , 120 , 1, 1,  getentityproperty(Plat, "x"), openborvariant("elapsed_time")+2000);	
  settextobj(4, 150 , 160 , 1, 1,  "climbdown LEFT", openborvariant("elapsed_time")+100);	
    }
@end_script
So this detects when youre standing under platform's corner or on top of platform near corners.
Instead of displaying text you can actually switch to follow anim that loooks like climbdown or climbup. and you have climbing working.I have this script in idle but i think it could work in walk animation too.
36mwc.png
36mwf.png

If someone has more compact solution, free to join and post examples.
So this is pretty m uch what i wanted to do long time ago but didnt had patience to figure it out, text objects really help a lot in debugging.
I wonder how hard would it be to code swinging on rope, kinda like jungle book games.
I also would like to try micromachines clone with enemies ai but thats different challenge.
 
Alternatively, you can paxplode Cherry On Top and Robo Magi to find examples for onblockw and onblockp scripts. Both scripts are used by enemies to change direction when hitting wall or platforms.

Both games also have script to prevent certain enemies from walking off platform or wall they are walking on

As for ledge detection, that might be tough since there's no way to acquire platform's length and width. That's why I used antigrab and grabforce to define platform's length and width respectively.
When standing on a platform, you can use checkplatformbelow to acquire the platform then acquire it's length and compare it with platform's x coord against entity's x coord to know if he/she/it is near ledge or not
 
I have them both, do You remember names of these scripts ? Its hard to find them and check each c file one by one looking for platform code.
 
Heres flashback platform climbing demo that Mohammed made, i modified it to use my method and its working very well, you climb down by pressing down, i dont use walkoff for climbdown cause i want player to jump off the platform when he walks too far, maybe someone will find it useful.
https://drive.google.com/file/d/1Si6txelVXL7hCOtX_PB639XTz2ztUjjL/view?usp=sharing
Maybe it will also give others clues how to interact with platforms .
I set platform length by using aggression and then its fairly easy,  at 17 pixels or less from platform edge you can press down and you climb down.So you can pretty much use whatever length and it would work.
 
Congratulation bWWd, you've made a very good job in this climbing down feature. I always wish that an horizontal climb under a wall or a platform be added to Openbor (see at 24:32):
But I think this is not an easy thing to do...
 
Ah yes, enemies which bounces off wall and platforms use this onblock script
Pantul.c
Code:
void main()
{// Script for 'pantul dinding'
// Flips facing direction & velocity
    void self = getlocalvar("self");
    float Vx = getentityproperty(self,"xdir");
    int dir = getentityproperty(self,"direction");

    if(dir==0){ // Facing left?
      changeentityproperty(self, "direction", 1);
    } else {
      changeentityproperty(self, "direction", 0);
    }
    changeentityproperty(self, "velocity", -Vx);
}

It's declared like this:
Code:
onblockwscript	data/scripts/pantul.c
onblockpscript	data/scripts/pantul.c

The script for keeping enemies ontop of platform or wall and also inside level is this:
Code:
anim	follow1
@script
    void self = getlocalvar("self");
    int Dir = getentityproperty(self, "direction");
    int x = getentityproperty(self, "x");
    int y = getentityproperty(self, "a");
    int z = getentityproperty(self, "z");
    int Width = openborvariant("levelwidth");
    void Plat = checkplatformbelow(x, z, y+2);
    int Length; int Px; void PlatA; void PlatB; int Wall;

    if(x > Width - 10){
      changeentityproperty(self, "velocity", -1);
      changeentityproperty(self, "direction", 0);
    } else if(x < 10){
      changeentityproperty(self, "velocity", 1);
      changeentityproperty(self, "direction", 1);
    } else if(Plat){ // on a platform
      Length = getentityproperty(Plat, "antigrab");
      Px = getentityproperty(Plat, "x");
      if(Dir==1){
        PlatA = checkplatformbelow(x+24, z, y+2);
        PlatB = checkplatformbelow(x+24, z, y-2);
      } else {
        PlatA = checkplatformbelow(x-24, z, y+2);
        PlatB = checkplatformbelow(x-24, z, y-2);
      } 

      if(x >= Px + Length/2 - 23 && PlatA==PlatB){
        changeentityproperty(self, "velocity", -1);
        changeentityproperty(self, "direction", 0);
      } else if(x <= Px - Length/2 + 23 && PlatA==PlatB){
        changeentityproperty(self, "velocity", 1);
        changeentityproperty(self, "direction", 1);
      }
    } else { // on a wall
      if(Dir==1){
        Wall = checkwall(x+26,z);
      } else {
        Wall = checkwall(x-26,z);
      } 

      if(y > Wall && Dir==1){
        changeentityproperty(self, "velocity", -1);
        changeentityproperty(self, "direction", 0);
      } else if(y > Wall && Dir==0){
        changeentityproperty(self, "velocity", 1);
        changeentityproperty(self, "direction", 1);
      }
    }
@end_script
	loop	1
...

It's long cause it checks 3 aspects for that 3 purpose

kimono said:
I always wish that an horizontal climb under a wall or a platform be added to Openbor

It's doable  8)
 
Thats nice a script,  multiple cases at once.

This contra behaviour would be very possible to implement from what i posted, basically just replace it with different animation and give it custom fake walking while hanging animation.
 
Back
Top Bottom