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

Jump to content

  • 119 Pages +
  • « First
  • 107
  • 108
  • 109
  • 110
  • 111
  • Last »
  • You cannot start a new topic
  • You cannot reply to this topic

EDuke32 Scripting  "CON coding help"

User is offline   MC84 

#3241

I am attempting to make a simple NPC/civilian that's stationary and one-sided, and simply cycles through different actions etc. I have followed Dan's tutorial from 2018 and setup the actions and have checked that they all work etc. The first thing I'm trying to do is just setup a basic idling routine, where the NPC alternates between a few different actions. So far this (sort of) works, however I want to specify the actioncount for some actions so that they don't quit mid-animation, which is currently what's happening.

Basically I want CIV1FLICK to only ever play 8 frames, and CIV1SMOKE 16 frames.


action CIV1IDLE 1 11 1 1 16
action CIV1FLICK 12 8 1 1 16
action CIV1SMOKE 20 16 1 1 16

useractor notenemy CIV1 NPCSTRENGTH
{

 fall
  
      ifcount 64 ifrnd 6
      {
        ifrnd 128
          action CIV1IDLE
        else
        {
          ifrnd 128
            action CIV1FLICK
          else
            ifrnd 128
            action CIV1SMOKE
        }
        resetcount
		
	ifaction CIV1FLICK ifactioncount 8 break
		
	ifaction CIV1SMOKE ifactioncount 16 break
		
      }

}
enda


0

User is offline   Danukem 

  • Duke Plus Developer

#3242

action CIV1IDLE 1 11 1 1 16
action CIV1FLICK 12 8 1 1 16
action CIV1SMOKE 20 16 1 1 16

useractor notenemy CIV1 NPCSTRENGTH CIV1IDLE

 fall
  
       ifaction CIV1IDLE ifactioncount 11
      {
        resetactioncount
        ifrnd 128
        {
          ifrnd 128
            action CIV1FLICK
          else
            action CIV1SMOKE
        }
      }
                
   ifaction CIV1FLICK ifactioncount 8 action CIV1IDLE
                
   ifaction CIV1SMOKE ifactioncount 16  action CIV1IDLE
                
enda

2

User is offline   MC84 

#3243

thanks Dan - I swear I had tried that command at some point... and thanks for improving some of the other code as well. I Appreciate it! Also is it best practice to include the death/hurt/interact branches of if statements first, and then have the default routine last? From looking at other code this seems to be a common approach.

This post has been edited by MC84: 24 March 2023 - 03:44 PM

1

User is offline   Danukem 

  • Duke Plus Developer

#3244

View PostMC84, on 24 March 2023 - 03:41 PM, said:

Also is it best practice to include the death/hurt/interact branches of if statements first, and then have the default routine last? From looking at other code this seems to be a common approach.


I do it that way but it's not necessary as long as you are careful and make sure that dead actors aren't running code they aren't supposed to.
1

User is online   Reaper_Man 

  • Once and Future King

#3245

As CON is executed from top to bottom, you can place the bail out conditions for dead actors sooner and prevent unnecessary later code from running, saving CPU time. It's why you generally always see character state machine built like:

ifaction SOMEACTION
	state actorstate
else
ifaction OTHERACTION
	state actorotherstate
else
[. . .]


The use of "else" here prevents different status states from running in a single tic. Without the elses, if the animation begins as SOMEACTION and the animation changes to OTHERACTION from within state actorstate, you would have both states run in a given tic, which is most likely not planned or expected behavior.

As far as freeing up CPU cycles, something else you can do to free it up is force it to stop being an actor by changing it's statnum - assuming you want it to run absolutely zero code, including "blow up corpses" type code. If so then you can do:

seta .statnum STAT_DEFAULT


And that turns it into a non-actor, static sprite.
2

User is offline   MC84 

#3246

I want to try to attempt a custom enemy that's based off the pigcop (ie basically the same behaviour). I'm still animating/rendering my actions however I have had a look at the GAME.CON code and while I can kinda follow most of it, I was hoping someone could shed some light on how the following if construction works?

