예제 #1
0
        // input event requires application of rules to determine next state
        void SetNextState(InputEvent input, int?intparam)
        {
            if (_modelstate == ModelState.Level && !IsValidInGame(input))
            {
                return;
            }

            // model state determines what to do with input
            switch (_modelstate)
            {
            case ModelState.Againing:
            case ModelState.Level:
                ApplyRules(input, intparam);
                if (_states.Last().IsAgaining)
                {
                    _modelstate = ModelState.Againing;
                    if (GameDef.GetSetting(OptionSetting.pause_on_again, false))
                    {
                        break;
                    }
                    while (_states.Last().IsAgaining)
                    {
                        if (Logger.Level >= 3)
                        {
                            ShowLevel("againing");
                        }
                        ApplyRules(InputEvent.Tick, null);
                    }
                }
                CheckNextState();
                break;

            // message level display ended, now find what's next
            case ModelState.Message:
                CheckNextState();
                break;

            case ModelState.EndLevel:
                LoadLevel(_levelindex + 1); // sets state directly
                break;

            case ModelState.Failed:
                break;

            default:
                throw Error.Assert("bad model state {0}", _modelstate);
            }
        }
예제 #2
0
 void CheckNextState()
 {
     if (CurrentLevelKind == LevelKind.Message)
     {
         LoadLevel(_levelindex + 1);
     }
     else if (!_states.Last().IsFinished)
     {
         _modelstate = ModelState.Level;
     }
     else if (GameDef.GetSetting(OptionSetting.pause_at_end_level, false))
     {
         _modelstate = ModelState.EndLevel;
     }
     else
     {
         LoadLevel(_levelindex + 1);
     }
 }
예제 #3
0
        // apply the result to decide what to do with the new state
        // sounds and messages not preserved
        void ApplyResult(GameState newstate)
        {
            var currentstate = _states.Last();

            // use the result to decide what to do with the new state
            switch (newstate.Result)
            {
            case StateResult.Cancel:
                VerboseLog("Cancel, keep current state");
                CheckTrigger(SoundTrigger.Cancel);
                if (currentstate.IsAgaining)
                {
                    _states.Remove(currentstate);
                }
                break; // as if nothing happened

            case StateResult.Restart:
                VerboseLog("Restart from checkpoint");
                CheckTrigger(SoundTrigger.Restart);
                Restart(newstate);
                break;

            case StateResult.Undo:
                if (_states.Count > 1)
                {
                    VerboseLog("Undo, discard current state");
                    CheckTrigger(SoundTrigger.Undo);
                    _states.Remove(currentstate);
                }
                else
                {
                    VerboseLog("Undo ignored");
                }
                break;

            case StateResult.Reset:
                VerboseLog("Reset, reload level");
                LoadLevel(_levelindex);
                break;

            case StateResult.Againing:
                if (currentstate.IsAgaining)
                {
                    _states.Remove(currentstate);
                }
                newstate.AgainCount = currentstate.AgainCount + 1;
                if (newstate.AgainCount >= 100)
                {
                    throw Error.Fatal("too many agains");
                }
                VerboseLog("Run rules again on current state");
                CheckTrigger(SoundTrigger.Again);
                Logger.WriteLine(2, "Again count {0}", newstate.AgainCount);
                _states.Add(newstate);
                break;

            case StateResult.Finished:
            case StateResult.Success:
                if (currentstate.IsAgaining || _initialinput)
                {
                    _states.Remove(currentstate);
                }
                // treat this combo as a cancel
                if (_playermovement &&
                    GameDef.GetSetting(OptionSetting.require_player_movement, false) &&
                    newstate.PlayerIndexes.SequenceEqual(currentstate.PlayerIndexes))
                {
                    VerboseLog("Player did not move, discard current state");
                    CheckTrigger(SoundTrigger.Cancel);
                }
                else
                {
                    VerboseLog("Move complete");
                    _states.Add(newstate);
                    if (newstate.Result == StateResult.Finished)
                    {
                        VerboseLog("Level complete");
                        CheckTrigger(SoundTrigger.Win);
                    }
                }
                break;

            default:
                throw Error.Assert("bad result {0}", newstate.Result);
            }
        }
예제 #4
0
 // get a puzzle object id given name
 public int GetObjectId(string name)
 {
     return(Enumerable.Range(1, GameDef.ObjectCount)
            .FirstOrDefault(x => GameDef.GetObject(x).Name
                            .Equals(name, StringComparison.InvariantCultureIgnoreCase))); // 0 if not found
 }
예제 #5
0
        // get a puzzle object, which may have been updated
        public PuzzleObject GetObject(int objid)
        {
            var obj = _states.Last().PuzzleObjects.SafeLookup(objid);

            return(obj ?? GameDef.GetObject(objid));
        }