Skip to content

Commit

Permalink
New marine squad system, improvements, and easter eggs.
Browse files Browse the repository at this point in the history
- Added a brand new squad system, now on top of marines being able to do certain things when near other marines, they can also be made to rally around a designated leader, for more information, check the updated documentation.
- Increased the default amount of time the marines spend looking for a target from 300 to 500.
- Added a new dark red color for the marines.
- Removed user_meleechance, it just took up space on the marines' custom tab for little value, as the marines are intentionally terrible at melee, and so have no reason NOT to avoid it, unless they have a berserk powerup in their inventory.
- Marine command icons will no longer appear on the map.
- Fixed a bug with the updated commands that made marines go back to staying still by default.
- Fixed a bug in SM_AlertNearbyMarines(), which ran checks on the calling marine, instead of the ally that the calling marine is trying to alert.
- The marine alerting functions can now also alert marines in the middle of fleeing from a grenade, by giving them a target to begin hunting after they stop running, if they didn't have one already.
- Removed even more YandereDev code.
- Added more easter eggs.
- Updated readme and documentation.
  • Loading branch information
inkoalawetrust committed Jun 15, 2022
1 parent 06d133c commit 407a70d
Show file tree
Hide file tree
Showing 18 changed files with 692 additions and 83 deletions.
2 changes: 1 addition & 1 deletion Design Document.txt
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ x===Worst case scenario I have to make them just keep facing the turret and walk
=MAKE A MARINE WITH A ROCKET LAUNCHER.
==Make firing states for the rocket launcher with fire coming out.
==Don't forget to crop out and add his pain frames in the file, once I make the firing sprites though, and know what frame name to give to his pain sprites.
==Make a custom rocket model, yes me, that's right, I'll try to learn Blender to make a rocket with different pitches.
*==Make a custom rocket model, yes me, that's right, I'll try to learn Blender to make a rocket with different pitches.
*==Figure out how to make the back facing sprites of the marine actually show the rocket launcher.| Done, TG5 redid all the sprites.
==Make the rocket launcher into a standalone sprite that can be picked up, and which rolls up in the air after the marine is killed.| Sprite made by me.

Expand Down
46 changes: 41 additions & 5 deletions Document.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ The editor name of their No Crouch Zone map spots (More info below) is "No Crouc
- Run away from the grenades they throw, if those grenades are about to explode.
- Intelligently dodge enemy or extremely harmful projectiles heading their way. More information below.
- Dynamically take cover behind sufficiently tall level geometry or shootable actors when attacking enemies. More information below.
- Can be set up into squads in which they stick together and follow a designated leader. And can change leaders if the previous one died.
- They have multiple death animations that can play randomly.
- Reload their rifles for every 20 rounds they fire in total.
- They first try a few times to run away from their target until out of sight, to not reload while vulnerable.
Expand All @@ -44,6 +45,7 @@ The editor name of their No Crouch Zone map spots (More info below) is "No Crouc
- Orange
- Pink
- Dark Green
- Dark Red
- 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.
Expand Down Expand Up @@ -147,12 +149,46 @@ Friendly marines can be commanded to do different things.
You can press use on them to cycle them through the following orders:

Wander: The marine will randomly wander around without following the player, and sometimes stay in place to look around.
Follow: The marine will follow the player that pressed use on him (If the player is friendly). Marines following a player are faster than when wandering, and will not stay in place.
Follow: The marine will follow the player that pressed use on him (If the player is friendly). Marines following a player move faster than when wandering, and will not stop to look around.
Stand Still: The marine will stay in place, like when first spawned. After they finish searching for enemies, they go back to standing still instead of wandering.
Exit Turret: Only applicable for marines on turrets, makes the marine exit the turret.

Pressing use on a hostile marine will cause him to alert other nearby hostile marines.

================|SQUAD BEHAVIOR|================
Marines can be optionally put into squads, in which they will follow the squads' leader around.
Marines in squads can also alert each other of enemies, this works similarly to how marines outside of squads alert each other, except there is no distance limit.

HOW TO SET UP:
To form a squad on your map, you need to give 2 or more marines a User_SquadName, this is the name of the squad the marines will be part of.
Then you need to give the squad a leader for them to rally around, to do that, just pick or make a marine that shares the same squad name,
and turn on the User_Leader variable, which will assign him as the squads' leader.

NOTE: You cannot have a squad with more than one leader, you also cannot make two opposing squads, that both share the same name.

LEADERSHIP CHANGES:
Marine squads can change their leadership around if their leader is killed. If the squads' leader is killed or entirely removed from the game,
then the squad will assign its' healthiest marine as their new leader.

