示例#1
0
        private static bool ResolveAutopilotBeginTravel(AutopilotBeginAction action, EncounterState state)
        {
            var           playerPosition = state.Player.GetComponent <PositionComponent>().EncounterPosition;
            EncounterZone zone           = state.GetZoneById(action.ZoneId);

            var foundPath      = Pathfinder.AStarWithNewGrid(playerPosition, zone.Center, state, 9000);
            int autopilotTries = 0;

            while (foundPath == null && autopilotTries < 5)
            {
                foundPath = Pathfinder.AStarWithNewGrid(playerPosition, zone.RandomEmptyPosition(state.EncounterRand, state), state, 9000);
                autopilotTries++;
            }
            if (foundPath != null && autopilotTries > 0)
            {
                state.LogMessage(String.Format("Autopilot could not find path to center of [b]{0}[/b]; autopiloting to randomly chosen position in [b]{0}[/b].", zone.ZoneName));
                state.Player.GetComponent <PlayerComponent>().LayInAutopilotPathForTravel(new EncounterPath(foundPath));
                return(true);
            }
            else if (foundPath != null)
            {
                state.LogMessage(String.Format("Autopiloting to [b]{0}[/b]", zone.ZoneName));
                state.Player.GetComponent <PlayerComponent>().LayInAutopilotPathForTravel(new EncounterPath(foundPath));
                return(true);
            }
            else
            {
                state.LogMessage(String.Format("Autopilot failed to plot course to to [b]{0}[/b]", zone.ZoneName), failed: true);
                return(false);
            }
        }
示例#2
0
 private static void LogAttack(DefenderComponent defenderComponent, string message, EncounterState state)
 {
     if (defenderComponent.ShouldLogDamage)
     {
         state.LogMessage(message);
     }
 }
示例#3
0
 private static void LogAttack(Entity attacker, Entity defender, DefenderComponent defenderComponent, string message, EncounterState state)
 {
     if (defenderComponent.ShouldLogDamage && (attacker == state.Player || defender == state.Player))
     {
         state.LogMessage(message);
     }
 }
示例#4
0
        // Currently, each use effect is its own component. If we run into a case where we have too many effects, we can push the
        // effects into the usable component itself, similarly to status effects (though status effects are their own mess right now)
        // which would probably be better for building on.
        private static bool ResolveUse(UseAction action, EncounterState state)
        {
            var user = state.GetEntityById(action.ActorId);

            // This is another issue that'd be solved with a global Entity lookup - though not the removal part.
            Entity usable = null;

            if (action.FromInventory)
            {
                var userInventory = user.GetComponent <InventoryComponent>();
                usable = userInventory.StoredEntityById(action.UsableId);
                if (usable.GetComponent <UsableComponent>() == null)
                {
                    state.LogMessage(string.Format("{0} is not usable!", usable.EntityName), failed: true);
                    return(false);
                }
                else
                {
                    userInventory.RemoveEntity(usable);
                }
            }
            else
            {
                usable = state.GetEntityById(action.UsableId);
                if (usable.GetComponent <UsableComponent>() == null)
                {
                    state.LogMessage(string.Format("{0} is not usable!", usable.EntityName), failed: true);
                    return(false);
                }
                else
                {
                    state.RemoveEntity(usable);
                }
            }

            state.LogMessage(string.Format("{0} used {1}!", user.EntityName, usable.EntityName));

            ResolveUseEffects(user, usable, state);

            // We assume all items are single-use; this will change if I deviate from the reference implementation!
            usable.QueueFree();
            return(true);
        }
