
EDuke32 Scripting "CON coding help"
#2993 Posted 16 September 2022 - 12:18 PM
#2994 Posted 16 September 2022 - 02:40 PM
#2995 Posted 16 September 2022 - 07:55 PM
MC84, on 16 September 2022 - 02:40 PM, said:
Sure, as long as you know what you are doing it should be fine. If you are worried about it, just make a copy of the tile to a different tile number and use one of them as the actor and the other as the non-actor.
#2996 Posted 23 September 2022 - 03:56 PM
action BLOODDRIP_FRAMES 0 1 1 1 1 actor REDBLOODDRIP 0 BLOODDRIP_FRAMES setactor[THISACTOR].xrepeat 20 setactor[THISACTOR].yrepeat 20 seta[].htflags 2048 fall state thisactor_getzrange // <---------- THIS IS WHERE I'M CALLING TO THE STATE DEFINED IN THE GETZRANGE.CON FILE iffloordistl 2 { ifge tagz_florhit 16384 { sub tagz_florhit 16384 ifrnd 128 { setactor[THISACTOR].picnum REDSPLAT1 cstat 4 sound BLOODSPLAT1SFX } else { setactor[THISACTOR].picnum REDSPLAT2 sound BLOODSPLAT2SFX } setactor[THISACTOR].xrepeat 6 setactor[THISACTOR].yrepeat 6 cstat 32 insertspriteq fall } } enda
No matter what I try the splats either appear on the player's head or an actor or they don't appear at all on the floor. Please tell me what I'm doing wrong. I think I'm completely lost. I need the blood drops to only splat on floors and not any other actor.
GETZRANGE.CON code:
// In gamevar tagz_z 0 0 // Temp gamevar tagz_cstat 0 0 // Out gamevar tagz_ceilz 0 0 gamevar tagz_ceilhit 0 0 gamevar tagz_florz 0 0 gamevar tagz_florhit 0 0 // ZOFFSET in the EDuke32 source. define TAGZ_ZOFFSET 256 // In the EDuke32 source, the <walldist> passed to VM_GetZRange(). define TAGZ_WALLDIST 127 gamevar check_count 0 2 // Updates the current actor's actor[].floorz and actor[].ceilngz members in // the same way A_GetZRange() does. defstate thisactor_getzrange ifl check_count 1 { set tagz_z sprite[].z, sub tagz_z TAGZ_ZOFFSET // Back up and clear cstat. set tagz_cstat sprite[].cstat seta[].cstat 0 getzrange sprite[].x sprite[].y tagz_z sprite[].sectnum /*out:*/ tagz_ceilz tagz_ceilhit tagz_florz tagz_florhit /*in:*/ TAGZ_WALLDIST CLIPMASK0 // Restore cstat. seta[].cstat tagz_cstat // Set actor[] members for the current actor. seta[].htceilingz tagz_ceilz seta[].htfloorz tagz_florz set check_count 5 } else sub check_count 1 ends
This post has been edited by VGames: 23 September 2022 - 03:58 PM
#2997 Posted 23 September 2022 - 05:41 PM
#2998 Posted 23 September 2022 - 10:02 PM
Reaper_Man, on 23 September 2022 - 05:41 PM, said:
Yes, but movesprite moves the sprite. I assume he wants his sprite to move only using the fall command. Otherwise, yeah, if he wants to make the sprite fall by putting a positive value on the z velocity parameter in the movesprite command, then he could use that. He would still need to decode the hit sprite in the same way he needs to for getzrange though, so I don't think it is any easier.
Anyway, here is code that should work for getzrange:
gamevar tempvar 0 0 gamevar floorz 0 0 gamevar floorhit 0 0
getzrange sprite[].x sprite[].y sprite[].z sprite[].sectnum tempvar tempvar floorz floorhit 256 CLIPMASK0 sub floorz sprite[].z ifl floorz 12288 ifge floorhit 49152 { sub floorhit 49152 ife floorhit player[].i killit }
I think that's all there is to it. You can use the same var to receive most of the data because the only ones you actually care about are <floorz> and <floorhit> returns. What that code does is check what the sprite would hit below it in a 256 build unit radius. If that thing is the player sprite and the base of the player sprite is < 12288 z units below the sprite doing the check, the sprite deletes itself.
#2999 Posted 24 September 2022 - 09:33 AM
Danukem, on 23 September 2022 - 10:02 PM, said:
Anyway, here is code that should work for getzrange:
gamevar tempvar 0 0 gamevar floorz 0 0 gamevar floorhit 0 0
getzrange sprite[].x sprite[].y sprite[].z sprite[].sectnum tempvar tempvar floorz floorhit 256 CLIPMASK0 sub floorz sprite[].z ifl floorz 12288 ifge floorhit 49152 { sub floorhit 49152 ife floorhit player[].i killit }
I think that's all there is to it. You can use the same var to receive most of the data because the only ones you actually care about are <floorz> and <floorhit> returns. What that code does is check what the sprite would hit below it in a 256 build unit radius. If that thing is the player sprite and the base of the player sprite is < 12288 z units below the sprite doing the check, the sprite deletes itself.
Wow thanks a lot. I’ll put this to use and see what I can do with it.
#3000 Posted 24 September 2022 - 10:27 AM
This post has been edited by VGames: 24 September 2022 - 10:41 AM
#3001 Posted 28 September 2022 - 06:17 AM
#3002 Posted 28 September 2022 - 06:42 AM
You could also check for the sprite being deleted during EVENT_KILLIT and stop it there, although that may have other unintended effects if it still exists in the sprite queue after the deletion attempt (I think, never tested/tried/looked in the source for this).
#3003 Posted 28 September 2022 - 11:50 AM
#3004 Posted 28 September 2022 - 12:39 PM
Reaper_Man, on 28 September 2022 - 06:42 AM, said:
This did the trick. Thanks for the help.
#3005 Posted 28 September 2022 - 01:02 PM
auto &deleteSpriteNum = SpriteDeletionQueue[g_spriteDeleteQueuePos]; if (deleteSpriteNum >= 0 && actor[deleteSpriteNum].flags & SFLAG_QUEUEDFORDELETE) A_DeleteSprite(deleteSpriteNum); deleteSpriteNum = spriteNum; actor[spriteNum].flags |= SFLAG_QUEUEDFORDELETE; g_spriteDeleteQueuePos = (g_spriteDeleteQueuePos+1)%g_deleteQueueSize;
This might cause weird behaviors when the queue is full, since the sprite ID is technically still in the SpriteDeletionQueue[] array. But removing the flag should stop it from being deleted. It also should be safe (or safer) to prevent it in EVENT_KILLIT, since that happens in A_DeleteSprite() and the sprite ID would be removed from the deletion queue array at that time. I'd still remove the flag at that time to be safe.
So all of that having been said - I'd agree, the safer method is to spawn your own sprite as a decal, kill off the original, and then manage your decal outside the internal deletion queue. It seems like you could get the deletion queue out of whack or misaligned and cause weird behaviors, or at worst a Too Many Sprites crash.
#3006 Posted 28 September 2022 - 01:15 PM
In this case what I would suggest is having the regular decal spawn the new actor decal, which would be a copy of it with the same properties applied (cstat, size, etc.) Then have the regular decal use cstator 32768. The regular decal will still be there until it deletes from the queue, but will never be seen or heard from again.
#3007 Posted 28 September 2022 - 03:01 PM
On the subject, I took a look at insertspriteq and all it does is call A_AddToDeleteQueue() like hardcoded actors. As shown above, this adds the SFLAG_QUEUEDFORDELETE flag to the sprite, but the actual deletion queue array is where, how, and why sprites get deleted. Simply having that flag isn't enough, and in fact it seems to only exist as a failsafe to make sure any sprite added to the queue is safe for deletion, which is why removing that flag works to prevent deletion while still advancing the queue.
I still think using EVENT_KILLIT would be my preferred method, you could catch the deletion and prevent it and deletion queue things would proceed like normal. You could remove the flag as well, but since it's no longer in the queue I don't think it affects anything either way. Something like removespriteq could be useful.
This post has been edited by Reaper_Man: 28 September 2022 - 03:31 PM
#3008 Posted 29 September 2022 - 05:57 AM
I’ve already tried using a brand new custom sprite actor for the new decal. It still gets deleted. It was being spawned by Bloodsplat1-4 as a replacement. It still got deleted no matter what I did until I removed the SFLAG_QUEUEDFORDELETE flag in the event_spawn. So far I’ve noticed zero issues with it. But if event_killit is safer I’d definitely want to use it instead.
Also how many sprites does there have to be to crash the game? Because I ran through a lot of maps and never got a crash with all the blood and gore staying forever. I’m talking blood splats on walls floors and ceilings with gibs everywhere. And I’m using maps that add lots and lots of enemies to them. And I blew up everybody and every corpse that didn’t gib when killed. And I also have a lot more gibs being spawned from bodies and blood that drips from ceilings.
This post has been edited by VGames: 29 September 2022 - 06:00 AM
#3009 Posted 29 September 2022 - 06:28 AM
As with most things, there's rarely a single correct way to accomplish something. After reading the source code, stripping the flag prevents deletion and shouldn't interfere with the deletion queue cycling the sprite ID out. Keyword is "shouldn't", without testing this to make sure I wouldn't feel certain. I'm pretty certain, nowhere else in the source code is SFLAG_QUEUEDFORDELETE checked for or used except in the code above. So it should be fine.
For me personally, my instinct would be to go with using EVENT_KILLIT to capture and cancel the deletion because it wouldn't interfere with the game handling the rest of the deletion queue code (shown above). But again, looking at that code, simply removing the flag from the sprite also accomplishes preventing the deletion in essentially the same manner, so I don't think it makes a difference in terms of effect or side-effect. The deletion is still prevented, the queue array still cycles, and everything should run fine. With that in mind, conceptually I would still go with EVENT_KILLIT, because again conceptually what I'm trying to do is stop the deletion of a sprite, which is an ideal use for that event.
Lastly, it also depends on the larger scope of the project. If you're already running a lot of code on decal sprites when they spawn, then it would be cleaner and slightly more performant to strip the flag at that time, rather than entering into another event on deletion (since again the end result is essentially identical).
#3010 Posted 29 September 2022 - 08:02 AM
#3011 Posted 04 October 2022 - 02:43 PM
#3013 Posted 07 October 2022 - 08:27 PM
#3014 Posted 08 October 2022 - 12:20 PM
Danukem, on 07 October 2022 - 08:27 PM, said:
Yeah, once the slimer enters the "eat face" routine, it will no longer check htextra for taking damage.
However, you can still kill it this way:
onevent EVENT_USE ifn player[screenpeek].somethingonplayer -1 { seta[player[screenpeek].somethingonplayer].htextra 1 seta[player[screenpeek].somethingonplayer].htg_t 0 0 setp[screenpeek].somethingonplayer -1 } endevent
#3015 Posted 08 October 2022 - 03:29 PM
#3016 Posted 09 October 2022 - 10:39 AM
Doom64hunter, on 08 October 2022 - 12:20 PM, said:
However, you can still kill it this way:
onevent EVENT_USE ifn player[screenpeek].somethingonplayer -1 { seta[player[screenpeek].somethingonplayer].htextra 1 seta[player[screenpeek].somethingonplayer].htg_t 0 0 setp[screenpeek].somethingonplayer -1 } endevent
Hey thanks for that. Saved some time and makes perfect sense.
I've got another little question. I got this blackhole that sucks in and swallows enemies. It works pretty good unless the blackhole is above the enemies. I can't get it to suck them up into it. I've tried forcing the enemies to move up to it but they won't budge. I'm using a universal state for all the enemies and it's basically the actor look at a certain actor code that I then added xvelocity to so they'll move to it real fast. Like I said it works great when the blackhole is at their level. Please help if you can.
state suckzone { findnearactor SC_BLACKHOLE 100000 TEMP ifvarn TEMP -1 { getactor[TEMP].x mx getactor[TEMP].y my getactor[THISACTOR].x x getactor[THISACTOR].y y subvarvar mx x subvarvar my y getangle ANGVAR mx my setactor[THISACTOR].ang ANGVAR seta[].xvel 500 } findnearactor SC_BLACKHOLE 1000 TEMP ifvarn TEMP -1 { ifstrength 100 { ifrnd 128 sound BODYEXPLODE1 else sound BODYEXPLODE2 guts JIBS6 15 killit } } } ends
#3017 Posted 09 October 2022 - 11:10 AM
#3018 Posted 09 October 2022 - 11:55 AM
Danukem, on 09 October 2022 - 11:10 AM, said:
Oh ok movesprite. That's what I was missing. Thanks.
Real quick while I got your attention. I'm trying to get a projectile to spawn right in front of the player instead of where it spawns by default on the Y axis. Ive tried using the rotatepoint command, but it doesn't seem to work for this or I'm just not using it correctly. Any ideas or examples from your projects that can shed some light on this? I feel like I'm making things way to complicated.
#3019 Posted 16 October 2022 - 10:07 AM
Reaper_Man, on 08 October 2022 - 03:29 PM, said:
It's specific to the slimer, and it's not the player variable that causes it.
The htg_t[0] entry keeps track of the slimer's state, and while it's eating a player's face, it does not process damage in htextra.
Setting this value to 0 resets it to the default state, where it will process the damage and get killed.
#3020 Posted 17 October 2022 - 10:29 PM
actor MYACTORSPAWNER spawn MYACTOR2 enda event_egs ifactor MYACTOR2 sizeat 32 32 getactor[THISACTOR].x TEMP addvar TEMP 1430 setactor[THISACTOR].x TEMP endevent --- actor MYACTORSPAWNER espawn MYACTOR2 enda event_egs ifactor MYACTOR2 sizeat 32 32 getactor[RETURN].x TEMP addvar TEMP 1430 setactor[RETURN].x TEMP endevent
The sizeat functions as it should but there is no change to the sprite's position.
Using the same code with espawn inside the actor block works but it gets executed after spawning first
actor MYACTORSPAWNER espawn MYACTOR2 getactor[RETURN].x TEMP addvar TEMP 1430 setactor[RETURN].x TEMP enda
This post has been edited by lllllllllllllll: 17 October 2022 - 10:31 PM
#3021 Posted 17 October 2022 - 10:38 PM
lllllllllllllll, on 17 October 2022 - 10:29 PM, said:
event_egs ifactor MYACTOR2 sizeat 32 32 getactor[THISACTOR].x TEMP addvar TEMP 1430 setactor[THISACTOR].x TEMP endevent
Indenting does nothing in CON script, you need to use braces, like this:
event_egs ifactor MYACTOR2 { sizeat 32 32 getactor[THISACTOR].x TEMP addvar TEMP 1430 setactor[THISACTOR].x TEMP } endevent
You code was making MYACTOR2 size 32 by 32, and then it was making every single spawned sprite move 1430 positive on the x axis, including the MYACTOR2 and all other spawned sprites. I'm not sure why that would make it appear to not be working, though.
#3022 Posted 17 October 2022 - 11:29 PM
Danukem, on 17 October 2022 - 10:38 PM, said:
event_egs ifactor MYACTOR2 { sizeat 32 32 getactor[THISACTOR].x TEMP addvar TEMP 1430 setactor[THISACTOR].x TEMP } endevent
You code was making MYACTOR2 size 32 by 32, and then it was making every single spawned sprite move 1430 positive on the x axis, including the MYACTOR2 and all other spawned sprites. I'm not sure why that would make it appear to not be working, though.
I see. I was testing it by spawning a bunch of sprites with different x/y changes and one with none but they all spawned in a stack~