Duke4.net Forums: EDuke32 Scripting - Duke4.net Forums

Jump to content

  • 124 Pages +
  • « First
  • 100
  • 101
  • 102
  • 103
  • 104
  • Last »
  • You cannot start a new topic
  • You cannot reply to this topic

EDuke32 Scripting  "CON coding help"

User is offline   VGames 

  • Extra Crispy

#3004

View PostReaper_Man, on 28 September 2022 - 06:42 AM, said:

You probably need to strip the SFLAG_QUEUEDFORDELETE flag from the sprite's .htflags property, as that is what actually controls it being identified and deleted by the sprite queue. The statnums STAT_ACTOR and STAT_MISC only allow a sprite to be deleted, but doesn't do the actual deleting of the sprite.


This did the trick. Thanks for the help.
0

User is offline   Reaper_Man 

  • Once and Future King

#3005

I dug into the source and I'd have to run some tests to confirm this, but it looks like the deletion of the sprite via A_DeleteSprite() happens independent of the deletion queue array advancing or updating. The actual call to A_DeleteSprite() only happens if the next sprite in line has the flag SFLAG_QUEUEDFORDELETE, and then the array updates anyway whether the sprite was deleted or not. It then forces the SFLAG_QUEUEDFORDELETE flag onto the newly spawned sprite (spriteNum here), because the deletion is happening in A_AddToDeleteQueue() when a sprite is being spawned. From actors.cpp:

    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.
1

User is online   Danukem 

  • Duke Plus Developer

#3006

In 2006 when I was just starting to mod Duke, I was getting weird random glitches. TerminX helped me figure out it was caused by me using "killit" on sprites that were already in the deletion queue, leading to undefined behavior. Since then I have been cautious when it comes to that.

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.
2

User is offline   Reaper_Man 

  • Once and Future King

#3007

Good call, and that code block actually explains why too. The deletion queue array is just a list of sprite IDs, but because sprite IDs get recycled, if a sprite is deleted early (via killit or similar), when the deletion queue also tries to delete it, that sprite ID is either A.) now invalid, or B.) assigned to a different sprite.

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

0

User is offline   VGames 

  • Extra Crispy

#3008

So instead of using the code I used to remove the SFLAG_QUEUEDFORDELETE flag in the Event_spawn I should use it in the event_killit?

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

1

User is offline   Reaper_Man 

  • Once and Future King

#3009

The engine sprite limit is 16384 sprites, any more than that and the game will crash. This is not just sprites spawned at runtime (like bulletholes), but all sprites in a map, including static sprites placed in Mapster.

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).
0

User is offline   VGames 

  • Extra Crispy

#3010

I understand completely. Thanks for the in depth info. I’ll set it up in the killit event for optimal reasons.
1

User is offline   VGames 

  • Extra Crispy

#3011

I want to remove the protozoid slimers from your face by pressing the USE button. Is this possible? Is there a way to detect if the slimer is on your face and is there a way to kill it?
1

User is offline   Reaper_Man 

  • Once and Future King

#3012

https://wiki.eduke32...methingonplayer
0

User is online   Danukem 

  • Duke Plus Developer

#3013

Fun fact though: while somethingonplayer does refer to the sprite number of the slime when nonzero, applying damage to that sprite by setting htextra will not work. I know because I went through this same thing a few years ago.
2

#3014

View PostDanukem, on 07 October 2022 - 08:27 PM, said:

Fun fact though: while somethingonplayer does refer to the sprite number of the slime when nonzero, applying damage to that sprite by setting htextra will not work. I know because I went through this same thing a few years ago.

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

4

User is offline   Reaper_Man 

  • Once and Future King

#3015

Is this specific to the Slimer, or does any actor put into .somethingonplayer no longer process damage?
0

User is offline   VGames 

  • Extra Crispy

#3016

View PostDoom64hunter, on 08 October 2022 - 12:20 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



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


