FightInputManager.cs
1 using Godot; 2 using Game.Util; 3 using System.Collections.Generic; 4 using System.Linq; 5 6 namespace Game.Nodes; 7 8 [GlobalClass] 9 public partial class FightInputManager : Node 10 { 11 public bool Playing { get; set; } 12 public int MultiPressFrameWindow { get; set; } = 5; 13 public Fighter PlayerOne { get; set; } 14 public Fighter PlayerTwo { get; set; } 15 16 private readonly Stack<InputMetadata> playerOneInputs = new(); 17 private readonly Stack<InputMetadata> playerTwoInputs = new(); 18 private int playerOneFrameCount; 19 private int playerTwoFrameCount; 20 private double frame; 21 22 public override void _PhysicsProcess(double delta) 23 { 24 if(Playing) 25 { 26 updateFrames(delta); 27 GD.Print("Frame Count: ", playerOneFrameCount); 28 var nextInput = readInput(); 29 GD.Print("Raw Next Input: ", nextInput); 30 var player = detectPlayer(nextInput); 31 nextInput = detectComplexInput(nextInput, player); 32 33 updateLog(nextInput, player); 34 processInput(nextInput, player); 35 } 36 } 37 38 public void Reset() 39 { 40 Playing = false; 41 42 frame = 0; 43 44 playerOneInputs.Clear(); 45 playerOneFrameCount = 0; 46 47 playerTwoInputs.Clear(); 48 playerTwoFrameCount = 0; 49 } 50 51 private void processInput(FightInput input, Player player) 52 { 53 switch(player) 54 { 55 case Player.One: 56 PlayerOne.HandleFightInput(input); 57 break; 58 59 case Player.Two: 60 PlayerTwo.HandleFightInput(input); 61 break; 62 } 63 } 64 65 private FightInput detectComplexInput(FightInput input, Player player) 66 { 67 var previousInputs = player switch 68 { 69 Player.Two => playerTwoInputs.TakeLast(2), 70 _ => playerOneInputs.TakeLast(2), 71 }; 72 73 switch(input) 74 { 75 case FightInput.MoveBackward: 76 if(previousInputs.FirstOrDefault().input == FightInput.MoveBackward 77 && previousInputs.LastOrDefault().input == FightInput.Neutral 78 && previousInputs.FirstOrDefault().frameCount + previousInputs.LastOrDefault().frameCount < MultiPressFrameWindow) 79 return FightInput.MoveDashBackward; 80 else 81 return FightInput.MoveBackward; 82 83 84 case FightInput.MoveForward: 85 if(previousInputs.FirstOrDefault().input == FightInput.MoveForward 86 && previousInputs.LastOrDefault().input == FightInput.Neutral 87 && previousInputs.FirstOrDefault().frameCount + previousInputs.LastOrDefault().frameCount < MultiPressFrameWindow) 88 return FightInput.MoveDashForward; 89 else 90 return FightInput.MoveForward; 91 92 case FightInput.MoveLeft: 93 return FightInput.MoveLeft; 94 95 case FightInput.MoveRight: 96 return FightInput.MoveRight; 97 98 default: 99 return input; 100 } 101 } 102 103 private static Player detectPlayer(FightInput input) 104 { 105 return input switch 106 { 107 FightInput.PlayerTwo_Attack1 or FightInput.PlayerTwo_Attack2 108 or FightInput.PlayerTwo_Attack3 or FightInput.PlayerTwo_Attack4 109 or FightInput.PlayerTwo_MoveBackward or FightInput.PlayerTwo_MoveDashBackward 110 or FightInput.PlayerTwo_MoveDashForward or FightInput.PlayerTwo_MoveForward 111 or FightInput.PlayerTwo_MoveLeft or FightInput.PlayerTwo_MoveRight 112 or FightInput.PlayerTwo_MoveSidewalkLeft or FightInput.PlayerTwo_MoveSidewalkRight => Player.Two, 113 114 _ => Player.One, 115 }; 116 } 117 118 private static FightInput readInput() 119 { 120 if(Input.IsActionPressed("Attack1") 121 && Input.IsActionPressed("Attack2") 122 && Input.IsActionPressed("Attack3") 123 && Input.IsActionPressed("Attack4")) 124 return FightInput.Attack1234; 125 126 else if(Input.IsActionPressed("Attack1") 127 && Input.IsActionPressed("Attack2") 128 && Input.IsActionPressed("Attack3")) 129 return FightInput.Attack123; 130 131 else if(Input.IsActionPressed("Attack1") 132 && Input.IsActionPressed("Attack2") 133 && Input.IsActionPressed("Attack4")) 134 return FightInput.Attack124; 135 136 else if(Input.IsActionPressed("Attack1") 137 && Input.IsActionPressed("Attack3") 138 && Input.IsActionPressed("Attack4")) 139 return FightInput.Attack134; 140 141 else if(Input.IsActionPressed("Attack2") 142 && Input.IsActionPressed("Attack3") 143 && Input.IsActionPressed("Attack4")) 144 return FightInput.Attack234; 145 146 else if(Input.IsActionPressed("Attack1") 147 && Input.IsActionPressed("Attack2")) 148 return FightInput.Attack12; 149 150 else if(Input.IsActionPressed("Attack1") 151 && Input.IsActionPressed("Attack3")) 152 return FightInput.Attack13; 153 154 else if(Input.IsActionPressed("Attack1") 155 && Input.IsActionPressed("Attack4")) 156 return FightInput.Attack14; 157 158 else if(Input.IsActionPressed("Attack2") 159 && Input.IsActionPressed("Attack3")) 160 return FightInput.Attack23; 161 162 else if(Input.IsActionPressed("Attack2") 163 && Input.IsActionPressed("Attack4")) 164 return FightInput.Attack24; 165 166 else if(Input.IsActionPressed("Attack3") 167 && Input.IsActionPressed("Attack4")) 168 return FightInput.Attack34; 169 170 else if(Input.IsActionPressed("Attack1")) 171 return FightInput.Attack1; 172 173 else if(Input.IsActionPressed("Attack2")) 174 return FightInput.Attack2; 175 176 else if(Input.IsActionPressed("Attack3")) 177 return FightInput.Attack3; 178 179 else if(Input.IsActionPressed("Attack4")) 180 return FightInput.Attack4; 181 182 else if(Input.IsActionPressed("MoveRight")) 183 return FightInput.MoveForward; 184 185 else if(Input.IsActionPressed("MoveLeft")) 186 return FightInput.MoveBackward; 187 188 else if(Input.IsActionPressed("MoveUp")) 189 return FightInput.MoveLeft; 190 191 else if(Input.IsActionPressed("MoveDown")) 192 return FightInput.MoveRight; 193 194 return FightInput.Neutral; 195 } 196 197 private void updateFrames(double delta) 198 { 199 frame += delta; 200 201 if(frame > 1) 202 { 203 frame = 0; 204 playerOneFrameCount++; 205 playerTwoFrameCount++; 206 } 207 } 208 209 private void updateLog(FightInput input, Player player) 210 { 211 switch(player) 212 { 213 case Player.One: 214 var previous = playerOneInputs.LastOrDefault(); 215 216 if(previous.input == input) 217 { 218 previous.frameCount = playerOneFrameCount; 219 } 220 else 221 { 222 playerOneFrameCount = 0; 223 playerOneInputs.Push(new() 224 { 225 frameCount = playerOneFrameCount, 226 input = input, 227 }); 228 } 229 break; 230 231 case Player.Two: 232 var previous2 = playerTwoInputs.LastOrDefault(); 233 234 if(previous2.input == input) 235 { 236 previous.frameCount = playerTwoFrameCount; 237 } 238 else 239 { 240 playerTwoFrameCount = 0; 241 playerTwoInputs.Push(new() 242 { 243 frameCount = playerOneFrameCount, 244 input = input, 245 }); 246 } 247 break; 248 } 249 } 250 }