/// <summary> /// Initializes a resource using tile as position /// </summary> /// <param id="entry">Entry defining the type of this game object</param> /// <param id="game">Game this game object is in</param> /// <param id="player">Owner of this game object</param> /// <param id="mapTiles">Tile where this game object is placed</param> public override void Initialize(EntryDb entry, WildmenGame game, Player player, Tile mapTile) { AssignUID(game); this.entry = (ResourceDb)entry; this.Amount = this.entry.InitialAmount; this.game = game; this.Owner = player; player.Assign(this); this.NearestTile = mapTile; this.MapPosition = mapTile.MapPosition; this.RecalculatePosition = true; }
/// <summary> /// Initialize the GameEffect /// </summary> /// <param id="game">game this effect belongs to</param> /// <param id="tile"></param> public virtual void Initialize(WildmenGame game, Tile tile) { this.game = game; this.Tile = tile; if (Entry != null) { if (Entry.Spell.OnSpellStartGameEntity != null && Entry.Spell.Target == SpellEntry.TargetType.GameEntity) { Entry.Spell.OnSpellStartGameEntity(game, this, caster, targetEntity); } else if (Entry.Spell.OnSpellStartTile != null && Entry.Spell.Target == SpellEntry.TargetType.Tile) { Entry.Spell.OnSpellStartTile(game, this, caster, targetTile); } } targetEntity = null; targetTile = null; UpdateOffset = -UI.Instance.UpdateNumber % Speed; UpdateOffset++; }
/// <summary> /// Initializes a game object using tile as position /// </summary> /// <param id="entry">Entry defining the type of this game object</param> /// <param id="game">Game this game object is in</param> /// <param id="player">Owner of this game object</param> /// <param id="mapTiles">Tile where this game object is placed</param> public abstract void Initialize(EntryDb entry, WildmenGame game, Player player, Tile mapTiles);
/// <summary> /// Gives unit an order with specified parameters /// </summary> /// <param id="order">New game object order</param> /// <param id="orderParam">Order's EntryDb parameter</param> /// <param id="targetTile">Tracked tile at the moment of giving order</param> /// <param id="targetGameObject">Tracked game object at the moment of giving order</param> /// <returns>Returns true if the order was successfully applied to the game object</returns> public virtual bool SetOrder(GameObjectOrder order, EntryDb orderParam, Tile targetTile, GameObject targetGameObject) { if (Health == 0) return false; CancelOrders(); if (targetTile == null && targetGameObject == null) return false; if (!CanDoOrder(order)) return false; return true; }
// /// <summary> /// Disposes resources used by this instance /// </summary> public override void Dispose() { entry = null; FurtestTile = null; Owner.Unassign(this); foreach (var item in claimedTiles) { item.Unassign(this); } claimedTiles.Clear(); base.Dispose(); }
public int GetTerrainBarHeight(Tile tile) { if (tile == null) return -1; Tile bot = GetSurroundingTile(tile, Direction.Bottom); if (bot == null) return tile.Elevation; Tile botLeft = GetSurroundingTile(tile, Direction.BottomLeft); Tile botRight = GetSurroundingTile(tile, Direction.BottomRight); int barsize = 1; if (botLeft != null) barsize = (int)Math.Max(barsize, (tile.Elevation - botLeft.Elevation)); if (botRight != null) barsize = (int)Math.Max(barsize, (tile.Elevation - botRight.Elevation)); barsize = (int)Math.Max(barsize, (tile.Elevation - bot.Elevation)); return barsize; }
// DRAWING private void DrawMap(Vector2 offset, Player controlPlayer, Tile mouseoverTile) { for (int y = 0; y < Map.Height; y++) { for (int x = 0; x < Map.Width; x++) { Tile tile = Map.Tiles[x, y]; if (UI.MakeRect(tile.GetDrawPosition(offset), MapBoard.TILE_SIZE).Intersects(UI.Instance.ScreenRectangle)) { tile.Draw(offset, tile == mouseoverTile, controlPlayer); } } } }
/// <summary> /// Method that deserializes the data from the line starting at given position in given context depending on the MessageType /// </summary> /// <param id="mt">MessageType defining the extend of deserialization which is to be performed</param> /// <param id="line">String array containing the serialized data</param> /// <param id="position">Current position in the array</param> /// <param id="context">Context of the serialized data, game where this INetworkSerializable object is in</param> public override void Deserialize(MessageType mt, string[] line, ref int position, WildmenGame context) { int id; base.Deserialize(mt, line, ref position, context); switch (mt) { case MessageType.GameTransfer: case MessageType.GameEffectCreate: id = int.Parse(line[position++]); owner = context.Players.First(p => p.Id == id); unitEntry = Db.Instance.Units[line[position++]]; color = new Color(byte.Parse(line[position++]), byte.Parse(line[position++]), byte.Parse(line[position++])); this.position = new Vector2(float.Parse(line[position++], CultureInfo.InvariantCulture), float.Parse(line[position++], CultureInfo.InvariantCulture)); tile = context.Map.Tiles[int.Parse(line[position++]), int.Parse(line[position++])]; break; default: throw new Exception(); } }
// /// <summary> /// Determines whether a building can be placed at given position /// </summary> /// <param name="map">Map, where the building-placement should be checked</param> /// <param name="baseTile">Base tile of the building-check</param> /// <param name="ignoreBuilding">Should the existing structures be ignored</param> /// <returns>Whether a building can be built at given position</returns> public static bool CanPlace(MapBoard map, Tile baseTile, bool ignoreBuilding = false) { int height = baseTile.Elevation; foreach (var d in new Direction[] { Direction.Center, Direction.TopLeft, Direction.Top, Direction.TopRight }) { Tile item = map.GetSurroundingTile(baseTile, d); if (item == null) return false; if (!ignoreBuilding && item.Building != null) return false; if (item.Resource != null) return false; if (item.Elevation < MapBoard.SEA_LEVEL) return false; if (Math.Abs(item.Elevation - height) > 1) return false; } return true; }
// MOUSE SELECTION /// <summary> /// Updates the tracking of game objects and tiles /// </summary> private void UpdateTracking() { bool mouseMoved = UI.Instance.MouseVector != lastMouseVector; // If tile targeting is enabled, select tile under the cursor if ((mouseoverTileTracking || autoCursor) && mouseMoved) { mouseoverTile = game.Map.GetTile(UI.Instance.MouseVector + screenOffset); } else if (!mouseoverTileTracking && !autoCursor) { mouseoverTile = null; } // If game object targeting is enabled, select game object under the cursor if ((gameObjectTracking || autoCursor) && mouseMoved) { GameObject temp = GetGameObject(UI.Instance.MouseVector + screenOffset); // Verify visibility if (temp != null && (temp.NearestTile == null || controllingPlayer.Fow[temp.NearestTile.X, temp.NearestTile.Y] != 2)) temp = null; mouseoverGameObject = temp; } else if (!gameObjectTracking && !autoCursor) { mouseoverGameObject = null; } }
// DISPOSING /// <summary> /// Flushes all the information about the map and resets the MapUI (while keeping the Game and ControllingPlayer) /// </summary> private void FlushMapInfo() { inGameState = InGameStateEnum.Default; mouseoverTile = null; mouseoverGameObject = null; map = null; mouseoverTileTracking = false; gameObjectTracking = true; mouseSelecting = false; }
public Direction? GetRelation(Tile origin, Tile target) { int oriX = origin.X; int oriY = origin.Y; int tgtX = target.X; int tgtY = target.Y; bool oddEq = origin.Odd == target.Odd; bool xEq = origin.X == target.X; bool yEq = origin.Y == target.Y; if (xEq && yEq && oddEq) return Direction.Center; int oddZero = origin.Odd ? 0 : 1; int oddOne = 1 - oddZero; if (oddEq) { if (xEq) { if (oriY - 1 == tgtY) return Direction.Top; if (oriY + 1 == tgtY) return Direction.Bottom; } else if (yEq) { if (oriX - 2 == tgtX) return Direction.Left; if (oriX + 2 == tgtX) return Direction.Right; } } else { if (oriY - oddZero == tgtY) { if (oriX - 1 == tgtX) return Direction.TopLeft; if (oriX + 1 == tgtX) return Direction.TopRight; } else if (oriY + oddOne == tgtY) { if (oriX - 1 == tgtX) return Direction.BottomLeft; if (oriX + 1 == tgtX) return Direction.BottomRight; } } return null; }
public Tile GetSurroundingTile(Tile tile, Direction direction) { bool oddTile = tile.Odd; int tileX = tile.X; int tileY = tile.Y; GetSurroundingTile(ref tileX, ref tileY, ref oddTile, direction); if (tileX < 0 || tileY < 0) return null; if (tileX >= Width || tileY >= Height) return null; return Tiles[tileX, tileY]; }
public void ChangeHeight(Tile tile, int newAmount) { tile.SetElevation(newAmount); tile.UpdateTerrainBarHeight(); Tile t; if (null != (t = GetSurroundingTile(tile, Direction.Top))) t.UpdateTerrainBarHeight(); if (null != (t = GetSurroundingTile(tile, Direction.TopLeft))) t.UpdateTerrainBarHeight(); if (null != (t = GetSurroundingTile(tile, Direction.TopRight))) t.UpdateTerrainBarHeight(); }
/// <summary> /// Constructor of this class /// </summary> /// <param name="unit">Unit, the death effect should be created from</param> public UnitDeathEffect(Unit unit) { owner = unit.Owner; color = owner.PlayerColor; unitEntry = (UnitDb)unit.Entry; position = unit.Position + unit.AlignmentOffset; tile = unit.NearestTile; Speed = 10; Duration = 10; Graphical = true; }
/// <summary> /// Initializes this instance and claims the tiles /// </summary> /// <param name="entry">Type of this building</param> /// <param name="game">The game this building is in</param> /// <param name="player">The owner of this building</param> /// <param name="baseTile">The base tile determining the position of this building</param> public override void Initialize(EntryDb entry, WildmenGame game, Player player, Tile baseTile) { AssignUID(game); Logger.Log(string.Format("Building #{0} initialized", this.ObjectUID), "Server update"); player.Assign(this); this.game = game; this.Owner = player; this.entry = (BuildingDb)entry; this.NearestTile = baseTile; ClaimTiles(baseTile); this.MapPosition = baseTile.MapPosition; this.RecalculatePosition = true; this.Health = this.entry.Health; this.Construction = 0; if (Construction >= this.entry.ConstructionAmount) { Completed(false); } }
/// <summary> /// Disposes resources used by this instance /// </summary> public override void Dispose() { owner = null; unitEntry = null; tile = null; base.Dispose(); }
/// <summary> /// Claim the surrounding tiles for this building /// </summary> /// <param name="baseTile">The base tile the surrounding tiles will be taken from</param> private void ClaimTiles(Tile baseTile) { this.NearestTile = baseTile; this.claimedTiles = new List<Tile>(); foreach (var d in new Direction[] { Direction.Center, Direction.TopLeft, Direction.Top, Direction.TopRight }) { Tile item = game.Map.GetSurroundingTile(baseTile, d); item.SetElevation(baseTile.Elevation); if (FurtestTile == null || FurtestTile.DrawZLevel > item.DrawZLevel) FurtestTile = item; this.claimedTiles.Add(item); item.Assign(this); } foreach (var tile in claimedTiles) { tile.UpdateTerrainBarHeight(); } }
/// <summary> /// Gives unit an order with specified parameters /// </summary> /// <param id="order">New game object order</param> /// <param id="orderParam">Order's EntryDb parameter</param> /// <param id="targetTile">Tracked tile at the moment of giving order</param> /// <param id="targetGameObject">Tracked game object at the moment of giving order</param> /// <returns>Returns true if the order was successfully applied to the game object</returns> public override bool SetOrder(GameObjectOrder order, EntryDb orderParam, Tile targetTile, GameObject targetGameObject) { if (this.game.IsServer) Debug.Fail("Server isn't supposed to call this routine"); if (!base.SetOrder(order, orderParam, targetTile, targetGameObject)) { game.SendData(Network.MakeClientMessage(MessageType.GameObjUpdate, this)); return false; } if (!CanDoOrder(order)) { GameEffect ge = new ScrollTextEffect("Unit cannot attack", Position, 50, new Vector2(0, -1f)); ge.Initialize(game, NearestTile); this.game.Effects.Add(ge); CancelOrders(true); return false; } BuildingDb bldgEntry; switch (order) { case GameObjectOrder.Idle: #region if (targetTile == null) return false; OrderTarget = null; OrderRange = MOVEMENT_RANGE; OrderPosition = targetTile.MapPosition + new Vector2(MapBoard.TILE_XSPACING, MapBoard.TILE_YSPACING) / 2; #endregion break; case GameObjectOrder.Attack: #region if (targetGameObject == null) return false; // Hit something if (targetGameObject == this) return false; // Don't hit yourself OrderTarget = targetGameObject; OrderRange = entry.AttackRange; OrderTimeout = entry.AttackSpeed; #endregion break; case GameObjectOrder.Construct: #region OrderRange = entry.ConstructRange; OrderTimeout = entry.ConstructSpeed; if (targetGameObject != null && targetGameObject.GetEntityType == GameEntityType.Building) { OrderTarget = targetGameObject; OrderEntry = null; } else if (targetGameObject == null || targetGameObject.GetEntityType == GameEntityType.Unit) { if (orderParam == null) return false; bldgEntry = (BuildingDb)orderParam; if (bldgEntry.OnlyOneAllowed && Owner.Buildings.Any(q => q.Entry == orderParam)) { ScrollUpMessage("Only one such building allowed at a time", 50, false); CancelOrders(true); return false; } if (bldgEntry.UnlockedBy != null) { Building bldg = Owner.Buildings.FirstOrDefault(q => q.Entry == bldgEntry.UnlockedBy); if (bldg == null || !bldg.Constructed) { ScrollUpMessage("Building unavailable", 100, true); CancelOrders(true); return false; } } OrderTarget = null; OrderEntry = (BuildingDb)orderParam; OrderPosition = targetTile.MapPosition + new Vector2(MapBoard.TILE_XSPACING, MapBoard.TILE_YSPACING) / 2; } #endregion break; case GameObjectOrder.Spell: #region EffectDb effect = (EffectDb)orderParam; if (effect.UnlockedBy != null) { Building bldg = Owner.Buildings.FirstOrDefault(q => q.Entry == effect.UnlockedBy); if (bldg == null || !bldg.Constructed) { ScrollUpMessage("Spell unavailable", 100, true); CancelOrders(true); return false; } } OrderEntry = effect; OrderRange = effect.CastRange; OrderTimeout = effect.Cooldown; switch (effect.Spell.Target) { case SpellEntry.TargetType.Tile: if (targetTile == null) return false; OrderRange = effect.CastRange; OrderPosition = targetTile.MapPosition + new Vector2(MapBoard.TILE_XSPACING, MapBoard.TILE_YSPACING) / 2; break; case SpellEntry.TargetType.GameEntity: if (targetGameObject == null) return false; OrderTarget = targetGameObject; break; } #endregion break; case GameObjectOrder.Gather: #region if (targetGameObject == null) return false; OrderTarget = targetGameObject; if (targetGameObject.GetEntityType == GameEntityType.Resource) { lastGatheredResource = (Resource)targetGameObject; } else if (targetTile != null && targetTile.Resource != null) { lastGatheredResource = targetTile.Resource; } else { CancelOrders(true); return false; } OrderRange = entry.GatherRange; OrderTimeout = entry.GatherSpeed; #endregion break; case GameObjectOrder.Train: #region if (targetGameObject == null) return false; if (targetGameObject.GetEntityType != GameEntityType.Building) return false; bldgEntry = (BuildingDb)((Building)targetGameObject).Entry; if (bldgEntry.Trains == null) return false; if (bldgEntry.Trains.All(p=>p.TrainFrom != this.Entry)) return false; OrderTarget = targetGameObject; OrderRange = MOVEMENT_RANGE; OrderTimeout = TRAIN_QUEUE_CHECK_TIMEOUT; #endregion break; default: break; } State = GameObjectState.MovingToOrder; this.Order = order; game.SendData(Network.MakeClientMessage(MessageType.GameObjUpdate, this)); return true; }
/// <summary> /// Draws a building of given type at given tile /// </summary> /// <param name="offset">Screen offset</param> /// <param name="tile">Tile, where the building should be drawn</param> /// <param name="highlight">Highlight mode</param> /// <param name="entry">Type of the building</param> public static void Draw(Vector2 offset, Tile tile, GameObjectHighlightMode highlight, BuildingDb entry) { float x = tile.MapPosition.X; int height = tile.Elevation; float y = tile.MapPosition.Y - height * MapBoard.ELEVATION_SCALING; Vector2 position = new Vector2(x, y).Round(); Vector2 textureSize = entry.Texture.Size(); float aOffX = textureSize.X / 2 - MapBoard.TILE_XSPACING / 2; float aOffY = textureSize.Y - MapBoard.TILE_YSPACING; Vector2 alignmentOffset = new Vector2(-aOffX, -aOffY); Vector2 drawPosition = position - offset + alignmentOffset; Color c = Color.Lerp(Color.White, Color.Transparent, .5f); if (highlight == GameObjectHighlightMode.InvalidPlacement) c = Color.Lerp(c, Color.Red, .5f); UI.Instance.Draw(drawPosition, entry.Texture, c, 1f); }
public void DrawOverlay(Vector2 offset, Player controlPlayer, Tile mouseoverTile, GameObject mouseoverGameObj) { DrawGameObjectsOverlay(offset, controlPlayer, mouseoverGameObj); DrawGameEffectsOverlay(offset, controlPlayer); }
public MapBoard(WildmenGame game, int width, int height) { Game = game; Valid = true; Width = width; Height = height; Tiles = new Tile[Width, Height]; float zLevelStep = 0.5f / (Height * 4); Tile.ConstructorParamBundle paramBundle = new Tile.ConstructorParamBundle(); paramBundle.zLevelStep = zLevelStep; paramBundle.map = this; for (int j = 0; j < Height; j++) { for (int i = 0; i < Width; i++) { bool oddTile = i % 2 == 1; paramBundle.isBorder = j == Height - 1; int layer = j * 2 + (oddTile ? 1 : 0); paramBundle.zLevel = zLevelStep * layer * 2; Tiles[i, j] = new Tile(i, j, paramBundle); } } }