![](https://forums.duke4.net/public/style_images/cgs/_custom/switch.png)
EDuke32 Scripting "CON coding help"
#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~
#3023 Posted 18 October 2022 - 06:27 AM
#3024 Posted 18 October 2022 - 10:08 AM
https://wiki.eduke32...i/Texture_(DEF)
This post has been edited by Reaper_Man: 18 October 2022 - 10:09 AM
#3025 Posted 18 October 2022 - 11:34 AM
Reaper_Man, on 18 October 2022 - 10:08 AM, said:
https://wiki.eduke32...i/Texture_(DEF)
Oh that sucks. So u have to make a different color variant for every sprite? I may have to think this over.
Aren’t the palettes that change the entire sprite to a certain color like blue or red the ones that are primarily used for sector lighting effects? Palette 1, 2, and 8?
This post has been edited by VGames: 18 October 2022 - 11:45 AM
#3026 Posted 18 October 2022 - 02:22 PM
VGames, on 18 October 2022 - 11:34 AM, said:
Pretty much.
Most of the other palettes might be get used on walls but not the floors because even default sprites don't look consistent.
If you're up to making sprites for 1 & 2 they can be reused for the few rare cases you would run into, like pal24 (deep red / greys), and 4(?) is just pitch black.
#3028 Posted 18 October 2022 - 05:39 PM
#3029 Posted 19 October 2022 - 03:50 AM
lllllllllllllll, on 18 October 2022 - 05:39 PM, said:
Not really, not in a straight forward manner at least. There is no "parent" attribute or anything like that.
Your method of manually offsetting position is what I'd do, but I'd do it in the orbit sprite's code rather than in the parent sprite's. Assuming the parent does the spawning, you can store the parent's sprite ID on spawn:
espawn ORBITSPRITE setav[RETURN].PARENT THISACTOR
Where PARENT is a per-actor var. Then in the orbit sprite you'd do something like this:
geta[PARENT].x TEMP sub TEMP sprite[PARENT].htbposx
htbposx/y/z already stores the sprite's position last game tic, so you subtract it from the current position and get the offset for free. From here you can just add it to the orbit sprite's X/Y/Z position or otherwise add it into the movement calculation.
I'd add in some safety checks to make sure the parent is still alive or otherwise hasn't gone away, stuff like that.
#3030 Posted 19 October 2022 - 10:37 AM
Reaper_Man, on 19 October 2022 - 03:50 AM, said:
espawn ORBITSPRITE setav[RETURN].PARENT THISACTOR
Where PARENT is a per-actor var.
Thank you, this helps with more things than just this question
Reaper_Man, on 19 October 2022 - 03:50 AM, said:
geta[PARENT].x TEMP
Does getav[PARENT].TEMP2 TEMP get the owner's value of TEMP2?
This post has been edited by lllllllllllllll: 19 October 2022 - 10:41 AM