0

User is online   Danukem 

  • Duke Plus Developer

#3017

If it is above them, try using movesprite on them with a negative zvel powerful enough to offset gravity, like -6144 or so. The x and y speeds for movesprite can be left at 0 since you are uxing xvel to move them on the other planes.
0

User is offline   VGames 

  • Extra Crispy

#3018

View PostDanukem, on 09 October 2022 - 11:10 AM, said:

If it is above them, try using movesprite on them with a negative zvel powerful enough to offset gravity, like -6144 or so. The x and y speeds for movesprite can be left at 0 since you are uxing xvel to move them on the other planes.


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.
0

#3019

View PostReaper_Man, on 08 October 2022 - 03:29 PM, said:

Is this specific to the Slimer, or does any actor put into .somethingonplayer no longer process damage?

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.
1

#3020

I'm trying to change the relative location of where a sprite spawns and don't understand why neither of these worked:

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

0

User is online   Danukem 

  • Duke Plus Developer

#3021

View Postlllllllllllllll, 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.
0

#3022

View PostDanukem, on 17 October 2022 - 10:38 PM, said:

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.

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~
0

User is offline   VGames 

  • Extra Crispy

#3023

So I’ve been adding new weapon sprites using the tilefromtexture method instead of putting the new sprites directly into an ART tile. This is due to forcing the new sprites to use their true 32 bit palettes with the texture command. I’ve noticed that when walking through sectors that have different lighting such as a night club that has flashing red and blue lights everywhere the weapon sprites do no adopt the sectors color palette as they should. I’m using the weapon examples CON file that comes with eduke32 as a base. I’ve made a lot of edits to it for animations and new fire mode features but I don’t think I’ve made any changes that would affect the hud_pal variable that seems to be in control of the displayed weapon sprites palette. Is there anything I should look for in the weapon animations or is there anything I should make sure is there regarding the original weapon display code and how palettes are utilized? Or do the weapon sprites have to be in the ART tiles for them to be affected by sector lighting effects?
0

User is offline   Reaper_Man 

  • Once and Future King

#3024

You have to explicitly create and define palette swap versions of hightile art, 32bit art can't rely on the engine to colorize tiles. See the bottom of this page for examples.

https://wiki.eduke32...i/Texture_(DEF)

This post has been edited by Reaper_Man: 18 October 2022 - 10:09 AM

0

User is offline   VGames 

  • Extra Crispy

#3025

View PostReaper_Man, on 18 October 2022 - 10:08 AM, said:

You have to explicitly create and define palette swap versions of hightile art, 32bit art can't rely on the engine to colorize tiles. See the bottom of this page for examples.

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

0

#3026

View PostVGames, on 18 October 2022 - 11:34 AM, said:

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?

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.
0

User is offline   VGames 

  • Extra Crispy

#3027

Thanks I’ll think this over and see what I want to do
0

#3028

Is there some means of anchoring multiple spawned sprites to their owner's movements?


Spoiler

Attached thumbnail(s)

  • Attached Image: weisnemsn.gif

0

User is offline   Reaper_Man 

  • Once and Future King

#3029

View Postlllllllllllllll, on 18 October 2022 - 05:39 PM, said:

Is there some means of anchoring multiple spawned sprites to their owner's movements?

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.
0

#3030

View PostReaper_Man, on 19 October 2022 - 03:50 AM, said:

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.

Thank you, this helps with more things than just this question


View PostReaper_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

0

User is offline   Reaper_Man 

  • Once and Future King

#3031

If by "owner" you mean the sprite that spawned it, the sprite that was set in the PARENT var, then yes. "owner" is a specific sprite property name so I try to avoid it as a general term.

When you retrieve a var or property, "THISACTOR" is a magic reference to the sprite ID of the actor running that code. But if you have another sprite's ID, you can use that instead to get or set data on it instead. A few examples:

