Minelayer: supports specifying both mine laying and post laying delays

This commit is contained in:
michaeldgg2
2023-07-08 20:10:12 +02:00
committed by Matthias Mailänder
parent 4a02e6c6cc
commit ce6e73dc92
3 changed files with 69 additions and 7 deletions

View File

@@ -30,6 +30,7 @@ namespace OpenRA.Mods.Common.Activities
List<CPos> minefield; List<CPos> minefield;
bool returnToBase; bool returnToBase;
Actor rearmTarget; Actor rearmTarget;
bool layingMine;
public LayMines(Actor self, List<CPos> minefield = null) public LayMines(Actor self, List<CPos> minefield = null)
{ {
@@ -61,7 +62,26 @@ namespace OpenRA.Mods.Common.Activities
returnToBase = false; returnToBase = false;
if (IsCanceling) if (IsCanceling)
{
if (layingMine)
foreach (var t in self.TraitsImplementing<INotifyMineLaying>())
t.MineLayingCanceled(self, self.Location);
return true; return true;
}
if (layingMine)
{
layingMine = false;
if (LayMine(self))
{
if (minelayer.Info.AfterLayingDelay > 0)
{
QueueChild(new Wait(minelayer.Info.AfterLayingDelay));
return false;
}
}
}
if ((minefield == null || minefield.Contains(self.Location)) && CanLayMine(self, self.Location)) if ((minefield == null || minefield.Contains(self.Location)) && CanLayMine(self, self.Location))
{ {
@@ -82,9 +102,20 @@ namespace OpenRA.Mods.Common.Activities
return false; return false;
} }
LayMine(self); if (!StartLayingMine(self))
QueueChild(new Wait(20)); // A little wait after placing each mine, for show return false;
minefield.Remove(self.Location);
if (minelayer.Info.PreLayDelay == 0)
{
if (LayMine(self) && minelayer.Info.AfterLayingDelay > 0)
QueueChild(new Wait(minelayer.Info.AfterLayingDelay));
}
else
{
layingMine = true;
QueueChild(new Wait(minelayer.Info.PreLayDelay));
}
return false; return false;
} }
@@ -136,20 +167,38 @@ namespace OpenRA.Mods.Common.Activities
return self.World.ActorMap.GetActorsAt(p).All(a => a == self); return self.World.ActorMap.GetActorsAt(p).All(a => a == self);
} }
void LayMine(Actor self) bool StartLayingMine(Actor self)
{ {
if (ammoPools != null) if (ammoPools != null)
{ {
var pool = ammoPools.FirstOrDefault(x => x.Info.Name == minelayer.Info.AmmoPoolName); var pool = ammoPools.FirstOrDefault(x => x.Info.Name == minelayer.Info.AmmoPoolName);
if (pool == null) if (pool == null)
return; return false;
pool.TakeAmmo(self, minelayer.Info.AmmoUsage); if (pool.CurrentAmmoCount < minelayer.Info.AmmoUsage)
return false;
} }
foreach (var t in self.TraitsImplementing<INotifyMineLaying>()) foreach (var t in self.TraitsImplementing<INotifyMineLaying>())
t.MineLaying(self, self.Location); t.MineLaying(self, self.Location);
return true;
}
bool LayMine(Actor self)
{
if (ammoPools != null)
{
var pool = ammoPools.FirstOrDefault(x => x.Info.Name == minelayer.Info.AmmoPoolName);
if (pool == null)
return false;
if (!pool.TakeAmmo(self, minelayer.Info.AmmoUsage))
return false;
}
minefield.Remove(self.Location);
self.World.AddFrameEndTask(w => self.World.AddFrameEndTask(w =>
{ {
var mine = w.CreateActor(minelayer.Info.Mine, new TypeDictionary var mine = w.CreateActor(minelayer.Info.Mine, new TypeDictionary
@@ -161,6 +210,8 @@ namespace OpenRA.Mods.Common.Activities
foreach (var t in self.TraitsImplementing<INotifyMineLaying>()) foreach (var t in self.TraitsImplementing<INotifyMineLaying>())
t.MineLaid(self, mine); t.MineLaid(self, mine);
}); });
return true;
} }
} }
} }

View File

@@ -63,6 +63,12 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Ammo the minelayer consumes per mine.")] [Desc("Ammo the minelayer consumes per mine.")]
public readonly int AmmoUsage = 1; public readonly int AmmoUsage = 1;
[Desc("Number of ticks it takes to lay a mine.")]
public readonly int PreLayDelay = 0;
[Desc("Number of ticks for the minelayer to wait after laying a mine. The wait can be interrupted by a player order.")]
public readonly int AfterLayingDelay = 20;
public override object Create(ActorInitializer init) { return new Minelayer(init.Self, this); } public override object Create(ActorInitializer init) { return new Minelayer(init.Self, this); }
} }

View File

@@ -159,7 +159,12 @@ namespace OpenRA.Mods.Common.Traits
public interface INotifyDelivery { void IncomingDelivery(Actor self); void Delivered(Actor self); } public interface INotifyDelivery { void IncomingDelivery(Actor self); void Delivered(Actor self); }
[RequireExplicitImplementation] [RequireExplicitImplementation]
public interface INotifyMineLaying { void MineLaying(Actor self, CPos location); void MineLaid(Actor self, Actor mine); } public interface INotifyMineLaying
{
void MineLaying(Actor self, CPos location);
void MineLaid(Actor self, Actor mine);
void MineLayingCanceled(Actor self, CPos location);
}
[RequireExplicitImplementation] [RequireExplicitImplementation]
public interface INotifyDockHost { void Docked(Actor self, Actor client); void Undocked(Actor self, Actor client); } public interface INotifyDockHost { void Docked(Actor self, Actor client); void Undocked(Actor self, Actor client); }