Help with bug y codes (for Silver Night's Crusaders)

Crimsondeath

Well-known member
Hi to everyone,
I know, I asked for some help in the "Readme" file of my demo of Silver Night's Crusaders, but I decided to change button configuration at the end. So, many of that bug aren't important now (most of the Sheeba's bugs were solved removing unnecesary skills for gameplay in fact xD), but i still need help with some little things:
  • Sub-weapon attack while pressing up button: I can do it with freespecial comand but that work just 1 time, when I press the "Attack" buttom again, while keep pressing the up button, the character do his attack as usual.
And some optional request (I really appreciate if you could help me with this):
  • Fran’s bat transformation should not pass the walls same problem happend when a character jumps under a wall, i use the "height" Terrain Interaction which is good to prevent that, but "height" applies to every wall and platform (even the ones which are passable x.x).
  • The equipped sub-weapon isn’t showing below the life icon.
  • The thunder attack of the first boss does not aim well (just go straight) when the player is on the ground.

Here I put some images trying to explain better the issues (click to expand):


Whoever helps me with those issues will receive their respectives credits and special thanks at the ending screen in the game, is all I can offer  :'( .

I'll upload a new demo after finishing with the new skills setting xd. Thanks anyway :) .
 
-About the sub weapon throw, you can try to use a CANCEL on the attack1 animation.
- The thunder attack needs to aim the player or chase it? If its chase, you can try to use a CHASE subtype. If it need to just aim, there is a function Bloodbane made called Target, so it will get the target position to use later.
- About wall height, you can set TYPE on walls too. So maybe you can check for the wall type to determine if its passable or not.
 
-About the sub weapon throw, you can try to use a CANCEL on the attack1 animation.

I tried that, but has the same issue with Freespecial. here is my code:
Code:
anim	attack1
	delay	7
	offset	45 75
	cancel	0 13 0 u a freespecial4 #this is the animation for the subweapon
	bbox	35 30 15 40
	frame	data/chars/ethan/attack1.gif
	frame	data/chars/ethan/attack2.gif
	delay	1
	sound	data/sounds/throw_whip.wav
	attack	70 15 91 30 6 0 0 0 0 0
	frame	data/chars/ethan/attack3.gif
	# ...

- The thunder attack needs to aim the player or chase it? If its chase, you can try to use a CHASE subtype. If it need to just aim, there is a function Bloodbane made called Target, so it will get the target position to use later.

Just need to aim the player, i used Target function and works fine when the enemy that use it is a floating entity, but when the enemy is a walker entity and the player is under him, the proyectile just go straight (but if the player jumps over the enemy, target function works as usual).

Code:
anim	upper
	delay	7
	offset	35 130
	bbox	15 25 40 105
	shock	15 25 40 105 19 0 0 0 0 0
	frame	data/chars/creature/special1.gif
	frame	data/chars/creature/special2.gif

	#... animation frames
	#... HERE IS THE FUNCTION
	frame	data/chars/creature/special13a.gif
	@cmd	target 2 2 0 0 0 0
	@cmd	shoot2 "CThunder" 22 95
	frame	data/chars/creature/special14.gif

	#... animation frames

	delay	1
	shock	0 0 0 0 0 0 0
	frame	data/chars/creature/special1.gif

- About wall height, you can set TYPE on walls too. So maybe you can check for the wall type to determine if its passable or not.

I'm sorry, it wasn't "walls" x.x, being more specific they were "platforms" that I use as walls.

Code:
name  		Platform_rock6
type		none
facing	  	1
setlayer		-1
antigravity	100
offscreenkill   9999

palette		data/bgs/underground/palette_object.gif

anim	idle
	delay	100
	offset	42 111
	platform	0 111 -8 -8 93 93 10 999
	frame	data/bgs/underground/platforms/platform_rock6.gif

I tried to add a Type like in openbor legacy manual, but the problem didn't solved x.x. I used "height" on players, but that makes that all my platforms impassable when they try to reach them from bellow. I haven't test using walls for some parts of my stages I'm gonna try that anyway.

Thanks.
 
-Subweapon: strange. Maybe you will need to use a keyscript to change the animation.
BB had a funcion for that too, I just forgot its name.

Just need to aim the player, i used Target function and works fine when the enemy that use it is a floating entity, but when the enemy is a walker entity and the player is under him,
You would need to customize the function to use the Alt too.

I tried to add a Type like in openbor legacy manual, but the problem didn't solved x.x.
Because platform has no type. Just walls and holes.

This is how I use on a onblockwscript. Notice that I check the wall type.
Code:
//Wall Jump without animationscript
//Author: O Ilusionista
//Version: V1 - 2018.03.03
//Thanks: Bloodbane, Damon Caskey and White Dragon
void actual_main()
{
  void vSelf = getlocalvar("self"); //Get calling player
	void facing = getentityproperty(vSelf, "direction"); // Get Direction
	void vAniID = getentityproperty(vSelf,"animationID"); //Get current animation ID
  void iJump = playerkeys(vSelf, 1, "jump"); //New key status of "Jump"
	int y = getentityproperty(vSelf, "a");	// Get Y pos
	int b = getentityproperty(vSelf, "base");	// Get Base pos
	void wType = getlocalvar("type"); //Get wall type
	
	if(vAniID == openborconstant("ANI_JUMP") || vAniID == openborconstant("ANI_FORWARDJUMP") || vAniID == openborconstant("ANI_RUNJUMP"))
	{ //Jumping, jumping forward or Run Jumping?

		if (wType==1) // Wall type 1?
		{
			if (iJump && y > b+20)
			{ //New jump key press and Y position is greater than the Base position by 20 pixels, so it won't trigger right when you start jumping?
			changeentityproperty(vSelf, "aiflag", "jumping", 0); // Disable jumping aiflag, so the common jump routine won't take action
			changeentityproperty(vSelf, "aiflag", "attacking", 1); // Enable attacking aiflag, so the common jumpattack routine won't take action
			changeentityproperty(vSelf, "animation", openborconstant("ANI_FOLLOW40")); // Change to FOLLOW40 anim
			}
		}
	}

}
With this, I can make the character execute a wall jump only against certain walls.

I remember BB had posted something about this here, make a search

 
Allow me to paxplode your demo before understanding your requests, Crimsondeath :) . I really need to see how heroes fly during transformed mode in your demo
 
I've paxploded the demo and made quick examination on some issues. I discovered some things:
1. Both Soul Bat and Sheeba Volaticus can pass platforms and walls
2. There's no subweapon icon display system

I thought you've copied #2 from CV Collab but looks like you didn't. Anyways, the system is not simple to implement. Simply put it works like this:
1. When game is loaded, all subweapon icons are loaded
2. When game is running, update.c checks for player's current subweapon and displays proper icon based on the subweapon
3. When game is closed, all loaded sprites are released

Do you want me to explain how it works in detail?

As for #1, I don't understand. If you don't want Fran's Bat form to pass through walls or platforms, why did you allow them pass platforms and walls?

The thunder attack of the first boss does not aim well (just go straight) when the player is on the ground.

I've found the problem:
Code:
	@cmd	target 2 2 0 0 0 0
	@cmd	shoot2 "CThunder" 22 95

With this setting, the creature will miss his shot by 95 pixels. In order to fix the accuracy, you need to raise shooting offset in target function into this:
Code:
	@cmd	target 2 2 0 75 0 0
	@cmd	shoot2 "CThunder" 22 95

I set 75 in target function to make it aim 20 pixels above player's offset, IOW aim player's torso. You can set 95 if you want
 
Bloodbane: Thanks :D, but let's just forget Sheeba now because I decided to remove some of her spells, like Volaticus, because they didn't have a real use on my game (just were an easter-egg to metroidvania games). The real issue with Sheeba's Volaticus was the game crashing that comes when you try to summon the skill while you were on air (at jumping).

I thought you've copied #2 from CV Collab but looks like you didn't. Anyways, the system is not simple to implement. Simply put it works like this:
1. When game is loaded, all subweapon icons are loaded
2. When game is running, update.c checks for player's current subweapon and displays proper icon based on the subweapon
3. When game is closed, all loaded sprites are released

Do you want me to explain how it works in detail?

It's ok, but i don't have an "update.c" file in my script folder, just an "Xupdate.c" which I never touched :-X . I look at the CV Collab post and I just found this (?) :0.

As for #1, I don't understand. If you don't want Fran's Bat form to pass through walls or platforms, why did you allow them pass platforms and walls?

I already tried setting "subject_to_wall 1", "subject_to_platform 1" and don't works on the Soul bat xD. Only works well If I add "height #" to the entity, but that makes all platforms impassable too.

I've found the problem:
...
I set 75 in target function to make it aim 20 pixels above player's offset, IOW aim player's torso. You can set 95 if you want

The creature "bug" was fixed successfully thanks :D.
 
I've fallen ill when I'm reading this so I had to abandon it

Anyways, now that I'm back

The real issue with Sheeba's Volaticus was the game crashing that comes when you try to summon the skill while you were on air (at jumping)

I'm going to figure out why

I look at the CV Collab post and I just found this (?) :0.

Yeah that's the one I'm offering. Don't hesitate to ask how update.c works there :D

I already tried setting "subject_to_wall 1", "subject_to_platform 1" and don't works on the Soul bat xD. Only works well If I add "height #" to the entity, but that makes all platforms impassable too.

(sigh)
I can imagine a solution but I'm afraid it might change all platform setting for stability
 
Bloodbane: Oh Hi :0, you don't have to take it so seriously they aren't dangerous bug after all xd.

I'm going to figure out why

About Sheeba, as I wrote before, I already removed her flying skill, you don't have to worry anymore :o .

(sigh)
I can imagine a solution but I'm afraid it might change all platform setting for stability

Yesterday, I tried to reemplace some platforms with unpassable walls in a debug scene i had in the game (if you paxploded the game you must already found it xd), and didn't work xd, even applying the "type" parameter at the end of walls and the "height" tag on the player. Anyway I think,  I can fix that issues with some "estetical tricks" in the stages. Thanks :) .

Yeah that's the one I'm offering. Don't hesitate to ask how update.c works there

I downloaded that CV Collab demo (and only found the "Xupdate.c" file, not the "update.c" file). the Xupdate.c contains this codes:
Code:
void main()
{// Update script for displaying checkplatform
    void P1 = getplayerproperty(0, "entity"); 
    int x = getentityproperty(P1,"x"); //Get entity's x
    int y = getentityproperty(P1,"a"); //Get entity's altitude
    int z = getentityproperty(P1,"z"); //Get entity's z
//    void e = checkplatformbelow(x+10, z, y+10);
    void f = checkplatformbelow(x, z, y+2);
    char FName = getentityproperty(f,"name");
    
//    drawstring(50,110,0, "Right & above "+e);
    drawstring(50,130,0, "Below "+FName);

//    void Familiar = getentityvar(P1, 1);
//    char FamName = getentityproperty(Familiar,"name");
//    int FamEx = getentityproperty(Familiar,"exists");

//    drawstring(150,130,3, FamName);
//    drawstring(150,150,3, FamEx);
}

Seems to be something for platforms and femiliars (?). I played CV Collab demo and sub-weapon system seems to be the same, no sub-weapon icon appeared under/aside players life bar like in CV games :0 or did I have to look on other files? Thanks :) .
 
