public Error LessThanStructureCount(IGameObject obj, IEnumerable <Effect> effects, string[] parms, uint id) { string type = parms[0]; // tmp basement string type2 = parms[1]; // basement var count1 = obj.City.Count(structure => objectTypeFactory.IsStructureType(type, structure)); var count2 = obj.City.Count(structure => objectTypeFactory.IsStructureType(type2, structure)); if (count1 < count2) { return(Error.Ok); } return(Error.EffectRequirementNotMet); }
public override Error Execute() { //Forest doesnt need to know the rate changed foreach (var camp in obj.City.Where(s => objectTypeFactory.IsStructureType("ForestCamp", s))) { object efficiency; if (!camp.Properties.TryGet("efficiency", out efficiency)) { continue; } var newRate = formula.GetWoodRateForForestCamp(camp, (float)efficiency); var oldRate = (int)camp["Rate"]; if (oldRate == newRate) { continue; } camp.BeginUpdate(); camp["Rate"] = newRate; camp.EndUpdate(); camp.City.BeginUpdate(); camp.City.Resource.Wood.Rate += newRate - oldRate; camp.City.EndUpdate(); } obj.BeginUpdate(); obj["Labor"] = formula.GetForestCampLaborerString(obj); obj.EndUpdate(); return(Error.Ok); }
public virtual Error CanStructureBeAttacked(IStructure structure) { // Can't attack structures that are being built if (structure.IsBlocked != 0 || structure.Stats.Hp == 0 || structure.Lvl == 0) { return(Error.ObjectNotAttackable); } // Can't attack structures that are marked as Unattackable if (objectTypeFactory.IsStructureType("Unattackable", structure)) { return(Error.ObjectNotAttackable); } // Can't attack understroyabled structure that are level 1 if ((objectTypeFactory.IsStructureType("Undestroyable", structure) && structure.Lvl <= 1)) { return(Error.StructureUndestroyable); } return(Error.Ok); }
private void Repair() { ushort repairPower = 0; InitVars += city => repairPower = 0; FirstLoop += (city, structure) => { if (city.Owner.IsIdleForAWeek) { return; } if (objectTypeFactory.IsStructureType("RepairBuilding", structure)) { repairPower += formula.RepairRate(structure); } }; SecondLoop += (city, structure) => { if (repairPower <= 0) { return; } if (structure.Stats.Base.Battle.MaxHp <= structure.Stats.Hp || objectTypeFactory.IsStructureType("NonRepairable", structure) || structure.State.Type == ObjectState.Battle) { return; } structure.BeginUpdate(); structure.Stats.Hp = (ushort)Math.Min(structure.Stats.Hp + repairPower, structure.Stats.Base.Battle.MaxHp); structure.EndUpdate(); }; }
public override Error Execute() { ICity city; IStructure structure; if (!world.TryGetObjects(cityId, structureId, out city, out structure)) { return(Error.ObjectNotFound); } if (objectTypeFactory.IsStructureType("MainBuilding", structure)) { return(Error.StructureUndowngradable); } if (objectTypeFactory.IsStructureType("NonUserDestroyable", structure)) { return(Error.StructureUndowngradable); } if (objectTypeFactory.IsStructureType("Undestroyable", structure)) { return(Error.StructureUndestroyable); } var buildTime = formula.BuildTime(structureCsvFactory.GetTime(structure.Type, (byte)(structure.Lvl + 1)), city, structure.Technologies) .Clamp((int)TimeSpan.FromMinutes(3).TotalSeconds, (int)TimeSpan.FromHours(1).TotalSeconds); endTime = DateTime.UtcNow.AddSeconds(CalculateTime(buildTime)); BeginTime = DateTime.UtcNow; if (WorkerObject.WorkerId != structureId) { city.References.Add(structure, this); } return(Error.Ok); }
public void HiddenResourceNoBasementsShouldNotProtectAnyResource(IObjectTypeFactory objectTypeFactory, Formula formula) { var city = Substitute.For <ICity>(); city.GetEnumerator() .Returns(args => new List <IStructure> { Substitute.For <IStructure>() }.GetEnumerator()); objectTypeFactory.IsStructureType("Basement", Arg.Any <IStructure>()).Returns(false); formula.HiddenResource(city).CompareTo(new Resource(0, 0, 0, 0, 0)).Should().Be(0); formula.HiddenResource(city, true).CompareTo(new Resource(0, 0, 0, 0, 0)).Should().Be(0); }
public override Error Execute() { //Forest doesnt need to know the rate changed var lumbermill = obj.City.FirstOrDefault(s => objectTypeFactory.IsStructureType("Lumbermill", s)); if (lumbermill == null) { return(Error.LumbermillUnavailable); } lumbermill.BeginUpdate(); lumbermill["Labor"] = formula.GetForestCampLaborerString(lumbermill); lumbermill.EndUpdate(); return(Error.Ok); }
public string ReloadForest(Session session, string[] parms) { bool help = false; int capacity = 400; try { var p = new OptionSet { { "capacity=", v => capacity = int.Parse(v) }, { "?|help|h", v => help = true }, }; p.Parse(parms); } catch (Exception) { help = true; } if (help) { return("reloadforest --capacity=count"); } forestManager.ReloadForests(capacity); foreach (ICity city in cityManager.AllCities()) { locker.Lock(city).Do(() => { var lumbermill = city.FirstOrDefault(structure => objectTypeFactory.IsStructureType("Lumbermill", structure)); if (lumbermill == null) { return; } lumbermill.BeginUpdate(); lumbermill["Labor"] = formula.GetForestCampLaborerString(lumbermill); lumbermill.EndUpdate(); }); } return(string.Format("OK! All forests' capacities set to [{0}]", capacity)); }
private void CreateForestCamp(Session session, Packet packet) { uint cityId; uint forestId; ushort type; ushort labor; try { cityId = packet.GetUInt32(); forestId = packet.GetUInt32(); type = packet.GetUInt16(); labor = packet.GetUInt16(); } catch (Exception) { ReplyError(session, packet, Error.Unexpected); return; } ICity city = session.Player.GetCity(cityId); if (city == null) { ReplyError(session, packet, Error.CityNotFound); return; } locker.Lock(forestManager.CallbackLockHandler, new object[] { forestId }, city).Do(() => { // Get the lumbermill IStructure lumbermill = city.FirstOrDefault(structure => objectTypeFactory.IsStructureType("Wood", structure)); if (lumbermill == null || lumbermill.Lvl == 0) { ReplyError(session, packet, Error.LumbermillUnavailable); return; } var buildaction = actionFactory.CreateForestCampBuildActiveAction(cityId, lumbermill.ObjectId, forestId, type, labor); Error ret = city.Worker.DoActive(structureCsvFactory.GetActionWorkerType(lumbermill), lumbermill, buildaction, lumbermill.Technologies); if (ret == Error.ActionTotalMaxReached) { ReplyError(session, packet, Error.LumbermillBusy); } else { ReplyWithResult(session, packet, ret); } }); }
public override Error Execute() { ICity city; IStructure lumbermill; IForest forest; if (!world.TryGetObjects(cityId, lumbermillId, out city, out lumbermill) || !forestManager.TryGetValue(forestId, out forest)) { return(Error.ObjectNotFound); } // Count number of camps and verify there's enough space left int campCount = city.Count(s => objectTypeFactory.IsStructureType("ForestCamp", s)); if (campCount >= 5) { return(Error.ForestCampMaxReached); } // Make sure some labors are being put in if (labors <= 0) { return(Error.LaborNotEnough); } // Make sure we have the specified number of laborers int currentInUsedLabor = lumbermill.City.Where(s => objectTypeFactory.IsStructureType("ForestCamp", s)).Sum(x => x.Stats.Labor); if (formula.GetLumbermillMaxLabor(lumbermill) < labors + currentInUsedLabor) { return(Error.LaborOverflow); } // Make sure it's within the limit of a forest camp if (labors > formula.GetForestCampMaxLabor(lumbermill)) { return(Error.ForestCampMaxLaborReached); } // Make sure this user is not already milking this forest. if (forest.Count(obj => obj.City == city) > 0) { return(Error.AlreadyInForest); } // Cost requirement Resource cost = formula.StructureCost(city, structureCsvFactory.GetBaseStats(campType, 1)); // Add labor count to the total cost cost.Labor += labors; if (!city.Resource.HasEnough(cost)) { return(Error.ResourceNotEnough); } // find an open space around the forest uint emptyX = 0; uint emptyY = 0; foreach (var position in tileLocator.ForeachTile(forest.PrimaryPosition.X, forest.PrimaryPosition.Y, 1, false).Reverse()) { // Make sure it's not taken if (world.Regions.GetObjectsInTile(position.X, position.Y).Any()) { continue; } emptyX = position.X; emptyY = position.Y; break; } if (emptyX == 0 || emptyY == 0) { return(Error.ForestFull); } world.Regions.LockRegion(emptyX, emptyY); // add structure to the map IStructure structure = city.CreateStructure(campType, 0, emptyX, emptyY); structure.BeginUpdate(); structure["Rate"] = 0; // Set initial rate for camp structure.Stats.Labor = labors; city.BeginUpdate(); city.Resource.Subtract(cost); city.EndUpdate(); if (!world.Regions.Add(structure)) { city.ScheduleRemove(structure, false); city.BeginUpdate(); city.Resource.Add(cost); city.EndUpdate(); structure.EndUpdate(); world.Regions.UnlockRegion(emptyX, emptyY); return(Error.MapFull); } structure.EndUpdate(); campId = structure.ObjectId; forest.BeginUpdate(); forest.AddLumberjack(structure); forest.RecalculateForest(); forest.EndUpdate(); lumbermill.BeginUpdate(); lumbermill["Labor"] = formula.GetForestCampLaborerString(lumbermill); lumbermill.EndUpdate(); // add to queue for completion var campBuildTime = structureCsvFactory.GetTime(campType, 1); var actionEndTime = formula.GetLumbermillCampBuildTime(campBuildTime, lumbermill, forest, tileLocator); endTime = SystemClock.Now.AddSeconds(CalculateTime(actionEndTime)); BeginTime = SystemClock.Now; city.References.Add(structure, this); world.Regions.UnlockRegion(emptyX, emptyY); return(Error.Ok); }
private void RoadCreate(Session session, Packet packet) { var reply = new Packet(packet); uint x; uint y; uint cityId; try { cityId = packet.GetUInt32(); x = packet.GetUInt32(); y = packet.GetUInt32(); } catch (Exception) { ReplyError(session, packet, Error.Unexpected); return; } if (!world.Regions.IsValidXandY(x, y)) { ReplyError(session, packet, Error.Unexpected); return; } // Make sure there is no structure at this point that has no road requirement if (world.Regions.GetObjectsInTile(x, y).Any( s => s is IStructure && objectTypeFactory.IsStructureType("NoRoadRequired", (IStructure)s))) { ReplyError(session, packet, Error.StructureExists); return; } ICity city; locker.Lock(cityId, out city).Do(() => { if (city == null) { ReplyError(session, packet, Error.CityNotFound); return; } // Make sure user is building road within city walls if (tileLocator.TileDistance(city.PrimaryPosition, 1, new Position(x, y), 1) >= city.Radius) { ReplyError(session, packet, Error.NotWithinWalls); return; } world.Regions.LockRegion(x, y); // Make sure this tile is not already a road if (world.Roads.IsRoad(x, y)) { world.Regions.UnlockRegion(x, y); ReplyError(session, packet, Error.RoadAlreadyExists); return; } // Make sure there is a road next to this tile bool hasRoad = false; foreach (var position in tileLocator.ForeachRadius(x, y, 1, false)) { if ((world.Roads.IsRoad(position.X, position.Y) && !world.Regions.GetObjectsInTile(position.X, position.Y).Any(s => s is IStructure && s != city.MainBuilding))) { hasRoad = true; break; } } if (!hasRoad) { world.Regions.UnlockRegion(x, y); ReplyError(session, packet, Error.RoadNotAround); return; } if (objectTypeFactory.IsTileType("TileResource", world.Regions.GetTileType(x, y))) { world.Regions.UnlockRegion(x, y); ReplyError(session, packet, Error.TileMismatch); return; } world.Roads.CreateRoad(x, y, city.RoadTheme); world.Regions.UnlockRegion(x, y); session.Write(reply); }); }