public float CalculateDistance(LayerTile tile) { float dist = visitedTiles.ContainsKey(tile) ? visitedTiles[tile] : 1; if (fog.IsVisible(tile)) { //Tile visible, we check real objects WorldObject obs = map.GetWorldObject(tile.X, tile.Y); WorldObject mob = map.GetMobile(tile.X, tile.Y); if (map.IsTileOccupied(tile.X, tile.Y) || (obs != null && !obs.IsTraversable(wo)) || (mob != null && !mob.IsTraversable(wo))) { dist = float.PositiveInfinity; } } else if (fog.IsPartiallyVisible(tile)) { //partial fog, we check only revealed entity WorldObject obs = fog.GetRevealedWO(tile.X, tile.Y); if (obs != null && !obs.IsTraversable(wo)) { dist = float.PositiveInfinity; } } return(dist); }
/** * <summary> * Assumes selectedWO is not null. Checks all posible actions between selectedWO and any of the mouse tile WOs * </summary> */ private void HandleAction() { //We can't do anything if we are moving (you'd better not modify that) if (!selectedWO.IsActionBlocking()) { ui.ClearActionButtons(); //As always, when handling actions we must save the instances at the moment //If you remove this lines, when a person tries to exit a cottage, for example, //the tile for exit will be the currentTile below the button at the moment it is pressed (which will probably be null), and not the tile that was selected WorldObject currentWO = null; WorldObject currentMobile = null; LayerTile currentTile = this.currentTile; if (fog == null || fog.IsVisible(currentTile.X, currentTile.Y)) { currentWO = this.currentWO; currentMobile = this.currentMobile; } else if (fog.IsPartiallyVisible(currentTile.X, currentTile.Y)) { currentWO = fog.GetRevealedWO(currentTile.X, currentTile.Y); } foreach (ActionBehavior act in selectedWO.allActions) { if (act.CanShowButton(currentMobile)) { ui.AddAction(act.GetCommandName(currentMobile), () => HandleMovementAction(currentMobile, currentTile, act)); } if (act.CanShowButton(currentWO)) { ui.AddAction(act.GetCommandName(currentWO), () => HandleMovementAction(currentWO, currentTile, act)); } } if (selectedWO.IsMobile()) { //A button to move if "we see" the tile is free if ((currentWO == null || currentWO.IsTraversable(selectedWO)) && (currentMobile == null || currentMobile.IsTraversable(selectedWO))) { ui.AddAction("Move", () => CalculatePathDStar(selectedWO, currentTile)); } } Cottage cottage = selectedWO.Owner.FindComponent <Cottage>(); if (cottage != null) { for (int i = 0; i < cottage.GetPeople().Count; i++) { //Careful with event handlers, actions in loops, because the i variable wont work int aux = i; WorldObject peopleInside = cottage.GetPeople()[aux]; if ((currentMobile == null || currentMobile.IsTraversable(peopleInside)) && (currentWO == null || currentWO.IsTraversable(peopleInside))) { ui.AddAction(string.Format("Exit cottage {0}: {1}", aux + 1, cottage.GetPeople()[aux].GetWoName()), () => SendExit(aux + 1, currentTile)); } } } if (ui.actions.Count == 1) { //if there is only an action, we directly execute it ui.ExecuteAction(0); } else if (ui.actions.Count > 1) { for (int i = 0; i < ui.actions.Count; i++) { //Careful with event handlers, actions in loops, because the i variable wont work int aux = i; if (i >= ui.buttons.Count) { //We have less buttons than actions, create a new one ui.CreateActionButton(); } ui.UpdateActionButton(aux); } ui.optionsAlreadyShown = true; lastActionTile = currentTile; WaveServices.Layout.PerformLayout(Owner.Scene); } } }
private Entity Create(LayerTile tile, Player p) { if (tile != null) { WorldObjectData data = WorldObjectData.GetData(creating); WorldObject wo = new WorldObject(); Entity entity = new Entity() .AddComponent(new Transform2D { Position = tile.LocalPosition, DrawOrder = data.traversable ? 1f : 0.5f //traversable should be rendered behind non traversable }) .AddComponent(wo) .AddComponent(new FogRevealBehavior()); data.AddTraits(entity); wo.SetWoName(creating); wo.SetTraversable(data.traversable); wo.SetMobile(data.mobile); wo.SetMaxHealth(data.maxHealth); wo.SetHealth(data.health); wo.player = p; bool canCreate = (!data.isBuilding || wo.player == null || ((fog == null || fog.IsVisible(tile)) && wo.player.HasEnoughWood(data.woodRequired))); if (creating == "FakeTree") { canCreate = canCreate && map.GetMobile(tile.X, tile.Y) == null; } //Has it passed all this requirements?Let's check the tiles if (canCreate) { //Reset the requirements canCreate = false; //¿can it move? if (data.mobile) { if (map.GetMobile(tile.X, tile.Y) == null) { if (data.traversable) { //traversable, mobile object //Nothing like this map.SetMobile(tile.X, tile.Y, wo); canCreate = true; } else { //non traversable, mobile object //Like person if (!map.IsTileOccupied(tile.X, tile.Y) && (map.GetWorldObject(tile.X, tile.Y) == null || map.GetWorldObject(tile.X, tile.Y).IsTraversable(wo))) { //must be free to create map.SetMobile(tile.X, tile.Y, wo); map.SetTileOccupied(tile.X, tile.Y, true); canCreate = true; } } } entity.AddComponent(new MovementBehavior()) .AddComponent(new DStarLite()) .AddComponent(new SwitchBehavior()) .AddComponent(new SpriteAtlas(WaveContent.Assets.persona_spritesheet)) .AddComponent(new SpriteAtlasRenderer()) .AddComponent(new Animation2D() { PlayAutomatically = false, }) .AddComponent(new AnimationBehavior()); } else { if ((map.GetWorldObject(tile.X, tile.Y) == null && creating != "Bridge") || (map.GetWorldObject(tile.X, tile.Y) != null && map.GetWorldObject(tile.X, tile.Y).GetWoName() == "Water" && creating == "Bridge")) { if (data.traversable) { //traversable, static object //fake tree,traps Trace.WriteLine(creating); if (creating == "Bridge") { WorldObject water = map.GetWorldObject(tile.X, tile.Y); entity.FindComponent <BridgeTraits>().water = water; water.Owner.IsVisible = false; map.SetTileOccupied(tile.X, tile.Y, false); } map.SetWorldObject(tile.X, tile.Y, wo); canCreate = true; } else { //non-traversable, static object //tree,rock if (!map.IsTileOccupied(tile.X, tile.Y)) { //must be free to create map.SetWorldObject(tile.X, tile.Y, wo); map.SetTileOccupied(tile.X, tile.Y, true); canCreate = true; } } } entity.AddComponent(new SpriteRenderer()) .AddComponent(new Sprite(data.sprite)); } //Has it passed all the requirements, including the tiles?Let's populate the entity with behaviors if (canCreate) { if (data.isBuilding && wo.player != null) { wo.player.RemoveWood(data.woodRequired); } data.AddComponents(entity); if (creating == "Person") { if (wo.player != null) { wo.player.GetPeople().Add(wo); } } //From now on, we must set the visibility for those tiles visible, otherwise they must be not visible //New fog of war handles this entity.IsVisible = fog == null || (wo.IsVisible(activePlayer) && fog.IsVisible(tile.X, tile.Y)); Owner.Scene.EntityManager.Add(entity); Uncheck(); //We update the tile visibility, in case it is revealed if (fog != null) { fog.AddUpdatedTile(tile); } } return(entity); } } return(null); }