Add a per-player handicap option to the lobby.

Handicaps reduce unit health, firepower, and build speed.
This commit is contained in:
Paul Chote
2020-12-30 15:17:44 +00:00
committed by reaperrr
parent c7c78eda80
commit 02a2624bcc
22 changed files with 346 additions and 0 deletions

View File

@@ -123,6 +123,7 @@ namespace OpenRA
DisplayFactionId = runtimePlayer.DisplayFaction.InternalName,
Color = runtimePlayer.Color,
Team = client.Team,
Handicap = client.Handicap,
SpawnPoint = runtimePlayer.SpawnPoint,
IsRandomFaction = runtimePlayer.Faction.InternalName != client.Faction,
IsRandomSpawnPoint = runtimePlayer.DisplaySpawnPoint == 0,
@@ -166,6 +167,7 @@ namespace OpenRA
/// <summary>The team ID on start-up, or 0 if the player is not part of a team.</summary>
public int Team;
public int SpawnPoint;
public int Handicap;
/// <summary>True if the faction was chosen at random; otherwise, false.</summary>
public bool IsRandomFaction;

View File

@@ -50,6 +50,9 @@ namespace OpenRA
public bool LockTeam = false;
public int Team = 0;
public bool LockHandicap = false;
public int Handicap = 0;
public string[] Allies = { };
public string[] Enemies = { };

View File

@@ -25,6 +25,7 @@ namespace OpenRA.Network
public readonly string Faction;
public readonly int SpawnPoint;
public readonly int Team;
public readonly int Handicap;
public readonly string Slot;
public readonly string Bot;
public readonly bool IsAdmin;
@@ -39,6 +40,7 @@ namespace OpenRA.Network
Faction = client.Faction;
SpawnPoint = client.SpawnPoint;
Team = client.Team;
Handicap = client.Handicap;
Slot = client.Slot;
Bot = client.Bot;
IsAdmin = client.IsAdmin;
@@ -53,6 +55,7 @@ namespace OpenRA.Network
client.Faction = Faction;
client.SpawnPoint = SpawnPoint;
client.Team = Team;
client.Handicap = Handicap;
client.Slot = Slot;
client.Bot = Bot;
client.IsAdmin = IsAdmin;

View File

@@ -144,6 +144,7 @@ namespace OpenRA.Network
public ClientState State = ClientState.Invalid;
public int Team;
public int Handicap;
public string Slot; // Slot ID, or null for observer
public string Bot; // Bot type, null for real clients
public int BotControllerClientIndex; // who added the bot to the slot
@@ -193,6 +194,7 @@ namespace OpenRA.Network
public bool LockFaction;
public bool LockColor;
public bool LockTeam;
public bool LockHandicap;
public bool LockSpawn;
public bool Required;

View File

@@ -58,6 +58,7 @@ namespace OpenRA
public readonly bool Playable = true;
public readonly int ClientIndex;
public readonly CPos HomeLocation;
public readonly int Handicap;
public readonly PlayerReference PlayerReference;
public readonly bool IsBot;
public readonly string BotType;
@@ -180,6 +181,8 @@ namespace OpenRA
HomeLocation = assignSpawnPoints?.AssignHomeLocation(world, client, playerRandom) ?? pr.HomeLocation;
SpawnPoint = assignSpawnPoints?.SpawnPointForPlayer(this) ?? client.SpawnPoint;
DisplaySpawnPoint = client.SpawnPoint;
Handicap = client.Handicap;
}
else
{
@@ -195,6 +198,7 @@ namespace OpenRA
DisplayFaction = ResolveDisplayFaction(world, pr.Faction);
HomeLocation = pr.HomeLocation;
SpawnPoint = DisplaySpawnPoint = 0;
Handicap = pr.Handicap;
}
if (!spectating)

View File

