Ask about ACS, DECORATE, ZScript, or any other scripting questions here!
Moderator:GZDoom Developers
Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.
Please bear in mind that the people helping you do not automatically know how much you know. You may be asked to upload your project file to look at. Don't be afraid to ask questions about what things mean, but also please be patient with the people trying to help you. (And helpers, please be patient with the person you're trying to help!)
9 posts
• Page 1 of 1
yum13241
Posts: 853
Joined: Mon May 10, 2021 8:08 pm
Preferred Pronouns: He/Him
Operating System Version (Optional): EndeavorOS (basically Arch)
Graphics Processor: Intel with Vulkan/Metal Support
I want to draw a string (from LANGUAGE) concatenated to a number a weapon based on a weapon's upgrade level, and this is an int called upgradelevel.
I want to draw this in the middle of the weapon (so 0,16 I believe), so the user can easily tell what upgrade they have on. HudMessage is ACS only, and I don't want to use dummy inventory items to display the upgrades in SBARINFO, which defeats the point of using variables. (ZScript HUDs are hard)
Without overriding the HUD, the only way I am aware of is to use RenderUnderlay/Overlay event handler.
Admittedly I am not good at this, so I am sure someone else could do this way better, but here's a working example:
Class TestEventHandler : EventHandler{
Override void RenderUnderlay(RenderEvent e){
If(players[consoleplayer].readyweapon is "PlasmaRifle"){ //If the currently selected weapon is a plasma rifle
int offset;
If(CVar.FindCVar("screenblocks").GetInt()==10){offset=32;} //Set the offset to 32 if the statusbar is enabled
Vector2 pos = Screen.VirtualToRealCoords((160,180-offset),(320,200),(320,200)); //Get real coordinates where to draw, in this case we want to draw in position 160,180
double scale = Screen.GetHeight()/200.0; //Get the scale so the string isn't drawn small
Screen.DrawText("bigfont",0,pos.x,pos.y,"A",DTA_ScaleX,scale,DTA_ScaleY,scale); //Draw an "A" in specified location with the BIGFONT
}
}
}
Thanks, but the "A" is off center. Also, I'm trying to display:
1. An int called upgradelevelchosen.
2. A "/" character.
3. An int called upgradelevel.
EX: 1/2
I only want to display these if upgradelevel > 1.
The problem is I cannot access the variable at all. I've tried player[consoleplayer].readyweapon.upgradelevel to no avail.
The weapon is called MWSPlasmaGun. These ints are public. If you need the weapon code I'll give it to you but I don't think that's the case.
Override void RenderUnderlay(RenderEvent e){
let playe = players[consoleplayer];
If(playe.readyweapon is "MWSPlasmaGun"){
let weap = MWSPlasmaGun(playe.mo.FindInventory("MWSPlasmaGun")); //Cast the weapon to this variable
If(!weap||weap.upgradelevel<=1){Return;} //Break the function if the weapon wasn't found or if the variable is lower than needed
string toprint = String.Format("%i/%i",weap.upgradelevelchosen,weap.upgradelevel); //This is where you can access your weapon's variables to set what you want to draw
double half = Font.GetFont("bigfont").StringWidth(toprint)/2; //This gets half the width of the string to center it, the rest is as before.
int offset;
If(CVar.FindCVar("screenblocks").GetInt()==10){offset=32;}
Vector2 pos = Screen.VirtualToRealCoords((160-half,180-offset),(320,200),(320,200));
double scale = Screen.GetHeight()/200.0;
Screen.DrawText("bigfont",0,pos.x,pos.y,toprint,DTA_ScaleX,scale,DTA_ScaleY,scale);
}
}
}
action void A_FastRaise(void)
{
// this is a leftover from when fast weapon switching was tied to responsive weapons being enabled.
A_Raise(MWS_switchspeed);
action void A_MoveOverlay(double x = 0, double y = 32, int flags = 0, int layer = PSP_WEAPON)
{
// introduced to avoid typing WOF_ADD everywhere. WOF_ADD implies WOF_INTERPOLATE.
A_OverlayOffset(x, y, WOF_ADD|flags, layer);
}
action void A_MoveOverlayAbs(double x = 0, double y= 32, int flags = 0, int layer = PSP_WEAPON)
{
// some offsets are absolute offsets, so to avoid typing WOF_INTERPOLATE all the time i use this.
A_OverlayOffset(x, y, WOF_INTERPOLATE|flags, layer);
}
The first issue is that the upgradelevel variable will never go above 1, meaning it will always pass the first check and return.
This is the correct logic for the check: if(!weap || weap.upgradelevel < 1) return;
And the second issue is that you forgot one 0 in the third set of coordinates, you had (320,20) instead of (320,200): Vector2 pos = Screen.VirtualToRealCoords((160-half,180-offset),(320,200),(320,200));