public virtual decimal GetTroopSpeed(ITroopStub stub) { if (stub.TotalCount == 0) { return(0); } int count = 0; decimal totalSpeed = 0; int machineSpeed = int.MaxValue; foreach (var formation in stub) { foreach (var kvp in formation) { IBaseUnitStats stats = stub.City.Template[kvp.Key]; // Use the slowest machine speed if available. if (stats.Battle.Armor == ArmorType.Machine) { machineSpeed = Math.Min(stats.Battle.Speed, machineSpeed); } else { count += (kvp.Value * stats.Upkeep); totalSpeed += (kvp.Value * stats.Upkeep * stats.Battle.Speed); } } } return(Math.Round(machineSpeed == int.MaxValue ? totalSpeed / count : machineSpeed, 1)); }
private static void CreateDefinition(IBaseUnitStats stats) { nodeDefintions[GetKey(stats)] = string.Format("[label=\"{0}\", labelloc=\"b\", height=1, shape=none, image=\"{1}.png\"]", lang[stats.Name + "_UNIT"], stats.SpriteClass); }
public virtual int TrainTime(int structureLvl, int unitCount, IBaseUnitStats stats) { int[] structureDiscountByLevel = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 10, 15, 15, 20, 30, 40 }; var structureLevelDiscount = structureDiscountByLevel[Math.Min(structureLvl, structureDiscountByLevel.Length - 1)].FromPercentageDiscount(); var trainTimePerUnit = stats.BuildTime * structureLevelDiscount; return((int)(trainTimePerUnit * unitCount)); }
public override Error Execute() { ICity city; IStructure structure; if (!world.TryGetObjects(cityId, structureId, out city, out structure)) { return(Error.ObjectNotFound); } if ( city.Worker.ActiveActions.Values.Any( action => action.Type == Type && UnitType == ((UnitUpgradeActiveAction)action).UnitType && action != this)) { return(Error.ActionAlreadyInProgress); } IBaseUnitStats unitStats = city.Template[UnitType]; if (unitStats == null) { return(Error.Unexpected); } Resource cost = formula.UnitUpgradeCost(city, UnitType, (byte)(unitStats.Lvl + 1)); if (cost == null) { return(Error.Unexpected); } if (!city.Resource.HasEnough(cost)) { return(Error.ResourceNotEnough); } city.BeginUpdate(); city.Resource.Subtract(cost); city.EndUpdate(); var upgradeTime = formula.BuildTime(unitFactory.GetUpgradeTime(UnitType, (byte)(unitStats.Lvl + 1)), city, structure.Technologies); endTime = DateTime.UtcNow.AddSeconds(CalculateTime(upgradeTime)); BeginTime = DateTime.UtcNow; return(Error.Ok); }
public void TrainTime_WhenNoDiscount_ShouldNotLowerTime(int baseTime, int expected, ITechnologyManager techManager, IBaseUnitStats baseUnitStats, ICity city, Formula formula) { city.Troops.Upkeep.Returns(15); baseUnitStats.BuildTime.Returns(100); // Act formula.TrainTime(1, 1, baseUnitStats).Should().Be(100); }
public void TrainTime_WhenHasDiscount_ShouldLowerTime(int baseTime, int structureLevel, int expected, ITechnologyManager techManager, ICity city, IBaseUnitStats baseUnitStats, Formula formula) { techManager.GetEffects(0).ReturnsForAnyArgs(new List <Effect>()); baseUnitStats.BuildTime.Returns(baseTime); formula.TrainTime(structureLevel, 2, baseUnitStats).Should().Be(expected * 2); }
public DefenseCombatUnit[] CreateDefenseCombatUnit(IBattleManager battleManager, ITroopStub stub, FormationType formation, ushort type, ushort count) { var battleFormulas = kernel.Get <IBattleFormulas>(); var formula = kernel.Get <Formula>(); var unitFactory = kernel.Get <UnitFactory>(); var dbManager = kernel.Get <IDbManager>(); IBaseUnitStats template = stub.City.Template[type]; BattleStats stats = stub.Template[type]; var groupSize = (from effect in stub.City.Technologies.GetEffects(EffectCode.UnitStatMod) where ((string)effect.Value[0]).ToLower() == "groupsize" && battleFormulas.UnitStatModCheck(stats.Base, TroopBattleGroup.Defense, (string)effect.Value[3]) select(int) effect.Value[2]).DefaultIfEmpty().Max() + stats.Base.GroupSize; var units = new DefenseCombatUnit[(count - 1) / groupSize + 1]; int i = 0; do { ushort size = (ushort)(groupSize > count ? count : groupSize); DefenseCombatUnit newUnit = new DefenseCombatUnit(battleManager.GetNextCombatObjectId(), battleManager.BattleId, stub, formation, type, template.Lvl, size, battleFormulas, formula, unitFactory, dbManager); units[i++] = newUnit; count -= size; }while (count > 0); return(units); }
public BarbarianTribeCombatUnit(uint id, uint battleId, ushort type, byte lvl, ushort count, IBaseUnitStats unitBaseStats, IBarbarianTribe barbarianTribe, IBattleFormulas battleFormulas, Formula formula, IDbManager dbManager) : base(id, battleId, battleFormulas, dbManager) { BarbarianTribe = barbarianTribe; this.type = type; this.count = count; this.lvl = lvl; this.formula = formula; baseStats = unitBaseStats; battleStats = new BattleStats(unitBaseStats.Battle); LeftOverHp = baseStats.Battle.MaxHp; }
public virtual void AddType(IBaseUnitStats baseUnitStats) { dict[baseUnitStats.Type * 100 + baseUnitStats.Lvl] = baseUnitStats; }
public void DbLoaderAdd(ushort type, IBaseUnitStats stats) { dict[type] = stats; }
private static void WriteNode(IStructureBaseStats from, IBaseUnitStats to) { nodeConnections.WriteLine("{0} -> {1};", GetKey(from), GetKey(to)); }
private static string GetKey(IBaseUnitStats unit) { return("UNIT_" + unit.UnitHash); }
private static Result ProcessStructure(IStructureBaseStats structureBaseStats, bool skipUpgrades) { int hash = structureBaseStats.Type * 100 + structureBaseStats.Lvl; if (processedStructures.Contains(hash)) { return(Result.AlreadyProcessed); } Console.Out.WriteLine("Parsing " + structureBaseStats.Name + " " + structureBaseStats.Lvl); ActionRequirementFactory.ActionRecord record = kernel.Get <ActionRequirementFactory>().GetActionRequirementRecord(structureBaseStats.WorkerId); processedStructures.Add(hash); bool hadConnection = false; if (structureBaseStats.Lvl == 1) { CreateDefinition(structureBaseStats); } if (record == null) { return(Result.Empty); } // First pass foreach (var action in record.List) { switch (action.Type) { case ActionType.StructureBuildActive: case ActionType.StructureChangeActive: IStructureBaseStats building = kernel.Get <IStructureCsvFactory>().GetBaseStats(ushort.Parse(action.Parms[0]), 1); Result result = ProcessStructure(building, false); if (result != Result.AlreadyProcessed) { if (action.Type == ActionType.StructureBuildActive) { WriteNode(structureBaseStats, building); } else if (action.Type == ActionType.StructureChangeActive) { WriteNode(structureBaseStats, building, "dashed", "Converts To"); } hadConnection = true; } break; case ActionType.UnitTrainActive: IBaseUnitStats training = kernel.Get <UnitFactory>().GetUnitStats(ushort.Parse(action.Parms[0]), 1); if (!processedUnits.Contains(training.UnitHash)) { WriteNode(structureBaseStats, training); CreateDefinition(training); hadConnection = true; processedUnits.Add(training.UnitHash); } break; case ActionType.TechnologyUpgradeActive: TechnologyBase tech = kernel.Get <TechnologyFactory>().GetTechnologyBase(ushort.Parse(action.Parms[0]), 1); if (!processedTechnologies.Contains(tech.TechnologyHash)) { WriteNode(structureBaseStats, tech); CreateDefinition(tech); hadConnection = true; processedTechnologies.Add(tech.TechnologyHash); } break; } } // Second pass foreach (var action in record.List) { switch (action.Type) { case ActionType.StructureUpgradeActive: if (!skipUpgrades) { byte maxLvl = byte.Parse(action.Parms[0]); IStructureBaseStats from = structureBaseStats; var newRank = new List <String> { GetKey(from) }; for (int i = from.Lvl; i < maxLvl; i++) { IStructureBaseStats to = kernel.Get <IStructureCsvFactory>() .GetBaseStats(from.Type, (byte)(i + 1)); Result result = ProcessStructure(to, true); if (result == Result.Ok || i == maxLvl - 1) { WriteNode(from, to); CreateDefinition(to); hadConnection = true; newRank.Add(GetKey(to)); from = to; } } if (newRank.Count > 1) { ranks.Add(newRank); } } break; } } return(hadConnection ? Result.Ok : Result.Empty); }
private static void Main() { string settings = string.Empty; try { var p = new OptionSet { { "output=", v => output = v }, { "settings=", v => settings = v } }; p.Parse(Environment.GetCommandLineArgs()); } catch (Exception) { } if (!string.IsNullOrEmpty(settings)) { Config.LoadConfigFile(settings); } kernel = Engine.CreateDefaultKernel(); kernel.Get <FactoriesInitializer>().CompileAndInit(); LoadLanguages(); // Get types structureTypes = from structure in kernel.Get <IStructureCsvFactory>().AllStructures() group structure by structure.Type into types orderby types.Key select types.Key; technologyTypes = from technology in kernel.Get <TechnologyFactory>().AllTechnologies() group technology by technology.Techtype into types orderby types.Key select types.Key; unitTypes = from unit in kernel.Get <UnitFactory>().AllUnits() group unit by unit.Type into types orderby types.Key select types.Key; // Process structures Directory.CreateDirectory(output); using (var writer = new StreamWriter(File.Create(Path.Combine(output, "structure_listing.inc.php")))) { writer.Write(@"<?php $structures = array( "); foreach (var type in structureTypes) { if (kernel.Get <IObjectTypeFactory>().IsObjectType("DatabaseIgnoreStructures", type)) { continue; } ProcessStructure(type); IStructureBaseStats stats = kernel.Get <IStructureCsvFactory>().GetBaseStats(type, 1); var sprite = stats.SpriteClass; // Sorry this is a bit of a hack, it's a CropField then we append the Mature status to it :) if (kernel.Get <IObjectTypeFactory>().IsObjectType("CropField", type)) { sprite = kernel.Get <IStructureCsvFactory>() .AllStructures() .First(structure => structure.Lvl == 1 && structure.Name == "MATURE_" + stats.Name) .SpriteClass; } writer.WriteLine("'{2}_STRUCTURE' => array('name' => '{1}', 'sprite' => '{0}'),", sprite, lang[stats.Name + "_STRUCTURE_NAME"], stats.Name); } writer.Write(@");"); } // Process units using (var writer = new StreamWriter(File.Create(Path.Combine(output, "unit_listing.inc.php")))) { writer.Write(@"<?php $units = array( "); foreach (var type in unitTypes) { ProcessUnit(type); IBaseUnitStats stats = kernel.Get <UnitFactory>().GetUnitStats(type, 1); writer.WriteLine("'{2}_UNIT' => array('name' => '{1}', 'sprite' => '{0}'),", stats.SpriteClass, lang[stats.Name + "_UNIT"], stats.Name); } writer.Write(@");"); } // Process technologies // Process units using (var writer = new StreamWriter(File.Create(Path.Combine(output, "technology_listing.inc.php")))) { writer.Write(@"<?php $technologies = array( "); foreach (var type in technologyTypes) { if (kernel.Get <IObjectTypeFactory>().IsObjectType("DatabaseIgnoreTech", (ushort)type)) { continue; } ProcessTechnology(type); TechnologyBase stats = kernel.Get <TechnologyFactory>().GetTechnologyBase(type, 1); writer.WriteLine("'{0}_TECHNOLOGY' => array('name' => '{1}'),", stats.Name, lang[stats.Name + "_TECHNOLOGY_NAME"]); } writer.Write(@");"); } }
// Units private static void ProcessUnit(ushort type) { string generalTemplate = @"<?php // Generated by DatabaseGenerator program on #DATE# $unitKey = '#UNIT#'; $unitName = '#UNIT_NAME#'; $description = '#DESCRIPTION#'; $trainedBy = array('name' => '#TRAINED_BY_NAME#', 'key' => '#TRAINED_BY#', 'level' => '#TRAINED_BY_LEVEL#'); // Levels array should contain: $levels = array( #LEVELS# ); include $includeLocation . 'unit_view.ctp'; "; const string levelTemplate = @"array('time' => #TIME#, 'carry' => #CARRY#, 'speed' => #SPEED#, 'upkeep' => #UPKEEP#, 'splash' => #SPLASH#, 'trainTime' => #TRAIN_TIME#, 'trainGold' => #TRAIN_GOLD#, 'trainCrop' => #TRAIN_CROP#, 'trainIron' => #TRAIN_IRON#, 'trainLabor' => #TRAIN_LABOR#, 'trainWood' => #TRAIN_WOOD#, 'gold' => #GOLD#, 'crop' => #CROP#, 'iron' => #IRON#, 'labor' => #LABOR#, 'wood' => #WOOD#, 'hp' => #HP#, 'attack' => #ATTACK#, 'range' => #RANGE#, 'stealth' => #STEALTH#, 'armor' => '#ARMOR#', 'weapon' => '#WEAPON#', 'weaponClass' => '#WEAPONCLASS#', 'unitClass' => '#UNITCLASS#', 'requirements' => array(#REQUIREMENTS#)),"; string requirementTemplate = @"'#REQUIREMENT#',"; // Get basic information IBaseUnitStats stats = kernel.Get <UnitFactory>().GetUnitStats(type, 1); generalTemplate = generalTemplate.Replace("#DATE#", DateTime.Now.ToString()); generalTemplate = generalTemplate.Replace("#UNIT#", stats.Name + "_UNIT"); generalTemplate = generalTemplate.Replace("#UNIT_NAME#", lang[stats.Name + "_UNIT"]); generalTemplate = generalTemplate.Replace("#DESCRIPTION#", lang[stats.Name + "_UNIT_DESC"].Replace("'", "\\'")); // Builder info IStructureBaseStats trainer; FindUnitTrainer(type, 1, out trainer); generalTemplate = generalTemplate.Replace("#TRAINED_BY_NAME#", trainer != null ? lang[trainer.Name + "_STRUCTURE_NAME"] : ""); generalTemplate = generalTemplate.Replace("#TRAINED_BY#", trainer != null ? trainer.Name + "_STRUCTURE" : ""); generalTemplate = generalTemplate.Replace("#TRAINED_BY_LEVEL#", trainer != null ? trainer.Lvl.ToString() : ""); // Level info byte level = 1; var levelsWriter = new StringWriter(new StringBuilder()); IBaseUnitStats currentStats = stats; do { string currentLevel = levelTemplate.Replace("#TIME#", currentStats.UpgradeTime.ToString()); currentLevel = currentLevel.Replace("#GOLD#", currentStats.UpgradeCost.Gold.ToString()); currentLevel = currentLevel.Replace("#CROP#", currentStats.UpgradeCost.Crop.ToString()); currentLevel = currentLevel.Replace("#IRON#", currentStats.UpgradeCost.Iron.ToString()); currentLevel = currentLevel.Replace("#LABOR#", currentStats.UpgradeCost.Labor.ToString()); currentLevel = currentLevel.Replace("#WOOD#", currentStats.UpgradeCost.Wood.ToString()); currentLevel = currentLevel.Replace("#TRAIN_TIME#", currentStats.BuildTime.ToString()); currentLevel = currentLevel.Replace("#TRAIN_GOLD#", currentStats.Cost.Gold.ToString()); currentLevel = currentLevel.Replace("#TRAIN_CROP#", currentStats.Cost.Crop.ToString()); currentLevel = currentLevel.Replace("#TRAIN_IRON#", currentStats.Cost.Iron.ToString()); currentLevel = currentLevel.Replace("#TRAIN_LABOR#", currentStats.Cost.Labor.ToString()); currentLevel = currentLevel.Replace("#TRAIN_WOOD#", currentStats.Cost.Wood.ToString()); currentLevel = currentLevel.Replace("#HP#", currentStats.Battle.MaxHp.ToString()); currentLevel = currentLevel.Replace("#SPLASH#", currentStats.Battle.Splash.ToString()); currentLevel = currentLevel.Replace("#ATTACK#", currentStats.Battle.Attack.ToString()); currentLevel = currentLevel.Replace("#RANGE#", currentStats.Battle.Range.ToString()); currentLevel = currentLevel.Replace("#STEALTH#", currentStats.Battle.Stealth.ToString()); currentLevel = currentLevel.Replace("#WEAPON#", currentStats.Battle.Weapon.ToString()); currentLevel = currentLevel.Replace("#CARRY#", currentStats.Battle.Carry.ToString()); currentLevel = currentLevel.Replace("#WEAPONCLASS#", currentStats.Battle.WeaponClass.ToString()); currentLevel = currentLevel.Replace("#ARMOR#", currentStats.Battle.Armor.ToString()); currentLevel = currentLevel.Replace("#UNITCLASS#", currentStats.Battle.ArmorClass.ToString()); currentLevel = currentLevel.Replace("#SPEED#", currentStats.Battle.Speed.ToString()); currentLevel = currentLevel.Replace("#UPKEEP#", currentStats.Upkeep.ToString()); // Get requirements var requirementsWriter = new StringWriter(new StringBuilder()); if (trainer != null) { foreach (var requirement in GetUnitRequirements(type, level, trainer)) { requirementsWriter.WriteLine(requirementTemplate.Replace("#REQUIREMENT#", requirement)); } } currentLevel = currentLevel.Replace("#REQUIREMENTS#", requirementsWriter.ToString()); levelsWriter.WriteLine(currentLevel); FindUnitTrainer(type, level, out trainer); level++; }while ((currentStats = kernel.Get <UnitFactory>().GetUnitStats(type, level)) != null); generalTemplate = generalTemplate.Replace("#LEVELS#", levelsWriter.ToString()); using ( var writer = new StreamWriter(File.Create(Path.Combine(output, string.Format("{0}_UNIT.ctp", stats.Name)))) ) { writer.Write(generalTemplate); } }