/// <summary> /// Performs the action and handles feedback /// </summary> /// <param name="?"></param> public void PerformAction(MapCoordinate coord, MapItem item, DRObjects.Enums.ActionType actionType, object[] args) { //remove any viewtiletext components or contextmenu components for (int i = 0; i < interfaceComponents.Count; i++) { var type = interfaceComponents[i].GetType(); if (type.Equals(typeof(ViewTileTextComponent)) || type.Equals(typeof(ContextMenuComponent))) { //delete interfaceComponents.RemoveAt(i); i--; } } ActionFeedback[] fb = UserInterfaceManager.PerformAction(coord, item, actionType, args); //go through all the feedback for (int i = 0; i < fb.Length; i++) { ActionFeedback feedback = fb[i]; if (feedback == null) { continue; } if (feedback.GetType().Equals(typeof(AttackFeedback))) { AttackFeedback af = feedback as AttackFeedback; var combatAf = CombatManager.Attack(af.Attacker, af.Defender, AttackLocation.CHEST); //always attack the chest var tempFBList = fb.ToList(); tempFBList.AddRange(combatAf); fb = tempFBList.ToArray(); } else if (feedback.GetType().Equals(typeof(OpenInterfaceFeedback))) { OpenInterfaceFeedback oif= feedback as OpenInterfaceFeedback; //Generate one if (oif.Interface.GetType() == typeof(CombatManualInterface)) { var cmi = oif.Interface as CombatManualInterface; CombatManualComponent cmc = new CombatManualComponent(GraphicsDevice.Viewport.Width / 2 - 200, GraphicsDevice.Viewport.Height / 2 - 150, cmi.Manual); interfaceComponents.Add(cmc); } else if (oif.Interface.GetType() == typeof(ThrowItemInterface)) { var tii = oif.Interface as ThrowItemInterface; //Do we have LoS to that point? if (GameState.LocalMap.HasDirectPath(GameState.PlayerCharacter.MapCharacter.Coordinate,tii.Coordinate)) { ThrowItemComponent tic = new ThrowItemComponent(Mouse.GetState().X, Mouse.GetState().Y, tii.Coordinate, GameState.PlayerCharacter); interfaceComponents.Add(tic); } else { var tempFBList = fb.ToList(); tempFBList.Add(new TextFeedback("You can't see there")); fb = tempFBList.ToArray(); } } } else if (feedback.GetType().Equals(typeof(TextFeedback))) { MouseState mouse = Mouse.GetState(); //Display it interfaceComponents.Add(new ViewTileTextComponent(mouse.X + 15, mouse.Y, (feedback as TextFeedback).Text)); } else if (feedback.GetType().Equals(typeof(LogFeedback))) { GameState.NewLog.Add(feedback as LogFeedback); } else if (feedback.GetType().Equals(typeof(InterfaceToggleFeedback))) { InterfaceToggleFeedback iop = feedback as InterfaceToggleFeedback; if (iop.InterfaceComponent == InternalActionEnum.OPEN_ATTACK && iop.Open) { //Open the attack interface for a particular actor. If one is not open already //Identify the actor in question var actorMapItem = iop.Argument as LocalCharacter; //Locate the actual actor Actor actor = GameState.LocalMap.Actors.Where(lm => lm.MapCharacter == actorMapItem).FirstOrDefault(); //Yep, it's a pointer equals bool openAlready = false; //Do we have one open already? foreach (AttackActorComponent aac in interfaceComponents.Where(ic => ic.GetType().Equals(typeof(AttackActorComponent)))) { if (aac.TargetActor.Equals(actor)) { openAlready = true; break; } } if (!openAlready) { //Open it. Otherwise don't do anything interfaceComponents.Add(new AttackActorComponent(150, 150, GameState.PlayerCharacter, actor) { Visible = true }); } } else if (iop.InterfaceComponent == InternalActionEnum.OPEN_ATTACK && !iop.Open) { //Close it var actor = iop.Argument as Actor; AttackActorComponent component = null; foreach (AttackActorComponent aac in interfaceComponents.Where(ic => ic.GetType().Equals(typeof(AttackActorComponent)))) { if (aac.TargetActor.Equals(actor)) { component = aac; } } //Did we have a match? if (component != null) { //remove it interfaceComponents.Remove(component); } } else if (iop.InterfaceComponent == InternalActionEnum.OPEN_TRADE && iop.Open) { //Open trade var arguments = iop.Argument as object[]; TradeDisplayComponent tdc = new TradeDisplayComponent(100, 100, arguments[1] as Actor, arguments[0] as Actor); interfaceComponents.Add(tdc); } else if (iop.InterfaceComponent == InternalActionEnum.OPEN_LOOT) { //Open Loot TreasureChest lootContainer = (iop.Argument as object[])[0] as TreasureChest; LootComponent lc = new LootComponent(100, 100, lootContainer); interfaceComponents.Add(lc); } } else if (feedback.GetType().Equals(typeof(CreateEventFeedback))) { CreateEventFeedback eventFeedback = feedback as CreateEventFeedback; var gameEvent = EventHandlingManager.CreateEvent(eventFeedback.EventName); //Create the actual control interfaceComponents.Add(new DecisionPopupComponent(PlayableWidth / 2 - 150, PlayableHeight / 2 - 150, gameEvent)); } else if (feedback.GetType().Equals(typeof(ReceiveEffectFeedback))) { ReceiveEffectFeedback recFeed = feedback as ReceiveEffectFeedback; EffectsManager.PerformEffect(recFeed.Effect.Actor, recFeed.Effect); } else if (feedback.GetType().Equals(typeof(ReceiveBlessingFeedback))) { ReceiveBlessingFeedback blessFeedback = feedback as ReceiveBlessingFeedback; LogFeedback lg = null; //Bless him! //Later we're going to want to do this properly so other characters can get blessed too BlessingManager.GetAndApplyBlessing(GameState.PlayerCharacter, out lg); if (lg != null) { //Log it GameState.NewLog.Add(lg); } } else if (feedback.GetType().Equals(typeof(ReceiveItemFeedback))) { ReceiveItemFeedback receiveFeedback = feedback as ReceiveItemFeedback; //Determine which item we're going to generate InventoryItemManager iim = new InventoryItemManager(); InventoryItem itm = iim.GetBestCanAfford(receiveFeedback.Category.ToString(), receiveFeedback.MaxValue); if (itm != null) { itm.InInventory = true; GameState.PlayerCharacter.Inventory.Inventory.Add(itm.Category, itm); GameState.NewLog.Add(new LogFeedback(InterfaceSpriteName.SUN, Color.DarkGreen, "You throw in your offering. You then see something glimmer and take it out")); } else { GameState.NewLog.Add(new LogFeedback(InterfaceSpriteName.MOON, Color.DarkBlue, "You throw in your offering. Nothing appears to be there. Hmm...")); } } else if (feedback.GetType().Equals(typeof(LocationChangeFeedback))) { //Remove settlement button and interface var locDetails = this.interfaceComponents.Where(ic => ic.GetType().Equals(typeof(LocationDetailsComponent))).FirstOrDefault(); if (locDetails != null) { this.interfaceComponents.Remove(locDetails); } var button = this.menuButtons.Where(mb => (mb as AutoSizeGameButton).Action == InternalActionEnum.TOGGLE_SETTLEMENT).FirstOrDefault(); if (button != null) { this.menuButtons.Remove(button); } LocationChangeFeedback lce = feedback as LocationChangeFeedback; if (lce.Location != null) { LoadLocation(lce.Location); if (lce.Location is Settlement) { //Makde the components visible LocationDetailsComponent ldc = new LocationDetailsComponent(GameState.LocalMap.Location as Settlement, PlayableWidth - 170, 0); ldc.Visible = true; interfaceComponents.Add(ldc); menuButtons.Add(new AutoSizeGameButton(" Settlement ", this.game.Content, InternalActionEnum.TOGGLE_SETTLEMENT, new object[] { }, 270, GraphicsDevice.Viewport.Height - 35)); Window_ClientSizeChanged(null, null); //button is in the wrong position for some reason } GameState.LocalMap.IsGlobalMap = false; } else if (lce.VisitMainMap) { //If it's a bandit camp or a site, update the values of the members if (GameState.LocalMap.Location as MapSite != null || GameState.LocalMap.Location as BanditCamp != null) { if (GameState.LocalMap.Location as BanditCamp != null) { var banditCamp = GameState.LocalMap.Location as BanditCamp; banditCamp.BanditTotal = GameState.LocalMap.Actors.Count(a => a.IsActive && a.IsAlive && !a.IsPlayerCharacter && a.EnemyData != null && a.EnemyData.Profession == ActorProfession.WARRIOR); //Has it been cleared? if (banditCamp.BanditTotal == 0) { //Find the item var campItem = GameState.GlobalMap.CampItems.FirstOrDefault(ci => ci.Camp == (GameState.LocalMap.Location as BanditCamp)); if (campItem != null) { campItem.IsActive = false; GameState.GlobalMap.CampItems.Remove(campItem); //Also find the coordinate of the camp, grab a circle around it and remove the owner var mapblocks = GameState.GlobalMap.GetBlocksAroundPoint(campItem.Coordinate, WorldGenerationManager.BANDIT_CLAIMING_RADIUS); foreach (var block in mapblocks) { var tile = (block.Tile as GlobalTile); //Owned by bandit if (tile.Owner == 50) { tile.RemoveOwner(); } } //Yes. Let's clear the camp GameState.NewLog.Add(new LogFeedback(InterfaceSpriteName.SWORD, Color.Black, "You drive the bandits away from the camp")); } } } else if (GameState.LocalMap.Location as MapSite != null) { var site = GameState.LocalMap.Location as MapSite; site.SiteData.ActorCounts.Clear(); foreach (var actorProfession in (ActorProfession[])Enum.GetValues(typeof(ActorProfession))) { int count = GameState.LocalMap.Actors.Count(a => a.IsActive && a.IsAlive && !a.IsPlayerCharacter && a.EnemyData != null && a.EnemyData.Profession == actorProfession); site.SiteData.ActorCounts.Add(actorProfession, count); } if (site.SiteData.ActorCounts[ActorProfession.WARRIOR] == 0) { //Out of warriors, abandon it. We'll decide who really owns it later site.SiteData.OwnerChanged = true; site.SiteData.MapRegenerationRequired = true; site.SiteData.Owners = OwningFactions.ABANDONED; site.SiteData.ActorCounts = new Dictionary<ActorProfession, int>(); } } } //Serialise the old map GameState.LocalMap.SerialiseLocalMap(); //Clear the stored location items GameState.LocalMap.Location = null; LoadGlobalMap(GameState.PlayerCharacter.GlobalCoordinates); GameState.LocalMap.IsGlobalMap = true; } else if (lce.RandomEncounter != null) { //Get the biome LoadRandomEncounter(lce.RandomEncounter.Value); } } else if (feedback.GetType().Equals(typeof(DropItemFeedback))) { DropItemFeedback dif = feedback as DropItemFeedback; //Drop the item underneath the player GameState.LocalMap.GetBlockAtCoordinate(dif.ItemToDrop.Coordinate).PutItemUnderneathOnBlock(dif.ItemToDrop); //Remove from inventory dif.ItemToDrop.InInventory = false; GameState.PlayerCharacter.Inventory.Inventory.Remove(dif.ItemToDrop.Category, dif.ItemToDrop); } else if (feedback.GetType().Equals(typeof(TimePassFeedback))) { TimePassFeedback tpf = feedback as TimePassFeedback; //Move time forth GameState.IncrementGameTime(DRTimeComponent.MINUTE, tpf.TimePassInMinutes); //Is the character dead? if (!GameState.PlayerCharacter.IsAlive) { var gameEvent = EventHandlingManager.CreateEvent("Hunger Death"); //Create the actual control interfaceComponents.Add(new DecisionPopupComponent(PlayableWidth / 2 - 150, PlayableHeight / 2 - 150, gameEvent)); } } else if (feedback.GetType().Equals(typeof(VisitedBlockFeedback))) { VisitedBlockFeedback vbf = feedback as VisitedBlockFeedback; //Visit a region equal to the line of sight of the player character - var blocks = GameState.LocalMap.GetBlocksAroundPoint(vbf.Coordinate, GameState.PlayerCharacter.LineOfSight); //Only do the ones which can be ray traced foreach (var block in RayTracingHelper.RayTraceForExploration(blocks, GameState.PlayerCharacter.MapCharacter.Coordinate)) { block.WasVisited = true; } } else if (feedback.GetType().Equals(typeof(DescendDungeonFeedback))) { DescendDungeonFeedback ddf = feedback as DescendDungeonFeedback; (GameState.LocalMap.Location as Dungeon).DifficultyLevel++; this.LoadLocation(GameState.LocalMap.Location, true); } } //Update the log control log.UpdateLog(); }
public override void Initialize() { base.Initialize(); if (parameters.Length == 0) { TestFunctions.PrepareFileTestMap(); } else if (parameters[0].ToString().Equals("Village")) { //TestFunctions.ParseXML(); TestFunctions.GenerateSettlement(); InventoryItemManager mgr = new InventoryItemManager(); for (int i = 0; i < 500; i++) { var block = GameState.LocalMap.GetBlockAtCoordinate(new MapCoordinate(GameState.Random.Next(GameState.LocalMap.localGameMap.GetLength(0)), GameState.Random.Next(GameState.LocalMap.localGameMap.GetLength(1)), 0, MapType.LOCAL)); if (block.MayContainItems) { var item = mgr.CreateItem(DatabaseHandling.GetItemIdFromTag(Archetype.INVENTORYITEMS, "loot")) as InventoryItem; item.Coordinate = new MapCoordinate(block.Tile.Coordinate); block.ForcePutItemOnBlock(item); } } //Create the new character stuff MultiDecisionComponent mdc = new MultiDecisionComponent(PlayableWidth / 2 - 250, 150, CharacterCreation.GenerateCharacterCreation()); mdc.Visible = true; interfaceComponents.Add(mdc); GameState.LocalMap.IsGlobalMap = false; } else if (parameters[0].ToString().Equals("Continue")) { GameState.LoadGame(); } else if (parameters[0].ToString().Equals("WorldMap")) { //Load from the world map var worldMap = GameState.GlobalMap.globalGameMap; List<MapBlock> collapsedMap = new List<MapBlock>(); foreach (var block in worldMap) { collapsedMap.Add(block); } GameState.LocalMap = new LocalMap(GameState.GlobalMap.globalGameMap.GetLength(0), GameState.GlobalMap.globalGameMap.GetLength(1), 1, 0); //Go through each of them, add them to the local map GameState.LocalMap.AddToLocalMap(collapsedMap.ToArray()); //Let's start the player off at the first capital var coordinate = GameState.GlobalMap.WorldSettlements.Where(w => w.IsCapital).Select(w => w.Coordinate).FirstOrDefault(); //Create the player character. For now randomly. Later we'll start at a capital MapItem player = new MapItem(); player.Coordinate = new MapCoordinate(coordinate); player.Description = "The player character"; player.Graphic = SpriteManager.GetSprite(LocalSpriteName.PLAYERCHAR_MALE); player.InternalName = "Player Char"; player.MayContainItems = false; player.Name = "Player"; MapBlock playerBlock = GameState.LocalMap.GetBlockAtCoordinate(player.Coordinate); playerBlock.PutItemOnBlock(player); GameState.PlayerCharacter = new Actor(); GameState.PlayerCharacter.MapCharacter = player; GameState.PlayerCharacter.IsPlayerCharacter = true; GameState.PlayerCharacter.Attributes = ActorGeneration.GenerateAttributes("human", DRObjects.ActorHandling.CharacterSheet.Enums.ActorProfession.WARRIOR, 10, GameState.PlayerCharacter); GameState.PlayerCharacter.Anatomy = ActorGeneration.GenerateAnatomy("human"); GameState.PlayerCharacter.Attributes.Health = GameState.PlayerCharacter.Anatomy; GameState.PlayerCharacter.Inventory.EquippedItems = ActorGeneration.GenerateEquippedItems(250); //give him 250 worth of stuff foreach (var item in GameState.PlayerCharacter.Inventory.EquippedItems.Values) { GameState.PlayerCharacter.Inventory.Inventory.Add(item.Category, item); } GameState.LocalMap.Actors.Add(GameState.PlayerCharacter); //What attributes do we want? MultiDecisionComponent mdc = new MultiDecisionComponent(PlayableWidth / 2 - 250, 150, CharacterCreation.GenerateCharacterCreation()); mdc.Visible = true; interfaceComponents.Add(mdc); GameState.LocalMap.IsGlobalMap = true; } else if (parameters[0].ToString().Equals("Camp")) { TestFunctions.ParseXML(); } else { TestFunctions.GenerateDungeon(); //Give him random stats so he won't completly suck CharacterCreation.ProcessParameters(CharacterCreation.GenerateRandom()); //Also give him a bow of some sort InventoryItemManager iim = new InventoryItemManager(); InventoryItem item = iim.GetBestCanAfford("WEAPON", 500); GameState.PlayerCharacter.SpecialAttacks[0] = SpecialAttacksGenerator.GenerateSpecialAttack(1); GameState.PlayerCharacter.SpecialAttacks[1] = SpecialAttacksGenerator.GenerateSpecialAttack(2); GameState.PlayerCharacter.SpecialAttacks[2] = SpecialAttacksGenerator.GenerateSpecialAttack(3); GameState.PlayerCharacter.SpecialAttacks[1].TimeOutLeft = 5; // GameState.PlayerCharacter.SpecialAttacks[3] = SpecialAttacksGenerator.GenerateSpecialAttack(4); // GameState.PlayerCharacter.SpecialAttacks[4] = SpecialAttacksGenerator.GenerateSpecialAttack(5); item.InInventory = true; //Give them a bunch of potions at random for (int i = 0; i < 5; i++ ) { var potionType = (PotionType[])Enum.GetValues(typeof(PotionType)); var potion = potionType.GetRandom(); var p = new Potion(potion); p.InInventory = true; GameState.PlayerCharacter.Inventory.Inventory.Add(p.Category, p); } GameState.PlayerCharacter.Inventory.Inventory.Add(item.Category, item); } //Add the health control HealthDisplayComponent hdc = new HealthDisplayComponent(50, 50, GameState.LocalMap.Actors.Where(a => a.IsPlayerCharacter).FirstOrDefault()); hdc.Visible = false; interfaceComponents.Add(hdc); CharacterSheetComponent csc = new CharacterSheetComponent(50, 50, GameState.LocalMap.Actors.Where(a => a.IsPlayerCharacter).FirstOrDefault()); csc.Visible = false; interfaceComponents.Add(csc); InventoryDisplayComponent ivt = new InventoryDisplayComponent(50, 50, GameState.LocalMap.Actors.Where(a => a.IsPlayerCharacter).FirstOrDefault()); ivt.Visible = false; interfaceComponents.Add(ivt); TextLogComponent tlc = new TextLogComponent(10, GraphicsDevice.Viewport.Height - 50, GameState.NewLog); tlc.Visible = true; interfaceComponents.Add(tlc); log = tlc; AdventureDisplayComponent tdc = new AdventureDisplayComponent(GraphicsDevice.Viewport.Width / 2 - 100, 0); interfaceComponents.Add(tdc); var cemetry = SpriteManager.GetSprite(InterfaceSpriteName.DEAD); //Create the menu buttons menuButtons.Add(new AutoSizeGameButton(" Health ", this.game.Content, InternalActionEnum.OPEN_HEALTH, new object[] { }, 50, GraphicsDevice.Viewport.Height - 35)); menuButtons.Add(new AutoSizeGameButton(" Attributes ", this.game.Content, InternalActionEnum.OPEN_ATTRIBUTES, new object[] { }, 150, GraphicsDevice.Viewport.Height - 35)); if (GameState.LocalMap.Location as Settlement != null) { menuButtons.Add(new AutoSizeGameButton(" Settlement ", this.game.Content, InternalActionEnum.TOGGLE_SETTLEMENT, new object[] { }, 270, GraphicsDevice.Viewport.Height - 35)); LocationDetailsComponent ldc = new LocationDetailsComponent(GameState.LocalMap.Location as Settlement, PlayableWidth - 170, 0); ldc.Visible = true; interfaceComponents.Add(ldc); } menuButtons.Add(new AutoSizeGameButton(" Inventory ", this.game.Content, InternalActionEnum.OPEN_INVENTORY, new object[] { }, 350, GraphicsDevice.Viewport.Height - 35)); //Invoke a size change Window_ClientSizeChanged(null, null); }