private MatchOutcome ResolveActions(SinglePlayerInputs _p1Inputs, SinglePlayerInputs _p2Inputs, GameState _currentState) { //1. Update individual actions and positions MatchOutcome p1_update_outcome = _currentState.P1_CState.UpdateCharacterState(); if (p1_update_outcome.IsEnd()) { return(p1_update_outcome); } MatchOutcome p2_update_outcome = _currentState.P2_CState.UpdateCharacterState(); if (p2_update_outcome.IsEnd()) { return(p2_update_outcome); } //2. Resolve hitbox interaction MatchOutcome hitbox_outcome = ResolveHitboxInteractions(_p1Inputs, _p2Inputs, _currentState); if (hitbox_outcome.IsEnd()) { return(hitbox_outcome); } //3. Resolve Positions ResolvePositions(_currentState); //4. Check timer if (_currentState.RemainingTime < 0) { return(new MatchOutcome(true, true, GameplayEnums.Outcome.TimeOut)); } return(new MatchOutcome()); }
void GameplayStateUpdate(SinglePlayerInputs _p1Inputs, SinglePlayerInputs _p2Inputs, bool skipRender = false) { //1.1 Check for pause? todo if (CurrentSplashState.CurrentState == SplashState.State.GameOver) { //check if any button is pressed to start a new game if (_p1Inputs.A || _p1Inputs.B || _p1Inputs.C || _p1Inputs.Start || _p2Inputs.A || _p2Inputs.B || _p2Inputs.C || _p2Inputs.Start) { ApplicationStateManager.GetInstance().SetCharacterSelectScreen(m_setData); } } else if (UpdateSplashScreen()) { } else if (m_previousState.RemainingHitstop > 0) { m_previousState.RemainingHitstop--; } else { //2. Sees if the inputs can be applied to current action GameState currentState = UpdateGameStateWithInputs(_p1Inputs, _p2Inputs, m_previousState); m_p1LastInputs = _p1Inputs; m_p2LastInputs = _p2Inputs; //3. Resolves actions MatchOutcome outcome = ResolveActions(_p1Inputs, _p2Inputs, currentState); //4. Checks if the match is over if (outcome.IsEnd()) { //Extra render on game end? GameplayRendererObject.RenderScene(m_previousState, Match, CurrentSplashState); HandleOutcome(outcome); CurrentSplashState.CurrentState = SplashState.State.RoundOver_ShowResult; CurrentSplashState.FramesRemaining = GameplayConstants.FRAMES_END_ROUND_SPLASH; //camera tests //isPanning = true; isRotating = true; } --currentState.RemainingTime; m_previousStates.Add(currentState); } if (!skipRender) { //5. Render Scene GameplayRendererObject.RenderScene(m_previousState, Match, CurrentSplashState); //6. Camera Tests CameraMoveTest(Match); } }
//updates this character's state by one frame public MatchOutcome UpdateCharacterState() { int positionOffset = 0; ++StateFrames; switch (State) { case GameplayEnums.CharacterState.AttackActive: if (StateFrames > GameplayConstants.ATTACK_ACTIVE) { State = GameplayEnums.CharacterState.AttackRecovery; StateFrames = 0; Hitboxes.RemoveAll(o => o.HitboxType == GameplayEnums.HitboxType.Hitbox_Attack); ModifyHitbox(Hitboxes, GameplayConstants.HURTBOX_WHIFF_EARLY); DisableThrowBreak = false; } if (StateFrames == GameplayConstants.ATTACK_FULL_EXTEND) { ModifyHitbox(Hitboxes, GameplayConstants.HITBOX_ACTIVE_LATE, GameplayEnums.HitboxType.Hitbox_Attack); } break; case GameplayEnums.CharacterState.AttackRecovery: if (StateFrames > GameplayConstants.ATTACK_RECOVERY_TOTAL) { State = GameplayEnums.CharacterState.Idle; StateFrames = 0; Hitboxes.RemoveAll(o => o.HitboxType == GameplayEnums.HitboxType.Hurtbox_Limb); } if (StateFrames == GameplayConstants.ATTACK_RECOVERY_SHORTEN) { ModifyHitbox(Hitboxes, GameplayConstants.HURTBOX_WHIFF_LATE); } break; case GameplayEnums.CharacterState.AttackStartup: if (StateFrames > GameplayConstants.ATTACK_STARTUP) { State = GameplayEnums.CharacterState.AttackActive; StateFrames = 0; Hitboxes.Add(CreateHitbox(GameplayEnums.HitboxType.Hitbox_Attack, GameplayConstants.HITBOX_ACTIVE_EARLY)); ModifyHitbox(Hitboxes, GameplayConstants.HURTBOX_ACTIVE); } break; case GameplayEnums.CharacterState.BeingThrown: SetCharacterHurtboxStanding(Hitboxes); if (StateFrames > GameplayConstants.THROW_BREAK_WINDOW) { if (P1) { return(new MatchOutcome(false, true, GameplayEnums.Outcome.Throw)); } else { return(new MatchOutcome(true, false, GameplayEnums.Outcome.Throw)); } } break; //this is handled in checking if a player wins case GameplayEnums.CharacterState.Blockstun: SetCharacterHurtboxStanding(Hitboxes); if (StateFrames < GameplayConstants.ATTACK_PUSHBACK_DURATION) { positionOffset = GameplayConstants.ATTACK_PUSHBACK_SPEED; } if (StateFrames > GameplayConstants.ATTACK_BLOCKSTUN) { State = GameplayEnums.CharacterState.Idle; StateFrames = 0; } break; case GameplayEnums.CharacterState.Clash: if (StateFrames > GameplayConstants.CLASH_PUSHBACK_DURATION) { State = GameplayEnums.CharacterState.Idle; StateFrames = 0; } positionOffset = GameplayConstants.CLASH_PUSHBACK_SPEED; break; case GameplayEnums.CharacterState.Crouch: SetCharacterHurtboxCrouching(Hitboxes); break; case GameplayEnums.CharacterState.Idle: SetCharacterHurtboxStanding(Hitboxes); break; case GameplayEnums.CharacterState.Inactive: throw new System.Exception("character state was inactive. not supposed to happen???"); case GameplayEnums.CharacterState.Special: MatchOutcome specialOutcome = SelectedCharacter.UpdateSpecial(this, ref positionOffset); if (specialOutcome.IsEnd()) { return(specialOutcome); } break; case GameplayEnums.CharacterState.ThrowActive: if (StateFrames > GameplayConstants.THROW_ACTIVE) { State = GameplayEnums.CharacterState.ThrowRecovery; StateFrames = 0; Hitboxes.RemoveAll(o => o.HitboxType == GameplayEnums.HitboxType.Hitbox_Throw); ModifyHitbox(Hitboxes, GameplayConstants.THROW_RECOVERY_HURTBOX); } break; case GameplayEnums.CharacterState.ThrowBreak: if (StateFrames > GameplayConstants.BREAK_DURATION) { State = GameplayEnums.CharacterState.Idle; StateFrames = 0; } positionOffset = GameplayConstants.BREAK_PUSHBACK; break; case GameplayEnums.CharacterState.ThrowingOpponent: if (StateFrames > GameplayConstants.THROW_BREAK_WINDOW) { if (P1) { return(new MatchOutcome(true, false, GameplayEnums.Outcome.Throw)); } else { return(new MatchOutcome(false, true, GameplayEnums.Outcome.Throw)); } } break; //this is handled in checking if a player wins case GameplayEnums.CharacterState.ThrowRecovery: if (StateFrames > GameplayConstants.THROW_RECOVERY) { State = GameplayEnums.CharacterState.Idle; StateFrames = 0; Hitboxes.RemoveAll(o => o.HitboxType == GameplayEnums.HitboxType.Hurtbox_Limb); } break; case GameplayEnums.CharacterState.ThrowStartup: SetCharacterHurtboxStanding(Hitboxes); if (StateFrames > GameplayConstants.THROW_STARTUP) { State = GameplayEnums.CharacterState.ThrowActive; StateFrames = 0; Hitboxes.Add(CreateHitbox(GameplayEnums.HitboxType.Hitbox_Throw, GameplayConstants.THROW_ACTIVE_RANGE)); ModifyHitbox(Hitboxes, GameplayConstants.THROW_STARTUP_HURTBOX); } break; case GameplayEnums.CharacterState.WalkBack: SetCharacterHurtboxStanding(Hitboxes); positionOffset = GameplayConstants.WALK_B_SPEED; break; case GameplayEnums.CharacterState.WalkForward: SetCharacterHurtboxStanding(Hitboxes); positionOffset = GameplayConstants.WALK_F_SPEED; break; default: throw new System.Exception("Ooops looks like I forgot to handle state : " + State.ToString()); } if (FacingRight) { Position += positionOffset; } else { Position -= positionOffset; } return(new MatchOutcome()); }