What determines if an actor can be hit by shrinker or not? "Using Protector Drone as an example"
#1 Posted 25 October 2025 - 08:16 AM
#2 Posted 25 October 2025 - 08:38 AM
ifwasweapon SHRINKSPARKclause in their hit check code (see
state checkoctahitstatefor an example), and a special action (ai) for the shrunk state that tells them to shrink (by calling
state genericshrunkcode) and then grow back when SHRUNKCOUNT is reached, and return to their normal action once SHRUNKDONECOUNT is reached.
If your enemy code does not contain all of that, the shrinker will be treated as a regular weapon (dealing zero damage).
This post has been edited by Jan Satcitananda: 25 October 2025 - 08:42 AM
#3 Posted 25 October 2025 - 09:48 AM
#4 Posted 25 October 2025 - 06:51 PM
#5 Posted 26 October 2025 - 10:46 AM
Jan Satcitananda, on 25 October 2025 - 08:38 AM, said:
ifwasweapon SHRINKSPARKclause in their hit check code (see
state checkoctahitstatefor an example), and a special action (ai) for the shrunk state that tells them to shrink (by calling
state genericshrunkcode) and then grow back when SHRUNKCOUNT is reached, and return to their normal action once SHRUNKDONECOUNT is reached.
If your enemy code does not contain all of that, the shrinker will be treated as a regular weapon (dealing zero damage).
Sadly, that didn't work, shrinker projectile still does nothing to the enemy. It doesn't even bleed or make any sounds.
Interestingly, when I increased SHRINKER_WEAPON_STRENGTH from it's original value 10 to 1000, projectile started doing serious knockback, but still no damage and no effect.
Reaper_Man, on 25 October 2025 - 09:48 AM, said:
One of the enemys ID is 341, which is a hardcoded thing, so it could potentially be the source of the problem.
However, there are also two other enemies that are immune to shrinker in the TC, and their IDs are 2620 and 2080, so, maybe not.
This post has been edited by zykov eddy: 26 October 2025 - 10:51 AM
#6 Posted 26 October 2025 - 12:53 PM
You could try simply redefining the actor as a useractor on a new tile ID to test, but if the other useractors at 2080 and 2620 are also immune, this is likely a CON oversight. The behavior you're describing sounds like improperly setup ifhitweapon / ifwasweapon ordering.
Post the code for one of the enemies and we can take a look what might be the problem.
#7 Posted 26 October 2025 - 03:26 PM
Reaper_Man, on 26 October 2025 - 12:53 PM, said:
You could try simply redefining the actor as a useractor on a new tile ID to test, but if the other useractors at 2080 and 2620 are also immune, this is likely a CON oversight. The behavior you're describing sounds like improperly setup ifhitweapon / ifwasweapon ordering.
Post the code for one of the enemies and we can take a look what might be the problem.
define RD 341
define RDSTAYPUT 342
define RDSTRENGTH 120
define RDWHIPAMOUNT -25
action ARDSTAND 0
action ARDWALKING 5 4 5 1 12
action ARDRUNNING 5 4 5 1 8
action ARDTHINK 0 1 5 1 40
action ARDWHIP 40 3 5 1 20
action ARDDYING 60 6 1 1 20
action ARDFLINTCH 55 1 5 1
action ARDLYINGDEAD 65 1 1
action ARDSCREAM 25 3 5 1 40
action ARDJUMP 35 2 5 1 50
action ARDFALL 50 1 5
action ARDFROZEN 5 1 5
action RTD 915 3 1 -1 20
move RDWALKVEL 200
move RDRUNVEL 240
move RDJUMPVEL 150
move RDSTOP
ai RDTODOP RTD RDWALKVEL faceplayer
ai AIRDGETENEMY ARDWALKING RDWALKVEL seekplayer
ai AIRDDODGE ARDRUNNING RDRUNVEL dodgebullet
ai AIRDCHARGEENEMY ARDRUNNING RDRUNVEL seekplayer
ai AIRDFLEENEMY ARDWALKING RDWALKVEL fleeenemy
ai AIRDWHIPENEMY ARDWHIP RDSTOP faceplayerslow
ai AIRDJUMPENEMY ARDJUMP RDJUMPVEL jumptoplayer
ai AIRDTHINK ARDTHINK RDSTOP
ai AIRDGROW ARDSTAND RDSTOP faceplayerslow
ai AIRDSHRINK ARDSTAND RDSTOP faceplayer
ai AIRDDYING ARDDYING RDSTOP faceplayer
ai AIRDSHOOT ARDSCREAM RDSTOP faceplayerslow
ai AIRDFLINTCH ARDFLINTCH RDSTOP faceplayerslow
state rdseekstate
ifactornotstayput
{
ifp palive
ifcansee
ifpdistl 1596
{
ai AIRDWHIPENEMY
break
}
ifai AIRDCHARGEENEMY
{
ifp palive
ifpdistl 1200
ifcansee
{
ai AIRDWHIPENEMY
break
}
ifrnd 8
ifpdistg 3000
ifp palive
ifcansee
{
ai AIRDSHOOT
break
}
}
else
ifpdistg 4096
{
ai AIRDCHARGEENEMY
break
}
iffloordistl 16
{
ifcount 32
ifrnd 16
{
ifceilingdistl 96 break
ai AIRDJUMPENEMY
}
break
}
ifrnd 4
{
ifnotmoving
operate
}
else
ifrnd 16
ifbulletnear
{
ifgapzl 128
ai AIRDDODGE
else
ifactornotstayput
{
ifrnd 128
{
ifceilingdistl 96 break
ai AIRDJUMPENEMY
}
else
ai AIRDDODGE
}
}
}
else
{
ifactioncount 16
{
ifp palive
ifpdistl 1596
ifcansee
{
ai AIRDWHIPENEMY
break
}
}
ifcount 16
ifrnd 32
move RDWALKVEL randomangle geth
}
ends
state rdfleestate
ifcount 8
{
ifrnd 64
ifpdistg 3500
ifp palive
ifcansee
ai AIRDSHOOT
}
else
{
iffloordistl 16
{
ifnotmoving
ai AIRDGETENEMY
}
else
ai AIRDGETENEMY
break
}
ends
state rdthinkstate
ifrnd 8
soundonce RD_ROAM
ifrnd 8
soundonce DRAG_ROAM
ifactioncount 5
{
ifrnd 2
{
ifpdistg 3500
ifp palive
ifcansee
ai AIRDSHOOT
}
else
ai AIRDGETENEMY
}
ifrnd 16
ifbulletnear
{
ifgapzl 96
ai AIRDDODGE
else
{
ifrnd 128
{
ifceilingdistl 144 break
ai AIRDJUMPENEMY
}
else
ai AIRDDODGE
}
}
ends
state rdwhipstate
ifcount 20
ifrnd 8
{
ifcansee
ifpdistl 2048
{
ifrnd 128
ai AIRDFLEENEMY
break
}
ifrnd 80
ai AIRDTHINK
else
ai AIRDGETENEMY
}
ifactioncount 3
{
ifpdistg 1596
ai AIRDTHINK
else ifp palive ifcansee
{
palfrom 16 16
addphealth RDWHIPAMOUNT
sound PISTOL_BODYHIT ifrnd 64 sound DUKE_GRUNT
resetactioncount
resetcount
}
}
else
ifcount 15
nullop
else
ifcount 14
{
ifpdistl 1596
soundonce RD_ATTACK
else
soundonce RD_ATTACKMISS
}
ends
state checkrdhit
spawn BLOOD
ifdead
{
state spawnsomeshit
ifwasweapon FREEZEBLAST
{
sound SOMETHINGFROZE
spritepal 1
move 0
action ARDFROZEN
strength 0
break
}
addkills 1
ifwasweapon RADIUSEXPLOSION
{
sound SQUISHED
state standard_jibs
state standard_jibs
killit
}
else
{
ai AIRDDYING
ifrnd 128
spawn BLOODPOOL
}
sound RD_DYING
}
else
{
sound RD_PAIN
ifwasweapon SHRINKSPARK
{
spawn ZAP
}
// foobar - modified by Blakwind for Lifeforce
ifwasweapon GROWSPARK
{ spawn LIFEFORCE }
state random_wall_jibs
ifrnd 32
ai AIRDFLINTCH
else
ifrnd 32
ifpdistg 3500
ifp palive
ifcansee
ai AIRDSHOOT
}
ends
state rdshrink
ifcount SHRUNKDONECOUNT
ai AIRDCHARGEENEMY
else
ifcount SHRUNKCOUNT
sizeto 40 40
else
state genericshrunkcode
ends
state rdjumpstate
ifaction ARDFALL
{
iffloordistl 16
ai AIRDGETENEMY
}
else
ifcount 20
action ARDFALL
ends
state rddyingstate
ifaction ARDLYINGDEAD
{
cstat 0
strength 0
ifhitweapon
ifwasweapon RADIUSEXPLOSION
{
sound SQUISHED
state standard_jibs
killit
}
ifcount RESPAWNACTORTIME
ifrespawn
{
spawn TRANSPORTERSTAR
cstat 257
strength RDSTRENGTH
ai AIRDGETENEMY
}
}
else
ifai AIRDDYING
ifactioncount 6
{
iffloordistl 8
// sound THUD
move RDSTOP
action ARDLYINGDEAD
}
ends
state rddodgestate
ifcount 13
ai AIRDGETENEMY
ends
useractor enemystayput RDSTAYPUT RDSTRENGTH ai AIRDGETENEMY cstator 257 cactor RD enda
state SRTD
ifactioncount 3 {
spawn DOP
sound morph3
killit
}
ends
state rdcode
state checksquished
ifai 0
{
cstator 257
ai AIRDGETENEMY
}
else
ifaction ARDLYINGDEAD
{
fall
state rddyingstate
break
}
else
ifaction ARDFROZEN
{
ifcount THAWTIME
{
ai AIRDGETENEMY
spritepal 0
}
else
ifcount FROZENDRIPTIME
{
ifactioncount 26
{
spawn WATERDRIP
resetactioncount
}
}
ifhitweapon
{
ifwasweapon FREEZEBLAST
{
strength 0
break
}
addkills 1
ifrnd 84
spawn BLOODPOOL
lotsofglass 30
sound GLASS_BREAKING
killit
}
ifp pfacing
ifpdistl FROZENQUICKKICKDIST
pkick
break
}
else
ifai AIRDJUMPENEMY
state rdjumpstate
else
{
fall
ifai AIRDGETENEMY
state rdseekstate
else
ifai AIRDCHARGEENEMY
state rdseekstate
else
ifai AIRDFLINTCH
{
ifcount 8
ai AIRDGETENEMY
}
else
ifai AIRDDODGE
state rddodgestate
else
ifai AIRDWHIPENEMY
state rdwhipstate
else
ifai RDTODOP
state SRTD
else
ifai AIRDFLEENEMY
state rdfleestate
else
ifai AIRDTHINK
state rdthinkstate
else
ifai AIRDGROW
state genericgrowcode
else
ifai AIRDSHRINK
state rdshrink
else
ifai AIRDDYING
state rddyingstate
else
ifai AIRDSHOOT
{
ifp pshrunk
ai AIRDGETENEMY
else
ifcount 26
ai AIRDGETENEMY
else
ifcount 20
{ ifinwater { spawn WATERBUBBLE } else { sound flamethr shoot FIRELASER } }
else
{
ifcount 5
nullop
else
ifcount 4
sound RD_SPIT
}
}
}
ifhitweapon
state checkrdhit
ends
useractor enemy RD RDSTRENGTH
fall
ifaction 0
{
sound RD_RECOG
cstator 257
sizeat 18 18
ai AIRDDODGE
}
ifaction ARDFROZEN
state rdcode
else
{
ifspawnedby DOP
ifrnd 1
ifrnd 135
ai RDTODOP
state rdcode
ifaction ARDFROZEN
break
getlastpal
}
enda
#8 Posted 26 October 2025 - 04:04 PM
#9 Posted 26 October 2025 - 11:24 PM
lllllllllllllll, on 26 October 2025 - 04:04 PM, said:
The enemy shouldn't shrink. It should only spawn the ZAP object. AIRDSHRINK was added by me as suggested by the second post in this thread.
#10 Posted 27 October 2025 - 04:23 AM
#11 Posted 27 October 2025 - 04:40 AM
Reaper_Man, on 27 October 2025 - 04:23 AM, said:
No, I don't want this enemy to be immune to shrinker.
#12 Posted 27 October 2025 - 09:22 AM
ifwasweapon shrinkspark
break
sound pred_pain
guts jibs6 2
sound pred_pain
ifwasweapon shrinkspark
break
guts jibs6 2
sound pred_pain
guts jibs6 2
ifwasweapon shrinkspark
{
ai AISHRUNK
break
}
The top block plays no sound and spawns no guts when hit with shrinker while the second block reacts with a pain sound but no guts and the third block reacts with pain, guts, and shrinking behavior.
If a hardcoded enemy were to be frozen with the freezer and then shot with the shrinker after thawing without using a 'break' I think it would die.
#13 Posted 30 October 2025 - 03:32 PM
lllllllllllllll, on 27 October 2025 - 09:22 AM, said:
ifwasweapon shrinkspark
break
sound pred_pain
guts jibs6 2
sound pred_pain
ifwasweapon shrinkspark
break
guts jibs6 2
sound pred_pain
guts jibs6 2
ifwasweapon shrinkspark
{
ai AISHRUNK
break
}
The top block plays no sound and spawns no guts when hit with shrinker while the second block reacts with a pain sound but no guts and the third block reacts with pain, guts, and shrinking behavior.
If a hardcoded enemy were to be frozen with the freezer and then shot with the shrinker after thawing without using a 'break' I think it would die.
Can you please suggest what I should change in the code that I provided to make the enemy not immune to shrinker projectile? Even if I increase the damage of the projectile, enemy won't be damaged by it.
It only needs to spawn the ZAP actor when hit by shrinker, that's it.
#14 Posted 30 October 2025 - 04:36 PM
zykov eddy, on 30 October 2025 - 03:32 PM, said:
It only needs to spawn the ZAP actor when hit by shrinker, that's it.
My guess is that it's caused by a side effect of ifhitweapon processing and resetting actor damage to prevent any further ifhitweapon from processing the same hit event. So make sure you are calling ifhitweapon only once per each hit. As a rule of thumb, you should isolate the code that causes the problem to troubleshoot it.
#15 Posted 30 October 2025 - 05:19 PM
I've never messed with ZAP, try espawning it and setting the size of RETURN to 32 32 and X Y Z to the enemy's.
Also for tiles that are not hardcoded enemies don't use strength 0 for freezer code. Their AI breaks at 0 health.
In the useractor block it looks like there is a misplaced bracket and maybe a missing pair of brackets involving "ifaction ARDFROZEN"
#16 Posted 31 October 2025 - 04:02 PM
Jan Satcitananda, on 30 October 2025 - 04:36 PM, said:
That can't be the case, because actor reacts to ifwasweapon GROWSPARK as intended, and it's placed in the code right after ifwasweapon SHRINKSPARK.
As a test, I replaced "ifwasweapon SHRINKSPARK" with "ifwasweapon FIRELASER", and actor started spawning ZAP after being hit with a laser projectile.
Actor purposely ignores the SHRINKSPARK projectile, no matter what I do.
This post has been edited by zykov eddy: 31 October 2025 - 04:04 PM
#18 Posted 31 October 2025 - 05:09 PM
#19 Posted 07 November 2025 - 02:17 PM
The problem was that this actor had sizeat 18 18.
When I changed it to sizeat 30 30, shrinker projectile started working.
... What the hell???
I need this enemy to be sizeat 18 18, though. It has a huge artwork and won't look good with bigger sizeat values.
#20 Posted 07 November 2025 - 03:51 PM
From this line in A_IncurDamage():
if (pActor->extra == 0 && pActor->picnum == SHRINKSPARK && pSprite->xrepeat < 24)
return -1;Presumably this is so already shrunk enemies don't try to get "shrunk" again when they're already in a shrunken state.
Your best option is to create a custom projectile altogether. Otherwise you have a hard floor of xrepeat 24 as the size before they ignore SHRINKSPARK hits.
It looks like if you give it a non-zero damage it should also ignore this, but since you said you've already tried increasing the SHRINKSPARK damage without any effect, I'm assuming the damage gets set to 0 somewhere deeper in the source.
This post has been edited by Reaper_Man: 07 November 2025 - 04:00 PM
#21 Posted 07 November 2025 - 07:33 PM
Reaper_Man, on 07 November 2025 - 03:51 PM, said:
From this line in A_IncurDamage():
if (pActor->extra == 0 && pActor->picnum == SHRINKSPARK && pSprite->xrepeat < 24)
return -1;Presumably this is so already shrunk enemies don't try to get "shrunk" again when they're already in a shrunken state.
Your best option is to create a custom projectile altogether. Otherwise you have a hard floor of xrepeat 24 as the size before they ignore SHRINKSPARK hits.
It looks like if you give it a non-zero damage it should also ignore this, but since you said you've already tried increasing the SHRINKSPARK damage without any effect, I'm assuming the damage gets set to 0 somewhere deeper in the source.
Pretty sure I have a babe smaller than that that gets shrunk with its size at 14 12 before shrinking. I've never noticed any problems shrinking all of them on a debug map.
#22 Posted 07 November 2025 - 09:59 PM
zykov eddy, on 07 November 2025 - 02:17 PM, said:
Yup, should have thought about why the original enemies can't be shrunk twice. You can always adjust the scale in EVENT_ANIMATESPRITES as a possible workaround (e.g. make it size 36x36 but appear as 18x18 by halving its tsprite dimensions).
#23 Posted 08 November 2025 - 10:30 AM
#24 Posted 08 November 2025 - 01:42 PM
actor SHRINKSPARK SHRINKER_WEAPON_STRENGTH enda
Assuming "SHRINKER_WEAPON_STRENGTH" is non-zero, it should be passing that value, but you could confirm with some debugging of .htextra. Actually you could probably modify .htextra to be non-zero and get around the hardcoded size check, then manually re-add the damage it deals.
#25 Posted 08 November 2025 - 01:59 PM
Checking the source code is fine, but really no one should be relying on reaper or anyone eles to come in and do that for you; it's very easy to just check and log values as you are testing things in the game and draw obvious conclusions.

Help
Duke4.net
DNF #1
Duke 3D #1