you don't have to take it so seriously they aren't dangerous bug after all xd.

A bug which causes crash is serious and somehow it piques my interest so I decided to investigate deeper

And I've done investigating, the cause of the crash was simply because Sheeba Volaticus doesn't have FREESPECIAL22. Looks like her transformed mode need to play same animation before fully transformed
I've added a temp FREESPECIAL22 and it worked :)

Seems to be something for platforms and femiliars (?)

Oh those are debug lines. I usually left some for debugging in update.c

Wait a second, where's the real update.c?
Anyways, it should look like this:

Code:
void main()
{// Update script for displaying current HP from player 1 with colored bar
// Also displays current MP with numbers & displays current subweapon
    void P1 = getplayerproperty(0, "entity");
    void Bar = getglobalvar("Bar");
    void WAx = getglobalvar("WAx");
    void WBib = getglobalvar("WBib");
    void WBom = getglobalvar("WBom");
    void WBwa = getglobalvar("WBwa");
    void WCrs = getglobalvar("WCrs");
    void WGre = getglobalvar("WGre");
    void WHoly = getglobalvar("WHoly");
    void WKap = getglobalvar("WKap");
    void WKua = getglobalvar("WKua");
    void WKun = getglobalvar("WKun");
    void WMAx = getglobalvar("WMAx");
    void WPis = getglobalvar("WPis");
    void WSpe = getglobalvar("WSpe");
    void WSBl = getglobalvar("WSBl");

    if(openborvariant("in_level")==1){
      if(P1){
        int HP1 = getentityproperty(P1, "health");
        int MP1 = getentityproperty(P1, "mp");
	int SubW = getglobalvar("00");
        drawsprite(Bar, 3, 3, 1000);

	if(MP1>=100){
	  MP1 = 99;
	}

	drawstring(15,29,4, MP1);
	drawbox(7,104-HP1,3,HP1,1500,rgbcolor(255,0,0),0);
	drawbox(8,104-HP1,1,HP1,1800,rgbcolor(255,104,104),0);
	drawbox(10,104-HP1,1,HP1,1500,rgbcolor(178,0,0),0);

	if(SubW==1){
          drawsprite(WAx, 13, 43, 1100);
	} else if(SubW==2){
          drawsprite(WCrs, 13, 43, 1100);
	} else if(SubW==3){
          drawsprite(WHoly, 13, 43, 1100);
	} else if(SubW==4){
          drawsprite(WSBl, 13, 43, 1100);
	} else if(SubW==5){
          drawsprite(WKun, 13, 43, 1100);
	} else if(SubW==6){
          drawsprite(WBom, 13, 43, 1100);
	} else if(SubW==7){
          drawsprite(WSpe, 13, 43, 1100);
	} else if(SubW==8){
          drawsprite(WKua, 13, 43, 1100);
	} else if(SubW==9){
          drawsprite(WMAx, 13, 43, 1100);
	} else if(SubW==10){
          drawsprite(WBib, 13, 43, 1100);
	} else if(SubW==11){
          drawsprite(WGre, 13, 43, 1100);
	} else if(SubW==12){
          drawsprite(WBwa, 13, 43, 1100);
	} else if(SubW==13){
          drawsprite(WPis, 13, 43, 1100);
	} else if(SubW==14){
          drawsprite(WKap, 13, 43, 1100);
	}
      }
    }
}

