@@ -305,6 +305,14 @@ namespace TFE_DarkForces
305305 attackMod->meleeDmg = 0 ;
306306 attackMod->meleeRate = FIXED (230 );
307307 attackMod->attackFlags = ATTFLAG_RANGED | ATTFLAG_LIT_RNG;
308+
309+ // new to TFE - burstfire
310+ attackMod->hasBurstFire = JFALSE;
311+ attackMod->burstFire .burstNumber = 5 ;
312+ attackMod->burstFire .variation = 2 ;
313+ attackMod->burstFire .interval = 29 ;
314+ attackMod->burstFire .shotCount = 5 ;
315+ attackMod->burstFire .lastShot = 0 ;
308316
309317 // Why is this being returned? This function maybe should be a void?
310318 return attackMod->fireOffset .y ;
@@ -318,6 +326,8 @@ namespace TFE_DarkForces
318326 moveMod->collisionFlags |= ACTORCOL_GRAVITY;
319327 // Added to disable auto-aim when dying.
320328 logic->logic .obj ->flags &= ~OBJ_FLAG_AIM;
329+
330+ logic->flags |= ACTOR_DYING; // added to stop burst fire when actor is dying
321331 }
322332
323333 // Returns JTRUE if the object is on the floor, or JFALSE is not on the floor or moving too fast.
@@ -987,6 +997,11 @@ namespace TFE_DarkForces
987997 // Do ranged attack (primary)
988998 attackMod->anim .state = STATE_ATTACK1;
989999 attackMod->timing .delay = attackMod->timing .rangedDelay ;
1000+
1001+ if (attackMod->hasBurstFire )
1002+ {
1003+ attackMod->anim .flags &= ~AFLAG_PLAYONCE; // if logic has burst fire, allow attack anim to loop
1004+ }
9901005 }
9911006
9921007 if (obj->type == OBJ_TYPE_SPRITE)
@@ -1020,7 +1035,7 @@ namespace TFE_DarkForces
10201035 } break ;
10211036 case STATE_ATTACK1:
10221037 {
1023- if (!(attackMod->anim .flags & AFLAG_READY))
1038+ if (!(attackMod->anim .flags & AFLAG_READY) && !attackMod-> hasBurstFire )
10241039 {
10251040 break ;
10261041 }
@@ -1049,7 +1064,42 @@ namespace TFE_DarkForces
10491064 obj->flags |= OBJ_FLAG_FULLBRIGHT;
10501065 }
10511066
1052- attackMod->anim .state = STATE_ANIMATE1;
1067+ // Burst fire option - set via custom logics
1068+ if (attackMod->hasBurstFire )
1069+ {
1070+ if (s_curTick < attackMod->burstFire .lastShot + attackMod->burstFire .interval )
1071+ {
1072+ break ;
1073+ }
1074+
1075+ if (logic->flags & ACTOR_DYING) { break ; }
1076+
1077+ if (attackMod->burstFire .shotCount <= 1 )
1078+ {
1079+ // Burst is finished, end the looping & reset the shot count
1080+ attackMod->anim .state = STATE_ANIMATE1;
1081+ attackMod->anim .flags |= AFLAG_PLAYONCE;
1082+
1083+ s32 var = random (attackMod->burstFire .variation * 2 );
1084+ s32 nextBurstNumber = attackMod->burstFire .burstNumber - attackMod->burstFire .variation + var;
1085+ attackMod->burstFire .shotCount = max (nextBurstNumber, 2 );
1086+ }
1087+ else
1088+ {
1089+ // Reorient towards the player
1090+ attackMod->target .yaw = vec2ToAngle (s_playerObject->posWS .x - obj->posWS .x , s_playerObject->posWS .z - obj->posWS .z );
1091+
1092+ // Fire the next shot in the burst
1093+ attackMod->burstFire .lastShot = s_curTick;
1094+ attackMod->burstFire .shotCount --;
1095+ }
1096+ }
1097+ else
1098+ {
1099+ // No burst fire -- vanilla logic
1100+ attackMod->anim .state = STATE_ANIMATE1;
1101+ }
1102+
10531103 vec3_fixed fireOffset = {};
10541104
10551105 // Calculate the X,Z fire offsets based on where the enemy is facing. It doesn't matter for Y.
0 commit comments