diff --git a/OpenRA.Game/GameRules/ActorInfo.cs b/OpenRA.Game/GameRules/ActorInfo.cs index fda52bb567..c7333361d5 100644 --- a/OpenRA.Game/GameRules/ActorInfo.cs +++ b/OpenRA.Game/GameRules/ActorInfo.cs @@ -16,8 +16,15 @@ using OpenRA.Traits; namespace OpenRA { + //TODO: This is not exported into the documentation yet. + [Desc("A unit/building inside the game. Every rules starts with one and adds trait to it.\n" + + "\t# Special actors like world or player are usually defined in system.yaml and effect everything.")] public class ActorInfo { + [Desc("The actor name can be anything, but the sprites used in the Render*: traits default to this one.\n" + + "\t# Also if you add an ^ in front of the name, the engine will recognize this as a collection of traits\n" + + "\t# that can be inherited by others (using Inherits:) and not a real unit." + + "\t# You can remove inherited traits by adding a - infront of them as in -TraitName: to inherit everything, but this trait.")] public readonly string Name; public readonly TypeDictionary Traits = new TypeDictionary(); diff --git a/OpenRA.Game/GameRules/WeaponInfo.cs b/OpenRA.Game/GameRules/WeaponInfo.cs index 071b40e6e7..a6a65ffd75 100644 --- a/OpenRA.Game/GameRules/WeaponInfo.cs +++ b/OpenRA.Game/GameRules/WeaponInfo.cs @@ -18,21 +18,35 @@ namespace OpenRA.GameRules { public class WarheadInfo { - public readonly int Spread = 1; // distance (in pixels) from the explosion center at which damage is 1/2. + [Desc("Distance (in pixels) from the explosion center at which damage is 1/2.")] + public readonly int Spread = 1; [FieldLoader.LoadUsing( "LoadVersus" )] - public readonly Dictionary Versus; // damage vs each armortype - public readonly bool Ore = false; // can this damage ore? - public readonly string Explosion = null; // explosion effect to use - public readonly string WaterExplosion = null; // explosion effect on hitting water (usually a splash) - public readonly string[] SmudgeType = { }; // type of smudge to apply - public readonly int[] Size = { 0, 0 }; // size of the explosion. provide 2 values for a ring effect (outer/inner) - public readonly int InfDeath = 1; // infantry death animation to use - public readonly string ImpactSound = null; // sound to play on impact - public readonly string WaterImpactSound = null; // sound to play on impact with water - public readonly int Damage = 0; // how much (raw) damage to deal - public readonly int Delay = 0; // delay in ticks before dealing the damage. 0=instant (old model) - public readonly DamageModel DamageModel = DamageModel.Normal; // which damage model to use - public readonly bool PreventProne = false; // whether we should prevent prone response in infantry. + [Desc("Damage vs each armortype. 0% = can't target.")] + public readonly Dictionary Versus; + [Desc("Can this damage ore?")] + public readonly bool Ore = false; + [Desc("Explosion effect to use.")] + public readonly string Explosion = null; + [Desc("Explosion effect on hitting water (usually a splash).")] + public readonly string WaterExplosion = null; + [Desc("Type of smudge to apply to terrain.")] + public readonly string[] SmudgeType = { }; + [Desc("Size of the explosion. provide 2 values for a ring effect (outer/inner).")] + public readonly int[] Size = { 0, 0 }; + [Desc("Infantry death animation to use")] + public readonly int InfDeath = 1; + [Desc("Sound to play on impact.")] + public readonly string ImpactSound = null; + [Desc("Sound to play on impact with water")] + public readonly string WaterImpactSound = null; + [Desc("How much (raw) damage to deal")] + public readonly int Damage = 0; + [Desc("Delay in ticks before dealing the damage, 0 = instant (old model).")] + public readonly int Delay = 0; + [Desc("Which damage model to use.")] + public readonly DamageModel DamageModel = DamageModel.Normal; + [Desc("Whether we should prevent prone response for infantry.")] + public readonly bool PreventProne = false; public float EffectivenessAgainst(Actor self) { @@ -87,6 +101,7 @@ namespace OpenRA.GameRules { public readonly float Range = 0; public readonly string[] Report = null; + [Desc("Rate of Fire")] public readonly int ROF = 1; public readonly int Burst = 1; public readonly bool Charges = false; diff --git a/OpenRA.Game/Graphics/TerrainRenderer.cs b/OpenRA.Game/Graphics/TerrainRenderer.cs index 7ead56a88b..1e17aac0a2 100644 --- a/OpenRA.Game/Graphics/TerrainRenderer.cs +++ b/OpenRA.Game/Graphics/TerrainRenderer.cs @@ -50,7 +50,7 @@ namespace OpenRA.Graphics nv += 4; if (tileMapping[map.MapTiles.Value[i, j]].sheet != terrainSheet) - throw new InvalidOperationException("Terrain sprites span multiple sheets"); + throw new InvalidOperationException("Terrain sprites span multiple sheets. Try increasing Game.Settings.Graphics.SheetSize."); } vertexBuffer = Game.Renderer.Device.CreateVertexBuffer( vertices.Length ); diff --git a/OpenRA.Game/Traits/Render/RenderSimple.cs b/OpenRA.Game/Traits/Render/RenderSimple.cs index 34ec41c879..eac7bdaa82 100755 --- a/OpenRA.Game/Traits/Render/RenderSimple.cs +++ b/OpenRA.Game/Traits/Render/RenderSimple.cs @@ -12,11 +12,13 @@ using System; using System.Collections.Generic; using System.Linq; using OpenRA.Graphics; +using OpenRA.FileFormats; namespace OpenRA.Traits { public class RenderSimpleInfo : ITraitInfo { + [Desc("Defaults to the actor name.")] public readonly string Image = null; public readonly string Palette = null; public readonly string PlayerPalette = "player"; diff --git a/OpenRA.Mods.Cnc/ProductionAirdrop.cs b/OpenRA.Mods.Cnc/ProductionAirdrop.cs index ccc439f851..6fca74b5e5 100644 --- a/OpenRA.Mods.Cnc/ProductionAirdrop.cs +++ b/OpenRA.Mods.Cnc/ProductionAirdrop.cs @@ -18,9 +18,11 @@ using OpenRA.Traits; namespace OpenRA.Mods.Cnc { + [Desc("Deliver the unit in production via skylift.")] public class ProductionAirdropInfo : ProductionInfo { public readonly string ReadyAudio = "Reinforce"; + [Desc("Cargo aircraft used.")] [ActorReference] public readonly string ActorType = "c17"; public override object Create(ActorInitializer init) { return new ProductionAirdrop(this); } diff --git a/OpenRA.Mods.RA/AcceptsSupplies.cs b/OpenRA.Mods.RA/AcceptsSupplies.cs index e37d908008..fea9571bd2 100644 --- a/OpenRA.Mods.RA/AcceptsSupplies.cs +++ b/OpenRA.Mods.RA/AcceptsSupplies.cs @@ -8,10 +8,12 @@ */ #endregion +using OpenRA.FileFormats; using OpenRA.Traits; namespace OpenRA.Mods.RA { + [Desc("Tag trait for SupplyTruck: actors.")] class AcceptsSuppliesInfo : TraitInfo {} class AcceptsSupplies {} diff --git a/OpenRA.Mods.RA/Attack/AttackBase.cs b/OpenRA.Mods.RA/Attack/AttackBase.cs index 1fa60073e8..399f5af28c 100644 --- a/OpenRA.Mods.RA/Attack/AttackBase.cs +++ b/OpenRA.Mods.RA/Attack/AttackBase.cs @@ -20,6 +20,7 @@ namespace OpenRA.Mods.RA public abstract class AttackBaseInfo : ITraitInfo { [WeaponReference] + [Desc("Has to be defined here and in weapons.yaml.")] public readonly string PrimaryWeapon = null; [WeaponReference] public readonly string SecondaryWeapon = null; diff --git a/OpenRA.Mods.RA/Attack/AttackMedic.cs b/OpenRA.Mods.RA/Attack/AttackMedic.cs index 142393d902..c557533ca4 100644 --- a/OpenRA.Mods.RA/Attack/AttackMedic.cs +++ b/OpenRA.Mods.RA/Attack/AttackMedic.cs @@ -10,9 +10,13 @@ using System; using OpenRA.Traits; +using OpenRA.FileFormats; namespace OpenRA.Mods.RA { + [Desc("Give the unit a \"heal-weapon\".\n" + + "\t# It conflicts with any other weapon or Attack*: trait because it will hurt friendlies during the\n" + + "\t# heal process then. It also won't work with buildings (use RepairsUnits: for them).")] public class AttackMedicInfo : AttackFrontalInfo { public override object Create( ActorInitializer init ) { return new AttackMedic( init.self, this ); } diff --git a/OpenRA.Mods.RA/AutoHeal.cs b/OpenRA.Mods.RA/AutoHeal.cs index 5b2e1c031b..60b4ca4f40 100644 --- a/OpenRA.Mods.RA/AutoHeal.cs +++ b/OpenRA.Mods.RA/AutoHeal.cs @@ -10,9 +10,11 @@ using System.Linq; using OpenRA.Traits; +using OpenRA.FileFormats; namespace OpenRA.Mods.RA { + [Desc("Used together with AttackMedic: to make the healer do it's job automatically to nearby units.")] class AutoHealInfo : TraitInfo, Requires { } class AutoHeal : INotifyIdle diff --git a/OpenRA.Mods.RA/AutoTarget.cs b/OpenRA.Mods.RA/AutoTarget.cs index 674fed66dd..5b0a380807 100644 --- a/OpenRA.Mods.RA/AutoTarget.cs +++ b/OpenRA.Mods.RA/AutoTarget.cs @@ -8,14 +8,17 @@ */ #endregion +using OpenRA.FileFormats; using OpenRA.Traits; using System.Drawing; using System.Linq; namespace OpenRA.Mods.RA { + [Desc("The actor will automatically engage the enemy when it is in range.")] public class AutoTargetInfo : ITraitInfo, Requires { + [Desc("It will try to hunt down the enemy if it is not set to defend.")] public readonly bool AllowMovement = true; public readonly int ScanRadius = -1; public readonly UnitStance InitialStance = UnitStance.AttackAnything; @@ -128,7 +131,7 @@ namespace OpenRA.Mods.RA } } } - + [Desc("Will not get automatically targeted by enemy (like walls)")] class AutoTargetIgnoreInfo : TraitInfo { } class AutoTargetIgnore { } } diff --git a/OpenRA.Mods.RA/BaseBuilding.cs b/OpenRA.Mods.RA/BaseBuilding.cs index 128dda6522..e7298e4660 100644 --- a/OpenRA.Mods.RA/BaseBuilding.cs +++ b/OpenRA.Mods.RA/BaseBuilding.cs @@ -9,10 +9,11 @@ #endregion using OpenRA.Traits; +using OpenRA.FileFormats; namespace OpenRA.Mods.RA { - /* tag trait for "bases": mcv/fact */ + [Desc("Tag trait for construction yard and MCVs. Used by the cycle bases hotkey to identify actors.")] public class BaseBuildingInfo : TraitInfo { } public class BaseBuilding { } } diff --git a/OpenRA.Mods.RA/Buildings/Building.cs b/OpenRA.Mods.RA/Buildings/Building.cs index fa4e9631b5..8f45f853cd 100755 --- a/OpenRA.Mods.RA/Buildings/Building.cs +++ b/OpenRA.Mods.RA/Buildings/Building.cs @@ -16,14 +16,19 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA.Buildings { + [Desc("Remove this trait to limit base-walking by cheap or defensive buildings.")] public class GivesBuildableAreaInfo : TraitInfo {} public class GivesBuildableArea {} public class BuildingInfo : ITraitInfo, UsesInit { + [Desc("If negative, it will drain power, if positive, it will provide power.")] public readonly int Power = 0; + [Desc("Where you are allowed to place the building (Water, Clear, ...)")] public readonly string[] TerrainTypes = {}; + [Desc("The range to the next building it can be constructed. Set it higher for walls.")] public readonly int Adjacent = 2; + [Desc("x means space it blocks, _ is a part that is passable by actors (like bridges).")] public readonly string Footprint = "x"; public readonly int2 Dimensions = new int2(1, 1); diff --git a/OpenRA.Mods.RA/Buildings/CustomBuildTimeValue.cs b/OpenRA.Mods.RA/Buildings/CustomBuildTimeValue.cs index cf3204c84e..ca8ca39843 100755 --- a/OpenRA.Mods.RA/Buildings/CustomBuildTimeValue.cs +++ b/OpenRA.Mods.RA/Buildings/CustomBuildTimeValue.cs @@ -8,12 +8,12 @@ */ #endregion +using OpenRA.FileFormats; using OpenRA.Traits; namespace OpenRA.Mods.RA.Buildings { - // allow a nonstandard build time value for a cnc classic mod - + [Desc("Overrides the build time calculated by actor value.")] public class CustomBuildTimeValueInfo : TraitInfo { public readonly int Value = 0; diff --git a/OpenRA.Mods.RA/Buildings/CustomSellValue.cs b/OpenRA.Mods.RA/Buildings/CustomSellValue.cs index 989791da50..302aa016bd 100755 --- a/OpenRA.Mods.RA/Buildings/CustomSellValue.cs +++ b/OpenRA.Mods.RA/Buildings/CustomSellValue.cs @@ -8,13 +8,12 @@ */ #endregion +using OpenRA.FileFormats; using OpenRA.Traits; namespace OpenRA.Mods.RA.Buildings { - // allow a nonstandard sell/repair value to avoid - // buy-sell exploits like c&c's PROC. - + [Desc("Allow a non-standard sell/repair value to avoid buy-sell exploits.")] public class CustomSellValueInfo : TraitInfo { public readonly int Value = 0; diff --git a/OpenRA.Mods.RA/Buildings/LineBuild.cs b/OpenRA.Mods.RA/Buildings/LineBuild.cs index 2b949f977c..621227c4bf 100755 --- a/OpenRA.Mods.RA/Buildings/LineBuild.cs +++ b/OpenRA.Mods.RA/Buildings/LineBuild.cs @@ -8,12 +8,15 @@ */ #endregion +using OpenRA.FileFormats; using OpenRA.Traits; namespace OpenRA.Mods.RA.Buildings { + [Desc("Place the second actor in line to build more of the same at once (used for walls).")] public class LineBuildInfo : TraitInfo { + [Desc("The maximum allowed length of the line.")] public readonly int Range = 5; } diff --git a/OpenRA.Mods.RA/Buildings/RepairableBuilding.cs b/OpenRA.Mods.RA/Buildings/RepairableBuilding.cs index 67b1095630..2b9cf42cdd 100755 --- a/OpenRA.Mods.RA/Buildings/RepairableBuilding.cs +++ b/OpenRA.Mods.RA/Buildings/RepairableBuilding.cs @@ -11,9 +11,11 @@ using System; using OpenRA.Mods.RA.Effects; using OpenRA.Traits; +using OpenRA.FileFormats; namespace OpenRA.Mods.RA.Buildings { + [Desc("Building can be repaired by the repair button.")] public class RepairableBuildingInfo : ITraitInfo, Requires { public readonly int RepairPercent = 20; diff --git a/OpenRA.Mods.RA/Capturable.cs b/OpenRA.Mods.RA/Capturable.cs index 46623edb4f..c6e9533c33 100644 --- a/OpenRA.Mods.RA/Capturable.cs +++ b/OpenRA.Mods.RA/Capturable.cs @@ -10,18 +10,22 @@ using System.Linq; using OpenRA.Effects; +using OpenRA.FileFormats; using OpenRA.Traits; using OpenRA.Mods.RA.Buildings; namespace OpenRA.Mods.RA { + [Desc("This actor can be captured by a unit with Captures: trait.")] public class CapturableInfo : ITraitInfo { public readonly string Type = "building"; public readonly bool AllowAllies = false; public readonly bool AllowNeutral = true; public readonly bool AllowEnemies = true; - public readonly int CaptureCompleteTime = 10; // seconds + [Desc("Seconds it takes to change the owner.\n" + + "\t# It stays neutral during this period. You might want to add a CapturableBar: trait, too.")] + public readonly int CaptureCompleteTime = 10; public object Create(ActorInitializer init) { return new Capturable(this); } } diff --git a/OpenRA.Mods.RA/CapturableBar.cs b/OpenRA.Mods.RA/CapturableBar.cs index f852b53c67..1aaa944f7d 100644 --- a/OpenRA.Mods.RA/CapturableBar.cs +++ b/OpenRA.Mods.RA/CapturableBar.cs @@ -10,10 +10,12 @@ using System.Drawing; using System.Linq; +using OpenRA.FileFormats; using OpenRA.Traits; namespace OpenRA.Mods.RA { + [Desc("Visualize the remaining CaptureCompleteTime from Capturable: trait.")] class CapturableBarInfo : ITraitInfo, Requires { public object Create(ActorInitializer init) { return new CapturableBar(init.self); } diff --git a/OpenRA.Mods.RA/CashTrickler.cs b/OpenRA.Mods.RA/CashTrickler.cs index f65a1e66c7..3b74567b97 100644 --- a/OpenRA.Mods.RA/CashTrickler.cs +++ b/OpenRA.Mods.RA/CashTrickler.cs @@ -10,15 +10,22 @@ using OpenRA.Traits; using OpenRA.Mods.RA.Effects; +using OpenRA.FileFormats; namespace OpenRA.Mods.RA { + [Desc("Let's the object generate cash in a set periodic time.")] class CashTricklerInfo : ITraitInfo { + [Desc("Amount of money to give each time.")] public readonly int Period = 50; + [Desc("Number of ticks to wait between giving money.")] public readonly int Amount = 15; + [Desc("Whether to show the cash tick indicators (+$15 rising from actor).")] public readonly bool ShowTicks = true; + [Desc("How long the cash tick indicator should be shown for.")] public readonly int TickLifetime = 30; + [Desc("Pixels/tick upward movement of the cash tick indicator.")] public readonly int TickVelocity = 1; public object Create (ActorInitializer init) { return new CashTrickler(this); } diff --git a/OpenRA.Mods.RA/Effects/Missile.cs b/OpenRA.Mods.RA/Effects/Missile.cs index d273a087a9..457230315d 100755 --- a/OpenRA.Mods.RA/Effects/Missile.cs +++ b/OpenRA.Mods.RA/Effects/Missile.cs @@ -13,6 +13,7 @@ using System.Collections.Generic; using System.Drawing; using System.Linq; using OpenRA.Effects; +using OpenRA.FileFormats; using OpenRA.GameRules; using OpenRA.Graphics; using OpenRA.Traits; @@ -29,6 +30,7 @@ namespace OpenRA.Mods.RA.Effects public readonly string Trail = null; public readonly float Inaccuracy = 0; public readonly string Image = null; + [Desc("Rate of Turning")] public readonly int ROT = 5; public readonly int RangeLimit = 0; public readonly bool TurboBoost = false; diff --git a/OpenRA.Mods.RA/FreeActor.cs b/OpenRA.Mods.RA/FreeActor.cs index ba96eb087b..3381a20962 100644 --- a/OpenRA.Mods.RA/FreeActor.cs +++ b/OpenRA.Mods.RA/FreeActor.cs @@ -13,12 +13,19 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA { + [Desc("Player recives a unit for free once the building is placed. This also works for structures.\n" + + "\t # If you want more then one unit to appear copy this section and assign IDs like FreeActor@2, ...")] public class FreeActorInfo : ITraitInfo { [ActorReference] + [Desc("Name of actor (HARV for refineries)")] public readonly string Actor = null; + [Desc("What the unit should start doing. Warning: If this is no harvester\n" + + "\t # it will break, when you add FindResources here.")] public readonly string InitialActivity = null; + [Desc("Offset relative to structure-center in 2D (e.g. 1, 2)")] public readonly int2 SpawnOffset = int2.Zero; + [Desc("Which direction the unit should face.")] public readonly int Facing = 0; public object Create( ActorInitializer init ) { return new FreeActor(init, this); } diff --git a/OpenRA.Mods.RA/GainsExperience.cs b/OpenRA.Mods.RA/GainsExperience.cs index d1a5b8db38..1674c9aa31 100644 --- a/OpenRA.Mods.RA/GainsExperience.cs +++ b/OpenRA.Mods.RA/GainsExperience.cs @@ -20,6 +20,7 @@ namespace OpenRA.Mods.RA { public class GainsExperienceInfo : ITraitInfo, Requires { + [Desc("XP requirements for each level, as multiples of our own cost.")] public readonly float[] CostThreshold = { 2, 4, 8, 16 }; public readonly float[] FirepowerModifier = { 1.1f, 1.15f, 1.2f, 1.5f }; public readonly float[] ArmorModifier = { 1.1f, 1.2f, 1.3f, 1.5f }; diff --git a/OpenRA.Mods.RA/GivesBounty.cs b/OpenRA.Mods.RA/GivesBounty.cs index 4cdc46e3a3..bdc7ec6fdb 100644 --- a/OpenRA.Mods.RA/GivesBounty.cs +++ b/OpenRA.Mods.RA/GivesBounty.cs @@ -11,14 +11,19 @@ using System.Linq; using OpenRA.Mods.RA.Buildings; using OpenRA.Mods.RA.Effects; +using OpenRA.FileFormats; using OpenRA.Traits; namespace OpenRA.Mods.RA { + [Desc("You get money for playing this actor.")] class GivesBountyInfo : TraitInfo { + [Desc("Calculated by Cost or CustomSellValue so they have to be set to avoid crashes.")] public readonly int Percentage = 10; + [Desc("Higher ranked units give higher bounties.")] public readonly int LevelMod = 125; + [Desc("Destroying creeps and enemies is rewarded.")] public readonly Stance[] Stances = {Stance.Neutral, Stance.Enemy}; } diff --git a/OpenRA.Mods.RA/GivesExperience.cs b/OpenRA.Mods.RA/GivesExperience.cs index 537d9d07b5..ab5dadbc06 100644 --- a/OpenRA.Mods.RA/GivesExperience.cs +++ b/OpenRA.Mods.RA/GivesExperience.cs @@ -8,11 +8,16 @@ */ #endregion +using OpenRA.FileFormats; using OpenRA.Traits; namespace OpenRA.Mods.RA { - class GivesExperienceInfo : TraitInfo { public readonly int Experience = -1; } + class GivesExperienceInfo : TraitInfo + { + [Desc("if -1, use the value of the unit cost.")] + public readonly int Experience = -1; + } class GivesExperience : INotifyKilled { diff --git a/OpenRA.Mods.RA/LimitedAmmo.cs b/OpenRA.Mods.RA/LimitedAmmo.cs index f09d9776fb..da5dee09ce 100644 --- a/OpenRA.Mods.RA/LimitedAmmo.cs +++ b/OpenRA.Mods.RA/LimitedAmmo.cs @@ -9,6 +9,7 @@ #endregion using System.Collections.Generic; +using OpenRA.FileFormats; using OpenRA.Traits; namespace OpenRA.Mods.RA @@ -16,8 +17,10 @@ namespace OpenRA.Mods.RA public class LimitedAmmoInfo : ITraitInfo { public readonly int Ammo = 0; + [Desc("Defaults to value in Ammo.")] public readonly int PipCount = 0; - public readonly int ReloadTicks = 25 * 2; // This is measured in ticks + [Desc("Time to reload measured in ticks.")] + public readonly int ReloadTicks = 25 * 2; public object Create(ActorInitializer init) { return new LimitedAmmo(this); } } diff --git a/OpenRA.Mods.RA/Move/Mobile.cs b/OpenRA.Mods.RA/Move/Mobile.cs index da7f4e0b5e..63744d9776 100755 --- a/OpenRA.Mods.RA/Move/Mobile.cs +++ b/OpenRA.Mods.RA/Move/Mobile.cs @@ -18,17 +18,22 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA.Move { + [Desc("Unit is able to move.")] public class MobileInfo : ITraitInfo, IFacingInfo, UsesInit, UsesInit, UsesInit { [FieldLoader.LoadUsing("LoadSpeeds")] + [Desc("Set Water: 0 for ground units and lower the value on rough terrain.")] public readonly Dictionary TerrainSpeeds; + [Desc("e.g. crate, wall, infantry")] public readonly string[] Crushes; public readonly int WaitAverage = 60; public readonly int WaitSpread = 20; public readonly int InitialFacing = 128; + [Desc("Rate of Turning")] public readonly int ROT = 255; public readonly int Speed = 1; public readonly bool OnRails = false; + [Desc("Allow multiple (infantry) units in one cell.")] public readonly bool SharesCell = false; public readonly int Altitude; diff --git a/OpenRA.Mods.RA/Player/ClassicProductionQueue.cs b/OpenRA.Mods.RA/Player/ClassicProductionQueue.cs index ca1ffb2135..62810ffe98 100755 --- a/OpenRA.Mods.RA/Player/ClassicProductionQueue.cs +++ b/OpenRA.Mods.RA/Player/ClassicProductionQueue.cs @@ -13,13 +13,24 @@ using System.Collections.Generic; using System.Linq; using OpenRA.Mods.RA.Buildings; using OpenRA.Traits; +using OpenRA.FileFormats; namespace OpenRA.Mods.RA { + [Desc("Attach this to the world actor (not a building!) to define a new shared build queue.\n" + + "\t# Will only work together with the Production: trait on the actor that actually does the production.\n" + + "\t# You will also want to add PrimaryBuildings: to let the user choose where new units should exit.")] public class ClassicProductionQueueInfo : ProductionQueueInfo, Requires, Requires, Requires { + [Desc("If you build more actors of the same type, \n" + + "\t# the same queue will get it's build time lowered for every actor produced there.")] public readonly bool SpeedUp = false; + [Desc("Everytime another production building of the same queue is\n" + + "\t# contructed, the build time of all actors in the queue\n" + + "\t#get divided by this value.")] public readonly int BuildTimeSpeedUpDivisor = 2; + [Desc("You can still build more production buildings\n" + + "\t# than this value, but the build time won't increase further.")] public readonly int MaxBuildTimeReductionSteps = 6; public override object Create(ActorInitializer init) { return new ClassicProductionQueue(init.self, this); } diff --git a/OpenRA.Mods.RA/Player/ProductionQueue.cs b/OpenRA.Mods.RA/Player/ProductionQueue.cs index 0ede600792..b107d9a50f 100755 --- a/OpenRA.Mods.RA/Player/ProductionQueue.cs +++ b/OpenRA.Mods.RA/Player/ProductionQueue.cs @@ -13,21 +13,41 @@ using System.Collections.Generic; using System.Linq; using OpenRA.Mods.RA.Buildings; using OpenRA.Traits; +using OpenRA.FileFormats; namespace OpenRA.Mods.RA { + [Desc("Attach this to an actor (usually a building) to let it produce units or construct buildings.\n" + + "\t# If one builds another actor of this type, he will get a separate queue to create two actors\n" + + "\t# at the same time. Will only work together with the Production: trait.")] public class ProductionQueueInfo : ITraitInfo { + [Desc("What kind of production will be added (e.g. Building, Infantry, Vehicle, ...)")] public readonly string Type = null; + [Desc("Group queues from separate buildings together into the same tab.")] public readonly string Group = null; + [Desc("This value is used to translate the unit cost into build time.")] public float BuildSpeedModifier = 0.4f; + [Desc("The build time is multiplied with this value on low power.")] public readonly int LowPowerSlowdown = 3; + [Desc("Notification played when production is complete.\n" + + "\t# The filename of the audio is defined per faction in notifications.yaml.")] public readonly string ReadyAudio = "UnitReady"; + [Desc("Notification played when you can't train another unit\n" + + "\t# when the build limit exceeded or the exit is jammed.\n" + + "\t# The filename of the audio is defined per faction in notifications.yaml.")] public readonly string BlockedAudio = "NoBuild"; + [Desc("Notification played when user clicks on the build palette icon.\n" + + "\t# The filename of the audio is defined per faction in notifications.yaml.")] public readonly string QueuedAudio = "Training"; + [Desc("Notification played when player right-clicks\n" + + "\t# on the build palette icon. The filename of the audio is defined per faction in notifications.yaml.")] public readonly string OnHoldAudio = "OnHold"; + [Desc("Notification played when player right-clicks\n" + + "\t# on a build palette icon that is already on hold.\n" + + "\t# The filename of the audio is defined per faction in notifications.yaml.")] public readonly string CancelledAudio = "Cancelled"; public virtual object Create(ActorInitializer init) { return new ProductionQueue(init.self, init.self.Owner.PlayerActor, this); } diff --git a/OpenRA.Mods.RA/PrimaryBuilding.cs b/OpenRA.Mods.RA/PrimaryBuilding.cs index 9e4b73bc51..301a5f4ded 100755 --- a/OpenRA.Mods.RA/PrimaryBuilding.cs +++ b/OpenRA.Mods.RA/PrimaryBuilding.cs @@ -11,10 +11,12 @@ using System.Collections.Generic; using System.Linq; using OpenRA.Mods.RA.Orders; +using OpenRA.FileFormats; using OpenRA.Traits; namespace OpenRA.Mods.RA { + [Desc("Used together with ClassicProductionQueue.")] class PrimaryBuildingInfo : TraitInfo { } class PrimaryBuilding : IIssueOrder, IResolveOrder, ITags @@ -54,7 +56,7 @@ namespace OpenRA.Mods.RA return; } - // THIS IS SHIT + // TODO: THIS IS SHIT // Cancel existing primaries foreach (var p in self.Info.Traits.Get().Produces) foreach (var b in self.World diff --git a/OpenRA.Mods.RA/Production.cs b/OpenRA.Mods.RA/Production.cs index 16325451a0..1f72be3454 100755 --- a/OpenRA.Mods.RA/Production.cs +++ b/OpenRA.Mods.RA/Production.cs @@ -18,13 +18,16 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA { + [Desc("This unit has access to build queues.")] public class ProductionInfo : ITraitInfo { + [Desc("e.g. Infantry, Vehicles, Aircraft, Buildings")] public readonly string[] Produces = { }; public virtual object Create(ActorInitializer init) { return new Production(this); } } + [Desc("Where the unit should leave the building. Multiples are allowed if IDs are added: Exit@2, ...")] public class ExitInfo : TraitInfo { public readonly int2 SpawnOffset = int2.Zero; // in px relative to CenterLocation diff --git a/OpenRA.Mods.RA/ProductionBar.cs b/OpenRA.Mods.RA/ProductionBar.cs index 6ca0ebf768..840b0c0153 100644 --- a/OpenRA.Mods.RA/ProductionBar.cs +++ b/OpenRA.Mods.RA/ProductionBar.cs @@ -10,10 +10,12 @@ using System.Drawing; using System.Linq; +using OpenRA.FileFormats; using OpenRA.Traits; namespace OpenRA.Mods.RA { + [Desc("Visualizes the remaining build time of actor produced here.")] class ProductionBarInfo : ITraitInfo { public object Create(ActorInitializer init) { return new ProductionBar( init.self ); } diff --git a/OpenRA.Mods.RA/RallyPoint.cs b/OpenRA.Mods.RA/RallyPoint.cs index ba7bebd280..2983d6c6c8 100755 --- a/OpenRA.Mods.RA/RallyPoint.cs +++ b/OpenRA.Mods.RA/RallyPoint.cs @@ -9,10 +9,12 @@ #endregion using System.Collections.Generic; +using OpenRA.FileFormats; using OpenRA.Traits; namespace OpenRA.Mods.RA { + [Desc("Used to waypoint units after production or repair is finished.")] public class RallyPointInfo : ITraitInfo { public readonly int[] RallyPoint = { 1, 3 }; diff --git a/OpenRA.Mods.RA/Reloads.cs b/OpenRA.Mods.RA/Reloads.cs index 40598f927a..124567da2f 100644 --- a/OpenRA.Mods.RA/Reloads.cs +++ b/OpenRA.Mods.RA/Reloads.cs @@ -8,13 +8,17 @@ */ #endregion +using OpenRA.FileFormats; using OpenRA.Traits; namespace OpenRA.Mods.RA { + [Desc("Unit will reload its limited ammo itself.")] public class ReloadsInfo : ITraitInfo, Requires { + [Desc("How much ammo is reloaded after a certain period.")] public readonly int Count = 0; + [Desc("How long it takes to do so.")] public readonly int Period = 50; public object Create(ActorInitializer init) { return new Reloads(init.self, this); } diff --git a/OpenRA.Mods.RA/Sellable.cs b/OpenRA.Mods.RA/Sellable.cs index 28fe77f27e..2e0dc184ac 100644 --- a/OpenRA.Mods.RA/Sellable.cs +++ b/OpenRA.Mods.RA/Sellable.cs @@ -12,9 +12,11 @@ using OpenRA.Mods.RA.Activities; using OpenRA.Mods.RA.Buildings; using OpenRA.Mods.RA.Render; using OpenRA.Traits; +using OpenRA.FileFormats; namespace OpenRA.Mods.RA { + [Desc("Building can be sold")] public class SellableInfo : TraitInfo { public readonly int RefundPercent = 50; diff --git a/OpenRA.Mods.RA/StoresOre.cs b/OpenRA.Mods.RA/StoresOre.cs index 569b619154..ddbd45c059 100644 --- a/OpenRA.Mods.RA/StoresOre.cs +++ b/OpenRA.Mods.RA/StoresOre.cs @@ -9,12 +9,14 @@ #endregion using System.Collections.Generic; +using OpenRA.FileFormats; using OpenRA.Traits; namespace OpenRA.Mods.RA { class StoresOreInfo : ITraitInfo { + [Desc("Number of little squares used to display how filled unit is.")] public readonly int PipCount = 0; public readonly PipType PipColor = PipType.Yellow; public readonly int Capacity = 0; diff --git a/OpenRA.Mods.RA/SupplyTruck.cs b/OpenRA.Mods.RA/SupplyTruck.cs index d7a6bfb5df..b14084f622 100644 --- a/OpenRA.Mods.RA/SupplyTruck.cs +++ b/OpenRA.Mods.RA/SupplyTruck.cs @@ -13,12 +13,15 @@ using System.Drawing; using OpenRA.Mods.RA.Activities; using OpenRA.Mods.RA.Buildings; using OpenRA.Mods.RA.Orders; +using OpenRA.FileFormats; using OpenRA.Traits; namespace OpenRA.Mods.RA { + [Desc("Donate money to building if it has the AcceptSupplies: trait.")] class SupplyTruckInfo : ITraitInfo { + [Desc("The amount of cash the owner of the building recieves.")] public readonly int Payload = 500; public object Create(ActorInitializer init) { return new SupplyTruck(this); } } diff --git a/OpenRA.Mods.RA/Valued.cs b/OpenRA.Mods.RA/Valued.cs index a27ca266d9..6df5487125 100755 --- a/OpenRA.Mods.RA/Valued.cs +++ b/OpenRA.Mods.RA/Valued.cs @@ -8,21 +8,26 @@ */ #endregion +using OpenRA.FileFormats; using OpenRA.Traits; namespace OpenRA.Mods.RA { + [Desc("How much the unit is worth.")] public class ValuedInfo : TraitInfo { + [Desc("Used in production, but also for bounties so remember to set it > 0 even for NPCs.")] public readonly int Cost = 0; } public class Valued { } + [Desc("Shown in the build palette widget.")] public class TooltipInfo : ITraitInfo { public readonly string Description = ""; public readonly string Name = ""; + [Desc("Defaults to actor name + icon suffix.")] public readonly string Icon = null; public virtual object Create(ActorInitializer init) { return new Tooltip(init.self, this); } diff --git a/OpenRA.Utility/Command.cs b/OpenRA.Utility/Command.cs index e5977e8f6f..53e320683f 100644 --- a/OpenRA.Utility/Command.cs +++ b/OpenRA.Utility/Command.cs @@ -492,7 +492,7 @@ namespace OpenRA.Utility Rules.LoadRules(Game.modData.Manifest, new Map()); Console.WriteLine("## Documentation"); - Console.WriteLine("This documentation is aimed at modders and contributers of OpenRA. Please do not edit it directly, but add new `[Desc(\"String\")]` tags to the source code. This file has been automatically generated on {0}.\n", DateTime.Now); + Console.WriteLine("This documentation is aimed at modders and contributers of OpenRA. It displays all traits with default values and developer commentary. Please do not edit it directly, but add new `[Desc(\"String\")]` tags to the source code. This file has been automatically generated on {0}. Type `make docs` to create a new one and put it on https://github.com/OpenRA/OpenRA/wiki/Traits afterwards. A copy of this is compiled to HTML and shipped with every release during the automated packaging process.\n", DateTime.Now); Console.WriteLine("```yaml\n\n"); foreach(var t in Game.modData.ObjectCreator.GetTypesImplementing()) @@ -502,23 +502,21 @@ namespace OpenRA.Utility var traitName = t.Name.Replace("Info",""); var traitDesc = t.GetCustomAttributes(false).Select(a => a.Description).FirstOrDefault(); - if (string.IsNullOrEmpty(traitDesc)) - traitDesc = "Trait documentation is missing."; + if (!string.IsNullOrEmpty(traitDesc)) + traitDesc = " # {0}".F(traitDesc); - Console.WriteLine("\t{0}: # {1}", traitName, traitDesc); + Console.WriteLine("\t{0}:{1}", traitName, traitDesc); var liveTraitInfo = Game.modData.ObjectCreator.CreateBasic(t); foreach(var f in t.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy)) { var fieldDesc = f.GetCustomAttributes(true).Select(a => a.Description).FirstOrDefault(); - if (string.IsNullOrEmpty(fieldDesc)) - fieldDesc = "No description provided."; + if (!string.IsNullOrEmpty(fieldDesc)) + fieldDesc = ", {0}".F(fieldDesc); var fieldType = NiceTypeName(f.FieldType); var defaultValue = FieldSaver.SaveField(liveTraitInfo, f.Name).Value.Value; - if (string.IsNullOrEmpty(defaultValue)) - defaultValue = ""; - Console.WriteLine("\t\t{0}: {2} # Type: {1}, {3}", f.Name, fieldType, defaultValue, fieldDesc); + Console.WriteLine("\t\t{0}: {2} # Type: {1}{3}", f.Name, fieldType, defaultValue, fieldDesc); } } Console.WriteLine("\n```");