Bring Mods.D2k in line with our new folder/namespace structure

This commit is contained in:
reaperrr
2014-12-15 00:02:17 +01:00
parent b5872d9fa5
commit c19d096d92
9 changed files with 27 additions and 21 deletions

View File

@@ -0,0 +1,198 @@
#region Copyright & License Information
/*
* Copyright 2007-2014 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 System.Drawing;
using System.Linq;
using OpenRA.Activities;
using OpenRA.Mods.D2k.Traits;
using OpenRA.Mods.RA;
using OpenRA.Mods.RA.Activities;
using OpenRA.Mods.RA.Traits;
using OpenRA.Traits;
namespace OpenRA.Mods.D2k.Activities
{
public class CarryUnit : Activity
{
readonly Actor self;
readonly Actor carryable;
readonly IMove movement;
readonly Carryable c;
readonly AutoCarryall aca;
readonly Helicopter helicopter;
readonly IPositionable positionable;
readonly IFacing cFacing; // Carryable facing
readonly IFacing sFacing; // Self facing
enum State { Intercept, LockCarryable, MoveToCarryable, Turn, Pickup, Transport, Land, Release, Takeoff, Done }
State state;
public CarryUnit(Actor self, Actor carryable)
{
this.self = self;
this.carryable = carryable;
movement = self.Trait<IMove>();
c = carryable.Trait<Carryable>();
aca = self.Trait<AutoCarryall>();
helicopter = self.Trait<Helicopter>();
positionable = carryable.Trait<IPositionable>();
cFacing = carryable.Trait<IFacing>();
sFacing = self.Trait<IFacing>();
state = State.Intercept;
}
// Find a suitable location to drop our carryable
CPos GetLocationToDrop(CPos requestedPosition)
{
if (positionable.CanEnterCell(requestedPosition))
return requestedPosition;
var candidateCells = Util.AdjacentCells(self.World, Target.FromCell(self.World, requestedPosition));
// TODO: This will behave badly if there is no suitable drop point nearby
do
{
foreach (var c in candidateCells)
if (positionable.CanEnterCell(c))
return c;
// Expanding dropable cells search area
// TODO: This also includes all of the cells we have just checked
candidateCells = Util.ExpandFootprint(candidateCells, true);
} while (true);
}
// Check if we can drop the unit at our current location.
bool CanDropHere()
{
return positionable.CanEnterCell(self.Location);
}
public override Activity Tick(Actor self)
{
if (carryable.IsDead)
{
aca.UnreserveCarryable();
return NextActivity;
}
switch (state)
{
case State.Intercept: // Move towards our carryable
state = State.LockCarryable;
return Util.SequenceActivities(movement.MoveWithinRange(Target.FromActor(carryable), WRange.FromCells(4)), this);
case State.LockCarryable:
// Last check
if (c.StandbyForPickup(self))
{
state = State.MoveToCarryable;
return this;
}
else
{
// We got cancelled
aca.UnreserveCarryable();
return NextActivity;
}
case State.MoveToCarryable: // We arrived, move on top
if (self.Location == carryable.Location)
{
state = State.Turn;
return this;
}
else
return Util.SequenceActivities(movement.MoveTo(carryable.Location, 0), this);
case State.Turn: // Align facing and Land
if (sFacing.Facing != cFacing.Facing)
return Util.SequenceActivities(new Turn(self, cFacing.Facing), this);
else
{
state = State.Pickup;
return Util.SequenceActivities(new HeliLand(false), new Wait(10), this);
}
case State.Pickup:
// Remove our carryable from world
self.World.AddFrameEndTask(w => carryable.World.Remove(carryable));
aca.AttachCarryable(carryable);
state = State.Transport;
return this;
case State.Transport:
// Move self to destination
var targetl = GetLocationToDrop(c.Destination);
state = State.Land;
return Util.SequenceActivities(movement.MoveTo(targetl, 0), this);
case State.Land:
if (!CanDropHere())
{
state = State.Transport;
return this;
}
if (HeliFly.AdjustAltitude(self, helicopter, helicopter.Info.LandAltitude))
return this;
else
{
state = State.Release;
return Util.SequenceActivities(new Wait(15), this);
}
case State.Release:
if (!CanDropHere())
{
state = State.Transport;
return this;
}
positionable.SetPosition(carryable, self.Location, SubCell.FullCell);
cFacing.Facing = sFacing.Facing;
// Put back into world
self.World.AddFrameEndTask(w => carryable.World.Add(carryable));
// Unlock carryable
aca.CarryableReleased();
c.Dropped();
state = State.Done;
return Util.SequenceActivities(new Wait(10), this);
case State.Done:
self.Trait<AutoCarryall>().UnreserveCarryable();
return NextActivity;
}
return NextActivity;
}
public override void Cancel(Actor self)
{
// TODO: Drop the unit at the nearest available cell
}
}
}

View File

@@ -0,0 +1,146 @@
#region Copyright & License Information
/*
* Copyright 2007-2014 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.Drawing;
using System.Linq;
using OpenRA.Activities;
using OpenRA.GameRules;
using OpenRA.Mods.Common;
using OpenRA.Mods.Common.Traits;
using OpenRA.Mods.D2k.Traits;
using OpenRA.Mods.RA.Move;
using OpenRA.Traits;
namespace OpenRA.Mods.D2k.Activities
{
enum AttackState { Burrowed, EmergingAboveGround, ReturningUnderground }
class SwallowActor : Activity
{
const int NearEnough = 1;
readonly CPos location;
readonly Target target;
readonly WeaponInfo weapon;
readonly RenderUnit renderUnit;
readonly RadarPings radarPings;
readonly AttackSwallow swallow;
readonly AttackSwallowInfo swallowInfo;
readonly IPositionable positionable;
int countdown;
AttackState stance;
public SwallowActor(Actor self, Target target, WeaponInfo weapon)
{
this.target = target;
this.weapon = weapon;
positionable = self.Trait<Mobile>();
swallow = self.Trait<AttackSwallow>();
swallowInfo = (AttackSwallowInfo)swallow.Info;
renderUnit = self.Trait<RenderUnit>();
radarPings = self.World.WorldActor.TraitOrDefault<RadarPings>();
countdown = swallowInfo.AttackTime;
renderUnit.DefaultAnimation.ReplaceAnim("burrowed");
stance = AttackState.Burrowed;
location = target.Actor.Location;
}
bool WormAttack(Actor worm)
{
var targetLocation = target.Actor.Location;
// The target has moved too far away
if ((location - targetLocation).Length > NearEnough)
return false;
var lunch = worm.World.ActorMap.GetUnitsAt(targetLocation)
.Where(t => !t.Equals(worm) && weapon.IsValidAgainst(t, worm));
if (!lunch.Any())
return false;
stance = AttackState.EmergingAboveGround;
foreach (var actor in lunch)
actor.World.AddFrameEndTask(_ => actor.Destroy());
positionable.SetPosition(worm, targetLocation);
PlayAttackAnimation(worm);
var attackPosition = worm.CenterPosition;
var affectedPlayers = lunch.Select(x => x.Owner).Distinct();
foreach (var affectedPlayer in affectedPlayers)
NotifyPlayer(affectedPlayer, attackPosition);
return true;
}
void PlayAttackAnimation(Actor self)
{
renderUnit.PlayCustomAnim(self, "sand");
renderUnit.PlayCustomAnim(self, "mouth");
}
void NotifyPlayer(Player player, WPos location)
{
Sound.PlayNotification(player.World.Map.Rules, player, "Speech", swallowInfo.WormAttackNotification, player.Country.Race);
radarPings.Add(() => true, location, Color.Red, 50);
}
public override Activity Tick(Actor self)
{
if (countdown > 0)
{
countdown--;
return this;
}
// Wait for the worm to get back underground
if (stance == AttackState.ReturningUnderground)
{
// There is a 50-50 chance that the worm would just go away
if (self.World.SharedRandom.Next() % 2 == 0)
{
self.CancelActivity();
self.World.AddFrameEndTask(w => w.Remove(self));
var wormManager = self.World.WorldActor.TraitOrDefault<WormManager>();
if (wormManager != null)
wormManager.DecreaseWorms();
}
else
renderUnit.DefaultAnimation.ReplaceAnim("idle");
return NextActivity;
}
// Wait for the worm to get in position
if (stance == AttackState.Burrowed)
{
// This is so that the worm cancels an attack against a target that has reached solid rock
if (!positionable.CanEnterCell(target.Actor.Location, null, false))
return NextActivity;
if (!WormAttack(self))
{
renderUnit.DefaultAnimation.ReplaceAnim("idle");
return NextActivity;
}
countdown = swallowInfo.ReturnTime;
stance = AttackState.ReturningUnderground;
}
return this;
}
}
}