@@ -93,6 +93,8 @@ namespace OpenRA.Server
c.SpawnPoint = pr.Spawn;
if (pr.LockTeam)
c.Team = pr.Team;
if (pr.LockHandicap)
c.Team = pr.Handicap;
c.Color = pr.LockColor ? pr.Color : c.PreferredColor;
}
@@ -437,6 +439,7 @@ namespace OpenRA.Server
Faction = "Random",
SpawnPoint = 0,
Team = 0,
Handicap = 0,
State = Session.ClientState.Invalid,
};

View File

@@ -52,6 +52,16 @@ namespace OpenRA.Mods.Common.Scripting
}
}
[Desc("The player's handicap level.")]
public int Handicap
{
get
{
var c = Player.World.LobbyInfo.Clients.FirstOrDefault(i => i.Index == Player.ClientIndex);
return c?.Handicap ?? 0;
}
}
[Desc("Returns true if the player is a bot.")]
public bool IsBot { get { return Player.IsBot; } }

View File

@@ -43,6 +43,7 @@ namespace OpenRA.Mods.Common.Server
{ "name", Name },
{ "faction", Faction },
{ "team", Team },
{ "handicap", Handicap },
{ "spawn", Spawn },
{ "clear_spawn", ClearPlayerSpawn },
{ "color", PlayerColor },
@@ -245,6 +246,7 @@ namespace OpenRA.Mods.Common.Server
client.Slot = null;
client.SpawnPoint = 0;
client.Team = 0;
client.Handicap = 0;
client.Color = Color.White;
server.SyncLobbyClients();
CheckAutoStart(server);
@@ -377,6 +379,7 @@ namespace OpenRA.Mods.Common.Server
Faction = "Random",
SpawnPoint = 0,
Team = 0,
Handicap = 0,
State = Session.ClientState.NotReady,
BotControllerClientIndex = controllerClientIndex
};
@@ -736,6 +739,7 @@ namespace OpenRA.Mods.Common.Server
targetClient.Slot = null;
targetClient.SpawnPoint = 0;
targetClient.Team = 0;
targetClient.Handicap = 0;
targetClient.Color = Color.White;
targetClient.State = Session.ClientState.NotReady;
server.SendMessage("{0} moved {1} to spectators.".F(client.Name, targetClient.Name));
@@ -824,6 +828,42 @@ namespace OpenRA.Mods.Common.Server
}
}
static bool Handicap(S server, Connection conn, Session.Client client, string s)
{
lock (server.LobbyInfo)
{
var parts = s.Split(' ');
var targetClient = server.LobbyInfo.ClientWithIndex(Exts.ParseIntegerInvariant(parts[0]));
// Only the host can change other client's info
if (targetClient.Index != client.Index && !client.IsAdmin)
return true;
// Map has disabled handicap changes
if (server.LobbyInfo.Slots[targetClient.Slot].LockHandicap)
return true;
if (!Exts.TryParseIntegerInvariant(parts[1], out var handicap))
{
Log.Write("server", "Invalid handicap: {0}", s);
return false;
}
// Handicaps may be set between 0 - 95% in steps of 5%
var options = Enumerable.Range(0, 20).Select(i => 5 * i);
if (!options.Contains(handicap))
{
Log.Write("server", "Invalid handicap: {0}", s);
return false;
}
targetClient.Handicap = handicap;
server.SyncLobbyClients();
return true;
}
}
static bool ClearPlayerSpawn(S server, Connection conn, Session.Client client, string s)
{
var spawnPoint = Exts.ParseIntegerInvariant(s);
@@ -1003,6 +1043,7 @@ namespace OpenRA.Mods.Common.Server
LockFaction = pr.LockFaction,
LockColor = pr.LockColor,
LockTeam = pr.LockTeam,
LockHandicap = pr.LockHandicap,
LockSpawn = pr.LockSpawn,
Required = pr.Required,
};

View File

