private ACTOR_STATE CheckTileState() { processedState = ACTOR_STATE.NONE; switch (currentTile.effectsOnTile) { case Tile.TILE_EFFECTS.CHILL | Tile.TILE_EFFECTS.HAUNT: case Tile.TILE_EFFECTS.HAUNT: GameObject player = GameObject.FindGameObjectWithTag("Player"); if (player) { Haunt h = player.GetComponent <Haunt>(); moveDirection = h.HauntActor(this); forceDirection = true; PlaySound(3, 0); gameObject.GetComponent <Animator>().Play("Run 01"); } else { Debug.LogError("Found haunted tile but no player for getting the haunt direction"); } processedState = ACTOR_STATE.HAUNTED; break; case Tile.TILE_EFFECTS.CHILL: processedState = ACTOR_STATE.CHILLED; break; default: processedState = ACTOR_STATE.NONE; break; } return(processedState); }
// place the currently held data in Output IEnumerator OUTPUT() { // detect possible errors first if (CurrentValue == null) { // cannot output null error = true; currentState = ACTOR_STATE.REPORTING; yield return(StartCoroutine(currentState.ToString())); } else if (!OutputBox.GetComponent <OutputBox>().Output(CurrentValue.Value)) { // current value is not correct for this solution error = true; currentState = ACTOR_STATE.REPORTING; yield return(StartCoroutine(currentState.ToString())); } // current value is correct HideDataCube(); CurrentValue = null; yield return(new WaitForSeconds(InstructionDelay)); currentState = ACTOR_STATE.REPORTING; }
// initial state of Computron public void Start() { // acquire Scene References commandStream = FindObjectOfType <Interpreter>(); cardContainer = GameObject.FindWithTag("RegisterContainer").GetComponent <CardContainer>(); InputBox = this.transform.parent.Find("Input").gameObject; OutputBox = this.transform.parent.Find("Output").gameObject; StepButton = GameObject.FindWithTag("Step"); // initialize starting parameters transform.position = RestWaypoint.transform.position; current = null; previous = null; // kick off the state machine currentState = ACTOR_STATE.IDLE; error = false; conditionalResult = null; CurrentValue = null; SecondValue = null; stepping = false; step = false; implicitSubmit = false; stepCount = 0; StartCoroutine(ActorStateMachine()); }
// if current value is null, jump; else, continue sequential execution IEnumerator JUMP_IF_NULL() { yield return(new WaitForSeconds(InstructionDelay)); conditionalResult = (CurrentValue == null); currentState = ACTOR_STATE.REPORTING; }
// place the currently held value in the specified Card IEnumerator MOVE_TO() { // grab card reference CurrentArg = current.Arg; CardLogic card = cardContainer.GetCard((int)CurrentArg); HideDataCube(); // trying to store null causes a runtime error if (CurrentValue == null) { error = true; currentState = ACTOR_STATE.REPORTING; yield return(StartCoroutine(currentState.ToString())); } else { // put down the value held, and hands are now empty card.MoveTo((int)CurrentValue); CurrentValue = null; yield return(new WaitForSeconds(InstructionDelay)); } currentState = ACTOR_STATE.REPORTING; }
// simulates the current command being carried out IEnumerator PROCESSING() { while (currentState == ACTOR_STATE.PROCESSING) { // grab the next instruction FetchCommand(); // need to ensure current position is accurate if (!(current.Instruction == OpCode.JUMP) && !(current.Instruction == OpCode.JUMP_IF_NULL) && !(current.Instruction == OpCode.NO_OP) && !(current.Instruction == OpCode.SUBMIT)) { currentState = ACTOR_STATE.MOVING; yield return(StartCoroutine(currentState.ToString())); } if (current == null) { Debug.Log("Processing aborted"); break; } // execute the instruction yield return(StartCoroutine(current.Instruction.ToString())); } }
public override void OnExitState(ACTOR_STATE state) { if (state == ACTOR_STATE.AS_RUN && curActorState == ACTOR_STATE.AS_RUN) { RunType = 0; if (AudioSource1 != null) { AudioSource1.loop = false; AudioSource1.Stop(); } } }
// pull a value from Input IEnumerator INPUT() { // insert a pause if grabbing consecutive inputs so the action is visible to the player if (previous != null && previous.Instruction == OpCode.INPUT) { yield return(new WaitForSeconds(InstructionDelay)); } // Computron picks up the top item from Input CurrentValue = InputBox.GetComponent <InputBox>().Input(); ShowDataCube(CurrentValue); currentState = ACTOR_STATE.REPORTING; }
// get a copy of the top value from the specified Card // the Card still keeps the value IEnumerator COPY_FROM() { // get card reference CurrentArg = current.Arg; CardLogic card = cardContainer.GetCard((int)CurrentArg); // insert a pause if grabbing consecutive inputs so the action is visible to the player if (previous != null && previous.Instruction == OpCode.COPY_FROM) { yield return(new WaitForSeconds(InstructionDelay)); } // Computron gets a copy of the top item from the specified Card CurrentValue = (int)card.CopyFrom(); ShowDataCube(CurrentValue); currentState = ACTOR_STATE.REPORTING; }
// if current value is less than value at destination, jump; else, continue sequential execution IEnumerator JUMP_IF_LESS() { // grab card reference CurrentArg = current.Arg; CardLogic card = cardContainer.GetCard((int)CurrentArg); // Computron gets a copy of the top item from the specified Card SecondValue = card.CopyFrom(); // ensure neither value is null if (CurrentValue == null || SecondValue == null) { error = true; currentState = ACTOR_STATE.REPORTING; yield return(StartCoroutine(currentState.ToString())); } yield return(new WaitForSeconds(InstructionDelay)); conditionalResult = (CurrentValue < SecondValue); // show the two values being compared DisplayMessage(CurrentValue.ToString()); yield return(new WaitForSeconds(InstructionDelay)); DisplayMessage(DisplayText.text + " < "); yield return(new WaitForSeconds(InstructionDelay)); DisplayMessage(DisplayText.text + SecondValue.ToString()); yield return(new WaitForSeconds(InstructionDelay)); DisplayMessage(DisplayText.text + " ?"); yield return(new WaitForSeconds(InstructionDelay)); DisplayMessage(conditionalResult.ToString()); yield return(new WaitForSeconds(InstructionDelay)); ShowDataCube(CurrentValue); HideTextBox(); currentState = ACTOR_STATE.REPORTING; }
public void ScreamedAt(ACTOR_DIRECTION dir) { moveDirection = dir; forceDirection = true; TryForceActorToNextTile(); if (forceDirection) { transform.LookAt(movementTarget.characterPosition, Vector3.up); gameObject.GetComponent <Animator>().Play("Run 01"); state = ACTOR_STATE.MOVING; } else { Debug.LogError("Screamed Actor in a non valid direction"); state = ACTOR_STATE.CHOOSING; } talkRefreshTimer = talkRefresh; talkCooldownTimer = talkCooldown; ResetTalkingActor(); }
// final instruction of every solution IEnumerator SUBMIT() { DisplayMessage("."); yield return(new WaitForSeconds(0.5f)); DisplayMessage(".."); yield return(new WaitForSeconds(0.5f)); DisplayMessage("..."); yield return(new WaitForSeconds(InstructionDelay)); HideTextBox(); // check the solution bool res = OutputBox.GetComponent <OutputBox>().GradeOutput(); if (!res) { error = true; } currentState = ACTOR_STATE.REPORTING; }
// place a copy of the currently held value in the specified Card // Computron still keeps the held value IEnumerator COPY_TO() { // get card reference CurrentArg = current.Arg; CardLogic card = cardContainer.GetCard((int)CurrentArg); // trying to store null causes a runtime error if (CurrentValue == null) { error = true; currentState = ACTOR_STATE.REPORTING; yield return(StartCoroutine(currentState.ToString())); } else { // put down a copy of the value held card.CopyTo((int)CurrentValue); yield return(new WaitForSeconds(InstructionDelay)); } currentState = ACTOR_STATE.REPORTING; }
// controls movement between waypoints IEnumerator MOVING() { while (currentState == ACTOR_STATE.MOVING) { // initialize values needed for movement var currentPosition = transform.position; var targetPosition = FindTargetWaypoint(); var translationVector = targetPosition - currentPosition; // stop within a certain distance and move to processing state if (translationVector.sqrMagnitude < 0.5) { currentState = ACTOR_STATE.PROCESSING; } else { UpdatePosition(currentPosition, targetPosition); } yield return(null); } }
// called via Interpreter when the player hits the Halt button public void AbortExecution() { // snap back to idle waypoint and reset all state machine values transform.position = RestWaypoint.transform.position; current = null; previous = null; stepping = false; CurrentValue = null; SecondValue = null; conditionalResult = null; error = false; implicitSubmit = false; stepCount = 0; MoveSpeed = 0.3f; InstructionDelay = 0.3f; // halt all processes and start a new instance of the state machine StopAllCoroutines(); currentState = ACTOR_STATE.IDLE; HideTextBox(); HideDataCube(); StartCoroutine(ActorStateMachine()); }
//*** END OF STATE MACHINE ***// //*** INTERPRETER INTERACTIONS ***// // signal function for the Interpreter to let the Actor know to begin collecting commands public void BeginProcessing() { currentState = ACTOR_STATE.PROCESSING; }
// used only as a landing spot for jump instructions IEnumerator NO_OP() { yield return(new WaitForSeconds(InstructionDelay)); currentState = ACTOR_STATE.REPORTING; }
// generates a report for the instruction that was executed IEnumerator REPORTING() { if (error) { // halt the simulation if an error was encountered in processing CompleteExecution(new ExecutionReport(error, conditionalResult)); currentState = ACTOR_STATE.HALTED; yield return(StartCoroutine(currentState.ToString())); } // if the player is stepping through a solution, we need to hold here while (stepping) { stepCount++; // if we have a Jump or Conditional Jump command, we need to adjust the stepCount accordingly if (current.Instruction == OpCode.JUMP || conditionalResult == true) { // update stepCount stepCount = (int)current.Target; // if this puts us on the second to last command, we need to implicitly submit the solution if (stepCount + 1 == commandStream.GetInstructionCount()) { implicitSubmit = true; } // otherwise, assert false else { implicitSubmit = false; } } // moves to the SUBMIT command without requiring the player to click step again if (implicitSubmit) { BeginProcessing(); } // wait for the player to click step again stepping = false; StepButton.GetComponent <UIControl>().Enable(); while (currentState == ACTOR_STATE.REPORTING) { yield return(null); } break; } // generate a report based on the current values CompleteExecution(new ExecutionReport(error, conditionalResult)); // reset values conditionalResult = null; error = false; // if the simulation is complete while (current.Instruction == OpCode.SUBMIT) { yield return(null); } // else, continue processing currentState = ACTOR_STATE.PROCESSING; }
// Update is called once per frame void Update() { #if UNITY_EDITOR if (currentTile == null) { Debug.Log(this.actorName + " no current tile"); } #endif //Updating the UI if (barScript != null) { if (fear < fearSpookedAmount) { fearStatus = "Normal"; } else if (fear >= fearSpookedAmount && fear < fearPanicAmount) { fearStatus = "Spooked"; } else if (fear >= fearPanicAmount && fear < 100) { fearStatus = "PANIC!"; } else if (fear >= 100) { fearStatus = "FAINTED!!!"; } barScript.SetAmount(fear * 0.01f, fearStatus); } //Updating state for the player if (fear > fearPanicAmount) { isPanicking = true; } else { isPanicking = false; } if (fear >= 100 && state != ACTOR_STATE.FIENTED) { PlaySound(4, 0.0f); string randoFall = "Fall 0" + Random.Range(1, 4); gameObject.GetComponent <Animator>().Play(randoFall); state = ACTOR_STATE.FIENTED; } //Always decrease fear if (fear > 0) { fear -= Time.deltaTime * fearReductionPerSecond; } //Lower limit is zero fear = Mathf.Max(fear, 0); if (state == ACTOR_STATE.FIENTED) { if (fear < 80) { roamingWaitTime = Random.Range(minRoamingWaitTime, maxRoamingWaitTime); roamingT = 0f; state = ACTOR_STATE.CHOOSING; } } else if (state == ACTOR_STATE.MOVING) { if (talkRefreshTimer > 0) { talkRefreshTimer -= Time.deltaTime; if (talkRefreshTimer < 0) { talkRefreshTimer = 0; } } if (GetActorFearState() == LevelController.ACTOR_STATES.NORMAL && !forceDirection) { gameObject.GetComponent <Animator>().Play("Walk 01"); } else { gameObject.GetComponent <Animator>().Play("Run 01"); } movementT += Time.deltaTime * GetSpeed(); if (movementT < 1.0f) { if (currentTile != null && movementTarget != null) { this.transform.position = Vector3.Lerp(currentTile.characterPosition, movementTarget.characterPosition, movementT); } else { Debug.LogError("Movement attempt without start or end tile"); } } else { this.transform.position = movementTarget.characterPosition; state = ACTOR_STATE.GETNEXTTILE; } } else if (state == ACTOR_STATE.GETNEXTTILE) { if (talkRefreshTimer > 0) { talkRefreshTimer -= Time.deltaTime; if (talkRefreshTimer < 0) { talkRefreshTimer = 0; } } previousTile = currentTile; currentTile = movementTarget; movementT = 0; currentTile.occupant = this.gameObject; //Checking if the tile is marked with something; //This will set Processed state //If none then next operation is talking or continue moving if panicked CheckTileState(); switch (processedState) { case ACTOR_STATE.NONE: if (forceDirection) { //forcing actor to move in a direction, if failing forcedirection will be setted to false TryForceActorToNextTile(); if (forceDirection) { transform.LookAt(movementTarget.characterPosition, Vector3.up); state = ACTOR_STATE.MOVING; } else { this.GetComponent <Animator>().Play("Run 06 Stop"); roamingWaitTime = Random.Range(minRoamingWaitTime, maxRoamingWaitTime); roamingT = 0f; currIdleAnimationPlaying = Random.Range(1, 5); state = ACTOR_STATE.CHOOSING; } } else { //can talk or continue to move if (talkTarget != null && !isPanicking && Mathf.Approximately(talkRefreshTimer, 0f)) { this.GetComponent <Animator>().Play(talkAnimation); talkCooldownTimer = talkCooldown; talkRefreshTimer = talkRefresh; state = ACTOR_STATE.TALKING; } else { if (isPanicking) { talkRefreshTimer = talkRefresh; talkCooldownTimer = talkCooldown; ResetTalkingActor(); } movementTarget = pathHelper.GetNextMove(); if (movementTarget == null) { //string str = "Idle 0"+Random.Range(1,5); //Debug.Log(str); //gameObject.GetComponent<Animator>().Play(str); roamingWaitTime = Random.Range(minRoamingWaitTime, maxRoamingWaitTime); roamingT = 0f; currIdleAnimationPlaying = Random.Range(1, 5); state = ACTOR_STATE.CHOOSING; } else { transform.LookAt(movementTarget.characterPosition, Vector3.up); state = ACTOR_STATE.MOVING; } } } break; case ACTOR_STATE.HAUNTED: if (forceDirection) { //forcing actor to move in a direction, if failing forcedirection will be setted to false TryForceActorToNextTile(); if (forceDirection) { transform.LookAt(movementTarget.characterPosition, Vector3.up); state = ACTOR_STATE.MOVING; } else { roamingWaitTime = Random.Range(minRoamingWaitTime, maxRoamingWaitTime); roamingT = 0f; currIdleAnimationPlaying = Random.Range(1, 5); state = ACTOR_STATE.CHOOSING; } } break; case ACTOR_STATE.CHILLED: scaredAnimation = "Scared 0" + Random.Range(1, 3); GameObject player = GameObject.FindGameObjectWithTag("Player"); if (player) { Chill c = player.GetComponent <Chill>(); if (c) { c.AddActorToCurrentChill(this); } } state = ACTOR_STATE.CHILLED; break; default: break; } } else if (state == ACTOR_STATE.CHOOSING) { roamingT += Time.deltaTime; CheckTileState(); switch (processedState) { case ACTOR_STATE.NONE: //If someone is asking me to talk do that if (talkTarget != null && !isPanicking) { this.GetComponent <Animator>().Play(talkAnimation); talkCooldownTimer = talkCooldown; state = ACTOR_STATE.TALKING; } //playing idle animation when choosing else if (roamingT < roamingWaitTime) { LevelController.ACTOR_STATES fearState = GetActorFearState(); if (fearState == LevelController.ACTOR_STATES.NORMAL) { string str = "Idle 0" + currIdleAnimationPlaying.ToString(); //Debug.Log(str); gameObject.GetComponent <Animator>().Play(str); } if (fearState == LevelController.ACTOR_STATES.SPOOKED) { gameObject.GetComponent <Animator>().Play("Scared 01"); } if (fearState == LevelController.ACTOR_STATES.PANICKED) { gameObject.GetComponent <Animator>().Play("Scared 02"); } } else { roamingT = 0; pathHelper.RequestNewRandomPath(currentTile); movementTarget = pathHelper.GetNextMove(); if (movementTarget == null) { roamingWaitTime = Random.Range(minRoamingWaitTime, maxRoamingWaitTime); roamingT = 0f; currIdleAnimationPlaying = Random.Range(1, 5); state = ACTOR_STATE.CHOOSING; } else { transform.LookAt(movementTarget.characterPosition, Vector3.up); currentTile.occupant = null; state = ACTOR_STATE.MOVING; } } break; case ACTOR_STATE.HAUNTED: if (forceDirection) { //forcing actor to move in a direction, if failing forcedirection will be setted to false TryForceActorToNextTile(); if (forceDirection) { transform.LookAt(movementTarget.characterPosition, Vector3.up); state = ACTOR_STATE.MOVING; } else { roamingWaitTime = Random.Range(minRoamingWaitTime, maxRoamingWaitTime); roamingT = 0f; currIdleAnimationPlaying = Random.Range(1, 5); state = ACTOR_STATE.CHOOSING; } } break; case ACTOR_STATE.CHILLED: scaredAnimation = "Scared 0" + Random.Range(1, 3); GameObject player = GameObject.FindGameObjectWithTag("Player"); if (player) { Chill c = player.GetComponent <Chill>(); if (c) { c.AddActorToCurrentChill(this); } } state = ACTOR_STATE.CHILLED; break; default: break; } } else if (state == ACTOR_STATE.TALKING) { fear -= Time.deltaTime * fearReductionPerSecond; if (talkCooldownTimer > 0) { talkCooldownTimer -= Time.deltaTime; if (talkCooldownTimer < 0) { talkCooldownTimer = 0; } } CheckTileState(); switch (processedState) { case ACTOR_STATE.NONE: //PLAY TALK ANIMATION if (talkTarget != null) { transform.LookAt(talkTarget.transform.position, Vector3.up); if (Mathf.Approximately(talkCooldownTimer, 0.0f)) { talkCooldownTimer = talkCooldown; talkRefreshTimer = talkRefresh; ResetTalkingActor(); roamingWaitTime = Random.Range(minRoamingWaitTime, maxRoamingWaitTime); roamingT = 0f; currIdleAnimationPlaying = Random.Range(1, 5); if (audioSource.isPlaying) { audioSource.Stop(); } state = ACTOR_STATE.CHOOSING; } else if (!audioSource.isPlaying) { PlaySound(Random.Range(0, 3), Random.Range(minDelayTimeTalking, maxDelayTimeTalking)); } } //NICE! This makes them go back to the previous tile for talking: //TODO can be dangerous when applying powers // if(talkTarget != null && this.currentTile == talkTarget.currentTile) // { // movementTarget = previousTile; // state = ACTOR_STATE.MOVING; // } //STOP talking go to do something else else if (talkTarget == null) { roamingWaitTime = Random.Range(minRoamingWaitTime, maxRoamingWaitTime); roamingT = 0f; currIdleAnimationPlaying = Random.Range(1, 5); talkCooldownTimer = talkCooldown; state = ACTOR_STATE.CHOOSING; } break; case ACTOR_STATE.HAUNTED: talkRefreshTimer = talkRefresh; talkCooldownTimer = talkCooldown; ResetTalkingActor(); if (forceDirection) { //forcing actor to move in a direction, if failing forcedirection will be setted to false TryForceActorToNextTile(); if (forceDirection) { transform.LookAt(movementTarget.characterPosition, Vector3.up); state = ACTOR_STATE.MOVING; } else { roamingWaitTime = Random.Range(minRoamingWaitTime, maxRoamingWaitTime); roamingT = 0f; currIdleAnimationPlaying = Random.Range(1, 5); state = ACTOR_STATE.CHOOSING; } } break; case ACTOR_STATE.CHILLED: scaredAnimation = "Scared 0" + Random.Range(1, 3); GameObject player = GameObject.FindGameObjectWithTag("Player"); if (player) { Chill c = player.GetComponent <Chill>(); if (c) { c.AddActorToCurrentChill(this); } else { Debug.LogError("Chilled activated but not detected from actrors"); } } talkRefreshTimer = talkRefresh; talkCooldownTimer = talkCooldown; ResetTalkingActor(); state = ACTOR_STATE.CHILLED; break; default: break; } } else if (state == ACTOR_STATE.CHILLED) { if (scaredAnimation != string.Empty) { gameObject.GetComponent <Animator>().Play(scaredAnimation); } if (deActivateChilled) { deActivateChilled = false; roamingWaitTime = Random.Range(minRoamingWaitTime, maxRoamingWaitTime); roamingT = 0f; currIdleAnimationPlaying = Random.Range(1, 5); state = ACTOR_STATE.CHOOSING; } } else if (state == ACTOR_STATE.NONE) { talkCooldownTimer = talkCooldown; talkRefreshTimer = talkRefresh; roamingWaitTime = Random.Range(minRoamingWaitTime, maxRoamingWaitTime); roamingT = 0f; currIdleAnimationPlaying = Random.Range(1, 5); state = ACTOR_STATE.CHOOSING; } }