In addition, marines, including the former leader, are not actually removed from their squad when killed, as there is still a chance for them
to be resurrected. However marines WILL be entirely removed from their squad if they are gibbed (Cannot be resurrected), or are entirely erased
from existance. If all the members are gibbed or erased, the squad is dissipated entirely.

NOTE: If an entire squad has been killed, and then one of the dead marines in it is resurrected. The surviving marine will set himself as the leader.

SQUAD MOVEMENT & BEHAVIOR:
When in a squad, marines will follow their leader around, and try to stay within range of him.
Generally, marine squads stay the closest together when fighting, but squad members whose current target is very powerful, will keep more distance
from their leader. To avoid all getting too close together and then being killed by whichever powerful enemy. When wandering around looking for enemies,
squads are at their most lax, and squad members are allowed to be as far as 1024 map units away from their leader without needing to head back to him.

Friendly marines that are part of a squad, but are not the squads' leader, will not follow the players' commands.
Instead, to command the members of a squad you have to give commands to the leader, which the rest of the squad
will then generally follow, such as making a squad stand still by ordering their leader to do so.

Note: Friendly marines in squads have little icons that appear over their heads for distinction, the icon with 4 human figures indicates that the marine
is a normal member. The star icon indicates that the marine is the squads' leader. Unfriendly marines do not have these icons over their heads.

================|USER VARIABLES|================
User variables allow an actor to be configured by the mapper through the editor on a per-actor basis, without requiring to modify the source code of the actor in any way.
If you don't know how to use and/or change the user variables of an actor, then click on this Imgur album to see how: https://imgur.com/a/IF9Ezo2
Expand All @@ -170,20 +206,20 @@ User_RetreatAttempts: The amount of times the marine tries to run out of sight o
- Default is 10. -1 makes the marine reload in the open, without trying to get behind cover at all.
User_AlertRange: The distance around which a marine will alert other marines on his side of a target.
- Default is 384 map units. -1 disables alerting entirely for this marine, but still allows them to hear the alerts of other marines.
User_Leader: If the marine also has a squad name specified, this tells the game that this marine should be the leader of that squad. Otherwise, it does nothing.
User_SquadName: The name of the squad the marine is in, if the squad has a leader, the marine will follow him around.
User_DodgeRange: The maximum range in which marines react to incoming projectiles.
- Default is 384 map units. -1 disables dodging entirely for this marine.
User_EnemyAlertHearingRange: The distance around which a marine can hear the alerts of other, enemy marines.
- Default is 1024 map units. -1 disables hearing enemy alerts entirely, but the marine can still be alerted by other marines on his side.
User_MeleeChance: The chance of the marine to try changing position after smacking something once.
- Default is 96, a value of 255 means that the marine will only smack a target when he gets into melee once, then change position. This variable ONLY uses a number range from 0 to 255.
User_TurretThreshold: How likely the marine is to use a turret near him. Marines are much more likely to use turrets, if they have friendly players and/or NPCs around to cover them.
- Default is 100, -1 means that the marine will never use a turret. Lower values increase the use chance.
User_FearDistance: The distance that the marine runs away to, if his target is scary enough.
- 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, and Random, which randomly picks any of the afformentioned 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_MeleeChance, User_FearDistance, and User_Color.
- 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.

Expand Down
2 changes: 1 addition & 1 deletion MAPINFO
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ DoomEdNums

GameInfo
{
AddEventHandlers = "SM_ProjectileHandler", "SM_LiquidTextureNameList"
AddEventHandlers = "SM_ProjectileHandler", "SM_LiquidTextureNameList", "SM_SquadHandler"
}
41 changes: 29 additions & 12 deletions MarineFunctions.zsc
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,12 @@ Mixin Class MarineFunctions
Return (!Other.bNoTarget && !Other.bNeverTarget && !(Other.Player && Other.Player.Cheats & CF_NOTARGET));
}

//Returns true if the marine is busy with something, mostly to prevent those stupid delicate state sequences from breaking by an abrupt state change.
Bool SM_IsBusy()
{
Return (GoingToTurret || OnTurret || RunningToReload || Evading || Crouching || SM_IsInState ("RunAway"));
}

