appendevent EVENT_SPAWN { // Ignore enemies disabled due to skill level ife sprite[].xrepeat 0 break switch sprite[].picnum { // Fixup sprite sizes
EDuke32 Scripting "CON coding help"
#3481 Posted 15 April 2024 - 05:52 AM
Their lotag might be clobbered at that point, so I wouldn't necessarily trust it either. I ran into this exact same issue very recently and I solved it by checking the xrepeat and bailing out.
#3482 Posted 15 April 2024 - 11:04 AM
Reaper_Man, on 15 April 2024 - 05:52 AM, said:
Their lotag might be clobbered at that point, so I wouldn't necessarily trust it either. I ran into this exact same issue very recently and I solved it by checking the xrepeat and bailing out.
appendevent EVENT_SPAWN { // Ignore enemies disabled due to skill level ife sprite[].xrepeat 0 break switch sprite[].picnum { // Fixup sprite sizes
Yes, if the xrepeat is 4 or less, then don't fuck with them. If any mapper actually put a tiny enemy in the map that's on them.
Also, there's no reason why this particular event needs to be used for this purpose at all. EVENT_LOADACTOR could be used instead and then it's a non-issue.
#3483 Posted 15 April 2024 - 11:26 AM
You mean when using EVENT_LOADACTOR I can use my original code without any check for player skill or xrepeat?
#3484 Posted 15 April 2024 - 11:42 AM
NightFright, on 15 April 2024 - 11:26 AM, said:
You mean when using EVENT_LOADACTOR I can use my original code without any check for player skill or xrepeat?
Yes. The one thing I'm not 100% sure about is whether spriteflags can be applied to individual sprites that early, or whether they get reset after that. But certainly size and cstat can be set there. But I also don't think spriteflags 8192 should be used for this purpose -- my memory is that in recent edukes smooth movement is now applied by default, and in fact I had an issue at one point where I was accidentally xoring it and turning it off because I didn't know about that change.
#3485 Posted 15 April 2024 - 12:24 PM
You are right. Spriteflags 8192 makes no difference in EDuke32 at this point, it seems. Tank moves just as before even without the flag being set manually. What about cactor? Would that work in LOADACTOR as well?
#3486 Posted 15 April 2024 - 12:37 PM
Yes, cactor just changes picnum. The main reason to use EVENT_SPAWN would be to catch the sprites that are spawned in later (such as from RESPAWN) and aren't present in the map at the start.
EDIT: I realize that could be misinterpreted. I'm not saying that EVENT_SPAWN only runs when sprites are spawned in during gameplay. Sprites placed in mapster are "spawned" when they are initialized which is before gameplay starts, but it is after certain things happen to them like the hardcoded size zeroing on enemies with lotag > difficulty. My point was that you don't *need* to use EVENT_SPAWN on sprites already present before gameplay starts because you can use LOADACTOR instead.
EDIT: I realize that could be misinterpreted. I'm not saying that EVENT_SPAWN only runs when sprites are spawned in during gameplay. Sprites placed in mapster are "spawned" when they are initialized which is before gameplay starts, but it is after certain things happen to them like the hardcoded size zeroing on enemies with lotag > difficulty. My point was that you don't *need* to use EVENT_SPAWN on sprites already present before gameplay starts because you can use LOADACTOR instead.
This post has been edited by Danukem: 15 April 2024 - 12:45 PM
#3487 Posted 15 April 2024 - 12:45 PM
Outstanding. Then I'll just remove the spriteflags line, change the whole event to LOADACTOR and call it a day. Dunno how to check whether clipdist works like that as well, but of all adjustments it's the least important one.
Thanks a lot again, Dan. You've been a great help. Like always!
Thanks a lot again, Dan. You've been a great help. Like always!
#3488 Posted 15 April 2024 - 01:13 PM
NightFright, on 15 April 2024 - 12:45 PM, said:
Outstanding. Then I'll just remove the spriteflags line, change the whole event to LOADACTOR and call it a day. Dunno how to check whether clipdist works like that as well, but of all adjustments it's the least important one.
Thanks a lot again, Dan. You've been a great help. Like always!
Thanks a lot again, Dan. You've been a great help. Like always!
clipdist is one of the sprite members and setting it in LOADACTOR surely does set it -- question is does it then get reset to the default number later on when the sprite is initialized for gameplay. My guess is it probably does.
in the newbeast code, you could just grab clipdist into a var and put it in the log during gameplay. If it's 64, then the code worked, if it's 80 then it didn't. Not sure why clipdist is being changed though, the default clipdist isn't a bug. The lower one is more accurate for certain things like rocket hits but the higher one probably has some situations where it is better too.
#3489 Posted 16 April 2024 - 06:23 AM
Ok, another issue. I'm unable to get this rather simple code (also taken from Darkus' con fixes) working. It's just supposed to fix the health bug of the miniboss versions of BOSS2 and BOSS3:
When testing this in a custom map, in this case "Chinatown" (1hk.map), it doesn't work. The miniboss still dies if you cough at him (it's a BOSS3 with pal4). Any ideas?
appendevent EVENT_SPAWN switch sprite[].picnum case BOSS2 case BOSS3 ifg sprite[].pal 0 strength BOSS1PALSTRENGTH break endswitch endevent
When testing this in a custom map, in this case "Chinatown" (1hk.map), it doesn't work. The miniboss still dies if you cough at him (it's a BOSS3 with pal4). Any ideas?
#3490 Posted 16 April 2024 - 07:02 AM
Assuming this is using the rest of the default GAME.CON without modifications, BOSS3 is scripted to set its strength to 1 here in this block in "state boss3code":
All actor code runs after EVENT_SPAWN, and any other on-spawn type events, would have executed. So technically your code does change it to BOSS1PALSTRENGTH, it just gets changed back to 1 later on.
The easiest fix here is just to edit that code block to change "strength 1" to "strength BOSS1PALSTRENGTH". However I'm assuming you are not wanting to edit the default GAME.CON file, so in that case you'll have to come up with another method.
What I would do is have some a per-actor gamevar to track the fixup, and check for it in EVENT_GAME. Something like:
This may be the way wrong approach though, I'm not sure if there's some other event that might be better suited. EVENT_GAME isn't great because it runs for every sprite, every frame, so it can easily get out of hand if you aren't careful or use it all over the place haphazardly.
Now that I think about it and look at the Boss scripts, it looks like the "ifai 0" check could safely be overridden. So you would move the behaviors that are checked/set in the actor code into an EVENT_SPAWN block, something like:
That maybe would work.
ifai 0 { ifspritepal 0 ai AIBOSS3RUNENEMY else { strength 1 ai AIBOSS3LOBENEMY } }
All actor code runs after EVENT_SPAWN, and any other on-spawn type events, would have executed. So technically your code does change it to BOSS1PALSTRENGTH, it just gets changed back to 1 later on.
The easiest fix here is just to edit that code block to change "strength 1" to "strength BOSS1PALSTRENGTH". However I'm assuming you are not wanting to edit the default GAME.CON file, so in that case you'll have to come up with another method.
What I would do is have some a per-actor gamevar to track the fixup, and check for it in EVENT_GAME. Something like:
var BOSSFIXUP 0 2 appendevent EVENT_GAME { // Check this first because EVENT_GAME is expensive ifn BOSSFIXUP 0 break // Make all sprites ignore subsequent checks set BOSSFIXUP 1 switch sprite[].picnum { case BOSS2 case BOSS3 ifn sprite[].pal 0 strength BOSS1PALSTRENGTH break } endswitch } endevent
This may be the way wrong approach though, I'm not sure if there's some other event that might be better suited. EVENT_GAME isn't great because it runs for every sprite, every frame, so it can easily get out of hand if you aren't careful or use it all over the place haphazardly.
Now that I think about it and look at the Boss scripts, it looks like the "ifai 0" check could safely be overridden. So you would move the behaviors that are checked/set in the actor code into an EVENT_SPAWN block, something like:
appendevent EVENT_SPAWN { ifn sprite[].pal 0 { ife sprite[].picnum BOSS2 { strength BOSS1PALSTRENGTH sound BOS2_ATTACK ai AIBOSS2SHOOTENEMY } ife sprite[].picnum BOSS3 { strength BOSS1PALSTRENGTH ai AIBOSS3LOBENEMY } } } endevent
That maybe would work.
This post has been edited by Reaper_Man: 16 April 2024 - 07:23 AM
#3491 Posted 16 April 2024 - 07:22 AM
OK, it seems that your second approach did the trick. I used this and it works in the custom map:
appendevent EVENT_SPAWN switch sprite[].picnum case BOSS2 ifn sprite[].pal 0 { strength BOSS1PALSTRENGTH sound BOS2_ATTACK ai AIBOSS2SHOOTENEMY } case BOSS3 ifn sprite[].pal 0 { strength BOSS1PALSTRENGTH ai AIBOSS3LOBENEMY } break endswitch endevent
#3492 Posted 16 April 2024 - 07:29 AM
FWIW the reason I did the pal check first is to process less code in more circumstances. Doing the check inside the switch still has every spawned sprite go through the switch. There's never an instance where this code block should run for a pal 0 sprite, so you can save some CPU checking that condition first.
Also in this instance you aren't getting any benefit from using a switch over a standard if statement, switch blocks are useful when multiple cases share identical code. Not that you can't or shouldn't use it here, or that there's anything wrong with using it here, but that's why I moved from a switch block to an if statement.
Also in this instance you aren't getting any benefit from using a switch over a standard if statement, switch blocks are useful when multiple cases share identical code. Not that you can't or shouldn't use it here, or that there's anything wrong with using it here, but that's why I moved from a switch block to an if statement.
#3493 Posted 16 April 2024 - 07:42 AM
Makes sense. I will adjust that. After all, encountering pal 0 versions of these bosses is happening far more often than any other, so this code should be skipped most of the time. Thanks a lot for the insight!
#3494 Posted 16 April 2024 - 05:52 PM
Using screen_size is there a way to check and see if the last version of the minihud is being used? Checking to see if screen_size equals 4 includes both versions of the minihud and not just the last version that you select before you remove the HUD altogether. I only want to make changes to the second version of the minihud.
This post has been edited by VGames: 16 April 2024 - 05:52 PM
#3495 Posted 16 April 2024 - 08:28 PM
VGames, on 16 April 2024 - 05:52 PM, said:
Using screen_size is there a way to check and see if the last version of the minihud is being used? Checking to see if screen_size equals 4 includes both versions of the minihud and not just the last version that you select before you remove the HUD altogether. I only want to make changes to the second version of the minihud.
https://wiki.eduke32.com/wiki/Althud
#3496 Posted 16 April 2024 - 09:18 PM
@VGames
If it's about the EDuke32 mini HUD, it should be something like
If it's about the EDuke32 mini HUD, it should be something like
ife userdef[].screen_size 4 ife userdef[].althud 1
#3497 Posted 17 April 2024 - 04:34 AM
Ah very nice. Thank u for the heads up. I knew I was missing something.
#3498 Posted 19 April 2024 - 07:01 AM
I have big blast rings that get created when a nuke goes off and I noticed that when they hit a wall they sometimes get all scrunched up and fail to keep their circular shape. They become more oval in shape sometimes. Is there some way to keep this from happening? I feel like there’s a setting I’m not using to make them clip through walls and not get affected by them.
#3499 Posted 29 April 2024 - 11:36 AM
Is there a method to check for how long the player has been shrunk? I'd like to turn that into a (visible) countdown (in seconds), but so far I haven't found a construct in the EDuke32 wiki which would allow one to tap into that.
#3500 Posted 29 April 2024 - 12:50 PM
It might be the player's count, assuming the player's move is reset when shrunk. But for easy access during display, I would just make a var for it and have it increment when the player is shrunk, zero otherwise. When the var is nonzero you display it in the hud.
#3501 Posted 29 April 2024 - 01:31 PM
I guess the same goes for frozen state. The thing is I want the counter to start at max duration and have it reach 0 when frozen/shrunk time ends.
#3502 Posted 29 April 2024 - 01:47 PM
Then wouldn't you just take the max count (once you know what it is) and subtract the current count from it to get your number?
I'm sure I remember seeing SHRUNKDONECOUNT or FROZENCOUNT somewhere, but perhaps it was just another mod that wanted to keep track of it for something. Perhaps it was in USER.CON.
I'm sure I remember seeing SHRUNKDONECOUNT or FROZENCOUNT somewhere, but perhaps it was just another mod that wanted to keep track of it for something. Perhaps it was in USER.CON.
#3503 Posted 29 April 2024 - 03:18 PM
THAWTIME is a vanilla define used to check the PFROZEN actioncount. SHRUNKDONECOUNT is a vanilla define used to check the APLAYER actor counter. The player being frozen behavior is handled with an action, the player being shrunk behavior is just a counter, although a move speed is used as a sort of "variable".
What all that means is you can access the player's current action, actioncount, named movement, and counter via the htg_t array, and use this to build a sort of timer. The only part of this that is missing is getting the animation speed of an animation, although in this case PFROZEN has no animation speed, so it's equal to the gametic counter.
So to build a frozen time remaining, you'd subtract the current .htg_t 2 from THAWTIME and that's how many gametics are remaining. The shrunk timer should be the same, except you'd use .htg_t 0 to get the current counter. Divide by 30 to get the real seconds to gametic conversion. If you want to get fancy you can mod the .htg_t 2 value by 30 to get milliseconds.
Here's an untested example based on some other code I have, no idea if this will work off the rip but should put you in the right direction.
What all that means is you can access the player's current action, actioncount, named movement, and counter via the htg_t array, and use this to build a sort of timer. The only part of this that is missing is getting the animation speed of an animation, although in this case PFROZEN has no animation speed, so it's equal to the gametic counter.
So to build a frozen time remaining, you'd subtract the current .htg_t 2 from THAWTIME and that's how many gametics are remaining. The shrunk timer should be the same, except you'd use .htg_t 0 to get the current counter. Divide by 30 to get the real seconds to gametic conversion. If you want to get fancy you can mod the .htg_t 2 value by 30 to get milliseconds.
Here's an untested example based on some other code I have, no idea if this will work off the rip but should put you in the right direction.
appendevent EVENT_DISPLAYREST { ifaction PFROZEN { set UI_ZOOM 24576 set UI_ORIENTATION 2 set UI_FLAGS 10 set ACTORTEMP THAWTIME sub ACTORTEMP sprite[].htg_t 2 // The player's current actioncount set ACTORTEMP2 ACTORTEMP div ACTORTEMP 30 mod ACTORTEMP2 30 // Process milliseconds redefinequote 253 %d redefinequote 254 00 qsprintf 253 253 ACTORTEMP2 qstrlen ACTORCHECK 253 set ACTORCHECK2 2 sub ACTORCHECK2 ACTORCHECK qstrncat 253 254 ACTORCHECK2 redefinequote 254 UNTHAWING IN %d.%s qsprintf 254 254 ACTORTEMP 253 screentext BIGALPHANUM 160 20 UI_ZOOM 0 0 254 0 1 UI_ORIENTATION 0 BIGALPHA_XSPACE BIGALPHA_YLINE BIGALPHA_XBETWEEN 0 UI_FLAGS 0 0 xdim ydim } } endevent
#3504 Posted 30 April 2024 - 02:44 AM
Ingenious! Actually I didn't need the display to be more precise than full seconds and it was rather for a HUD display, so the whole lower part about messages wasn't necessary. Anyway, you definitely provided all the hints I had been looking for. Got it working already the way I wanted, so thanks a lot!
#3505 Posted 01 May 2024 - 12:49 PM
Additional question:
I've found that my "shrunk state display" has a slight delay and will only be active once the player has finished shrinking. I'm operating with ifp pshrunk. Would the following be a valid/efficient approach for a more instantaneous effect? (Not that it'd be absolutely necessary, but out of curiosity.)
ifl sprite[].yrepeat 36
Assuming default player dimensions of 42 36. I dunno if there's any mod out there which changes player size, which might be the only possible weakness of such an approach. Guess I could do a geta[].yrepeat and store it in a variable to catch such cases, but I might be overdoing it.
I've found that my "shrunk state display" has a slight delay and will only be active once the player has finished shrinking. I'm operating with ifp pshrunk. Would the following be a valid/efficient approach for a more instantaneous effect? (Not that it'd be absolutely necessary, but out of curiosity.)
ifl sprite[].yrepeat 36
Assuming default player dimensions of 42 36. I dunno if there's any mod out there which changes player size, which might be the only possible weakness of such an approach. Guess I could do a geta[].yrepeat and store it in a variable to catch such cases, but I might be overdoing it.
#3506 Posted 01 May 2024 - 01:22 PM
The APLAYER actor checks "ifmove PSHRINKING" to initiate the shrunk effect. Looking in the source code real quick, it looks like "ifp pshrunk" only returns true after the APLAYER xrepeat is less than 32. Checking the xrepeat would work, or you can just check "ifmove PSHRINKING" like the APLAYER actor does and that would mimic the vanilla behaviors.
#3508 Posted 01 May 2024 - 01:48 PM
I think xrepeat and yrepeat don't give you the realtime values you see as it shrinks or expands until after the sizing stops
#3509 Posted 02 May 2024 - 03:38 PM
I just did some tests and it does appear "sizeto" does immediately make the change. "ifp pshrunk" won't trigger immediately because it checks for the xrepeat, which takes half a second or so to "sizeto" down past, and same for on the way back up. You can test for yourself:
NightFright - Depending on what you want the timer to show exactly, you may want to stick with "ifp pshrunk" or otherwise checking the xrepeat. Specifically because the player can technically still be squished by being in a small space while they are going back to normal size. So if your timer is for when you are safe again after being shrunk, it's not until you are fully back to normal size, or very close to it at least.
Spoiler
NightFright - Depending on what you want the timer to show exactly, you may want to stick with "ifp pshrunk" or otherwise checking the xrepeat. Specifically because the player can technically still be squished by being in a small space while they are going back to normal size. So if your timer is for when you are safe again after being shrunk, it's not until you are fully back to normal size, or very close to it at least.
This post has been edited by Reaper_Man: 02 May 2024 - 03:57 PM
#3510 Posted 02 May 2024 - 09:12 PM
Well, as long as there are no mods which mess with player size... If there's none which changes that, guess I could use ifl sprite[].xrepeat 42. While testing though, it seems the check pretty much behaves like ifmove PSHRINKING, at least for what I intend to do with it (show a HUD overlay tile for as long as player is shrunk), so it apparently does not come with any benefit. At least not for the purpose I need it, that is.
*UPDATE*
OK, maybe the xrepeat solution is useful after all. What I'm still missing is an abort condition for a state. What it's basically supposed to do is to abort drawing some HUD graphics if the player dies while being frozen. The trick is I cannot just use ifp pdead since technically, the player is dead when frozen (0 HP), but gets "revived" with 1 HP if not hit. My current approach is:
ifp pdead
ifn sprite[].pal 1
break
However, not sure how this would behave if player dies in a sector with blue light (which is also pal 1, unless I'm mistaken). It should be something fool-proof.
*UPDATE*
OK, maybe the xrepeat solution is useful after all. What I'm still missing is an abort condition for a state. What it's basically supposed to do is to abort drawing some HUD graphics if the player dies while being frozen. The trick is I cannot just use ifp pdead since technically, the player is dead when frozen (0 HP), but gets "revived" with 1 HP if not hit. My current approach is:
ifp pdead
ifn sprite[].pal 1
break
However, not sure how this would behave if player dies in a sector with blue light (which is also pal 1, unless I'm mistaken). It should be something fool-proof.