示例#5
0
        private static bool ResolveGetItem(GetItemAction action, EncounterState state)
        {
            var actor = state.GetEntityById(action.ActorId);
            var inventoryComponent = actor.GetComponent <InventoryComponent>();
            var actorPosition      = actor.GetComponent <PositionComponent>().EncounterPosition;
            var item = state.EntitiesAtPosition(actorPosition.X, actorPosition.Y)
                       .FirstOrDefault(e => e.GetComponent <StorableComponent>() != null);

            if (item == null)
            {
                state.LogMessage("No item found!", failed: true);
                return(false);
            }
            else if (item.GetComponent <UsableComponent>() != null && item.GetComponent <UsableComponent>().UseOnGet)
            {
                // The responsibility for removing/not removing the usable from the EncounterState is in the usage code.
                bool successfulUsage = ResolveUse(new UseAction(actor.EntityId, item.EntityId, false), state);
                if (!successfulUsage)
                {
                    GD.PrintErr(string.Format("Item {0} was not successfully used after being picked up!", item.EntityName));
                }
                return(true);
            }
            else if (!inventoryComponent.CanFit(item))
            {
                state.LogMessage(string.Format("[b]{0}[/b] can't fit the [b]{1}[/b] in its inventory!",
                                               actor.EntityName, item.EntityName), failed: true);
                return(false);
            }
            else
            {
                state.RemoveEntity(item);
                actor.GetComponent <InventoryComponent>().AddEntity(item);

                var logMessage = string.Format("[b]{0}[/b] has taken the [b]{1}[/b]", actor.EntityName, item.EntityName);
                state.LogMessage(logMessage);
                return(true);
            }
        }
示例#6
0
        private static bool ResolveUseStairs(UseStairsAction action, EncounterState state)
        {
            var actorPosition = state.GetEntityById(action.ActorId).GetComponent <PositionComponent>().EncounterPosition;
            var stairs        = state.EntitiesAtPosition(actorPosition.X, actorPosition.Y)
                                .FirstOrDefault(e => e.GetComponent <StairsComponent>() != null);

            if (stairs != null)
            {
                state.ResetStateForNewLevel(state.Player, state.DungeonLevel + 1);
                state.WriteToFile();
                return(true);
            }
            else
            {
                state.LogMessage("No jump point found!", failed: true);
                return(false);
            }
        }
示例#7
0
        private static bool ResolveAutopilotEnd(AutopilotEndAction action, EncounterState state)
        {
            var playerComponent = state.Player.GetComponent <PlayerComponent>();

            if (action.Reason == AutopilotEndReason.PLAYER_INPUT)
            {
                state.LogMessage(String.Format("Autopilot ending - [b]overridden by pilot[/b]"));
            }
            else if (action.Reason == AutopilotEndReason.ENEMY_DETECTED)
            {
                state.LogMessage(String.Format("Autopilot ending - [b]enemy detected[/b]"));
            }
            else if (action.Reason == AutopilotEndReason.TASK_COMPLETED)
            {
                if (playerComponent.ActiveAutopilotMode == AutopilotMode.TRAVEL)
                {
                    state.LogMessage(String.Format("Autopilot ending - [b]travel completed[/b]"));
                }
                else if (playerComponent.ActiveAutopilotMode == AutopilotMode.EXPLORE)
                {
                    state.LogMessage(String.Format("Autopilot ending - [b]exploration completed[/b]"));
                }
                else
                {
                    throw new NotImplementedException("no such explore mode known");
                }
            }
            else if (action.Reason == AutopilotEndReason.INVENTORY_FULL)
            {
                state.LogMessage(String.Format("Autopilot ending - [b]inventory was full[/b]"));
            }
            else if (action.Reason == AutopilotEndReason.NO_PATH)
            {
                state.LogMessage(String.Format("Autopilot ending - [b]path to next location blocked[/b]"));
            }
            else
            {
                throw new NotImplementedException("no such matching clause for enum");
            }

            state.Player.GetComponent <PlayerComponent>().StopAutopiloting();

            return(true);
        }
示例#8
0
 public void AddPrestige(int dPrestige, EncounterState state, string message, PrestigeSource source)
 {
     this._PrestigeBySource[source] += dPrestige;
     state.LogMessage(message);
 }