@@ -0,0 +1,40 @@
#region Copyright & License Information
/*
* Copyright 2007-2020 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version. For more
* information, see COPYING.
*/
#endregion
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Modifies the damage applied to this actor based on the owner's handicap.")]
public class HandicapDamageMultiplierInfo : TraitInfo
{
public override object Create(ActorInitializer init) { return new HandicapDamageMultiplier(init.Self); }
}
public class HandicapDamageMultiplier : IDamageModifier
{
readonly Actor self;
public HandicapDamageMultiplier(Actor self)
{
this.self = self;
}
int IDamageModifier.GetDamageModifier(Actor attacker, Damage damage)
{
// Equivalent to the health handicap from C&C3:
// 5% handicap = 95% health = 105% damage
// 50% handicap = 50% health = 200% damage
// 95% handicap = 5% health = 2000% damage
return 10000 / (100 - self.Owner.Handicap);
}
}
}

View File

@@ -0,0 +1,40 @@
#region Copyright & License Information
/*
* Copyright 2007-2020 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version. For more
* information, see COPYING.
*/
#endregion
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Modifies the damage applied by this actor based on the owner's handicap.")]
public class HandicapFirepowerMultiplierInfo : TraitInfo
{
public override object Create(ActorInitializer init) { return new HandicapFirepowerMultiplier(init.Self); }
}
public class HandicapFirepowerMultiplier : IFirepowerModifier
{
readonly Actor self;
public HandicapFirepowerMultiplier(Actor self)
{
this.self = self;
}
int IFirepowerModifier.GetFirepowerModifier()
{
// Equivalent to the firepower handicap from C&C3:
// 5% handicap = 95% firepower
// 50% handicap = 50% firepower
// 95% handicap = 5% firepower
return 100 - self.Owner.Handicap;
}
}
}

View File

@@ -0,0 +1,32 @@
#region Copyright & License Information
/*
* Copyright 2007-2020 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version. For more
* information, see COPYING.
*/
#endregion
using System.Collections.Generic;
using System.Linq;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Modifies the production time of this actor based on the producer's handicap.")]
public class HandicapProductionTimeMultiplierInfo : TraitInfo<HandicapProductionTimeMultiplier>, IProductionTimeModifierInfo
{
int IProductionTimeModifierInfo.GetProductionTimeModifier(TechTree techTree, string queue)
{
// Equivalent to the build speed handicap from C&C3:
// 5% handicap = 105% build time
// 50% handicap = 150% build time
// 95% handicap = 195% build time
return 100 + techTree.Owner.Handicap;
}
}
public class HandicapProductionTimeMultiplier { }
}

View File

@@ -106,6 +106,8 @@ namespace OpenRA.Mods.Common.Traits
return ret;
}
public Player Owner { get { return player; } }
class Watcher
{
public readonly string Key;

View File

@@ -64,6 +64,7 @@ namespace OpenRA.Mods.Common.Traits
DisplayFactionId = clientFaction.InternalName,
Color = client.Color,
Team = client.Team,
Handicap = client.Handicap,
SpawnPoint = resolvedSpawnPoint,
IsRandomFaction = clientFaction.RandomFactionMembers.Any(),
IsRandomSpawnPoint = client.SpawnPoint == 0,

View File

@@ -624,6 +624,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
LobbyUtils.SetupEditableColorWidget(template, slot, client, orderManager, shellmapWorld, colorPreview);
LobbyUtils.SetupEditableFactionWidget(template, slot, client, orderManager, factions);
LobbyUtils.SetupEditableTeamWidget(template, slot, client, orderManager, map);
LobbyUtils.SetupEditableHandicapWidget(template, slot, client, orderManager, map);
LobbyUtils.SetupEditableSpawnWidget(template, slot, client, orderManager, map);
LobbyUtils.SetupEditableReadyWidget(template, slot, client, orderManager, map);
}
@@ -640,6 +641,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (isHost)
{
LobbyUtils.SetupEditableTeamWidget(template, slot, client, orderManager, map);
LobbyUtils.SetupEditableHandicapWidget(template, slot, client, orderManager, map);
LobbyUtils.SetupEditableSpawnWidget(template, slot, client, orderManager, map);
LobbyUtils.SetupPlayerActionWidget(template, slot, client, orderManager, worldRenderer,
lobby, () => panel = PanelType.Kick, () => panel = PanelType.Players);
@@ -648,6 +650,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
LobbyUtils.SetupNameWidget(template, slot, client, orderManager, worldRenderer);
LobbyUtils.SetupTeamWidget(template, slot, client);
LobbyUtils.SetupHandicapWidget(template, slot, client);
LobbyUtils.SetupSpawnWidget(template, slot, client);
}