void oncreate()
{
    void Bar;
    void WAx; void WBib; void WBom; void WBwa; void WCrs; void WGre; void WHoly; 
    void WKua; void WKun; void WMAx; void WSpe; void WSBl; void WPis; void WKap; 

    Bar = loadsprite("data/sprites/lifebar.png");
    WAx = loadsprite("data/sprites/WAxe.png");
    WBib = loadsprite("data/sprites/WBible.png");
    WBom = loadsprite("data/sprites/WBomrad.png");
    WBwa = loadsprite("data/sprites/WBwaka.png");
    WCrs = loadsprite("data/sprites/WCross.png");
    WGre = loadsprite("data/sprites/WGrenade.png");
    WHoly = loadsprite("data/sprites/WHolyW.png");
    WKap = loadsprite("data/sprites/WKapak.png");
    WKua = loadsprite("data/sprites/WKunai.png");
    WKun = loadsprite("data/sprites/WKuni.png");
    WMAx = loadsprite("data/sprites/WMAxe.png");
    WPis = loadsprite("data/sprites/WPisau.png");
    WSpe = loadsprite("data/sprites/WSpear.png");
    WSBl = loadsprite("data/sprites/WStBall.png");

    setglobalvar("Bar", Bar);
    setglobalvar("WAx", WAx);
    setglobalvar("WBib", WBib);
    setglobalvar("WBom", WBom);
    setglobalvar("WBwa", WBwa);
    setglobalvar("WCrs", WCrs);
    setglobalvar("WGre", WGre);
    setglobalvar("WHoly", WHoly);
    setglobalvar("WKap", WKap);
    setglobalvar("WKua", WKua);
    setglobalvar("WKun", WKun);
    setglobalvar("WMAx", WMAx);
    setglobalvar("WPis", WPis);
    setglobalvar("WSpe", WSpe);
    setglobalvar("WSBl", WSBl);
}