示例#9
0
        private static void ResolveUseEffects(Entity user, Entity usable, EncounterState state)
        {
            // We keep this logic here instead of in the component itself because the component should have only state data. That said
            // we shouldn't keep it, like, *here* here, 'least not indefinitely.
            var useEffectHeal = usable.GetComponent <UseEffectHealComponent>();

            if (useEffectHeal != null)
            {
                var restored = user.GetComponent <DefenderComponent>().RestoreHP(useEffectHeal.Healpower);
                state.LogMessage(string.Format("{0} restored {1} HP to {2}!", usable.EntityName, restored, user.EntityName));
            }

            var useEffectAddIntel = usable.GetComponent <UseEffectAddIntelComponent>();

            if (useEffectAddIntel != null)
            {
                // Kinda funny because player's the only one for which this effect is meaningful so we just grab player it's fiiiiiine
                state.Player.GetComponent <PlayerComponent>().RegisterIntel(useEffectAddIntel.TargetDungeonLevel);
                state.LogMessage(string.Format("Discovered intel for [b]sector {0}[/b]!", useEffectAddIntel.TargetDungeonLevel));
            }

            var useEffectBoostPower = usable.GetComponent <UseEffectBoostPowerComponent>();

            if (useEffectBoostPower != null)
            {
                state.LogMessage(String.Format("Attack power boosted by {0} for duration {1}!",
                                               useEffectBoostPower.BoostPower, useEffectBoostPower.Duration));
                var statusEffectTracker = user.GetComponent <StatusEffectTrackerComponent>();
                statusEffectTracker.AddEffect(new StatusEffectTimedPowerBoost(
                                                  boostPower: useEffectBoostPower.BoostPower,
                                                  startTick: state.CurrentTick,
                                                  endTick: state.CurrentTick + useEffectBoostPower.Duration
                                                  ));
            }

            var useEffectBoostSpeed = usable.GetComponent <UseEffectBoostSpeedComponent>();

            if (useEffectBoostSpeed != null)
            {
                state.LogMessage(String.Format("Speed boosted by {0} for duration {1}!",
                                               useEffectBoostSpeed.BoostPower, useEffectBoostSpeed.Duration));
                var statusEffectTracker = user.GetComponent <StatusEffectTrackerComponent>();
                statusEffectTracker.AddEffect(new StatusEffectTimedSpeedBoost(
                                                  boostPower: useEffectBoostSpeed.BoostPower,
                                                  startTick: state.CurrentTick,
                                                  endTick: state.CurrentTick + useEffectBoostSpeed.Duration
                                                  ));
            }

            var useEffectEMP = usable.GetComponent <UseEffectEMPComponent>();

            if (useEffectEMP != null)
            {
                state.LogMessage(String.Format("EMP detonated in radius {0} - disables {1} turns!",
                                               useEffectEMP.Radius, useEffectEMP.DisableTurns));
                var userPosition = user.GetComponent <PositionComponent>().EncounterPosition;
                for (int x = userPosition.X - useEffectEMP.Radius; x <= userPosition.X + useEffectEMP.Radius; x++)
                {
                    for (int y = userPosition.Y - useEffectEMP.Radius; y <= userPosition.Y + useEffectEMP.Radius; y++)
                    {
                        var distance = userPosition.DistanceTo(x, y);
                        if (distance <= useEffectEMP.Radius && state.IsInBounds(x, y))
                        {
                            var entitiesAtPosition = state.EntitiesAtPosition(x, y);
                            foreach (var entity in entitiesAtPosition)
                            {
                                var speedComponent = entity.GetComponent <SpeedComponent>();
                                var statusTracker  = entity.GetComponent <StatusEffectTrackerComponent>();
                                if (entity != user && speedComponent != null && statusTracker != null)
                                {
                                    var disableTicks = speedComponent.Speed * useEffectEMP.DisableTurns;
                                    statusTracker.AddEffect(new StatusEffectTimedDisable(state.CurrentTick, state.CurrentTick + disableTicks));
                                    state.LogMessage(String.Format("{0} was disabled for {1} ticks!", entity.EntityName, disableTicks));
                                }
                            }
                        }
                    }
                }
            }
        }