Solved Drawstring question

Question that is answered or resolved.

O Ilusionista

Captain 100K
Guys, I want to make to draw some strings on the select screen based on which map the player has for now.
I've tried to use this code inside a ondrawscript but it works only during stages - so I assume ondrawscripts doesn't works on outside stages.

Then I moved to updated.c using "in_selectscreen" check.
It works, but there is a part which doesn't works and I can't understand why:

Code:
	if(openborvariant("in_selectscreen"))
	{	

		int P1 = getplayerproperty(0, "entity");
		char Tname = getplayerproperty(P1, "name");
		drawstring(30,50,0,Tname,1000); // works
		drawstring(30,60,1,P1,1000); // return <VT_EMPTY>

       if (P1){// this check fails and anything inside it isn't displayed
		int Map = getentityproperty(P1, "map");
		int x 		= getentityproperty(P1, "x");
		int y 		= getentityproperty(P1, "y");
		int z 		= getentityproperty(P1, "z");
		char Tname = getentityproperty(P1, "defaultname");
		drawstring(30,100,2,Tname,1000);
		drawbox(120,100,100,10,1000,rgbcolor(0xFF,0xE0,0x03), 0);
		drawstring(30,120,2,"P1 on the game",1000);
       }

Why the if(p1) part fails?

msmalik681 Kratus Damon Caskey can any of you guys give me a hand here?
 
And there is more: even if I try to get the P2, it returns me the P1 name again:

Code:
	if(openborvariant("in_selectscreen"))
	{	

		void P1 = getplayerproperty(0, "entity");
		char Tname = getplayerproperty(P1, "name");

		void P2 = getplayerproperty(1, "entity");
		char Tname2 = getplayerproperty(P2, "name");

		drawstring(30,50,0,Tname,1000); // works
		drawstring(330,50,2,Tname2,1000); // works
		drawstring(30,60,1,P1,1000); // return <VT_EMPTY>

 
		int Map = getentityproperty(P1, "map");
		int x 		= getentityproperty(P1, "x");
		int y 		= getentityproperty(P1, "y");
		int z 		= getentityproperty(P1, "z");
		char Tname = getentityproperty(P1, "defaultname");
		drawstring(30,100,2,Tname,1000);
		drawbox(120,100,100,10,1000,rgbcolor(0xFF,0xE0,0x03), 0);
		drawstring(30,120,2,"P1 on the game",1000);

See the IRON FIST string over Coloussus
wMQq3YT.png
 
Yeah i am pretty sure i came across this issue when trying to optimize sor2x select screen.  If you look at the code behind that there is a different way you have to look up current player properties and i think there is limited things you can check sorry not at my pc look up sor2x select screen code for more information.
 
Some more info:

I have a type NONE entity on the screen called BIOS, and I've pasted a simple ondraw on its header and it works:

ondrawscript @script
void main()
{
drawstring(80,210,2,"BIOS",1000);
}
  @end_script

But If I paste the same code on a type PLAYER, it doens't works

ondrawscript @script
void main()
{
drawstring(80,220,2,"TESTE",1000);
}
  @end_script

So maybe ondrawscript doesn't works for type PLAYER on the select screen?
Confirmed: I've used the same code on a type PLAYER and type NONE as ondrawscript. The code works for type NONE, but not for type PLAYER in select screen.
 
O Ilusionista said:
Some more info:

I have a type NONE entity on the screen called BIOS, and I've pasted a simple ondraw on its header and it works:

ondrawscript @script
void main()
{
drawstring(80,210,2,"BIOS",1000);
}
  @end_script

But If I paste the same code on a type PLAYER, it doens't works

ondrawscript @script
void main()
{
drawstring(80,220,2,"TESTE",1000);
}
  @end_script

So maybe ondrawscript doesn't works for type PLAYER on the select screen?
Confirmed: I've used the same code on a type PLAYER and type NONE as ondrawscript. The code works for type NONE, but not for type PLAYER in select screen.

O Ilusionista
Is there a way to disable the ondrawscript in the engine? Maybe msmalik681 or Damon Caskey can give a light for us, because it works in my game but I can't make it work in your Avengers game. I tried to change positions, layers, etc but no success.

Maybe some kind of "alwaysupdate" but only for ondrawscript...
 
Kratus not that I am aware of.

I had changed the way I will implement this - using an extra entity to get its parent data

Code:
void main()
{
void self = getlocalvar("self"); // get caller
void parent = getentityproperty(self, "parent"); // get parent
void type = getentityproperty(parent, "type");

if(type == openborconstant("TYPE_PLAYER")){drawstring(40, 135, 2, "TEST_PLAYER");}

        if(parent!=NULL()){ // is parent valid?
        void parMap = getentityproperty(parent, "map"); // get parent map
        void parName = getentityproperty(parent, "defaultmodel"); // get parent default name

        int x = getentityproperty(parent, "x");
        int y = getentityproperty(parent, "y");
        int z = getentityproperty(parent, "z"); 

        drawstring(x,z,2,parMap);
        drawstring(x,z-20,1,parName);

   }

}

It works perfectly - except for ONE thing:
I am using this at Captain America's wait animation, but it retrieves the first name on the select file as default name - Iron Fist.
kv69DEk.png


I've double checked it and Iron Fist doesn't have this code AT ALL...
 
The more I handle OpenBOR select screen, the more I hate it and the more I think its...strange, to say at least.

On the whole game, I can use this to retrieve the parent name:
Code:
        void parName = getentityproperty(parent, "name"); // get parent default name
But on the select screen, it returns the first name on the select.txt, for whatever reason!

Then I need to change to this:
Code:
        void parName = getentityproperty(parent, "model"); // get parent default name

Let me convert the talk to a non-coder language:

Let's say that we have a list of objects:
- CHAIR
- DESK
- PHONE

We have an object called PHONE and it has a second part called BATTERY.
• During the whole game, I can ask to phone "Hey, who is your parent?" and he reply "PHONE". "what is its name?" and he reply "PHONE".
• But during the select screen, if I ask "Hey, who is your parent?" and he reply "PHONE". But once I ask "what is its name?", he replies... CHAIR.

Don't get me wrong, I do like the engine a lot. But there are things like that which makes no sense AT ALL.
 
O Ilusionista
In the select screen I don't think you can get "entity" from player properties maybe because you have not selected your player yet. Try getting player properties instead.

int Map = getplayerproperty(0, "map");  // see if this returns the current map.

Edit: woops just checked and "map" is not a valid property maybe its "colourmap" here is a list:

enum playerproperty_enum
{
    _pp_colourmap,
    _pp_combokey,
    _pp_combostep,
    _pp_credits,
    _pp_disablekeys,
    _pp_ent,
    _pp_entity,
    _pp_hasplayed,
    _pp_hmapl,
    _pp_hmapu,
    _pp_inputtime,
    _pp_joining,
    _pp_keys,
    _pp_lives,
    _pp_mapcount,
    _pp_name,
    _pp_newkeys,
    _pp_numweapons,
    _pp_playkeys,
    _pp_releasekeys,
    _pp_score,
    _pp_spawnhealth,
    _pp_spawnmp,
    _pp_weapnum,
    _pp_weapon,
    _pp_the_end
};
 
msmalik681 Last night I was talking with Kratus and I managed to solve this.

Definitely, ondrawscript works differently in type PLAYER and type NONE in selectscreen.

We found that the code even works, but only if you put it in the first playable character that appears in models.txt - that is, the order that they appear in models.txt influences the code.

In my file, Iron Fist is the first to be uploaded, while Iron Man is the sixth on the list. If you try to get "defaultname", it will always return the name of the first character on the list - which is why it always returned "Iron Fist".

#players==============================================================
load Iron_Fist data/chars/ironfist/ironfist.txt
load Colossus data/chars/colossus/colossus.txt
load NightCrawler data/chars/ncrawler/ncrawler.txt
know Deadpool data/chars/deadpool/deadpool.txt

#------AVENGERS
load Captain_America data/chars/captain/captain.txt
load Iron_Man data/chars/ironman/ironman.txt

Another strange point is that, in selectscreen, you can only get playerindex 0 - if you try to get playerindex 1, it returns 0.

So if you want to validate whether P1 exists, you can't use the original post method (using getentityproperty), as it doesn't work. You can only get the name, which is not practical.

What was the solution I found?

I have an entity of type NONE, called BIOS, which is loaded by all players in the first frame of the "wait" animation using "summonframe". In it, I used a code to get the name and position of the parent and, from there, built all the logic.

And it was at that time that I discovered something curious: If you are with the character CAP AMERICA, that entity knows that his parent is Cap America. But if you switch to HULK on the selection screen, the parent of the entity becomes ... Hulk.

Here is the code I developed - I just put the first "case" because the rest is redundant.


Code:
void main()
{
void self = getlocalvar("self"); // get caller
void parent = getentityproperty(self, "parent"); // get parent

        if(parent!=NULL()){ // is parent valid?
        void parMap = getentityproperty(parent, "map"); // get parent map
        void parName = getentityproperty(parent, "model"); // get parent default name

        int x = getentityproperty(parent, "x"); // get parent X pos
        int z = getentityproperty(parent, "z"); // get parent Z pos

        switch(parName) { // check the character name

        case "Captain_America" : //=================================================
        if (parMap==1){
        char pName = "Bucky";
        int posX = x-(strwidth(pName,2)/2); // Center the text based on it's length
        drawstring(posX,z+7,1,pName);
        }
        else {
        char pName = "Normal";
        int posX = x-(strwidth(pName,2)/2); // Center the text based on it's length
        drawstring(posX,z+7,2,pName);
        }
        break;

}

The code in action:

En85Gm7XEAAMSfo


Thanks everyone
 
Sorry you had all the difficulty O Ilusionista. The select screen is indeed a strange animal, and believe it or not it was done that way intentionally. SX coded it to be as absolutely memory minimal as possible. This was back when OpenBOR was being ported to anything with a screen, and didn't have a sprite database yet.

Believe it or not, if someone wanted to, it wouldn't be nearly as hard as you think to code your own select screen. The native select works by swapping player models, and OpenBOR script can do that easily. I've gone through the engine select code and documented it so creators who are interested can read up and duplicate its functionality in game.

DC
 
O Ilusionista said:
Damon Caskey hey buddy, I know its not your fault.

The native select works by swapping player models,
That answers why you have to rely on "model" instead of "name".
O Ilusionista
Yes buddy, basically this is the base to change the desired character using up/down keys. But, I discovered that only changing the model is not enough, you need to change the player name before confirming the character selection and get out of the select screen. Making this, the engine will understand that you really changed the character.


Damon Caskey said:
Sorry you had all the difficulty O Ilusionista. The select screen is indeed a strange animal, and believe it or not it was done that way intentionally. SX coded it to be as absolutely memory minimal as possible. This was back when OpenBOR was being ported to anything with a screen, and didn't have a sprite database yet.

Believe it or not, if someone wanted to, it wouldn't be nearly as hard as you think to code your own select screen. The native select works by swapping player models, and OpenBOR script can do that easily. I've gone through the engine select code and documented it so creators who are interested can read up and duplicate its functionality in game.

DC
Damon Caskey
Don't worry man, we can always develop scripted solutions for any feature we want :)

Only for knowledge, I will post below some of my last tests.

In fact it's not too hard to duplicate how the select screen works. The bad part is about accessing some player/entity properties, even if some basics like "playerindex". Some of them will not work, others will work in a different way just as Ilu showed.

Below is an example of what I need to access the default engine spawned model at the select screen:
Code:
//CAUTION!!! THE LINES BELOW ARE VERY IMPORTANT BECAUSE IS THE ONLY WAY TO GET ALL PREVIEW MODELS SPAWNED BY THE ENGINE IN THE SELECT SCREEN!
	//THIS CODE WILL SAVE THE DEFAULT PREVIEW MODELS IN A VARIABLE AND ALLOWS TO EDIT SOME PROPERTIES
	//THE ONLY WAY TO DEFINE EVERY INDEX IS BY GETTING THE X POSITION AT THE SELECT SCREEN, PLEASE CHECK EACH POSITION IN THE LEVELS.TXT FILE
	//NEED TO REMEMBER THAT THE ENTITIES IN THE SELECT SCREEN WILL NOT ALLOW YOU TO GET SOME PROPERTIES BY REGULAR METHODS, LIKE "PLAYERINDEX"
	void type = getentityproperty(self, "type");
	int xPos  = getentityproperty(self, "x");
	int index;

	if(xPos == 59){ index = 0;}else
	if(xPos == 179){index = 1;}else
	if(xPos == 299){index = 2;}else
	if(xPos == 419){index = 3;}

	if(type != openborconstant("TYPE_NPC")){setglobalvar("defaultEntity"+index, self);}

This is needed because the select screen works based on the character's "waiting/select" animations (the "waiting" is only accessible by the number "59"). Once you have accessed the entity, you can manage the charater's animation/frame and then you can apply the effects you want.

For example, to control the select screen duration, you need to freeze the "select" animation in any frame before it ends, and then you can create a "second-step" process, waiting for the player to change the palette. Once you select the palette, you need to access the entity again to do a "updateframe" and then finish the "select" animation.

Another thing, once you access the preview model you will haven't full control over it and some glitches can happen. To solve this problem you need to spawn a clone entity and hide the default one with a very high X/Y position number in the levels.txt using the function "p#smenu".
So, the default one will not appear on the screen and will not show the glitches. In fact the default entity will act only like a "backend" feature, and the clone entity will work like a "frontend" feature.

A last thing, the clone entity needs to have your type changed, otherwise it will remain "type player" and cause confusion while some properties are changed. This is why in the last line I used the following code:
Code:
if(type != openborconstant("TYPE_NPC")){setglobalvar("defaultEntity"+index, self);}

When the custom select screen is ready, I will post the full code if someone wants to know how it works  ;)
 
Damon Caskey said:
Believe it or not, if someone wanted to, it wouldn't be nearly as hard as you think to code your own select screen. The native select works by swapping player models, and OpenBOR script can do that easily.

I wanted to create custom select screen myself. I know about weapon model swapping script but the problem with that is it's not permanent, meaning that after changing level player's model will revert to original model.
Unless I can change model directly but last time I tried, it doesn't work :(.
 
Bloodbane
According to my tests, if you change the player property "name" the engine will understand that you really changed your character in the select screen. After I applied it to my custom select screen, I played a lot of times with no model reversion.

The player property "name" is one of a few functions that works there. Thanks to that now I can now change characters using up/down keys.

Code:
changeplayerproperty(index, "name");

https://www.youtube.com/watch?v=4eoi6Z2DRU8
 
Thanks for the tip  ;D

[couple minutes later]

Tested that in levels and changing model with that script doesn't work. Looks like it can only be done in select screen.
 
Bloodbane yeah, during stages it won't work. You will need to use "model" instead.

changeplayerproperty(playerindex, propname, value)

getmodelproperty/changemodelproperty are still undocumented
 
O Ilusionista said:
changeplayerproperty(playerindex, propname, value)

getmodelproperty/changemodelproperty are still undocumented

It's probably better they stay that way. It's one of the main things I'm working on and the finished version will be completely different.

DC
 
After more tests, combining model change and player's name change works.

Code:
anim freespecial2
@script
    if(frame==2){
      void self = getlocalvar("self");
      int PIndex = getentityproperty(self,"playerindex");

      changeplayerproperty(PIndex,"name","Donovan");
      changeentityproperty(self, "model", "Donovan", 1);
      changeentityproperty(self, "name", "Donovan");
      setidle(self, openborconstant("ANI_IDLE"));
    }
@end_script
...

After changing to Donovan and dies, player will start as Donovan even though player starts as other playable before.

With this, stable custom select screen is doable!  8)
 
Bloodbane said:
After more tests, combining model change and player's name change works.

Code:
anim freespecial2
@script
    if(frame==2){
      void self = getlocalvar("self");
      int PIndex = getentityproperty(self,"playerindex");

      changeplayerproperty(PIndex,"name","Donovan");
      changeentityproperty(self, "model", "Donovan", 1);
      changeentityproperty(self, "name", "Donovan");
      setidle(self, openborconstant("ANI_IDLE"));
    }
@end_script
...

After changing to Donovan and dies, player will start as Donovan even though player starts as other playable before.

With this, stable custom select screen is doable!  8)
Yes, the custom select screen work like this way. In my game, the model is changed if up/down/left/right keys are pressed, and the player name is changed after any attack key is pressed to confirm.

EDIT: I can confirm Bloodbanes's tests, like I said
Kratus said:
O Ilusionista said:
Damon Caskey hey buddy, I know its not your fault.

The native select works by swapping player models,
That answers why you have to rely on "model" instead of "name".
O Ilusionista
Yes buddy, basically this is the base to change the desired character using up/down keys. But, I discovered that only changing the model is not enough, you need to change the player name before confirming the character selection and get out of the select screen. Making this, the engine will understand that you really changed the character.
 
Back
Top Bottom