/ godot / nodes / FightInputManager.cs
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  }