1078: Added ally repairing for CNC and RA

This commit is contained in:
Curtis S
2011-09-10 16:41:40 -06:00
parent 1d052bbfa2
commit be9948426c
11 changed files with 115 additions and 41 deletions

View File

@@ -22,11 +22,11 @@ namespace OpenRA.Mods.RA.Buildings
public object Create(ActorInitializer init) { return new RepairableBuilding(init.self, this); } public object Create(ActorInitializer init) { return new RepairableBuilding(init.self, this); }
} }
public class RepairableBuilding : ITick, IResolveOrder, ISync public class RepairableBuilding : ITick, ISync
{ {
[Sync] [Sync]
bool isRepairing = false; public Player Repairer = null;
Health Health; Health Health;
RepairableBuildingInfo Info; RepairableBuildingInfo Info;
public RepairableBuilding(Actor self, RepairableBuildingInfo info) public RepairableBuilding(Actor self, RepairableBuildingInfo info)
@@ -34,42 +34,56 @@ namespace OpenRA.Mods.RA.Buildings
Health = self.Trait<Health>(); Health = self.Trait<Health>();
Info = info; Info = info;
} }
public void ResolveOrder(Actor self, Order order) public void RepairBuilding(Actor self, Player p)
{ {
if (order.OrderString == "Repair") if (self.HasTrait<RepairableBuilding>())
{ {
isRepairing = !isRepairing; if (self.AppearsFriendlyTo(p.PlayerActor))
if (isRepairing) {
Sound.PlayToPlayer(self.Owner, self.World.WorldActor.Info.Traits.Get<EvaAlertsInfo>().Repairing); if (Repairer == p)
Repairer = null;
else
{
Repairer = p;
Sound.PlayToPlayer(Repairer, p.World.WorldActor.Info.Traits.Get<EvaAlertsInfo>().Repairing);
self.World.AddFrameEndTask(
w => w.Add(new RepairIndicator(self, p)));
}
}
} }
} }
int remainingTicks; int remainingTicks;
public void Tick(Actor self) public void Tick(Actor self)
{ {
if (!isRepairing) return; if (Repairer == null) return;
if (remainingTicks == 0) if (remainingTicks == 0)
{ {
if (Repairer.WinState != WinState.Undefined)
{
Repairer = null;
return;
}
var buildingValue = self.GetSellValue(); var buildingValue = self.GetSellValue();
var hpToRepair = Math.Min(Info.RepairStep, Health.MaxHP - Health.HP); var hpToRepair = Math.Min(Info.RepairStep, Health.MaxHP - Health.HP);
var cost = (hpToRepair * Info.RepairPercent * buildingValue) / (Health.MaxHP * 100); var cost = (hpToRepair * Info.RepairPercent * buildingValue) / (Health.MaxHP * 100);
if (!self.Owner.PlayerActor.Trait<PlayerResources>().TakeCash(cost)) if (!Repairer.PlayerActor.Trait<PlayerResources>().TakeCash(cost))
{ {
remainingTicks = 1; remainingTicks = 1;
return; return;
} }
self.World.AddFrameEndTask(
w => w.Add(new RepairIndicator(self, Info.RepairInterval / 2)));
self.InflictDamage(self, -hpToRepair, null); self.InflictDamage(self, -hpToRepair, null);
if (Health.DamageState == DamageState.Undamaged) if (Health.DamageState == DamageState.Undamaged)
{ {
isRepairing = false; Repairer = null;
return; return;
} }
@@ -79,7 +93,7 @@ namespace OpenRA.Mods.RA.Buildings
--remainingTicks; --remainingTicks;
} }
} }
public class AllowsBuildingRepairInfo : TraitInfo<AllowsBuildingRepair> {} public class AllowsBuildingRepairInfo : TraitInfo<AllowsBuildingRepair> { }
public class AllowsBuildingRepair {} public class AllowsBuildingRepair { }
} }

View File

@@ -18,27 +18,37 @@ namespace OpenRA.Mods.RA.Effects
{ {
class RepairIndicator : IEffect class RepairIndicator : IEffect
{ {
int framesLeft; Actor building;
Actor a; Player player;
Animation anim = new Animation("select"); Animation anim = new Animation("allyrepair");
public RepairIndicator(Actor a, int frames) public RepairIndicator(Actor building, Player player)
{ {
this.a = a; anim.PlayRepeating("repair"); this.building = building;
framesLeft = frames; this.player = player;
anim.PlayRepeating("repair");
} }
public void Tick( World world ) public void Tick(World world)
{ {
if (--framesLeft == 0 || !a.IsInWorld || a.IsDead()) if (!building.IsInWorld ||
building.IsDead() ||
building.Trait<RepairableBuilding>().Repairer == null ||
building.Trait<RepairableBuilding>().Repairer != player)
world.AddFrameEndTask(w => w.Remove(this)); world.AddFrameEndTask(w => w.Remove(this));
anim.Tick();
} }
public IEnumerable<Renderable> Render() public IEnumerable<Renderable> Render()
{ {
if (!a.Destroyed) if (!building.Destroyed)
yield return new Renderable(anim.Image, {
a.CenterLocation - .5f * anim.Image.size, "chrome", (int)a.CenterLocation.Y); var palette = building.Trait<RenderSimple>().Palette(player);
yield return new Renderable(anim.Image,
building.CenterLocation - .5f * anim.Image.size, palette, (int)building.CenterLocation.Y);
}
} }
} }
} }

View File