Bool GrenadeAttackDecision (Double BlastRadius = 192, Double ThrowDistance = 1024, Double DangerDistance = 224)
{
Int ThrowChance;
Expand Down Expand Up @@ -336,7 +342,7 @@ Mixin Class MarineFunctions
//Check the list of water textures.
For (Int I = 0; I < LiquidList.WaterTextures.Size(); I++)
{
//Did we hit a solid sector or 3D floor, if yes, does its' texture much any of the ones on the list ?
//Did we hit a solid sector or 3D floor, if yes, does its' texture match any of the ones on the list ?
If (LiquidCheck.HitTexture == TexMan.CheckForTexture(LiquidList.WaterTextures[I]))
{
Splash = Spawn ("SM_BulletSplash",LiquidCheck.HitLocation);
Expand All @@ -348,7 +354,7 @@ Mixin Class MarineFunctions
//Check the list of nukage textures.
For (Int I = 0; I < LiquidList.NukageTextures.Size(); I++)
{
//Did we hit a solid sector or 3D floor, if yes, does its' texture much any of the ones on the list ?
//Did we hit a solid sector or 3D floor, if yes, does its' texture match any of the ones on the list ?
If (LiquidCheck.HitTexture == TexMan.CheckForTexture(LiquidList.NukageTextures[I]))
{
Splash = Spawn ("SM_BulletSplash",LiquidCheck.HitLocation);
Expand All @@ -361,7 +367,7 @@ Mixin Class MarineFunctions
//Check the list of blood textures.
For (Int I = 0; I < LiquidList.BloodTextures.Size(); I++)
{
//Did we hit a solid sector or 3D floor, if yes, does its' texture much any of the ones on the list ?
//Did we hit a solid sector or 3D floor, if yes, does its' texture match any of the ones on the list ?
If (LiquidCheck.HitTexture == TexMan.CheckForTexture(LiquidList.BloodTextures[I]))
{
Splash = Spawn ("SM_BulletSplash",LiquidCheck.HitLocation);
Expand All @@ -374,7 +380,7 @@ Mixin Class MarineFunctions
//Check the list of slime textures.
For (Int I = 0; I < LiquidList.SlimeTextures.Size(); I++)
{
//Did we hit a solid sector or 3D floor, if yes, does its' texture much any of the ones on the list ?
//Did we hit a solid sector or 3D floor, if yes, does its' texture match any of the ones on the list ?
If (LiquidCheck.HitTexture == TexMan.CheckForTexture(LiquidList.SlimeTextures[I]))
{
Splash = Spawn ("SM_BulletSplash",LiquidCheck.HitLocation);
Expand All @@ -387,7 +393,7 @@ Mixin Class MarineFunctions
//Check the list of lava textures.
For (Int I = 0; I < LiquidList.LavaTextures.Size(); I++)
{
//Did we hit a solid sector or 3D floor, if yes, does its' texture much any of the ones on the list ?
//Did we hit a solid sector or 3D floor, if yes, does its' texture match any of the ones on the list ?
If (LiquidCheck.HitTexture == TexMan.CheckForTexture(LiquidList.LavaTextures[I]))
{
Splash = Spawn ("SM_BulletSplash",LiquidCheck.HitLocation);
Expand Down Expand Up @@ -569,7 +575,7 @@ Mixin Class MarineFunctions
{
return (((A - B) cross (C - B))).length() / (C - B).length();
}

//Alerts nearby marines friendly to the calling one of the callers' target.
Void SM_AlertNearbyMarines (Double Range = 256, Bool SkipCheck = False)
{
Expand All @@ -588,23 +594,34 @@ Mixin Class MarineFunctions
{
PotentialMarine = AlertNearbyMarines.Thing;

If (!PotentialMarine.bDormant && PotentialMarine.GetClassName() == "SmartMarine" && Distance3DSquared (PotentialMarine) <= Range*Range && PotentialMarine.Health > 0 && !IsHostile (PotentialMarine) && !(PotentialMarine.Target)) //If the actor is not dormant, a marine, in range, is not hostile to you, and has no target already.
If (PotentialMarine != Self && !PotentialMarine.bDormant && PotentialMarine.GetClassName() == "SmartMarine" && Distance3DSquared (PotentialMarine) <= Range*Range && PotentialMarine.Health > 0 && !IsHostile (PotentialMarine)) //If the actor is not dormant, a marine, in range, is not hostile to you, and has no target already.
{
//Make sure the marine isn't in its' RunAway state or crouching, that state must NEVER be broken by being changed or having the marines' target changed during it.
If (!SM_IsInState ("RunAway") && !Crouching)
//If the marine isn't running away from a grenade and has no target currently.
If (!SmartMarine(PotentialMarine).SM_IsInState ("RunAway") && !PotentialMarine.Target)
{
PotentialMarine.Target = PotentialMarine.LastHeard = Target; //Have the marine share your target.
PotentialMarine.LastHeard = PotentialMarine.Target = Target; //Have the marine share your target.
FoundMarines = True; //A marine has been found.
If (!SM_IsInState ("See")) //If the marine isn't in its' see state already, to chase the target.
If (!SmartMarine(PotentialMarine).SM_IsInState ("See") && !SmartMarine(PotentialMarine).SM_IsBusy()) //Put the marine in his see state to begin chasing the target, if he isn't only it already and isn't busy.
{
PotentialMarine.SetStateLabel ("See"); //Then send them to it.
}
}
//If he IS running away from a grenade. But has no target that he was attacking before running away from the grenade.
Else If (SmartMarine(PotentialMarine).SM_IsInState ("RunAway") && !SmartMarine(PotentialMarine).OriginalTarget)
{
SmartMarine(PotentialMarine).OriginalTarget = PotentialMarine.LastHeard = Target; //Have the marine share your target.
FoundMarines = True; //A marine has been found.
}
}
}

If (FoundMarines) //If at least one marine was found to alert.
A_StartSound ("Marine/AlertAllies",CHAN_VOICE,attenuation:0.75);
{
If (Random (0,256) == Random (0,256))
A_StartSound ("Marine/AlertAlliesAlt",CHAN_VOICE,attenuation:0.75);
Else
A_StartSound ("Marine/AlertAllies",CHAN_VOICE,attenuation:0.75);
}
}
}

Expand Down
76 changes: 64 additions & 12 deletions Marine_Deaths.zsc
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,36 @@ Extend Class SmartMarine
{
LeaveTurret();
Super.Die (Source, Inflictor, DmgFlags, MeansOfDeath);
If (Icon)
Icon.Alpha = 0.0;
//If you were a squad leader. Then stay on the list still in case you are resurrected, but assign a new leader.
If (Squad)
{
//Remove yourself from the member list if you were gibbed.
If (Health <= GetGibHealth())
Squad.LeaveSquad(Self);

Squad.AssignNewSquadLeader(Self);
}
Else If (Master && SmartMarine(Master).Squad && Health <= GetGibHealth())
SmartMarine(Master).Squad.LeaveSquad (Self);
}

Override Void OnDestroy() //I'd consider this to be a form of death.
{
LeaveTurret();

//If you were a squad leader before erasure, remove your entry from the members array, so there are no null entries. And try assigning a new leader.
If (Squad)
{
Squad.Members.Delete(Squad.Members.Find(Self));
Squad.AssignNewSquadLeader(Self);
}

//If you were in a squad, access the squad class from your leader to remove yourself from the member list.
If (Master && SmartMarine(Master).Squad)
SmartMarine(Master).Squad.Members.Delete(SmartMarine(Master).Squad.Members.Find(Self));

If (!bDormant && Random (0,512) == Random (0,512))
{
Tracer = Spawn ("SmartMarineErased",Pos);
Expand Down Expand Up @@ -107,19 +131,47 @@ Extend Class SmartMarine
Raise:
TNT1 A 0
{
If (Icon)
Icon.Alpha = 1.0;
Else If (!Icon && Master)
{
Icon = Spawn ("SmartMarineSquadIcon",(Pos.X,Pos.Y,Pos.Z+Height));
If (Icon)
Icon.Master = Self;
}
Else If (!Icon && Squad && Squad.Leader == Self)
{;
Icon = Spawn ("SmartMarineLeaderIcon",(Pos.X,Pos.Y,Pos.Z+Height));
If (Icon)
Icon.Master = Self;
}

//Leave the squad if it is now hostile to you.
If (SmartMarine(Master) && SmartMarine(Master).Squad && IsHostile(Master))
SmartMarine(Master).Squad.LeaveSquad(Self);

//Make yourself the squad leader if after being resurrected, you find out that you are the only living squad member.
If (SmartMarine(Master) && SmartMarine(Master).Squad && SmartMarine(Master).Squad.IsEveryoneDead(Self))
SmartMarine(Master).Squad.MakeSquadLeader (Self);

//I could shorten this using String.Format(), if strings/names could even be converted to state labels that is.
If (DeathAnimPlayed == 0 || DeathAnimPlayed == 1)
Return ResolveState ("RaiseAnim1");
Else If (DeathAnimPlayed == 2)
Return ResolveState ("RaiseAnim2");
Else If (DeathAnimPlayed == 3)
Return ResolveState ("RaiseAnim3");
Else If (DeathAnimPlayed == 4)
Return ResolveState ("RaiseAnim4");
Else If (DeathAnimPlayed == 5)
Return ResolveState ("RaiseAnim5");
Else If (DeathAnimPlayed == 6)
Return ResolveState ("CrouchRaise");
Switch (DeathAnimPlayed)
{
Case 0:
Return ResolveState ("RaiseAnim1");
Case 1:
Return ResolveState ("RaiseAnim1");
Case 2:
Return ResolveState ("RaiseAnim2");
Case 3:
Return ResolveState ("RaiseAnim3");
Case 4:
Return ResolveState ("RaiseAnim4");
Case 5:
Return ResolveState ("RaiseAnim5");
Case 6:
Return ResolveState ("CrouchRaise");
}

Return ResolveState (Null);
}
Expand Down
Loading

0 comments on commit 407a70d

Please sign in to comment.