Beispiel #1
0
        private void HandleResult(ResultSet resultSet, Result result, out bool tookTurn)
        {
            tookTurn = false;
            var game = (RetroDungeoneerGame)RB.Game;

            switch (result.type)
            {
            case Result.Type.Move:
            {
                Vector2i delta = result.veci1;
                if ((delta.x != 0 || delta.y != 0) && !mGameMap.IsBlocked(mPlayer.e.pos + delta))
                {
                    var destPos      = mPlayer.e.pos + delta;
                    var targetEntity = EntityFunctions.GetBlockingEntityAtPos(destPos);

                    if (!targetEntity.isEmpty)
                    {
                        mPlayer.e.fighter.Attack(mResultSet, targetEntity);
                    }
                    else
                    {
                        var  entities   = EntityFunctions.GetEntitiesAtPos(mPlayer.e.pos);
                        bool stuckInWeb = false;
                        for (int i = 0; i < entities.Count; i++)
                        {
                            if (entities[i].e.groundTrigger != null && entities[i].e.groundTrigger.type == GroundTrigger.GroundTriggerType.Web)
                            {
                                stuckInWeb = true;
                                break;
                            }
                        }

                        // Attempt to free from web
                        if (stuckInWeb)
                        {
                            if (Random.Range(0, 6) == 0)
                            {
                                stuckInWeb = false;
                                resultSet.AddMessage(C.FSTR.Set("You manage to free yourself from the web."));
                            }
                        }

                        if (!stuckInWeb)
                        {
                            mPlayer.e.Move(delta);
                            mFOVRecompute = true;

                            RB.SoundPlay(game.assets.soundFootStep, 0.66f, RandomUtils.RandomPitch(0.1f));

                            var entitesAtDest = EntityFunctions.GetEntitiesAtPos(mPlayer.e.pos);
                            for (int i = 0; i < entitesAtDest.Count; i++)
                            {
                                var trigger = entitesAtDest[i].e.groundTrigger;
                                if (trigger != null)
                                {
                                    trigger.Trigger(resultSet);
                                }
                            }
                        }
                        else
                        {
                            resultSet.AddMessage(C.FSTR.Set("You fail to free yourself from the web, keep trying."));
                            RB.SoundPlay(game.assets.soundWeb, 0.5f, RandomUtils.RandomPitch(0.1f));
                        }
                    }

                    mFloodRecompute = true;

                    tookTurn = true;
                }
                else if (delta.x == 0 && delta.y == 0)
                {
                    // Do nothing, wait
                    tookTurn = true;
                }
            }

            break;

            case Result.Type.Exit:
                if (mGameState == GameState.SHOW_INVENTORY ||
                    mGameState == GameState.DROP_INVENTORY ||
                    mGameState == GameState.SHOW_HELP ||
                    mGameState == GameState.CHARACTER_SCREEN)
                {
                    RB.SoundPlay(game.assets.soundMenuClose, 1, RandomUtils.RandomPitch(0.1f));
                    ChangeState(mPreviousGameState);
                }
                else if (mGameState == GameState.TARGETING)
                {
                    resultSet.AddTargetingCancelled();
                }
                else
                {
                    // Exit back to main menu
                    game.ChangeScene(SceneEnum.MAIN_MENU);
                }

                break;

            case Result.Type.Message:
                mConsole.Log(result.str1);
                break;

            case Result.Type.Dead:
                if (result.entity1 == mPlayer)
                {
                    DeathFunctions.KillPlayer(mResultSet, result.entity1);
                    ChangeState(GameState.PLAYER_DEAD);
                }
                else
                {
                    DeathFunctions.KillMonster(mResultSet, result.entity1);
                }

                break;

            case Result.Type.Pickup:
            {
                var receiver = result.entity1;
                if (receiver.e.inventory == null)
                {
                    break;
                }

                var entityList = EntityFunctions.GetEntitiesAtPos(receiver.e.pos);
                if (entityList != null)
                {
                    for (int j = 0; j < entityList.Count; j++)
                    {
                        var e = entityList[j].e;

                        if (e.item != null)
                        {
                            receiver.e.inventory.AddItem(resultSet, e.id);
                        }
                    }
                }
            }

            break;

            case Result.Type.ItemAdded:
                result.entity1.e.renderOrder = RenderFunctions.RenderOrder.HIDDEN;
                result.entity1.e.pos         = new Vector2i(-1, -1);

                RB.SoundPlay(game.assets.soundInventory, 1, RandomUtils.RandomPitch(0.1f));

                break;

            case Result.Type.ShowInventory:
                if (mGameState != GameState.SHOW_INVENTORY)
                {
                    ChangeState(GameState.SHOW_INVENTORY);
                }
                else
                {
                    ChangeState(mPreviousGameState);
                }

                break;

            case Result.Type.InventoryIndex:
            {
                var entity = result.entity1;
                var item   = entity.e.inventory.items[result.int1];

                mUseParams.Clear();
                mUseParams.map = mGameMap;

                if (mGameState == GameState.SHOW_INVENTORY)
                {
                    entity.e.inventory.UseItem(resultSet, item, mUseParams);
                }
                else if (mGameState == GameState.DROP_INVENTORY)
                {
                    entity.e.inventory.DropItem(resultSet, item);
                }
            }

            break;

            case Result.Type.Consumed:
            {
                var entity = result.entity1;
                var item   = result.entity2;

                entity.e.inventory.RemoveItem(resultSet, item);

                tookTurn = true;
            }

            break;

            case Result.Type.DropInventory:
                if (mGameState != GameState.DROP_INVENTORY)
                {
                    ChangeState(GameState.DROP_INVENTORY);
                }
                else
                {
                    ChangeState(mPreviousGameState);
                }

                break;

            case Result.Type.ItemDropped:
                result.entity1.e.renderOrder = RenderFunctions.RenderOrder.ITEM;
                tookTurn = true;

                RB.SoundPlay(game.assets.soundInventory, 1, RandomUtils.RandomPitch(0.1f));
                break;

            case Result.Type.Equip:
            {
                var equipper = result.entity1;
                var item     = result.entity2;

                if (equipper.e == null || equipper.e.equipment == null || item.e == null || item.e.equippable == null)
                {
                    break;
                }

                equipper.e.equipment.ToggleEquip(resultSet, item);
            }

            break;

            case Result.Type.Equipped:
            {
                var equipper = result.entity1;
                var item     = result.entity2;

                if (equipper.e == null || equipper.e.equipment == null || item.e == null || item.e.equippable == null)
                {
                    break;
                }

                RB.SoundPlay(game.assets.soundInventory, 1, RandomUtils.RandomPitch(0.1f));
            }

            break;

            case Result.Type.Dequipped:
            {
                var equipper = result.entity1;
                var item     = result.entity2;

                if (equipper.e == null || equipper.e.equipment == null || item.e == null || item.e.equippable == null)
                {
                    break;
                }

                RB.SoundPlay(game.assets.soundInventory, 1, RandomUtils.RandomPitch(0.1f));
            }

            break;

            case Result.Type.Targeting:
                // Set previous state to players turn to go back to players turn if targeting is cancelled
                mPreviousGameState = GameState.PLAYER_TURN;
                ChangeState(GameState.TARGETING);
                mTargetingItem = result.entity1;

                mConsole.Log(mTargetingItem.e.item.targetingMessage);
                break;

            case Result.Type.LeftClick:
            {
                if (mGameState == GameState.TARGETING && !mTargetingItem.isEmpty)
                {
                    var targetingPos = result.veci1;

                    if (mTargetingItem.e.equippable != null && mTargetingItem.e.equippable.slot == EquipmentSlot.Ranged)
                    {
                        var arrow = mPlayer.e.inventory.GetArrow();
                        if (SkillFunctions.ShootBow(resultSet, mPlayer, arrow, mTargetingItem.e.item.int2, mTargetingItem.e.item.int1, targetingPos))
                        {
                            mPlayer.e.inventory.RemoveItem(resultSet, arrow);
                            EntityStore.DestroyEntity(arrow);
                        }

                        ChangeState(GameState.ENEMY_TURN);
                    }
                    else
                    {
                        mUseParams.Clear();
                        mUseParams.map   = mGameMap;
                        mUseParams.veci1 = targetingPos;
                        mUseParams.bool1 = true;

                        mPlayer.e.inventory.UseItem(resultSet, mTargetingItem, mUseParams);
                    }
                }
            }

            break;

            case Result.Type.RightClick:
                if (mGameState == GameState.TARGETING)
                {
                    resultSet.AddTargetingCancelled();
                }

                break;

            case Result.Type.TargetingCancelled:
                ChangeState(GameState.PLAYER_TURN);
                mTargetingItem = EntityID.empty;
                mConsole.Log(C.FSTR.Set("Targeting cancelled."));
                break;

            case Result.Type.ShowHelp:
                if (mGameState != GameState.SHOW_HELP)
                {
                    ChangeState(GameState.SHOW_HELP);
                }
                else
                {
                    ChangeState(mPreviousGameState);
                }

                break;

            case Result.Type.TakeStairs:
            {
                int  i;
                bool foundStairs = false;

                var entityList = EntityFunctions.GetEntitiesAtPos(mPlayer.e.pos);
                if (entityList != null)
                {
                    for (i = 0; i < entityList.Count; i++)
                    {
                        var e = entityList[i].e;
                        if (e.stairs != null && e.stairs.type != Stairs.StairType.WELL_CLOSED)
                        {
                            EffectManager.Instance.Clear();

                            mGameMap.NextFloor(resultSet, mPlayer, mConsole);
                            mFOVRecompute   = true;
                            mFloodRecompute = true;

                            // Snap the camera to player
                            mCamera.SetPos(mPlayer);

                            foundStairs = true;

                            if (e.stairs.type == Stairs.StairType.STAIRS)
                            {
                                RB.SoundPlay(game.assets.soundStairs);

                                mPlayer.e.fighter.Heal(resultSet, mPlayer.e.fighter.maxHp / 2);
                                mConsole.Log(C.FSTR.Set("You take a moment to rest, and recover your strength."));
                            }
                            else if (e.stairs.type == Stairs.StairType.PORTAL)
                            {
                                RB.SoundPlay(game.assets.soundPortal);
                                mPlayer.e.fighter.Heal(resultSet, mPlayer.e.fighter.maxHp / 2);
                                mConsole.Log(C.FSTR.Set("You step into the mysterious portal..."));
                            }
                            else if (e.stairs.type == Stairs.StairType.WELL)
                            {
                                RB.SoundPlay(game.assets.soundJump);
                                mConsole.Log(C.FSTR.Set("You jump down the well into the darkness below..."));
                            }

                            if (mCurrentMusic != mGameMap.music)
                            {
                                RB.MusicPlay(mGameMap.music);
                                mCurrentMusic = mGameMap.music;
                            }

                            // Save the game after descending
                            DataLoaders.SaveGame(C.SAVE_FILENAME, mPlayer, mGameMap, mConsole, mGameState);

                            break;
                        }
                        else if (e.stairs != null && e.stairs.type == Stairs.StairType.WELL_CLOSED)
                        {
                            foundStairs = true;

                            mConsole.Log(C.FSTR.Set("You look down the well. That won't be necessary, not this time..."));
                        }
                    }
                }

                if (!foundStairs)
                {
                    mConsole.Log(C.FSTR.Set("There are no stairs here."));
                }
            }

            break;

            case Result.Type.Xp:
                int xp        = result.int1;
                var leveledUp = mPlayer.e.level.AddXp(xp);
                mConsole.Log(C.FSTR.Set("You gain ").Append(xp).Append(" experience points."));

                if (leveledUp)
                {
                    mConsole.Log(C.FSTR.Set("Your battle skills grow stronger! You reached level ").Append(mPlayer.e.level.currentLevel).Append("!"));
                    mPreviousGameState = mGameState;
                    ChangeState(GameState.LEVEL_UP);

                    mMenuLevelUp.ClearOptions();
                    mMenuLevelUp.AddOption(C.FSTR.Set("Constitution (+20 HP, from ").Append(mPlayer.e.fighter.maxHp).Append(")"));
                    mMenuLevelUp.AddOption(C.FSTR.Set("Strength (+1 attack, from ").Append(mPlayer.e.fighter.power).Append(")"));
                    mMenuLevelUp.AddOption(C.FSTR.Set("Agility (+1 defense, from ").Append(mPlayer.e.fighter.defense).Append(")"));

                    RB.SoundPlay(game.assets.soundLevelUp);
                }

                break;

            case Result.Type.LevelUp:
                var levelUp = (LevelUp)result.int1;

                switch (levelUp)
                {
                case LevelUp.Hp:
                    mPlayer.e.fighter.baseMaxHp += 20;
                    mPlayer.e.fighter.hp        += 20;
                    break;

                case LevelUp.Str:
                    mPlayer.e.fighter.basePower += 1;
                    break;

                case LevelUp.Def:
                    mPlayer.e.fighter.baseDefense += 1;
                    break;
                }

                mGameState = mPreviousGameState;

                break;

            case Result.Type.ShowCharacterScreen:
                mPreviousGameState = mGameState;
                ChangeState(GameState.CHARACTER_SCREEN);

                C.FSTR.Clear();
                C.FSTR.Append("@FFFFFFLevel: ").Append(C.STR_COLOR_NAME).Append(mPlayer.e.level.currentLevel).Append("\n");
                C.FSTR.Append("@FFFFFFExperience: ").Append(C.STR_COLOR_NAME).Append(mPlayer.e.level.currentXp).Append("\n");
                C.FSTR.Append("@FFFFFFExperience to Level: ").Append(C.STR_COLOR_NAME).Append(mPlayer.e.level.ExperienceToNextLevel()).Append("\n");
                C.FSTR.Append("@FFFFFFMaximum HP: ").Append(C.STR_COLOR_NAME).Append(mPlayer.e.fighter.maxHp).Append("\n");
                C.FSTR.Append("@FFFFFFAttack: ").Append(C.STR_COLOR_NAME).Append(mPlayer.e.fighter.power).Append("\n");
                C.FSTR.Append("@FFFFFFDefense: ").Append(C.STR_COLOR_NAME).Append(mPlayer.e.fighter.defense);
                mMenuCharacterScreen.SetSummary(C.FSTR);

                break;

            case Result.Type.BossDefeated:
                var boss = result.entity1;
                map.SpawnExitPortal(boss.e.pos);
                break;

            case Result.Type.GameWon:
            {
                var options = new List <SceneMessage.MessageBoxOption>();
                options.Add(new SceneMessage.MessageBoxOption(C.FSTR.Set("Return to Main Menu"), CloseGameWonMessageBox));

                C.FSTR.Set(C.STR_COLOR_DIALOG);
                C.FSTR.Append("You make it out of the forest clearing with adrenaline still pumping through your veins.");
                C.FSTR.Append("\n\n");
                C.FSTR.Append("Your adventure flashes through your mind and you realize you're not the same person you were before. ");
                C.FSTR.Append("The concerns you once had seem insignificant now.");
                C.FSTR.Append("\n\n");
                C.FSTR.Append("Moments later you calm down, and you find yourself wondering what lies at the bottom of other old wells...");
                C.FSTR.Append("\n\n");
                C.FSTR.Append(C.STR_COLOR_NAME);
                C.FSTR.Append("You've won!\nCongratulations!");

                game.ShowMessageBox(
                    C.FSTR2.Set("A New Life"),
                    C.FSTR,
                    options);
                break;
            }

            case Result.Type.FellDownWell:
            {
                var options = new List <SceneMessage.MessageBoxOption>();
                options.Add(new SceneMessage.MessageBoxOption(C.FSTR.Set("Continue"), CloseMessageBox));

                C.FSTR.Set(C.STR_COLOR_DIALOG);
                C.FSTR.Append("This is not what you expected. It seems that not only has the bottom of this well ran dry, it has collapsed into some old dungeon! ");
                C.FSTR.Append("There must be some way out of this place, there has to be.");
                C.FSTR.Append("\n\n");
                C.FSTR.Append("A sound of skittering creatures can be heard coming from the nearby rooms. ");
                C.FSTR.Append("You spot a rusty dagger lying beside you.");
                C.FSTR.Append("\n\n");
                C.FSTR.Append("Finding an exit may prove... difficult.");

                game.ShowMessageBox(
                    C.FSTR2.Set("Bottom of the Well"),
                    C.FSTR,
                    options);
                break;
            }

            case Result.Type.BossEncounter:
            {
                var options = new List <SceneMessage.MessageBoxOption>();
                options.Add(new SceneMessage.MessageBoxOption(C.FSTR.Set("Continue"), CloseMessageBox));

                C.FSTR.Set(C.STR_COLOR_DIALOG);
                C.FSTR.Append("Before you stands a towering golem. It lurches forward, slowly at first, as if it has not moved in ages.");
                C.FSTR.Append("\n\n");
                C.FSTR.Append(C.STR_COLOR_NAME);
                C.FSTR.Append("\"Who awakens the Gatekeeper?\"").Append(C.STR_COLOR_DIALOG).Append(" it belows.");
                C.FSTR.Append("\n\n");
                C.FSTR.Append("A Gatekeeper is just what you were looking for. This is your chance to escape the dungeon! You steady yourself, this will not be an easy fight.");

                game.ShowMessageBox(
                    C.FSTR2.Set("The Gatekeeper"),
                    C.FSTR,
                    options);
                break;
            }
            }
        }