void ondestroy(){
    void Bar = getglobalvar("Bar");
    void WAx = getglobalvar("WAx");
    void WBib = getglobalvar("WBib");
    void WBom = getglobalvar("WBom");
    void WBwa = getglobalvar("WBwa");
    void WCrs = getglobalvar("WCrs");
    void WGre = getglobalvar("WGre");
    void WHoly = getglobalvar("WHoly");
    void WKap = getglobalvar("WKap");
    void WKua = getglobalvar("WKua");
    void WKun = getglobalvar("WKun");
    void WMAx = getglobalvar("WMAx");
    void WPis = getglobalvar("WPis");
    void WSpe = getglobalvar("WSpe");
    void WSBl = getglobalvar("WSBl");

    free(Bar);
    free(WAx);
    free(WBib);
    free(WBom);
    free(WBwa);
    free(WCrs);
    free(WGre);
    free(WHoly);
    free(WKap);
    free(WKua);
    free(WKun);
    free(WMAx);
    free(WPis);
    free(WSpe);
    free(WSBl);

    setglobalvar("Bar", NULL());
    setglobalvar("WAx", NULL());
    setglobalvar("WBib", NULL());
    setglobalvar("WBom", NULL());
    setglobalvar("WBwa", NULL());
    setglobalvar("WCrs", NULL());
    setglobalvar("WGre", NULL());
    setglobalvar("WHoly", NULL());
    setglobalvar("WKap", NULL());
    setglobalvar("WKua", NULL());
    setglobalvar("WKun", NULL());
    setglobalvar("WMAx", NULL());
    setglobalvar("WPis", NULL());
    setglobalvar("WSpe", NULL());
    setglobalvar("WSBl", NULL());
}


