/// <summary> /// Loads an Ability from abilities.slk /// </summary> /// <param name="aid">The unique ID of this Ability</param> public Ability(string aid) { Aid = aid; Code = GameData.GetAbilityData <string>(aid, "code"); CastTime = GameData.GetAbilityData <float>(aid, "cast"); Duration = GameData.GetAbilityData <float>(aid, "duration"); Cooldown = GameData.GetAbilityData <float>(aid, "cooldown"); Energy = GameData.GetAbilityData <int>(aid, "energy"); Area = GameData.GetAbilityData <float>(aid, "aoe"); CastRange = GameData.GetAbilityData <float>(aid, "range"); AllowedTarget = (GameData.GetAbilityData <string>(aid, "target") != null ? GameData.GetAbilityData <string>(aid, "target").Split(',') : new string[0]); Target = new Target(GameData.GetAbilityData <string>(aid, "target") != null ? GameData.GetAbilityData <string>(aid, "target") : ""); for (int i = 0; i < 4; i++) { Data[i] = GameData.GetAbilityData <string>(aid, "data" + (i + 1).ToString()); } Texture2D icon = null; IconPath = GameData.GetAbilityData <string>(aid, "icon"); // If it does not have an icon, we'll provide one if (String.IsNullOrEmpty(IconPath)) { IconPath = "jamie"; } if (League.Engine != null) { icon = League.Engine.Content.Load <Texture2D>("icons/" + IconPath); } IconX = GameData.GetAbilityData <int>(aid, "x"); IconY = GameData.GetAbilityData <int>(aid, "y"); Name = GameData.GetAbilityData <string>(aid, "comment"); Desc = GameData.GetAbilityData <string>(aid, "desc"); if (League.Engine != null) { Button = new ContextButton(icon, Name, Desc, null, IconX, IconY, AbilityButton); Button.Tag = aid; } }
/// <summary> /// Finishes creating the UnitType. This must be done separately so we don't get stack overflows /// when we add references to other UnitTypes. /// </summary> public void FinishConstruction() { if (!String.IsNullOrEmpty(GameData.GetUnitData <string>(Uid, "trains"))) { if (League.Engine != null) { Actions.Add(ContextButton.Rally); } Trains = new List <string>(); UnitsTrained = GameData.GetUnitData <string>(Uid, "trains").Split(','); if (League.Engine != null) { foreach (string tuid in UnitsTrained) { Actions.Add(UnitType.GetUnitType(tuid)); Trains.Add(tuid); } } } if (!String.IsNullOrEmpty(GameData.GetUnitData <string>(Uid, "builds"))) { List <ContextButton> builds = new List <ContextButton>(); UnitsBuilt = GameData.GetUnitData <string>(Uid, "builds").Split(','); if (League.Engine != null) { foreach (string tuid in UnitsBuilt) { builds.Add(UnitType.GetUnitType(tuid)); } // This is a button which looks like a cancel but actually just resets our buttons builds.Add(new ContextButton(League.Engine.Content.Load <Texture2D>("icons/cancel"), "Cancel", "", null, 4, 2, ContextButton.ChangeActions)); ContextButton button = new ContextButton(League.Engine.Content.Load <Texture2D>("icons/cancel"), "Build Structure", "", null, 0, 2, ContextButton.ChangeActions); button.Tag = new List <ContextButton>(builds.ToArray()); Actions.Add(button); } } if (!String.IsNullOrEmpty(GameData.GetUnitData <string>(Uid, "abilities"))) { Abilities = GameData.GetUnitData <string>(Uid, "abilities").Split(','); if (League.Engine != null) { foreach (string aid in Abilities) { Actions.Add(Ability.GetAbility(aid)); } } } }
/// <summary> /// Updates the Gui /// </summary> /// <param name="gameTime">A snapshot of timing values</param> public override void Update(GameTime gameTime) { if (Player.CurrentPlayer.Selected.Count > 0) { // Create a cooldown texture for all abilities which need it foreach (KeyValuePair <string, float> pair in Player.CurrentPlayer.Selected[0].AbilityCooldown) { Ability a = Ability.GetAbility(pair.Key); if (a.IconX != -1 && a.IconY != -1) { float complete = (a.Cooldown - pair.Value) / a.Cooldown; GetCooldownCircle(CooldownTextures[a.IconX, a.IconY], complete); } } } // Increase GC count if (!GCD.IsAlive) { GCR++; GCD = new WeakReference(new object()); } float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds; MouseState ms = Mouse.GetState(); Rectangle mouse = new Rectangle(ms.X, ms.Y, 1, 1); Cooldown -= elapsed; KeyboardState ks = Keyboard.GetState(); // There are multiple units selected - show the selection UI if (Player.CurrentPlayer.Selected.Count > 1) { TooltipButton = ContextButton.Null; int x = 0; int y = 0; for (int i = 0; i < Player.CurrentPlayer.Selected.Count; i++) { Unit selected = Player.CurrentPlayer.Selected[i]; // We don't have rectangles for these, so we need to do the math ourselves if (ms.X >= 173 + x * 36 && ms.Y >= 481 + y * 36 && ms.X < 209 + x * 36 && ms.Y < 520 + y * 36) { if (ms.LeftButton == ButtonState.Pressed && Cooldown <= 0f) { if (ks.IsKeyDown(Keys.LeftControl)) { Player.CurrentPlayer.Selected.Remove(selected); } else { if ((Engine.OnSelect != null && Engine.OnSelect.Invoke(selected, Engine.OnSelectTag)) || Engine.OnSelect == null) { Player.CurrentPlayer.Selected.Clear(); Player.CurrentPlayer.Selected.Add(selected); } } Cooldown = 0.2f; return; } // Create a non-ContextButton tooltip TooltipButton = null; Tooltip = new Tooltip(selected.Type.Name, " ", null); return; } x++; if (x == 9) { x = 0; y++; } } } // There is one unit selected and it is training else if (Player.CurrentPlayer.Selected.Count == 1 && Player.CurrentPlayer.Selected[0].Training.Count != 0) { TooltipButton = ContextButton.Null; int x = 0; int y = 0; for (int i = 0; i < Player.CurrentPlayer.Selected[0].Training.Count; i++) { if (ms.X >= 173 + x * 36 && ms.Y >= 504 + y * 36 && ms.X < 209 + x * 36 && ms.Y < 540 + y * 36) { if (ms.LeftButton == ButtonState.Pressed && Cooldown <= 0f) { // Cancel training units Player.CurrentPlayer.Selected[0].Training.DequeueAt(i); if (i == 0 && Player.CurrentPlayer.Selected[0].Training.Count > 0) { Player.CurrentPlayer.Selected[0].TrainTime = GameData.GetUnitData <int>(Player.CurrentPlayer.Selected[0].Training.Peek(), "buildTime"); } Cooldown = 0.2f; return; } TooltipButton = null; Tooltip = new Tooltip(UnitType.GetUnitType(Player.CurrentPlayer.Selected[0].Training.Peek(i)).Name, " ", null); return; } if (y == 0) { y++; } else { x++; } if (x == 9) { x = 0; y++; } } } // There is a tooltip to be shown if (TooltipButton != null) { Tooltip = null; TooltipButton = ContextButton.Null; if (Actions != null) { foreach (ContextButton button in Actions) { if ((ks.IsKeyDown(button.Hotkey) || (button.Rectangle.Intersects(mouse) && ms.LeftButton == ButtonState.Pressed)) && Cooldown <= 0f) { button.Action.Invoke(button.Name, button.Tag); //Player.CurrentPlayer.RefreshActions(); Cooldown = 0.2f; } if (button.Rectangle.Intersects(mouse)) { TooltipButton = button; Tooltip = button.Tooltip; } } } } // Coerce messages count if (Messages.Count > 6) { for (int i = 0; i < Messages.Count - 6; i++) { Messages.RemoveAt(0); } } base.Update(gameTime); }
/// <summary> /// Loads a UnitType from a uid /// </summary> /// <param name="uid">The uid to load</param> public UnitType(string uid) { // Load lots of goodies from the SLK MeshPath = GameData.GetUnitData <string>(uid, "model"); if (League.Engine != null) { Mesh = new GameModel(League.Engine.Content.Load <Model>("models/" + MeshPath)); } Height = GameData.GetUnitData <float>(uid, "moveHeight"); Speed = GameData.GetUnitData <float>(uid, "moveSpeed"); TurnSpeed = GameData.GetUnitData <float>(uid, "turnSpeed"); ConstrainToGround = GameData.GetUnitData <bool>(uid, "moveOnGround"); Scale = GameData.GetUnitData <float>(uid, "scale"); BuildTime = GameData.GetUnitData <int>(uid, "buildTime"); Name = GameData.GetUnitData <string>(uid, "comment"); SelectionCircleSize = GameData.GetUnitData <float>(uid, "selectionCircle"); IsBuilding = GameData.GetUnitData <bool>(uid, "isBuilding"); UseTeamColor = GameData.GetUnitData <bool>(uid, "useTeamColor"); Moves = GameData.GetUnitData <bool>(uid, "moveSpeed"); Attacks = GameData.GetUnitData <bool>(uid, "attack1"); AttackGfx = GameData.GetUnitData <string>(uid, "attackGfx1"); AttackGfxSize = GameData.GetUnitData <float>(uid, "attackScale1"); AttackMagic = GameData.GetUnitData <string>(uid, "attackMagic1"); AttackMagicData = GameData.GetUnitData <string>(uid, "attackMagicData1"); AttackRange = GameData.GetUnitData <int>(uid, "attackRng1"); AttackSpeed = GameData.GetUnitData <int>(uid, "attackSpeed1"); AttackEngage = GameData.GetUnitData <int>(uid, "attackEngage1"); AttackDamage = GameData.GetUnitData <int>(uid, "attackDmg1"); AttackAllowedTarget = GameData.GetUnitData <string>(uid, "attackTarget1") != null ? GameData.GetUnitData <string>(uid, "attackTarget1").Split(',') : new string[0]; AttackTarget = new Target(GameData.GetUnitData <string>(uid, "attackTarget1") != null ? GameData.GetUnitData <string>(uid, "attackTarget1") : ""); Sight = GameData.GetUnitData <int>(uid, "sight"); AttackCooldown = GameData.GetUnitData <float>(uid, "attackCooldown1"); Hp = GameData.GetUnitData <int>(uid, "hp"); Energy = GameData.GetUnitData <int>(uid, "energy"); Description = GameData.GetUnitData <string>(uid, "desc"); SkinPath = GameData.GetUnitData <string>(uid, "skin"); if (String.IsNullOrEmpty(SkinPath)) { SkinPath = "jamie"; } if (League.Engine != null) { Skin = League.Engine.Content.Load <Texture2D>("textures/" + SkinPath); } if (GameData.GetUnitData <string>(uid, "classification") != null) { ClassifiedAs = GameData.GetUnitData <string>(uid, "classification").Split(','); Classification = Target.GetClassification(GameData.GetUnitData <string>(uid, "classification")); } List <ContextButton> actions = new List <ContextButton>(); if (Moves) { // Give him appropriate actions actions.Add(ContextButton.Move); actions.Add(ContextButton.Stop); actions.Add(ContextButton.Patrol); } if (Attacks) { // Give him appropriate actions actions.Add(ContextButton.Guard); actions.Add(ContextButton.Attack); Classification |= Classification.Attacks; // TODO: Actually see if they can attack air and or ground Classification |= Classification.AttacksAir; Classification |= Classification.AttacksGround; } Costs = new Dictionary <string, int>(); if (!String.IsNullOrEmpty(GameData.GetUnitData <string>(uid, "cost"))) { ResourceCosts = GameData.GetUnitData <string>(uid, "cost").Split(','); foreach (string dat in ResourceCosts) { string[] bits = dat.Split('='); Costs.Add(bits[0].ToLower(), int.Parse(bits[1])); } } if (!String.IsNullOrEmpty(GameData.GetUnitData <string>(uid, "requires"))) { Dependencies = GameData.GetUnitData <string>(uid, "requires").Split(','); Requirements = new List <string>(Dependencies); } else { Requirements = new List <string>(); } // Construct the tooltip IconPath = GameData.GetUnitData <string>(uid, "icon"); IconX = GameData.GetUnitData <int>(uid, "x"); IconY = GameData.GetUnitData <int>(uid, "y"); if (League.Engine != null) { Button = new ContextButton(League.Engine.Content.Load <Texture2D>("icons/" + IconPath), "Train " + Name, Description, Requirements, IconX, IconY, TrainPress); foreach (KeyValuePair <string, int> pair in Costs) { Resource r = Resource.Resources[pair.Key.ToLower()]; switch (r.PreferredIconNumber) { case 1: Button.Tooltip.Icon1 = new Tooltip.IconNumber(r.Icon, pair.Value); break; case 2: Button.Tooltip.Icon2 = new Tooltip.IconNumber(r.Icon, pair.Value); break; case 3: Button.Tooltip.Icon3 = new Tooltip.IconNumber(r.Icon, pair.Value); break; case 4: Button.Tooltip.Icon4 = new Tooltip.IconNumber(r.Icon, pair.Value); break; case 5: Button.Tooltip.Icon5 = new Tooltip.IconNumber(r.Icon, pair.Value); break; case 6: Button.Tooltip.Icon6 = new Tooltip.IconNumber(r.Icon, pair.Value); break; } } } if (League.Engine != null) { if (IsBuilding) { Button.Tooltip.Name = "Build " + Name; Button.Action = BuildPress; Classification |= Classification.Structure; } Button.Tag = uid; Button.TypeOf = typeof(UnitType); Actions = new List <ContextButton>(actions.ToArray()); } UnitData = GameData.UnitData.GetRow(uid); Uid = uid; }