getav[PARENT].TEMP2 TEMP // where TEMP and TEMP2 are per-actor vars, retrieve PARENT's current value of TEMP2 to the sprite making the call's value of TEMP
geta[PARENT].extra TEMP // Retrieve PARENT's extra value, IE their current HP

seta[PARENT].xrepeat 0 // Force xrepeat to 0...
seta[PARENT].statnum STAT_ACTOR // ... and statnum to STAT_ACTOR, essentially doing a remote killit on PARENT


This is also why you need to do validation on the value of PARENT because if the sprite referenced in PARENT goes away (via killit or other methods), you'll get fucky behavior and/or errors. Also, I'd suggest defaulting the value of PARENT to -1 because technically 0 could be a valid sprite ID, meaning you can check for the -1 value to bail out early on if the sprite is somehow spawned invalidly.
1

#3032

View PostReaper_Man, on 19 October 2022 - 11:07 AM, said:

If by "owner" you mean the sprite that spawned it, the sprite that was set in the PARENT var, then yes. "owner" is a specific sprite property name so I try to avoid it as a general term.

When you retrieve a var or property, "THISACTOR" is a magic reference to the sprite ID of the actor running that code. But if you have another sprite's ID, you can use that instead to get or set data on it instead. A few examples:

getav[PARENT].TEMP2 TEMP // where TEMP and TEMP2 are per-actor vars, retrieve PARENT's current value of TEMP2 to the sprite making the call's value of TEMP
geta[PARENT].extra TEMP // Retrieve PARENT's extra value, IE their current HP

seta[PARENT].xrepeat 0 // Force xrepeat to 0...
seta[PARENT].statnum STAT_ACTOR // ... and statnum to STAT_ACTOR, essentially doing a remote killit on PARENT


This is also why you need to do validation on the value of PARENT because if the sprite referenced in PARENT goes away (via killit or other methods), you'll get fucky behavior and/or errors. Also, I'd suggest defaulting the value of PARENT to -1 because technically 0 could be a valid sprite ID, meaning you can check for the -1 value to bail out early on if the sprite is somehow spawned invalidly.

Does a var default on its own when the actor id it's set to is removed? Or does it default when an invalid sprite is referenced? Or only when that particular var tries to call it?


and using multiple per-actor vars from different actors in the same statement like:


actor orbitsprite
  getav[TEMP1].TEMP2 TEMP2  //getav[enemy].enemy'sTEMP2  orbitsprite'sTEMP2
enda

actor enemy
  espawn orbitsprite
  setav[RETURN].TEMP1 THISACTOR
enda





do they get handled correctly?
0

User is offline   Reaper_Man 

  • Once and Future King

#3033

No, the var is not linked to the sprite ID and won't automatically update or revert to default when that sprite is destroyed, you have to maintain your own reference. If "enemy" is destroyed, "orbitsprite" doesn't automatically know that, and so the TEMP1 reference can become invalid and throw errors. How to resolve this depends on exactly how your codebase is setup and how you want orbitsprites to behave when their parent dies. One way is to have the orbitsprite check for its parent sprite's .extra to see when it's dead. Another is to have the "enemy" loop through all existing sprites, checking for ones that have its parent var set to itself. As with most things, there's no single correct solution.

Yes, using the same per-actor var won't cause issues. Both sprites have their own copy of that var and its data, that's what makes the vars "per-actor". Personally I'd rather have additional vars and have more readable code than try to code golf and use as few vars as possible. I don't know what "TEMP1" is doing but I have a good idea what "PARENT" is doing.
0

Share this topic:


  • 124 Pages +
  • « First
  • 100
  • 101
  • 102
  • 103
  • 104
  • Last »
  • You cannot start a new topic
  • You cannot reply to this topic


All copyrights and trademarks not owned by Voidpoint, LLC are the sole property of their respective owners. Play Ion Fury! ;) © Voidpoint, LLC

Enter your sign in name and password


Sign in options