Beispiel #2
0
        private bool DoSkill(ResultSet resultSet, EntityID target)
        {
            if (mSkills.Count == 0)
            {
                return(false);
            }

            int skillIndex = RandomUtils.RandomChoiceIndex(mSkillChances);

            Skill randomSkill = mSkills[skillIndex];

            // Check if there is a backup melee skill
            bool hasMeleeSkill = false;

            for (int i = 0; i < mSkills.Count; i++)
            {
                if (mSkills[i] == Skill.MeleeAttack)
                {
                    hasMeleeSkill = true;
                    break;
                }
            }

            var game = (RetroDungeoneerGame)RB.Game;

            bool skillResult = false;

            switch (randomSkill)
            {
            case Skill.MeleeAttack:
                return(SkillFunctions.MeleeAttack(resultSet, owner, target));

            case Skill.CastWeb:
                skillResult = SkillFunctions.CastWeb(resultSet, owner, target.e.pos);
                break;

            case Skill.CastLightning:
                skillResult = SkillFunctions.CastLightning(resultSet, owner, target.e.pos, 6, 12);
                break;

            case Skill.ShootBow:
            {
                var arrow = owner.e.inventory.GetArrow();
                if (!arrow.isEmpty)
                {
                    skillResult = SkillFunctions.ShootBow(resultSet, owner, arrow, 6, 10, target.e.pos);
                    if (skillResult)
                    {
                        owner.e.inventory.RemoveItem(null, arrow);
                        EntityStore.DestroyEntity(arrow);
                    }
                }
            }

            break;

            case Skill.CastRandomFireball:
            {
                int attempts = 40;

                while (attempts > 0)
                {
                    var fireballPos = new Vector2i(target.e.pos.x, target.e.pos.y);
                    fireballPos.x += Random.Range(-20, 21);
                    fireballPos.y += Random.Range(-20, 21);

                    if (game.map.IsInFOV(fireballPos))
                    {
                        skillResult = SkillFunctions.CastFireball(resultSet, owner, 4, 10, fireballPos, false);
                        break;
                    }

                    attempts--;
                }
            }

            break;

            case Skill.Teleport:
            {
                // Find a location to teleport on the furthest side of target from where the entity is now
                // Limited attempts are made, so this may not end up being furthest
                var furthestPos  = new Vector2i(-1, -1);
                var furthestDist = 0.0f;

                int      attempts  = 40;
                Vector2i targetPos = target.e.pos;

                while (attempts > 0)
                {
                    var randomPos = new Vector2i(Random.Range(targetPos.x - 1, targetPos.x + 2), Random.Range(targetPos.y - 1, targetPos.y + 2));

                    if (EntityFunctions.GetBlockingEntityAtPos(randomPos).isEmpty&& !game.map.IsBlocked(randomPos))
                    {
                        float dist = (owner.e.pos - randomPos).SqrMagnitude();
                        if (dist > furthestDist)
                        {
                            furthestDist = dist;
                            furthestPos  = randomPos;
                        }
                    }

                    attempts--;
                }

                if (furthestPos.x != -1)
                {
                    skillResult = SkillFunctions.Teleport(resultSet, owner, furthestPos);
                }
                else
                {
                    Debug.Log("Failed");
                }
            }

            break;
            }

            if (skillResult == false && hasMeleeSkill)
            {
                skillResult = SkillFunctions.MeleeAttack(resultSet, owner, target);
            }

            return(skillResult);
        }