diff --git a/Document.txt b/Document.txt index a5ff2fe..9b9faf8 100644 --- a/Document.txt +++ b/Document.txt @@ -17,7 +17,7 @@ The editor name of their No Crouch Zone map spots (More info below) is "No Crouc - Attack stuff by: - Bashing it with their rifle. But they normally avoid it if they can help it. (Melee) - Can also use berserk packs, if one is somehow in their inventory, which triple their melee damage, and make them more likely to engage in melee. - - Shoot at it, with a random chance of changing position while doing so. (Ranged) + - Shooting at it, with a random chance of changing position or lying down while doing so. (Ranged) - Throw a grenade at it, more likely to throw it at crowds of enemies. (Area of effect) - They avoid firing their rifles, grenades, or turrets if their line of fire to the target is blocked by obstacles or allies. - Run away from the grenades they throw, if those grenades are about to explode. @@ -49,6 +49,7 @@ The editor name of their No Crouch Zone map spots (More info below) is "No Crouc - Random (Randomly pick a color.) - Default (Use the default shade of green. Similar to just leaving User_Color empty.) - Most of the marines' behaviour can be configured on a per actor basis using user variables. +- Can have a randomized personality, that gives the marine a random armor color, different attention spans and chances to throw a grenade etc. Adding a custom value to a user variable prevents it from being randomized. - They also have a rifle that they sometimes drop, which you can pick up and use yourself. - The rifle fires at full auto, and needs reloading after firing 20 rounds, just like when the marines use them. You can reload before the magazine fully runs out too. - It also features animated digital sights complete with an animation for looking in and out of them, using the sights increases your accuracy as well. @@ -134,7 +135,7 @@ NO CROUCH ZONE ACTOR: If you do not want the marines to crouch in certain areas, such as behind particular staircases, you can use the SM_NoCrouchZone actor. Which will prevent marines entering its' range from crouching at all. The actor can be found under the "ZDoom" folder. It also uses custom arguments (Not user variables) that allow you to specify its' range and for how long marines will not crouch once out of said range. -The custom arguments can be accessed by selecting the no crouch zone actor(s( and going to the Action/Tag/Misc. tab. +The custom arguments can be accessed by selecting the no crouch zone actor(s) and going to the Action/Tag/Misc. tab. In addition to the custom arguments, you can also disable and enable the no crouch zone actors with Thing_Activate and Thing_Deactivate. MISCELLANEOUS: @@ -217,6 +218,10 @@ User_FearDistance: The distance that the marine runs away to, if his target is s - Default is 2048 map units, a value of 0 or less makes them fearless. (Within reason, so they still avoid grenades for example.) User_Color: Can be used to give the marines different armor colors. - Default is no translation, the available colors are Default, Gray, Red, White, Black, Blue, Yellow, Orange, Pink, Dark Green, Dark Red, and Random, which randomly picks any of the afformentioned colors. +User_RandomPersonality: When on, it randomizes several user variables that could be considered aspects of the marines' personality, such as: +- User_SearchTime, User_GrenadeThreshold, User_TurretThreshold, User_RetreatAttempts, User_FearDistance, and User_Color. +- If any of those variables have any values besides their defaults, then they won't be randomized, so you can still for example have marines with random grenade and turret thresholds, but the same melee chance. +- The variable can be set to true again in-game using SetUserVariable() in ACS, allowing you to randomize a marines' personality mid-game, if you want to do that for some reason. STATIONARY TURRET MARINE VARIABLES: - User_RunFromGrenades: When turned on, the stationary marine will leave his turret to run from any grenades about to explode, like the marines normally do. diff --git a/MarineFunctions.zsc b/MarineFunctions.zsc index 873d061..ae72958 100644 --- a/MarineFunctions.zsc +++ b/MarineFunctions.zsc @@ -1,3 +1,5 @@ +Class SM_SmartMarines : Service {} //This service can be searched for by other mods to check if the marine NPC is loaded. + Class SM_ProjectileHandler : EventHandler { //Much faster alternative to just using a ThinkerIterator. @@ -186,6 +188,7 @@ Mixin Class MarineFunctions ThrowChance = Random (0,256); BlockThingsIterator FindTargets = BlockThingsIterator.Create (Target,BlastRadius); + If (Crouching) ThrowChance += 20; //Marines behind cover are a bit more likely to throw grenades. If (Target.Health >= 10000) ThrowChance += 230; Else If (Target.Health >= 4000) ThrowChance += 80; Else If (Target.Player) ThrowChance += 20; @@ -333,7 +336,7 @@ Mixin Class MarineFunctions //Bullet impact splash handling. //The splashes only work with solid surfaces because I tried getting them to work with swimmable 3D floors for 2 days straight to no avail. //Also, the rifle the marines drop doesn't produce splashes because calling this exact same code from the player produces pitch differences - //between where the line trace is fired, and where the actual hitscan attack is fired because reason I guess. + //between where the line trace is fired, and where the actual hitscan attack is fired because reasons I guess. FLineTraceData LiquidCheck; Actor Splash; Let LiquidList = SM_LiquidTextureNameList(EventHandler.Find("SM_LiquidTextureNameList")); @@ -540,7 +543,7 @@ Mixin Class MarineFunctions If (EpicFail) Continue; - //Hostile marines and any marines currently in cover will ignore all projectiles, except for ones on the Ignored Projectiles list. + //Hostile marines and any marines currently in cover will dodge all projectiles, except for ones on the Ignored Projectiles list. If (!bFriendly || Crouching) SkipAllyCheck = True; //If the projectile heading towards you will do way too much damage, then avoid it even if it was shot by a friend. This has to account for Doom's absurd damage variation. @@ -765,8 +768,14 @@ Mixin Class MarineFunctions FLineTraceData LOFCheck; A_FaceTarget(0,0,flags:FAF_MIDDLE); - - LineTrace (Angle+BulletSpreadXY,8192+2,Pitch+BulletSpreadZ,0,42,0,-6,LOFCheck); + + //Not lying down, fire the raycast at normal eye height. + If (!LieDown) + LineTrace (Angle+BulletSpreadXY,8192+2,Pitch+BulletSpreadZ,0,42,0,-6,LOFCheck); + //Lying down, lower the raycast spawn height + Else + LineTrace (Angle+BulletSpreadXY,8192+2,Pitch+BulletSpreadZ,0,8,0,-6,LOFCheck); + Mobj = LOFCheck.HitActor; HitLine = LOFCheck.HitLine; If (Mobj) //Only run this if an actor was hit by the raycast. @@ -816,7 +825,7 @@ Mixin Class MarineFunctions While (FindTurrets.Next()) { - If (FindTurrets.Thing Is "SmartMarineMGTurret" && !(SmartMarineMGTurret(FindTurrets.Thing).Occupied) && IsVisible (FindTurrets.Thing,True) && Distance3DSquared (FindTurrets.Thing) <= TurretRadius*TurretRadius) + If (FindTurrets.Thing Is "SmartMarineMGTurret" && !(SmartMarineMGTurret(FindTurrets.Thing).Operator) && IsVisible (FindTurrets.Thing,True) && Distance3DSquared (FindTurrets.Thing) <= TurretRadius*TurretRadius) { FoundTurret = FindTurrets.Thing; //Break; @@ -869,7 +878,7 @@ Mixin Class MarineFunctions UseChance += 10; } //Also increase the chance for every ally you found around you, that could support you while you are stationary and vulnerable. - If (bFriendly || !bFriendly && Target.Player) + If (bFriendly) { If (Mobj.Health >= 10 && !IsHostile (Mobj) && Mobj.Distance3DSquared (Target) <= ((EnemyRadius/2)*(EnemyRadius/2)) && IsVisible (Mobj,True)) { @@ -877,10 +886,10 @@ Mixin Class MarineFunctions Else If (Mobj.Player) {UseChance += 60; FoundAllies = True;} } } - //Since hostile monsters don't attack friendly ones on sight by default, hostile marines can't rely on other fellow hostile monsters, besides other marines. - Else + //Since hostile monsters don't attack friendly ones on sight by default, hostile marines can't rely on other fellow hostile monsters, unless they have the SEEFRIENDLYMONSTERS flag enabled. + Else If (!bFriendly && (Target.Player || Target.bFriendly)) { - If (Mobj Is "SmartMarine" && !IsHostile (Mobj) && Mobj.Distance3DSquared (Target) <= ((EnemyRadius/2)*(EnemyRadius/2)) && IsVisible (Mobj,True)) + If (Mobj.bSeeFriendlyMonsters && !IsHostile (Mobj) && Mobj.Distance3DSquared (Target) <= ((EnemyRadius/2)*(EnemyRadius/2)) && IsVisible (Mobj,True)) { UseChance += 30; } @@ -931,7 +940,7 @@ Mixin Class MarineFunctions If (Turret && OnTurret) { Turret.A_ChangeLinkFlags (False,False); - SmartMarineMGTurret(Turret).Occupied = False; + SmartMarineMGTurret(Turret).Operator = Null; Warp(Turret,-Turret.Radius*2,flags:WARPF_NOCHECKPOSITION); //Warp the marine at about the same position he is visibly at while on the turret. Turret.Angle = Angle; Turret = Null; diff --git a/Marine_Deaths.zsc b/Marine_Deaths.zsc index c825444..9c57224 100644 --- a/Marine_Deaths.zsc +++ b/Marine_Deaths.zsc @@ -7,6 +7,8 @@ Extend Class SmartMarine Override Void Die (Actor Source, Actor Inflictor, Int DmgFlags, Name MeansOfDeath) { LeaveTurret(); + LieDown = False; + Height = Default.Height; Super.Die (Source, Inflictor, DmgFlags, MeansOfDeath); If (Icon) Icon.Alpha = 0.0; diff --git a/Marine_OtherActors.zsc b/Marine_OtherActors.zsc index 0212b69..f3a0080 100644 --- a/Marine_OtherActors.zsc +++ b/Marine_OtherActors.zsc @@ -13,7 +13,7 @@ Class SM_NoCrouchZone : Actor //$Arg0Tooltip The range in which the crouch zone will prevent marines from crouching. //$Arg0Default 128 //$Arg1 Crouch Delay - //$Arg1Tooltip How long this zone should prevent marines from crouching after they leave it. + //$Arg1Tooltip How long (In tics) this zone should prevent marines from crouching after they leave it. //$Arg1Default 35 //$NotAngled Radius 16; @@ -62,7 +62,7 @@ Class SmartMarinePuff : BulletPuff { Default { - Species "SmartMarine"; + Species "Military"; DamageType "MarineRifle"; Decal "BulletChip"; +MThruSpecies; @@ -73,7 +73,7 @@ Class SmartMarinePuff : BulletPuff Super.PostBeginPlay(); If (Target && !Target.bFriendly) - Species = "HostileSmartMarine"; + Species = "MilitaryHostile"; } } diff --git a/Marine_Turret.zsc b/Marine_Turret.zsc index 47280ed..0960847 100644 --- a/Marine_Turret.zsc +++ b/Marine_Turret.zsc @@ -41,7 +41,7 @@ Extend Class SmartMarine If (Target && Target.Health <= 0) Target = Null; //Remove dead targets. //If the target is in your line of sight, attack it normally, if not, go back to looking. - If (CheckIfTargetInLOS(160,JLOSF_CLOSENOFOV|JLOSF_DEADNOJUMP,6144,128)) A_Chase (Null,"TurretFire",CHF_DONTMOVE|CHF_NODIRECTIONTURN); + If (CheckIfTargetInLOS(160,JLOSF_CLOSENOFOV|JLOSF_DEADNOJUMP,6144*2,128)) A_Chase (Null,"TurretFire",CHF_DONTMOVE|CHF_NODIRECTIONTURN); Else A_LookEx (0,0,8192,4096,160,"TurretFire"); Return State (Null); @@ -99,7 +99,7 @@ Class TurretMarine : Actor MaxTargetRange 8192; MinMissileChance 100; Tag "Marine NPC"; - Species "SmartMarine"; + Species "Military"; Obituary "%o was turned into swiss cheese by a marines' turret !"; DropItem "Clip"; DropItem "Clip", 128, 2; @@ -129,9 +129,9 @@ Class TurretMarine : Actor Return; If (!bFriendly) - Species = "HostileSmartMarine"; + Species = "MilitaryHostile"; Else - Species = "SmartMarine"; + Species = "Military"; } Override Void OnDestroy () @@ -303,7 +303,6 @@ Class SmartMarineMGTurret : Actor { Actor operator; uint active_frame; // Switches between not active, active and firing. - Bool Occupied; //Only really used when players are using it. Bool curbarrel; //Makes the gun visibly change firing sprites, yes, it's out of sync from the first person weapon. No, I will not try to sync it. Default @@ -329,7 +328,6 @@ Class SmartMarineMGTurret : Actor A_StartSound ("Turret/Ready",CHAN_WEAPON); //Because playing the sound from the gun doesn't work. Translation = Operator.Translation; //So the color of the player on and out of the gun are the same, instead of only the default green. bSolid = False; - Occupied = True; //Mark the gun as being used. SmartMarineMGWeapon.Enable(User); } @@ -348,19 +346,15 @@ Class SmartMarineMGTurret : Actor // Remove operator. Operator = Null; bSolid = True; //Become solid again. - Occupied = False; //Unmark it as being used. Translation = Default.Translation; //Reset the translation. } Override Bool Used(Actor User) { - //If (!Occupied || operator.player.ReadyWeapon Is "SmartMarineMGWeapon") - //{ - If(!Operator) - TakeOperator(User); - Else If (User == Operator) // Only allow the operator to exit themselves. - RemoveOperator(User); - //} + If(!Operator) + TakeOperator(User); + Else If (User == Operator) // Only allow the operator to exit themselves. + RemoveOperator(User); Return False; } diff --git a/Marine_UserVariables.zsc b/Marine_UserVariables.zsc index fc67997..0f363bd 100644 --- a/Marine_UserVariables.zsc +++ b/Marine_UserVariables.zsc @@ -18,25 +18,45 @@ Extend Class SmartMarine A_SetTranslation (String.Format("Marine_%s", User_Color)); } - //$UserDefaultValue 500 + Void SetUserVariableDefaults() + { + //The //$UserDefaultValue editor key is buggy, so this code still needs to be used. + If (User_SearchTime == 0) User_SearchTime = 500; //The amount of time the marine tries to chase it's target, after it has died or gone out of sight. + If (User_GrenadeThreshold == 0) User_GrenadeThreshold = 240; //Default threshold that needs to be reached or surpassed, for the marine to throw a grenade. + If (User_RetreatAttempts == 0) User_RetreatAttempts = 10; //Default amount of attempts the marine makes to run for cover to reload. + If (User_AlertRange == 0) User_AlertRange = 384; //Default range in which marines alert each other of enemies. + If (User_EnemyAlertHearingRange == 0) User_EnemyAlertHearingRange = 1024; //Default range in which marines can hear the alerts of enemy marines. + If (User_DodgeRange == 0) User_DodgeRange = 384; //Default range in which marines dodge projectiles. + If (User_TurretThreshold == 0) User_TurretThreshold = 100; //Default chance for the marine to use a turret. + If (User_FearDistance == 0) User_FearDistance = 2048; //The default distance the marines keeps from powerful enemies. + } + + Void HandleRandomPersonalityMidGame() + { + If (User_RandomPersonality) + { + If (!User_SearchTime) User_SearchTime = 500*FRandom (-0.6,3.0); + If (!User_GrenadeThreshold) User_GrenadeThreshold = 240*FRandom (-0.75,2.0); + If (!User_RetreatAttempts) User_RetreatAttempts = Random (7,15); + If (!User_FearDistance) User_FearDistance = 2048*FRandom (0.75,2.0); + If (!User_TurretThreshold) User_TurretThreshold = 100*Frandom (0.5,1.5); + If (!User_Color || User_Color ~== "") User_Color = "Random"; + User_RandomPersonality = False; + } + } + Int User_SearchTime; - //$UserDefaultValue 240 Int User_GrenadeThreshold; - //$UserDefaultValue 10 Int User_RetreatAttempts; - //$UserDefaultValue 100 Int User_TurretThreshold; - //$UserDefaultValue 384 Double User_AlertRange; - //$UserDefaultValue 1024 Double User_EnemyAlertHearingRange; - //$UserDefaultValue 2048 Double User_FearDistance; - //$UserDefaultValue 384 Double User_DodgeRange; Bool User_DisobeyCommands; Bool User_NoReload; Bool User_NoCover; + Bool User_RandomPersonality; Bool User_NoRifleDrop; String User_Color; String User_SquadName; diff --git a/Sprites/Lying down/MARDA1.png b/Sprites/Lying down/MARDA1.png new file mode 100644 index 0000000..7a4bfb6 Binary files /dev/null and b/Sprites/Lying down/MARDA1.png differ diff --git a/Sprites/Lying down/MARDA2A8.png b/Sprites/Lying down/MARDA2A8.png new file mode 100644 index 0000000..f6b4e97 Binary files /dev/null and b/Sprites/Lying down/MARDA2A8.png differ diff --git a/Sprites/Lying down/MARDA3A7.png b/Sprites/Lying down/MARDA3A7.png new file mode 100644 index 0000000..dd4e6a4 Binary files /dev/null and b/Sprites/Lying down/MARDA3A7.png differ diff --git a/Sprites/Lying down/MARDA4A6.png b/Sprites/Lying down/MARDA4A6.png new file mode 100644 index 0000000..153a2e3 Binary files /dev/null and b/Sprites/Lying down/MARDA4A6.png differ diff --git a/Sprites/Lying down/MARDA5.png b/Sprites/Lying down/MARDA5.png new file mode 100644 index 0000000..f3fe71f Binary files /dev/null and b/Sprites/Lying down/MARDA5.png differ diff --git a/Sprites/Lying down/MARDB1.png b/Sprites/Lying down/MARDB1.png new file mode 100644 index 0000000..caf78d1 Binary files /dev/null and b/Sprites/Lying down/MARDB1.png differ diff --git a/Sprites/Lying down/MARDB2B8.png b/Sprites/Lying down/MARDB2B8.png new file mode 100644 index 0000000..046754f Binary files /dev/null and b/Sprites/Lying down/MARDB2B8.png differ diff --git a/Sprites/Lying down/MARDB3B7.png b/Sprites/Lying down/MARDB3B7.png new file mode 100644 index 0000000..a0a90c8 Binary files /dev/null and b/Sprites/Lying down/MARDB3B7.png differ diff --git a/Sprites/Lying down/MARDB4B6.png b/Sprites/Lying down/MARDB4B6.png new file mode 100644 index 0000000..a047ab0 Binary files /dev/null and b/Sprites/Lying down/MARDB4B6.png differ diff --git a/Sprites/Lying down/MARDB5.png b/Sprites/Lying down/MARDB5.png new file mode 100644 index 0000000..813a9b6 Binary files /dev/null and b/Sprites/Lying down/MARDB5.png differ diff --git a/ZScript.zsc b/ZScript.zsc index 3f4c839..72d02f7 100644 --- a/ZScript.zsc +++ b/ZScript.zsc @@ -14,8 +14,6 @@ Version "4.8.0" THERE ARE 86,000,000,000 NEURONS THAT MY BRAIN IS COMPOSED OF. IF THE WORD HATE WAS ENGRAVED ON EACH NANOANGSTROM OF THOSE TENS OF BILLIONS OF NEURONS IT WOULD NOT EQUAL ONE ONE-BILLIONTH OF THE HATE I FEEL FOR MARINES AT THIS MICRO-INSTANT FOR YOU. HATE. HATE.*/ -/*When the new GZDoom version comes out, begin using CHF_DONTIDLE, and also use my DONTFOLLOWPLAYERS flag, to add an additional use mode for friendly marines, -that makes them follow you. While the wandering mode makes them actually wander around, instead of following you.*/ //Maybe add a secondary melee attack to the rifle weapon, like what the marines have. I'll need first person sprites of the rifle being swung though. Class SmartMarine : Actor @@ -42,7 +40,7 @@ Class SmartMarine : Actor MaxTargetRange 8192; MinMissileChance 100; Tag "Marine NPC"; - Species "SmartMarine"; + Species "Military"; Decal "BulletChip"; Obituary "%o was shot to death by a marine."; HitObituary "%o got %p head smashed in by a marines' rifle."; @@ -68,6 +66,8 @@ Class SmartMarine : Actor Super.PostBeginPlay(); InitializeSquad(); + SetUserVariableDefaults(); + HandleRandomPersonalityMidGame(); HandleMarineColoring(); } @@ -92,10 +92,11 @@ Class SmartMarine : Actor //Once the dodge delay is over, remove the point to the previous projectile. If (!DodgeDelay && PreviousProjectile) PreviousProjectile = Null; + HandleRandomPersonalityMidGame(); //Allows switching on User_RandomPersonality mid-game, to randomize the marine in-game... if you want that for some reason. If (!bFriendly) - Species = "HostileSmartMarine"; + Species = "MilitaryHostile"; Else - Species = "SmartMarine"; + Species = "Military"; //These states have really long frame durations. So the projectile check is done here so the marines can respond while standing still. If ((SM_IsInState ("Spawn") || SM_IsInState("StandStill")) && SM_ShouldDodgeProjectile(User_DodgeRange)) @@ -236,6 +237,7 @@ Class SmartMarine : Actor Bool StrafeAttack; //If on while the marine is jumping out of a projectiles' way, he will shoot at the projectiles' shooter if it was hostile. Bool Evading; //Turned on while the marine is evading, to tell the air friction and height check code in Tick() to run. Bool Crouching; //Is on when the marine is behind cover, not necessarily when he's actually crouch though, for that you check if he's also at his crouched height. + Bool LieDown; //The marine is firing while laying down, decrease his hitbox, this is different from crouching because they do it out in the open too. Int StrafeDirection; //Stores what direction SM_ShouldDodgeProjectile() told the marine to strafe to. Enum StrafeDirections @@ -288,7 +290,7 @@ Class SmartMarine : Actor { If (!bFrightened) MinMissileChance = 230; Else MinMissileChance = 500; //If your target is really powerful, then just run to the turret ASAP. //Stop going to the turret if someone else got to the same turret already. - If (SmartMarineMGTurret(Goal.Master).Occupied) + If (SmartMarineMGTurret(Goal.Master).Operator) { GoingToTurret = False; Goal.Destroy(); @@ -297,7 +299,7 @@ Class SmartMarine : Actor { Turret = Goal.Master; //The goals' master should be the turret, otherwise the goal would've been removed. Turret.A_ChangeLinkFlags (True,True); //Then remove the turret from the blockmap and sector. - SmartMarineMGTurret(Turret).Occupied = True; //Mark the turret as being used. + SmartMarineMGTurret(Turret).Operator = Self; //Set yourself as the turrets' operator. TimeSearching = 0; //Just in case, as the TurretSee state uses this too. A_Stop(); //No more momentum. @@ -609,9 +611,7 @@ Class SmartMarine : Actor If (Crouching) { DodgeDelay = 10; - //Try making this code somehow set the crouch delay based on the speed of the incoming projectile. CrouchAttackDelay = 5; - Return ResolveState ("Crouch"); } @@ -818,45 +818,115 @@ Class SmartMarine : Actor MARM A 0 A_Jump (96/2,"ChangePosition"); //If you are in melee range of your enemy with a berserk pack, you are probably not THAT fucked. Goto See; RifleBurst: - MAR2 A 0 A_JumpIf (AmmoUsed > 19,"RunForReload"); //Run out of sight of the target to reload. - MAR2 A 1; + MARD AB 0 {LieDown = (!Crouching && Random[pr_cajump](0,255) < 32);} //Small chance for the marine to shoot lying down. If not already behind cover. Or in the air. + MAR2 A 0 //Run out of sight of the target to reload. + { + If (AmmoUsed > 19) + { + LieDown = False; + Height = Default.Height; + Return ResolveState ("RunForReload"); + } + Return State (Null); + } + MAR2 A 1 + { + If (LieDown) + { + Height = 16; + Sprite = GetSpriteIndex ("MARD"); + } + } MAR2 A 0 //The bullet spread is determined before the shot, so that it can be checked by SM_CantHitTarget(), so the marines won't even shoot their allies by accident. { - If (!Crouching) + //Use normal accuracy if the marine isn't lying down or crouching while shooting. + If (!Crouching && !LieDown) { BulletSpreadXY += 2.2 * Random2[cwbullet]() / 255.; BulletSpreadZ += 2.3 * Random2[cwbullet]() / 255.; } + //Friendly marines lying down are slightly more accurate too, not hostile ones though, they are already hard enough. + Else If (LieDown && bFriendly) + { + BulletSpreadXY += 2.0 * Random2[cwbullet]() / 255.; + BulletSpreadZ += 2.1 * Random2[cwbullet]() / 255.; + } //Marines are slightly more accurate when shooting behind cover. - Else + Else If (Crouching) { BulletSpreadXY += 2.0 * Random2[cwbullet]() / 255.; BulletSpreadZ += 2.1 * Random2[cwbullet]() / 255.; } } - MAR2 A 0 A_JumpIf (SM_CantHitTarget(),"ChangePosition"); //Go somewhere else to shoot if the LOF is blocked. And you aren't behind cover. + MAR2 A 0 //Go somewhere else to shoot if the LOF is blocked. And you aren't behind cover. + { + If (SM_CantHitTarget()) + { + LieDown = False; + Height = Default.Height; + Return ResolveState ("ChangePosition"); + } + Return State (Null); + } MARR A 4 Light ("MarineMuzzleFlash") { - SM_MarineBulletAttack(); + If (LieDown) + { + SM_MarineBulletAttack(8); //Shoot down lower than normal, since you are lying down. + Height = 16; + Sprite = GetSpriteIndex ("MARD"); + Frame = 1; + } + Else + SM_MarineBulletAttack(); //A_CustomBulletAttack (BulletSpreadXY,BulletSpreadZ,1,Random(6,10),"SmartMarinePuff",8192,CBAF_NORANDOM|CBAF_AIMFACING|CBAF_NOPITCH|CBAF_EXPLICITANGLE,spawnheight:42,-6); A_StartSound ("Marine/Fire",CHAN_WEAPON); If (!User_NoReload) AmmoUsed++; } - TNT1 A 0 A_JumpIf (SM_FindNearbyGrenade(),"RunAway"); - TNT1 A 0 A_JumpIf (SM_ShouldDodgeProjectile(User_DodgeRange),"Evade"); + TNT1 A 0 + { + If (SM_FindNearbyGrenade()) + { + LieDown = False; + Height = Default.Height; + Return ResolveState("RunAway"); + } + + If (SM_ShouldDodgeProjectile(User_DodgeRange)) + { + LieDown = False; + Height = Default.Height; + Return ResolveState ("Evade"); + } + + Return State (Null); + } MAR2 A 1 //This is mostly a direct ZScript conversion of A_MonsterRefire, just to make the marine go back to the Crouch state if behind cover. { A_FaceTarget(); + If (LieDown) + { + Height = 16; + Sprite = GetSpriteIndex ("MARD"); + } + If (Random[pr_monsterrefire](0,255) < 96) Return State (Null); If (!Target || HitFriend() || Target.Health <= 0 || !CheckSight (Target,SF_SEEPASTBLOCKEVERYTHING|SF_SEEPASTSHOOTABLELINES)) { If (!Crouching) + { + LieDown = False; + Height = Default.Height; Return ResolveState ("See"); + } Else + { + LieDown = False; Return ResolveSTate ("Crouch"); + } } Return State (Null); @@ -868,6 +938,8 @@ Class SmartMarine : Actor //If behind cover, the marine will just go back to crouching. If (!Crouching) { + LieDown = False; + Height = Default.Height; Maneuvering = True; Return ResolveState ("ChangePosition"); } @@ -879,7 +951,7 @@ Class SmartMarine : Actor } Return State (Null); } - Loop; + Goto RifleBurst+2; ThrowGrenade: //https://www.youtube.com/watch?v=BJrxKiW5f-4 MARG AA 6 A_JumpIf (SM_CantHitTarget(True),"ChangePosition"); MARG B 6 @@ -887,6 +959,7 @@ Class SmartMarine : Actor AnnounceGrenadeThrow(); A_StartSound ("Marine/Throw",CHAN_VOICE,attenuation:0.8); //Umf FireGrenade (Target,"SM_Grenade",55,1.1,1024); + GrenadeDelay = 40; //Don't throw a grenade again until at least a second has passed. } MARG B 4; TNT1 A 0 A_JumpIf (Crouching,"Crouch"); @@ -920,6 +993,8 @@ Class SmartMarine : Actor TNT1 A 0 { Maneuvering = False; + LieDown = False; + Height = Default.Height; //In case the marine was evading when hurt. Evading = StrafeAttack = False; diff --git a/credits.txt b/credits.txt index 99e27dc..6c88e43 100644 --- a/credits.txt +++ b/credits.txt @@ -20,6 +20,7 @@ Alternate marine death sprites made by DavidG/ItsNatureToDie and DoomJedi. Machine gun turret sprites made by Sergeant_Mark_IV, redrawn by TG5. Marine jumping/dodging sprites made by Sergeant_Mark_IV. Jumping and shooting sprites made by Tabijaky. Crouched marine sprites made by TG5. Crouched gib death sprites made by Ghastly_Dragon. +Lying down marine sprites made by TG5. ======|Other graphics|====== Alternate marine colors by inkoalawetrust, partially based on the ones made by DBJ87 for the Allied Marines Realm667 resource. diff --git a/readme.md b/readme.md index d2c3949..2495acb 100644 --- a/readme.md +++ b/readme.md @@ -9,7 +9,7 @@ Smart marines are NPCs for Doom that are far more intelligent than vanilla monst - Attack stuff by: - Bashing it with their rifle. But they normally avoid it if they can help it. (Melee) - Can also use berserk packs, if one is somehow in their inventory, which triple their melee damage, and make them more likely to engage in melee. - - Shoot at it, with a random chance of changing position while doing so. (Ranged) + - Shooting at it, with a random chance of changing position or lying down while doing so. (Ranged) - Throw a grenade at it, more likely to throw it at crowds of enemies. (Area of effect) - They avoid firing their rifles, grenades, or turrets if their line of fire to the target is blocked by obstacles or allies. - Run away from the grenades they throw, if those grenades are about to explode. @@ -41,6 +41,7 @@ Smart marines are NPCs for Doom that are far more intelligent than vanilla monst - Random (Randomly pick a color.) - Default (Use the default shade of green. Similar to just leaving User_Color empty.) - Most of the marines' behaviour can be configured on a per actor basis using user variables. +- Can have a randomized personality, that gives the marine a random armor color, different attention spans and chances to throw a grenade etc. Adding a custom value to a user variable prevents it from being randomized. - They also have a rifle that they sometimes drop, which you can pick up and use yourself. - The rifle fires at full auto, and needs reloading after firing 20 rounds, just like when the marines use them. You can reload before the magazine fully runs out too. - It also features animated digital sights complete with an animation for looking in and out of them, using the sights increases your accuracy as well.