/// <summary> /// Creates a resource of given entry at given tile /// </summary> /// <param id="entry">Db entry of the resource</param> /// <param id="tile">Tile if the resource</param> /// <returns>The created resource</returns> public IScriptResource CreateResource(IScriptDbEntry entry, IScriptTile tile) { Resource r = new Resource(); r.Initialize((EntryDb)entry, this, NaturePlayer, (Tile)tile); r.InitializeGraphics(); SendData(Network.MakeServerMessage(MessageType.GameObjCreate, tile)); return r; }
/// <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> /// Cancels game object's orders /// </summary> /// <param id="announce">Announce the cancellation to server/clients</param> public override void CancelOrders(bool announce = false) { State = GameObjectState.DoOrder; Order = GameObjectOrder.Idle; OrderEntry = null; OrderTarget = null; OrderTimeout = 0; OrderRange = MOVEMENT_RANGE; OrderPosition = MapPosition; lastGatheredResource = null; if (game.IsServer && announce) game.SendData(Network.MakeClientMessage(MessageType.GameObjUpdate, this)); }
/// <summary> /// Creates a new instance of the Resource class using the serialized data /// </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> /// <returns>Resource created using the provided serialized data</returns> public static Resource Create(MessageType mt, string[] line, ref int position, WildmenGame context) { Resource r = new Resource(); r.Deserialize(mt, line, ref position, context); r.NearestTile.Assign(r); r.game = context; r.InitializeGraphics(); return r; }
/// <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) { base.Deserialize(mt, line, ref position, context); long lastGatheredResId; string carryTypeId; switch (mt) { case MessageType.GameTransfer: case MessageType.GameObjCreate: // Entry entry = Db.Instance.Units[line[position++]].Clone(); entry.Deserialize(mt, line, ref position, context); // Last gathered resource lastGatheredResId = long.Parse(line[position++]); if (lastGatheredResId == -1) { lastGatheredResource = null; } else { lastGatheredResource = (Resource)game.GetGameObjectById(lastGatheredResId); } // Carrying resource entry carryTypeId = line[position++]; if (carryTypeId == Db.NOENTRY) { carryType = null; } else { carryType = Db.Instance.Resources[carryTypeId]; } // Carrying resource amount carryAmount = int.Parse(line[position++]); break; case MessageType.GameObjUpdate: // Entry lastGatheredResId = long.Parse(line[position++]); // Last gathered resource if (lastGatheredResId == -1) { lastGatheredResource = null; } else { lastGatheredResource = (Resource)game.GetGameObjectById(lastGatheredResId); } // Carrying resource entry carryTypeId = line[position++]; if (carryTypeId == Db.NOENTRY) { carryType = null; } else { carryType = Db.Instance.Resources[carryTypeId]; } // Carrying resource amount carryAmount = int.Parse(line[position++]); break; case MessageType.GameObjEntryUpdate: entry = Db.Instance.Units[line[position++]].Clone(); entry.Deserialize(mt, line, ref position, context); break; case MessageType.GameObjKill: break; default: throw new Exception("Unit deserialization error"); } }
public void Unassign(Resource res) { Resources.Remove(res); game.GameObjectListChanged = true; }
public void Assign(Resource res) { Resources.Add(res); res.Owner = this; game.GameObjectListChanged = true; }
/// <summary> /// Unassigns resource from this Tile /// </summary> public void Unassign(Resource res) { Debug.Assert(this.Resource == res); this.Resource = null; }
/// <summary> /// Assigns resource to this Tile /// </summary> public void Assign(Resource res) { if (this.Resource == res) return; Debug.Assert(this.Resource == null); this.Resource = res; }
public void Generate(Random random, int players) { var terrain = new MapGenerator(random, ROUGHNESS, Width, Height, players, MAP_GEN_ATTEMPTS); terrain.Generate(); if (!terrain.Valid) { Valid = false; return; } StartLocations = new List<Tile>(); foreach (var position in terrain.StartLocations) { StartLocations.Add(Tiles[position.X, position.Y]); } for (int iRow = 0; iRow < Height; iRow++) { for (int iCol = 0; iCol < Width; iCol++) { Tile tile = Tiles[iCol, iRow]; int elevation = terrain.MapElevations[iCol, iRow]; tile.SetElevation(elevation); if (elevation < MapBoard.SEA_LEVEL) continue; foreach (var item in Db.Instance.Resources) { if (random.NextDouble() < item.Value.OccurChance) { Resource r = new Resource(); r.Initialize(item.Value, Game, Game.NaturePlayer, tile); r.InitializeGraphics(); break; } } } } foreach (var item in Tiles) { item.UpdateTerrainBarHeight(); } }