The lines in oncreate and ondestroy are for loading sprites and unloading sprites respectively.
In main(), there are scripts to display player's lifebar with colored bar, MP with numbers and current subweapon
 
Hey Bloodbane , just a tip: at ondestroy you don't need to get those variables values with getglobalvar.
Just set them to NULL() directly - if the variable exits, its value will set to NULL(); if not, nothing will happens and the engine will ignore it.
The problem happens on the opposite direction - when you get a value from a non existent variable and try to pass it/use it on another place - you will get a Null Point crash - which is the only thing which will really crash the engine (and its not an issue with the engine, is how coding works).

Also, you don't neeed to use free() either, since they are only valid for (according to the manual) allocscreen.
 
O Ilusionista, the part about free() isn't correct, and I'm not sure who put that in the manual. You can use free() on nearly anything, though for most things it's pointless. But in the case of loaded sprites or sounds it's important. If you don't free them, they lay around in memory until the engine shuts down and IIRC, the engine nags you in the log about it.

DC
 
Damon Caskey than this should to be fixed. But I remember I was using free with globalvariables and I received an error thanks to that.
I can't remember if the engine had quit or was just an error at the log. I will confirm it.

*Edit by DC:* I accidentally edited your post when I was trying to quote it. Restored to original state.
 
O Ilusionista said:
Damon Caskey than this should to be fixed. But I remember I was using free with globalvariables and I received an error thanks to that.
I can't remember if the engine had quit or was just an error at the log. I will confirm it.