state pigshootenemystate
//  ifcansee
  {
    ifcount 12 nullop
    else
      ifcount 11
    {
      ifcanshoottarget
      {
        sound PIG_ATTACK
        shoot SHOTGUN etc.
      }
      else
        ai AIPIGSEEKENEMY
    }
    ifcount 25 nullop
    else
      ifcount 24
      {
        action APIGCOCK
        sound SHOTGUN_COCK
      }
    ifcount 48 nullop
    etc. etc.


I thought that 'ifcount' was just based off the in-game tic counter, so how does this construction work when presumably all of the values will eventually be true? Clearly I'm missing something here, but take the first ifcount; won't the tic counter always reach 11? hence making the 12 null and void? And then how can the counter then advance to the higher values (25,24,48,etc)?
0

User is offline   Danukem 

  • Duke Plus Developer

#3247

The expression "ifcount 12" can be read as "if the count is AT LEAST 12"

So in quasi-English, what that part is saying is: "If the counter is 12 or higher do nothing, otherwise if the counter is at least 11 execute what is in the following braces". This can be simplified to "If the counter is exactly 11, execute what is in the following braces."

The count commands in old CON don't have an equals operator, so it has to be written out in the more complex way using the nullop command.

There's no denying the code is needlessly difficult to read and could be simplified using eduke syntax. In my code, if a behavior is tied to an animation, I try to stick to actioncount when determining what behavior to switch to. One advantage of this is that if the animations are sped up (either through redefining the actions or by hacking the hgt_t members) the actor will still behave correctly.
2

#3248

You'll notice there is no 'else' between ifcount 12/11 - ifcount 25/24 - ifcount 48, so they will not prevent the other from running.
ifactioncount is sometimes used in the same manner but needs more care because the delay used on the action changes the amount of ticks inbetween single actions. For example:

  action FAST 0 1 1 1 1
  action SLOW 0 1 1 1 16

  //
  ifaction FAST
  {
    ifactioncount 3 nullop
    else
    ifactioncount 2
      shoot SHOTGUN
  }
  ifaction SLOW
  {
    ifactioncount 3 nullop
    else
    ifactioncount 2
      shoot SHOTGUN
  }
//


the FAST action will have its actioncount at 2 for one tic (I think) and fire once
the SLOW action will have its actioncount at 2 for 4 tics (I think) and fire 4 times in what will seem like an instant since it is happening once per tic
2

User is online   Reaper_Man 

  • Once and Future King

#3249

It's also worth noting that to get the expected behavior, you have to setup your ifcount / ifactioncount with the higher value checked first. That's why they go in order of 12 and then 11, so that the 12 block takes precedence. If you reversed those (or got rid of the nullop blocks altogether), instead of basically "pausing" for the time in between shooting and cocking, after 11 gametics it would shoot every gametic for 13 more gametics (24 - 11), then play the cocking sound every gametic for 23 gametics (47 - 24), and so on.

This is also while you'll often see this setup:

ifcount 13
    resetcount
else
ifcount 12
    state dosomething


This resets the counter if it ever exceeds 12 (the desired target count), because otherwise if the counter is never reset, then because an actor's count is always incrementing, when your code steps into the branch where it's checking "ifcount 12", it will instantly execute because the count will be at 500 or something.
2

User is offline   VGames 

#3250

Is there a way to capture the moment the RESPAWN actor is activated and it spawns an actor? Event_Killit is a little too late. I’m trying to replace the moment an actor is spawned with a new enemy spawning actor to help further randomize the type of enemy spawned but I can’t figure out how to tap into the moment the RESPAWN actor is activated by a touch plate or some other means of getting it to activate.
0

User is offline   Fox 

  • Fraka kaka kaka kaka-kow!

#3251

Can you not use EVENT_LOADACTOR to change the RESPAWN tag?
1

User is offline   Danukem 

  • Duke Plus Developer

#3252

View PostFox, on 03 April 2023 - 01:36 AM, said:

Can you not use EVENT_LOADACTOR to change the RESPAWN tag?


that's an Even Greater Solution than the one which more closely matches his prompt lol
0

User is offline   VGames 

#3253

Event_EGS doesn’t work because the enemies being spawned in by Respawn actors are considered to be part of the enemies loaded into the map when it first loads. I found Event_Spawn to actually work the best for my needs. I just have to set it up for each enemy.
0

User is offline   Danukem 

  • Duke Plus Developer

#3254

View PostVGames, on 03 April 2023 - 01:49 PM, said:

Event_EGS doesn’t work because the enemies being spawned in by Respawn actors are considered to be part of the enemies loaded into the map when it first loads. I found Event_Spawn to actually work the best for my needs. I just have to set it up for each enemy.


Are you talking about for the purposes of the kill counter?

You can use "ifspawnedby RESPAWN" in EVENT_EGS and it works fine, you can then change them however you want.
0

User is offline   MC84 

#3255

I've been following Dan's enemy coding tutorial and am currently trying to setup the states for my enemy attacks. I was able to get decent results using the code from the PIGCOP (using ifcount 12 nullop else ifcount 11 etc).. however I wanted to try and replace these ifcount statements with ifactioncount; however it needs some fine-tuning... Basically my shoot action is 5 frames; the first 2 frames are firing the shotgun and the next 3 are reloading/pumping it. The following code works pretty much as I'd like, however the shotgun sounds occur on the 5th frame of the action... obviously if I change ifactioncount to 2 then it just plays the shotgun sound every 2 frames of the action... Is there a simple way around this, or should I split up my action into two actions? I was reluctant to do this as I've already got 15-20 for this enemy type.

defstate VALDUCKSHOOTstate
{
	ifactioncount 5
	{
		ifcanshoottarget
		{
			sound PIG_ATTACK
			shoot SHOTGUN
			ifrnd 64
			{	
				ai AIVALSTAND else
				ai AIVALDUCKSHOOT
			}
			resetactioncount
		
		}
		
	}
}
else 
ai AIVALSTAND

ends	


This state is placed inside the following AI:

ifai AIVALDUCKSHOOT state VALDUCKSHOOTstate


which contains the 5 framed action:

action AVALDUCKSHOOT 196 5 8 1 20

0

User is offline   jimbob 

#3256

personally i'd split the actions into firing and reloading, this gives you much more controll imho, maybe there is an easier way but thats how i'd do it. right now everything triggers at the same time, on frame 5 of the animation so after the actual firing frames. you could try to code it like ifactioncount 2 { sound PIG_ATTACK shoot SHOTGUN } ifactioncount 3 { sound RELOAD } ifactioncount 5 { ifrnd 64 { ifrnd 128 { ai AIVALSTAND } else { ai AIVALDUCKSHOOT } } } } resetactioncount ( got the bracketing wrong but you get the idea. right now it also seems to trigger AIVALSTAND and AIVALDUCKSHOOT at once, the else doesnt really do anything without some if statements.

but im pretty sleep deprived so i might be mistaken :P

[edit] one of the reasons i'd split it, is because once ifactioncount reaches number X it starts running the code, and afaik it will continue to do so until it gets something else to do, so ifactioncount 2, shoot stuff, and then ifactioncount 3 sound reload might just stack those things together until it reaches actioncount 5 and goes into another AI routine. so splitting it up should prevent continuous firing and sounds going off...
i'd better take a nap though :P

This post has been edited by jimbob: 12 April 2023 - 01:48 AM

2

User is offline   Danukem 

  • Duke Plus Developer

#3257

Actions normally take longer than a tic, so splitting the firing into two actions makes a lot of sense, and I do it all the time. One action is the actor aiming, the other is the frame that shows the muzzleflash. This also allows for one frame to be shown longer than the other -- I will make the aiming frame display significantly longer than the flash frame. What you want to do is make the actor fire the projectiles and make the firing sound at the moment it transitions to the muzzleflash frame. Here is an example from the army ant of AA:

state antshootstate

	ifaction ANTSHOOT
	{
		ifactioncount 1
		{
			ife bottarget -1 set botclip 10
			ifg botclip 8
			{
				ai AIANTWAIT
				set botclip 0
				break
			}
			action ANTSHOOT2
			add botclip 1
			ifvarand initflags 32 state antshootpurple else
			state antshootbullet
		}
	}
	ifaction ANTSHOOT2
	{
		ifactioncount 1
		action ANTSHOOT
	}
ends


ANTSHOOT is the aiming frame. When it reaches actioncount 1, it checks to see if it has fired 9 rounds or if there is no longer a target. If either of those conditions is true it changes to AIANTWAIT and leaves the state, at which point it will reassess what to do next tic. If those conditions are not true it fires the next bullet (or the purple plasma if it's a special ant), increments the clip counter, and switches to the muzzleflash firing frame ANTSHOOT2. Once there it simply waits one actioncount and goes back to the aiming frame.

I removed the part where it checks to see if it needs to dodge something just to keep it relatively simple.

For further reference here is the state referred to above where the bullet firing happens:

state antshootbullet
	
	sound M4FIRE
	state hitscan_targetprep
	zshoot zdist SHOTSPARK1

ends


The state hitscan_targetprep is a routine that aims the bullet up/down appropriately at the target and it takes into account additional factors. This isn't necessary if your actors will only be targeting the player though.
1

User is offline   MC84 

#3258

Thanks guys - and thanks for the detailed explanation Dan; I managed to get it working to my satisfaction.

I also had another quick question; is there some hard-coded behaviour for actors in water? I tried to quickly slap together a drowning action for my enemy but it just stays frozen on a single frame;

action AVALDROWNING 262 8 1 1 12
move VALSINKVEL 0 4
ai AIVALDROWNING		AVALDROWNING VALSINKVEL getv


ifinwater
{
	ai AIVALDROWNING else nullop
}


I mean it can't get any more basic than that; when the actor falls into water he does change to the AVALDROWNING action... but the action doesn't animate..I've triple-checked the tiles/that the action is referencing the correct number etc... so either I'm doing something really dumb or there is some hard-coded behaviour I'm unaware of..
0

User is offline   Danukem 

  • Duke Plus Developer

#3259

View PostMC84, on 12 April 2023 - 01:08 PM, said:

Thanks guys - and thanks for the detailed explanation Dan; I managed to get it working to my satisfaction.

I also had another quick question; is there some hard-coded behaviour for actors in water? I tried to quickly slap together a drowning action for my enemy but it just stays frozen on a single frame;

action AVALDROWNING 262 8 1 1 12
move VALSINKVEL 0 4
ai AIVALDROWNING		AVALDROWNING VALSINKVEL getv


ifinwater
{
	ai AIVALDROWNING else nullop
}


I mean it can't get any more basic than that; when the actor falls into water he does change to the AVALDROWNING action... but the action doesn't animate..I've triple-checked the tiles/that the action is referencing the correct number etc... so either I'm doing something really dumb or there is some hard-coded behaviour I'm unaware of..


I'm not sure if this will fully address the problem, but that snippet of code is not correct. I think what you intend is this:

ifai AIVALDROWNING nullop else ifinwater ai AIVALDROWNING

1

User is offline   MC84 

#3260

View PostDanukem, on 12 April 2023 - 01:12 PM, said:

I'm not sure if this will fully address the problem, but that snippet of code is not correct. I think what you intend is this:

ifai AIVALDROWNING nullop else ifinwater ai AIVALDROWNING



That was quick! And yes bingo the action plays now. Thanks!
0

User is offline   jimbob 

#3261

hmm, could this potentially work for realistic falldamage for enemies aswell? right now they can fall off of infinitely high sectors and be just fine... if i where to make a state
 
state falldamage
iffloordistl 1024 nullop // maximum hight, just taking a random guess here, will need to be adjusted to taste
else
ifai ai AIDROPDEAD nullop else ai AIDROPDEAD
ends


and just call it in the main line of the actors code somewhere, with the apropriate transition to when they actually hit the floor like

ifai AIDROPDEAD
 action falling
iffloordistl 32 
 ai AIDYING
sound SPLAT


or am i way off on this. its annoying they keep falling off of my bridges and buildings and not go down screaming. i would have to make several exclusions for special floor textures that will trigger a similar effect though.

This post has been edited by jimbob: 13 April 2023 - 12:30 PM

0

User is offline   Danukem 

  • Duke Plus Developer

#3262

iffloordistl is not reliable enough

For example, if you have a jumping actor that can jump across a gap, then that code would make them immediately start screaming and falling when over the gap, which would be hilarious. I also think the engine will screw you on false positives sometimes, in situations with sprite bridges or TROR, and possibly sloped floors as well. And don't forget that falling into water should not necessarily be fatal.

What I would do instead is increment a falling counter when the actor's zvel is positive (similar to the player's falling_counter, but per-actor). If the counter reaches 15 or so (i.e. 15 tics of falling), then you start their falling animation. If the actor's zvel suddenly goes from positive to not-positive it means they landed, check the surface type and apply damage appropriately based on how high the counter incremented. They could potentially survive and go back to their normal animation, too (e.g. if they landed on water)
0

User is offline   jimbob 

#3263

well the reason i want it to be pretty much instantanious is because i dont want them to fall out of sight before starting to scream and flail thier arms about, i can always make exclusions for sectors tagged 1, or using the water texture.
0

User is offline   VGames 

#3264

I was trying to add a cool floating effect to bodies and gibs and debris that's in water, but I noticed that when they reach the surface of the water they disappear. Is there a way to keep the actors from simply disappearing when they reach the surface of the water? I expected them to simply show up on top of the water above the surface, but they don't. If there is a way, how would I go about it?
0

User is offline   Mark 

#3265

are you using ifinwater while under the surface and ifonwater when they are on the surface?
0

#3266

When they're in an underwater sector have them stop at x distance from the ceiling
0

User is offline   VGames 

#3267

View Postlllllllllllllll, on 15 April 2023 - 08:24 AM, said:

When they're in an underwater sector have them stop at x distance from the ceiling


I’m doing exactly this but I’d like them to go all the way up to the surface. If I have them stop right before exiting the water I can’t see them on the water’s surface. Is there a way to have them show up on the surface too after floating all the way up until they hit the ceiling when under water?
0

#3268

Yeah. When items surface from below water they can be picked up on the surface even though they are not visible. If the jibs travel high enough to surface it would just be an issue of subtracting some Z after it stops (or stop it) on the surface of the water
0

User is offline   Danukem 

  • Duke Plus Developer

#3269

View PostVGames, on 15 April 2023 - 08:29 AM, said:

I’m doing exactly this but I’d like them to go all the way up to the surface. If I have them stop right before exiting the water I can’t see them on the water’s surface. Is there a way to have them show up on the surface too after floating all the way up until they hit the ceiling when under water?


A sprite can't be in two sectors at once, so either have it spawn a copy to be in the other sector, or transport it along with the player.
0

User is offline   Mark 

#3270

Would using TROR water be another possible solution?
0

Share this topic:


  • 119 Pages +
  • « First
  • 107
  • 108
  • 109
  • 110
  • 111
  • 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