//everything is already checked, locked, checked again //write and unlock will also be done by the caller public Ship buildShip(int newShipId, ShipTemplate template, Field field, int userId, Colony colony, bool fastBuild) { Ship newShip = new Ship(newShipId); newShip.userid = userId; newShip.FormerOwner = userId; newShip.initFromTemplate(template, newShip.id); newShip.initFromField(field); newShip.initFromColony(colony); StatisticsCalculator.calc(newShip, Core.Instance); Core.Instance.ships[newShip.id] = newShip; Core.Instance.addShipToField(newShip); Core.Instance.users[userId].ships.Add(newShip); //remove ressources removeGoods(colony, template, fastBuild); return(newShip); }
/// <summary> /// calculates statistics for ships and templates /// <para></para> /// <param name="ship">an object implementing the ShipStatistics interface </param> /// </summary> public static void calc(ShipStatistics ship, Core core) { int moduleMaximumCount = core.ShipHulls[ship.hullid].ShipHullsModulePositions.Count; resetStatistics(ship); addModuleStatistics(ship, core.ShipHulls[ship.hullid].ShipHullGain); int scanners = 0; int shield = 0; int armor = 0; foreach (var module in ship.shipStatisticsModules) { addModuleStatistics(ship, core.Modules[module.moduleId].moduleGain); if (core.Modules[module.moduleId].moduleGain.scanRange > 0) { scanners++; } if (core.Modules[module.moduleId].moduleGain.damagereduction > 0) { shield++; } if (core.Modules[module.moduleId].moduleGain.hitpoints > 0) { armor++; } } moduleMaximumCount = Math.Max(moduleMaximumCount, 1); ship.max_hyper = ship.max_hyper / moduleMaximumCount * (decimal)core.ShipHulls[ship.hullid].ShipHullGain.speedFactor; ship.max_impuls = ship.max_impuls / moduleMaximumCount * (decimal)core.ShipHulls[ship.hullid].ShipHullGain.speedFactor; //5 turns: ship.max_hyper = ship.max_hyper * 5; ship.max_impuls = ship.max_impuls * 5; //some modules loose efficiency when multiples are built in: double scannerFactorShip = 0.8; double scannerFactorStation = 0.85; double shieldFactor = 0.7; double armorFactor = 1; //Effectivity reduction: ship.scanRange = (byte)applyFactor(ship.scanRange, scanners, StatisticsCalculator.isSpaceStation(ship) ? scannerFactorStation : scannerFactorShip); ship.hitpoints = (short)applyFactor(ship.hitpoints, armor, armorFactor); ship.damagereduction = (byte)applyFactor(ship.damagereduction, shield, shieldFactor); if (ship is SpacegameServer.Core.Ship) { ((SpacegameServer.Core.Ship)ship).CombatMaxHitpoint = ship.hitpoints; ((SpacegameServer.Core.Ship)ship).CombatStartHitpoint = ship.hitpoints; if (ship.energy < 0 || ship.crew < 0) { ship.attack = 0; ship.defense = 0; ship.max_hyper = 0; ship.max_impuls = 0; } } //ToDO: if no impuls is present, remove the shipHull-Evasion -(but, full evasion is always calculated, so this seems not to be necessary... /* * if (scanners > 1) * { * var factor = StatisticsCalculator.isSpaceStation(ship) ? 0.85 : 0.8; // 15% - 20% loss if multiples scanners are used * factor = Math.Pow(factor, scanners - 1); //will lead to 1 scanner = 100% * ship.scanRange =(byte) Math.Ceiling(ship.scanRange * factor); * } */ //apply movement reduction according to number of cargo modules var CargoFactor = Math.Min(1.0m, 1.6m - (decimal)core.ShipHulls[ship.hullid].ShipHullGain.speedFactor); foreach (var module in ship.shipStatisticsModules) { if (core.Modules[module.moduleId].moduleGain.cargoroom == 0) { continue; } ship.max_hyper = Math.Round(ship.max_hyper * CargoFactor); ship.max_impuls = Math.Round(ship.max_impuls * CargoFactor); //ship.max_hyper = ship.max_hyper / moduleMaximumCount * (decimal)core.ShipHulls[ship.hullid].ShipHullGain.speedFactor; //ship.max_impuls = ship.max_impuls / moduleMaximumCount * (decimal)core.ShipHulls[ship.hullid].ShipHullGain.speedFactor; } if (ship is SpacegameServer.Core.Ship && (ship as SpacegameServer.Core.Ship).refitCounter > 0) { refitStatistics(ship); } }
public static bool createUpdate(string xml, int userId, ref SpacegameServer.Core.ShipTemplate template, ref SpacegameServer.Core.ShipTemplate oldTemplate) { /* * <?xml version="1.0" encoding="utf-8" ?> * <ShipTemplate> * <ShipTemplateId>1</ShipTemplateId> * <ShipTemplateHullId>1</ShipTemplateHullId> * <name>testName</name> * <gif>scout.png</gif> * <shipHullsImage>1</shipHullsImage> * <modulePositions> * <modulePosition> * <posX>3</posX> * <posY>3</posY> * <moduleId>1</moduleId> * </modulePosition> * <modulePosition> * <posX>2</posX> * <posY>3</posY> * <moduleId>2</moduleId> * </modulePosition> * </modulePositions> * </ShipTemplate> */ Core core = Core.Instance; List <Lockable> elementsToLock = new List <Lockable>(2); SpacegameServer.Core.User user = core.users[userId]; XmlDocument doc = new XmlDocument(); doc.LoadXml(xml); string templateIdString = doc.DocumentElement.SelectSingleNode("/ShipTemplate/ShipTemplateId").InnerText; int templateId; if (!Int32.TryParse(templateIdString, out templateId)) { return(false); } string templateHullIdString = doc.DocumentElement.SelectSingleNode("/ShipTemplate/ShipTemplateHullId").InnerText; byte templateHullId; if (!System.Byte.TryParse(templateHullIdString, out templateHullId)) { return(false); } string shipHullsImageString = doc.DocumentElement.SelectSingleNode("/ShipTemplate/shipHullsImage").InnerText; int shipHullsImage; if (!Int32.TryParse(shipHullsImageString, out shipHullsImage)) { return(false); } if (templateId != -1) { template = core.shipTemplate[templateId]; if (template.userId != userId) { return(false); } if (template.amountbuilt > 0) { oldTemplate = template; int newTemplateId = (int)SpacegameServer.Core.Core.Instance.identities.templateLock.getNext(); template = new SpacegameServer.Core.ShipTemplate(newTemplateId); } } else { int newTemplateId = (int)SpacegameServer.Core.Core.Instance.identities.templateLock.getNext(); template = new SpacegameServer.Core.ShipTemplate(newTemplateId); template.userId = userId; template.gif = "Dummy"; } template.name = doc.DocumentElement.SelectSingleNode("/ShipTemplate/name").InnerText; template.hullid = templateHullId; template.shipHullsImage = shipHullsImage; elementsToLock.Add(template); if (oldTemplate != null) { elementsToLock.Add(oldTemplate); } if (!LockingManager.lockAllOrSleep(elementsToLock)) { return(false); } try { template.shipModules.Clear(); System.Xml.XmlNodeList modules = doc.DocumentElement.SelectNodes("/ShipTemplate/modulePositions/modulePosition"); foreach (System.Xml.XmlNode node in modules) { string posXS = node.SelectSingleNode("posX").InnerText; //or loop through its children as well string posYS = node.SelectSingleNode("posY").InnerText; //or loop through its children as well string moduleIdS = node.SelectSingleNode("moduleId").InnerText; //or loop through its children as well byte posX, posY; short moduleId; if (!(Byte.TryParse(posXS, out posX) && Byte.TryParse(posYS, out posY) && Int16.TryParse(moduleIdS, out moduleId))) { LockingManager.unlockAll(elementsToLock); return(false); } ShipTemplateModules newModule = new ShipTemplateModules(); newModule.posX = posX; newModule.posY = posY; newModule.moduleId = moduleId; newModule.shiptemplateid = template.id; template.shipModules.Add(newModule); } StatisticsCalculator.calc(template, Core.Instance); template.isConstructable = template.energy >= 0 && template.crew >= 0; if (!core.shipTemplate.ContainsKey(template.id)) { core.shipTemplate[template.id] = template; } //save newTemplate and oldTemplate List <AsyncSaveable> elementsToSave = new List <AsyncSaveable>(); elementsToSave.Add(template); if (oldTemplate != null) { oldTemplate.obsolete = true; elementsToSave.Add(oldTemplate); } core.dataConnection.saveAsync(elementsToSave); } catch (Exception ex) { core.writeExceptionToLog(ex); } finally { LockingManager.unlockAll(elementsToLock); } return(true); }