You can't free() a globalvar() because globalvar() is not a variable. It's a function. You don't have direct access to global variables, just functions to set and get their values. But inline variables "int x = <whatever>" can be freed, and if it's a pointer, it will free the memory associated.

Thus, in the case of sprites that you loaded and then kept the pointer for using globalvar(), you need to later get the pointer into an inline var, and then free() it. That destroys the sprite. Same goes for sounds, arrays, and so on.

HTH,
DC
 
Damon Caskey Ah, now I get it. So the statement that they could be used into almost anything isnt't 100% right, right?
It would be needed to used with inline variables.

On this case:
void WSBl = getglobalvar("WSBl");
Will be considered an inline variable? Or just INT variables are considered?

Plus, if you use free(), should you use setglobalvar to NULL after it or its overkill?
 
O Ilusionista said:
Damon Caskey Ah, now I get it. So the statement that they could be used into almost anything isnt't 100% right, right?
It would be needed to used with inline variables.

On this case:
void WSBl = getglobalvar("WSBl");
Will be considered an inline variable? Or just INT variables are considered?

No, it's inline. Or you can call it a function variable. By inline, I mean the scope, which is different from type. When you declare a variable in a function, it's a variable.

Plus, if you use free(), should you use setglobalvar to NULL after it or its overkill?

No, you still need to delete the global. It will help if I walk through step by step of what happens...

1.

Code:
void WSBl = getglobalvar("WSBl");

This creates a function variable "WSBI". Then it gets the return value of  getglobalvar("WSBl"); and copies that value to "WSBI".

2.

Code:
free(WSBI);

This deletes the value of WSBI, and if it is a pointer, the item that pointer pointed to. So if this was a pointer to a sprite you loaded earlier, this gets rid of it and frees the memory. IIRC remember correctly, the variable still exists, and may still contain the original pointer value (but the pointer now points to nothing - it's what we call a dangling pointer and shouldn't be used for anything). That's how C code behaves and if again if I recall correctly it's what OpenBOR script does as well.

Like any function variable, it will be completely destroyed when the function is finished.

3.

Code:
setglobalvar("WSBl", NULL());

Now you are clearing the the copy being stored as a globalvar. OpenBOR will also delete the variable from memory.
 
I want to say thanks to everyone for the help :D .

Bloodbane: The "update.c" works great on my Mod :D, thanks you're the greatest (I'll make sure to dedicate you a full page of credits, as well to thanks Chronocrash for the great help :D) . I just have one little bug, which I forgot to mention >.< (and is also present in the Castlevania collaborative demo).  When the player dies and goes to gameover screen and restart a new game from the beginning, the sub-weapon that player had when he died carries over.

Is there a code or setting to "clear" the subweapon when the player start a new game?

Thanks anyway :D
 
You're welcome :D

When the player dies and goes to gameover screen and restart a new game from the beginning, the sub-weapon that player had when he died carries over.

Ah, I left that feature there so players could get a subweapon from a game mode to use it in other game mode  ;).
If you want to reset subweapon when going to main menu, you need to do some things:

First, set alwaysupdate 1 in script.txt

Then, declare this line in update.c:
Code:
if(openborvariant("in_menuscreen")==1){
      setglobalvar("00", NULL());
}

This will reset player 1's subweapon in main menu
 
Back
Top Bottom