@@ -72,6 +72,7 @@
<Compile Include="Lint\LintBuildablePrerequisites.cs" /> <Compile Include="Lint\LintBuildablePrerequisites.cs" />
<Compile Include="Lint\CheckAutotargetWiring.cs" /> <Compile Include="Lint\CheckAutotargetWiring.cs" />
<Compile Include="Lint\CheckSyncAnnotations.cs" /> <Compile Include="Lint\CheckSyncAnnotations.cs" />
<Compile Include="Player\AllyRepair.cs" />
<Compile Include="ProductionBar.cs" /> <Compile Include="ProductionBar.cs" />
<Compile Include="Render\RenderEditorOnly.cs" /> <Compile Include="Render\RenderEditorOnly.cs" />
<Compile Include="SmokeTrailWhenDamaged.cs" /> <Compile Include="SmokeTrailWhenDamaged.cs" />

View File

@@ -31,36 +31,36 @@ namespace OpenRA.Mods.RA.Orders
if (mi.Button == MouseButton.Left) if (mi.Button == MouseButton.Left)
{ {
var underCursor = world.FindUnitsAtMouse(mi.Location) var underCursor = world.FindUnitsAtMouse(mi.Location)
.Where(a => a.Owner == world.LocalPlayer && a.HasTrait<RepairableBuilding>()).FirstOrDefault(); .Where(a => a.AppearsFriendlyTo(world.LocalPlayer.PlayerActor) && a.HasTrait<RepairableBuilding>()).FirstOrDefault();
if (underCursor == null) if (underCursor == null)
yield break; yield break;
if (underCursor.Info.Traits.Contains<RepairableBuildingInfo>() if (underCursor.Info.Traits.Contains<RepairableBuildingInfo>()
&& underCursor.GetDamageState() > DamageState.Undamaged) && underCursor.GetDamageState() > DamageState.Undamaged)
yield return new Order("Repair", underCursor, false); yield return new Order("RepairBuilding", world.LocalPlayer.PlayerActor, false) { TargetActor = underCursor };
} }
} }
public void Tick( World world ) public void Tick(World world)
{ {
if( !PlayerIsAllowedToRepair( world ) ) if (!PlayerIsAllowedToRepair(world))
world.CancelInputMode(); world.CancelInputMode();
} }
public static bool PlayerIsAllowedToRepair( World world ) public static bool PlayerIsAllowedToRepair(World world)
{ {
return world.ActorsWithTrait<AllowsBuildingRepair>() return world.ActorsWithTrait<AllowsBuildingRepair>()
.Any(a => a.Actor.Owner == world.LocalPlayer); .Any(a => a.Actor.AppearsFriendlyTo(world.LocalPlayer.PlayerActor));
} }
public void RenderAfterWorld( WorldRenderer wr, World world ) { } public void RenderAfterWorld(WorldRenderer wr, World world) { }
public void RenderBeforeWorld( WorldRenderer wr, World world ) { } public void RenderBeforeWorld(WorldRenderer wr, World world) { }
public string GetCursor(World world, int2 xy, MouseInput mi) public string GetCursor(World world, int2 xy, MouseInput mi)
{ {
mi.Button = MouseButton.Left; mi.Button = MouseButton.Left;
return OrderInner(world, xy, mi).Any() return OrderInner(world, xy, mi).Any()
? "repair" : "repair-blocked"; ? "repair" : "repair-blocked";
} }
} }

View File

@@ -0,0 +1,35 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 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. For more information,
* see COPYING.
*/
#endregion
using System;
using OpenRA.Mods.RA.Buildings;
using OpenRA.Mods.RA.Effects;
using OpenRA.Traits;
namespace OpenRA.Mods.RA
{
class AllyRepairInfo : TraitInfo<AllyRepair> { }
class AllyRepair : IResolveOrder
{
public void ResolveOrder(Actor self, Order order)
{
if (order.OrderString == "RepairBuilding")
{
var building = order.TargetActor;
if (building.HasTrait<RepairableBuilding>())
if (building.AppearsFriendlyTo(self))
building.Trait<RepairableBuilding>().RepairBuilding(building, self.Owner);
}
}
}
}

Binary file not shown.

View File

@@ -6,6 +6,7 @@ Player:
WinNotification:accom1.aud WinNotification:accom1.aud
LoseNotification:fail1.aud LoseNotification:fail1.aud
PowerManager: PowerManager:
AllyRepair:
PlayerResources: PlayerResources:
InitialCash: 5000 InitialCash: 5000
ActorGroupProxy: ActorGroupProxy:

View File

@@ -111,6 +111,12 @@ select:
repair: repair:
Start: 2 Start: 2
allyrepair:
repair:
Start: 0
Length: *
Tick: 160
crate: crate:
idle: wcrate idle: wcrate
Start: 0 Start: 0

BIN
mods/ra/bits/allyrepair.shp Normal file

Binary file not shown.

View File

@@ -34,6 +34,7 @@ Player:
WinNotification:misnwon1.aud WinNotification:misnwon1.aud
LoseNotification:misnlst1.aud LoseNotification:misnlst1.aud
PowerManager: PowerManager:
AllyRepair:
PlayerResources: PlayerResources:
InitialCash: 5000 InitialCash: 5000
ActorGroupProxy: ActorGroupProxy:

View File

@@ -1546,6 +1546,12 @@ poweroff:
Length: * Length: *
Tick: 160 Tick: 160
allyrepair:
repair:
Start: 0
Length: *
Tick: 160
tabs: tabs:
left-normal: left-normal:
Start: 0 Start: 0