View File

@@ -146,6 +146,25 @@ namespace OpenRA.Mods.Common.Widgets.Logic
dropdown.ShowDropDown("TEAM_DROPDOWN_TEMPLATE", 150, options, setupItem);
}
public static void ShowHandicapDropDown(DropDownButtonWidget dropdown, Session.Client client,
OrderManager orderManager)
{
Func<int, ScrollItemWidget, ScrollItemWidget> setupItem = (ii, itemTemplate) =>
{
var item = ScrollItemWidget.Setup(itemTemplate,
() => client.Handicap == ii,
() => orderManager.IssueOrder(Order.Command("handicap {0} {1}".F(client.Index, ii))));
var label = "{0}%".F(ii);
item.Get<LabelWidget>("LABEL").GetText = () => label;
return item;
};
// Handicaps may be set between 0 - 95% in steps of 5%
var options = Enumerable.Range(0, 20).Select(i => 5 * i);
dropdown.ShowDropDown("TEAM_DROPDOWN_TEMPLATE", 150, options, setupItem);
}
public static void ShowSpawnDropDown(DropDownButtonWidget dropdown, Session.Client client,
OrderManager orderManager, IEnumerable<int> spawnPoints)
{
@@ -562,6 +581,29 @@ namespace OpenRA.Mods.Common.Widgets.Logic
HideChildWidget(parent, "TEAM_DROPDOWN");
}
public static void SetupEditableHandicapWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager, MapPreview map)
{
var dropdown = parent.Get<DropDownButtonWidget>("HANDICAP_DROPDOWN");
dropdown.IsVisible = () => true;
dropdown.IsDisabled = () => s.LockTeam || orderManager.LocalClient.IsReady;
dropdown.OnMouseDown = _ => ShowHandicapDropDown(dropdown, c, orderManager);
var handicapLabel = new CachedTransform<int, string>(h => "{0}%".F(h));
dropdown.GetText = () => handicapLabel.Update(c.Handicap);
HideChildWidget(parent, "HANDICAP");
}
public static void SetupHandicapWidget(Widget parent, Session.Slot s, Session.Client c)
{
var team = parent.Get<LabelWidget>("HANDICAP");
team.IsVisible = () => true;
var handicapLabel = new CachedTransform<int, string>(h => "{0}%".F(h));
team.GetText = () => handicapLabel.Update(c.Handicap);
HideChildWidget(parent, "HANDICAP_DROPDOWN");
}
public static void SetupEditableSpawnWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager, MapPreview map)
{
var dropdown = parent.Get<DropDownButtonWidget>("SPAWN_DROPDOWN");

View File

@@ -35,6 +35,13 @@ Container@LOBBY_PLAYER_BIN:
Text: Team
Align: Center
Font: Bold
Label@HANDICAP:
X: 491
Width: 75
Height: 25
Text: Handicap
Align: Center
Font: Bold
Label@SPAWN:
X: 571
Width: 50
@@ -142,6 +149,13 @@ Container@LOBBY_PLAYER_BIN:
Width: 50
Height: 25
Font: Regular
DropDownButton@HANDICAP_DROPDOWN:
X: 491
Width: 75
Height: 25
Font: Regular
TooltipContainer: TOOLTIP_CONTAINER
TooltipText: A handicap decreases the combat effectiveness of the player's forces
DropDownButton@SPAWN_DROPDOWN:
X: 571
Width: 50
@@ -252,6 +266,18 @@ Container@LOBBY_PLAYER_BIN:
Height: 25
Font: Regular
Visible: false
Label@HANDICAP:
X: 491
Width: 50
Height: 25
Align: Center
DropDownButton@HANDICAP_DROPDOWN:
X: 491
Width: 75
Height: 25
Font: Regular
TooltipContainer: TOOLTIP_CONTAINER
TooltipText: A handicap decreases the combat effectiveness of the player's forces
Label@SPAWN:
X: 571
Width: 25

View File

@@ -187,6 +187,11 @@
AttackMove:
AssaultMoveCondition: assault-move
^PlayerHandicaps:
HandicapFirepowerMultiplier:
HandicapDamageMultiplier:
HandicapProductionTimeMultiplier:
^AcceptsCloakCrate:
Cloak:
InitialDelay: 15
@@ -224,6 +229,7 @@
Inherits@1: ^ExistsInWorld
Inherits@3: ^ClassicFacingSpriteActor
Inherits@selection: ^SelectableCombatUnit
Inherits@handicaps: ^PlayerHandicaps
Huntable:
OwnerLostAction:
Action: Kill
@@ -269,6 +275,7 @@
Inherits@1: ^ExistsInWorld
Inherits@3: ^ClassicFacingSpriteActor
Inherits@selection: ^SelectableCombatUnit
Inherits@handicaps: ^PlayerHandicaps
Huntable:
OwnerLostAction:
Action: Kill
@@ -323,6 +330,7 @@
Inherits@1: ^ExistsInWorld
Inherits@3: ^SpriteActor
Inherits@selection: ^SelectableCombatUnit
Inherits@handicaps: ^PlayerHandicaps
Huntable:
OwnerLostAction:
Action: Kill
@@ -492,6 +500,7 @@
Inherits@2: ^SpriteActor
Inherits@AUTOTARGET: ^AutoTargetGroundAssaultMove
Inherits@selection: ^SelectableCombatUnit
Inherits@handicaps: ^PlayerHandicaps
Huntable:
OwnerLostAction:
Action: Kill
@@ -546,6 +555,7 @@
Inherits@2: ^SpriteActor
Inherits@AUTOTARGET: ^AutoTargetGroundAssaultMove
Inherits@selection: ^SelectableCombatUnit
Inherits@handicaps: ^PlayerHandicaps
Huntable:
Health:
HP: 40000
@@ -601,6 +611,7 @@
^Plane:
Inherits@1: ^ExistsInWorld
Inherits@2: ^ClassicFacingSpriteActor
Inherits@handicaps: ^PlayerHandicaps
Huntable:
OwnerLostAction:
Action: Kill
@@ -626,6 +637,7 @@
Inherits@1: ^ExistsInWorld
Inherits@3: ^SpriteActor
Inherits@selection: ^SelectableCombatUnit
Inherits@handicaps: ^PlayerHandicaps
Huntable:
OwnerLostAction:
Action: Kill
@@ -653,6 +665,7 @@
Inherits@2: ^SpriteActor
Inherits@shape: ^1x1Shape
Inherits@selection: ^SelectableBuilding
Inherits@handicaps: ^PlayerHandicaps
Huntable:
OwnerLostAction:
Action: Kill

View File

@@ -35,6 +35,13 @@ Container@LOBBY_PLAYER_BIN:
Text: Team
Align: Center
Font: Bold
Label@LABEL_LOBBY_HANDICAP:
X: 478
Width: 72
Height: 25
Text: Handicap
Align: Center
Font: Bold
Label@LABEL_LOBBY_SPAWN:
X: 560
Width: 48
@@ -139,6 +146,12 @@ Container@LOBBY_PLAYER_BIN:
Width: 48
Height: 25
Text: Team
DropDownButton@HANDICAP_DROPDOWN:
X: 478
Width: 72
Height: 25
TooltipContainer: TOOLTIP_CONTAINER
TooltipText: A handicap decreases the combat effectiveness of the player's forces
DropDownButton@SPAWN_DROPDOWN:
X: 560
Width: 48
@@ -249,6 +262,17 @@ Container@LOBBY_PLAYER_BIN:
Width: 48
Height: 25
Visible: false
Label@HANDICAP:
X: 478
Width: 47
Height: 25
Align: Center
DropDownButton@HANDICAP_DROPDOWN:
X: 478
Width: 72
Height: 25
TooltipContainer: TOOLTIP_CONTAINER
TooltipText: A handicap decreases the combat effectiveness of the player's forces
Label@SPAWN:
X: 560
Width: 23

View File

@@ -35,6 +35,13 @@ Container@LOBBY_PLAYER_BIN:
Text: Team
Align: Center
Font: Bold
Label@LABEL_LOBBY_HANDICAP:
X: 478
Width: 72
Height: 25
Text: Handicap
Align: Center
Font: Bold
Label@LABEL_LOBBY_SPAWN:
X: 560
Width: 48
@@ -139,6 +146,12 @@ Container@LOBBY_PLAYER_BIN:
Width: 48
Height: 25
Text: Team
DropDownButton@HANDICAP_DROPDOWN:
X: 478
Width: 72
Height: 25
TooltipContainer: TOOLTIP_CONTAINER
TooltipText: A handicap decreases the combat effectiveness of the player's forces
DropDownButton@SPAWN_DROPDOWN:
X: 560
Width: 48
@@ -249,6 +262,17 @@ Container@LOBBY_PLAYER_BIN:
Width: 48
Height: 25
Visible: false
Label@HANDICAP:
X: 478
Width: 47
Height: 25
Align: Center
DropDownButton@HANDICAP_DROPDOWN:
X: 478
Width: 72
Height: 25
TooltipContainer: TOOLTIP_CONTAINER
TooltipText: A handicap decreases the combat effectiveness of the player's forces
Label@SPAWN:
X: 560
Width: 23

View File

@@ -184,10 +184,16 @@
AttackMoveCondition: attack-move
AssaultMoveCondition: assault-move
^PlayerHandicaps:
HandicapFirepowerMultiplier:
HandicapDamageMultiplier:
HandicapProductionTimeMultiplier:
^Vehicle:
Inherits@1: ^ExistsInWorld
Inherits@2: ^SpriteActor
Inherits@selection: ^SelectableCombatUnit
Inherits@handicaps: ^PlayerHandicaps
Tooltip:
GenericName: Unit
Huntable:
@@ -298,6 +304,7 @@
Inherits@2: ^GainsExperience
Inherits@3: ^SpriteActor
Inherits@selection: ^SelectableCombatUnit
Inherits@handicaps: ^PlayerHandicaps
Tooltip:
GenericName: Unit
Huntable:
@@ -366,6 +373,7 @@
^Plane:
Inherits@1: ^ExistsInWorld
Inherits@2: ^SpriteActor
Inherits@handicaps: ^PlayerHandicaps
Interactable:
Tooltip:
GenericName: Unit
@@ -391,6 +399,7 @@
Inherits@1: ^ExistsInWorld
Inherits@2: ^SpriteActor
Inherits@selection: ^SelectableBuilding
Inherits@handicaps: ^PlayerHandicaps
Tooltip:
GenericName: Structure
Huntable:

View File

@@ -221,6 +221,11 @@
AttackMove:
AssaultMoveCondition: assault-move
^PlayerHandicaps:
HandicapFirepowerMultiplier:
HandicapDamageMultiplier:
HandicapProductionTimeMultiplier:
^GlobalBounty:
GrantConditionOnPrerequisite@GLOBALBOUNTY:
Condition: global-bounty
@@ -234,6 +239,7 @@
Inherits@3: ^ClassicFacingSpriteActor
Inherits@bounty: ^GlobalBounty
Inherits@selection: ^SelectableCombatUnit
Inherits@handicaps: ^PlayerHandicaps
Huntable:
OwnerLostAction:
Action: Kill
@@ -313,6 +319,7 @@
Inherits@4: ^SpriteActor
Inherits@bounty: ^GlobalBounty
Inherits@selection: ^SelectableCombatUnit
Inherits@handicaps: ^PlayerHandicaps
Huntable:
OwnerLostAction:
Action: Kill
@@ -483,6 +490,7 @@
Inherits@4: ^SpriteActor
Inherits@bounty: ^GlobalBounty
Inherits@selection: ^SelectableCombatUnit
Inherits@handicaps: ^PlayerHandicaps
Huntable:
OwnerLostAction:
Action: Kill
@@ -532,6 +540,7 @@
Inherits@4: ^SpriteActor
Inherits@bounty: ^GlobalBounty
Inherits@selection: ^SelectableCombatUnit
Inherits@handicaps: ^PlayerHandicaps
Huntable:
OwnerLostAction:
Action: Kill
@@ -632,6 +641,7 @@
Inherits@shape: ^1x1Shape
Inherits@bounty: ^GlobalBounty
Inherits@selection: ^SelectableBuilding
Inherits@handicaps: ^PlayerHandicaps
Targetable:
TargetTypes: GroundActor, C4, DetonateAttack, Structure
Building:
@@ -737,6 +747,7 @@
Inherits@1: ^ExistsInWorld
Inherits@2: ^SpriteActor
Inherits@shape: ^1x1Shape
Inherits@handicaps: ^PlayerHandicaps
Interactable:
Bounds: 24,24
OwnerLostAction:

View File

@@ -183,6 +183,11 @@
AttackMove:
AssaultMoveCondition: assault-move
^PlayerHandicaps:
HandicapFirepowerMultiplier:
HandicapDamageMultiplier:
HandicapProductionTimeMultiplier:
^2x1Shape:
HitShape:
Type: Rectangle
@@ -302,6 +307,7 @@
Inherits@2: ^SpriteActor
Inherits@3: ^Cloakable
Inherits@selection: ^SelectableBuilding
Inherits@handicaps: ^PlayerHandicaps
Huntable:
Targetable:
TargetTypes: Ground, Building, C4
@@ -538,6 +544,7 @@
Inherits@4: ^Cloakable
Inherits@CRATESTATS: ^CrateStatModifiers
Inherits@selection: ^SelectableCombatUnit
Inherits@handicaps: ^PlayerHandicaps
Huntable:
OwnerLostAction:
Action: Kill
@@ -754,6 +761,7 @@
Inherits@5: ^DamagedByVeins
Inherits@CRATESTATS: ^CrateStatModifiers
Inherits@selection: ^SelectableCombatUnit
Inherits@handicaps: ^PlayerHandicaps
Huntable:
OwnerLostAction:
Action: Kill
@@ -860,6 +868,7 @@
Inherits@2: ^ExistsInWorld
Inherits@3: ^Cloakable
Inherits@selection: ^SelectableCombatUnit
Inherits@handicaps: ^PlayerHandicaps
Huntable:
OwnerLostAction:
Action: Kill
@@ -958,6 +967,7 @@
Inherits@2: ^SpriteActor
Inherits@3: ^HealsOnTiberium
Inherits@selection: ^SelectableCombatUnit
Inherits@handicaps: ^PlayerHandicaps
Huntable:
Health:
Armor:
@@ -1108,6 +1118,7 @@
Inherits@2: ^ExistsInWorld
Inherits@3: ^Cloakable
Inherits@selection: ^SelectableCombatUnit
Inherits@handicaps: ^PlayerHandicaps
Huntable:
RenderVoxels:
RenderSprites: