Merge branch 'master' into minelayer

This commit is contained in:
Chris Forbes
2009-12-28 13:21:21 +13:00
13 changed files with 105 additions and 30 deletions

View File

@@ -50,7 +50,6 @@ namespace OpenRa.Game
public void Tick()
{
while (currentActivity != null)
{
var a = currentActivity;
@@ -93,11 +92,8 @@ namespace OpenRa.Game
if (!Rules.Map.IsInMap(xy.X, xy.Y))
return null;
// HACK: Get the first unit in the cell
// This will need to be updated for multiple-infantry-in-a-cell
// HACK: this doesn't work for targeting air units either
var underCursor = Game.UnitInfluence.GetUnitsAt( xy ).FirstOrDefault()
?? Game.BuildingInfluence.GetBuildingAt( xy );
var loc = mi.Location + Game.viewport.Location;
var underCursor = Game.FindUnits(loc, loc).FirstOrDefault();
if (underCursor != null && !underCursor.Info.Selectable)
underCursor = null;
@@ -107,19 +103,18 @@ namespace OpenRa.Game
.FirstOrDefault( x => x != null );
}
public RectangleF Bounds
public RectangleF GetBounds(bool useAltitude)
{
get
var size = SelectedSize;
var loc = CenterLocation - 0.5f * size;
if (useAltitude)
{
var size = SelectedSize;
var loc = CenterLocation - 0.5f * size;
var unit = traits.GetOrDefault<Unit>();
if (unit != null)
loc -= new float2(0, unit.Altitude);
return new RectangleF(loc.X, loc.Y, size.X, size.Y);
if (unit != null) loc -= new float2(0, unit.Altitude);
}
return new RectangleF(loc.X, loc.Y, size.X, size.Y);
}
public bool IsDead { get { return Health <= 0; } }
@@ -150,6 +145,8 @@ namespace OpenRa.Game
Game.world.AddFrameEndTask(w => w.Remove(this));
}
if (Health > Info.Strength)
Health = Info.Strength;
var newState = GetDamageState();

View File

@@ -39,7 +39,7 @@ namespace OpenRa.Game
static float GetMaximumSpread(WeaponInfo weapon, WarheadInfo warhead)
{
return (int)(warhead.Spread * Math.Log(weapon.Damage, 2));
return (int)(warhead.Spread * Math.Log(Math.Abs(weapon.Damage), 2));
}
static float GetDamageToInflict(Actor target, int2 loc, WeaponInfo weapon, WarheadInfo warhead)

View File

@@ -124,7 +124,7 @@ namespace OpenRa.Game
{
var mods = GetModifierKeys();
var c = (orderGenerator is UnitOrderGenerator) ? orderGenerator.Order(dragEnd.ToInt2(),
new MouseInput { Button = MouseButton.Right, Modifiers = mods })
new MouseInput { Location = (Game.CellSize * dragEnd - Game.viewport.Location).ToInt2(), Button = MouseButton.Right, Modifiers = mods })
.Where(o => o.Validate())
.Select(o => CursorForOrderString(o.OrderString, o.Subject, o.TargetLocation))
.FirstOrDefault(a => a != null) : null;

View File

@@ -269,13 +269,19 @@ namespace OpenRa.Game
var rect = new RectangleF(min.X, min.Y, max.X - min.X, max.Y - min.Y);
return world.Actors
.Where(x => x.Bounds.IntersectsWith(rect));
.Where(x => x.GetBounds(true).IntersectsWith(rect));
}
public static IEnumerable<Actor> FindUnitsInCircle(float2 a, float r)
{
return FindUnits(a - new float2(r, r), a + new float2(r, r))
.Where(x => (x.CenterLocation - a).LengthSquared < r * r);
var min = a - new float2(r, r);
var max = a + new float2(r, r);
var rect = new RectangleF(min.X, min.Y, max.X - min.X, max.Y - min.Y);
var inBox = world.Actors.Where(x => x.GetBounds(false).IntersectsWith(rect));
return inBox.Where(x => (x.CenterLocation - a).LengthSquared < r * r);
}
public static IEnumerable<int2> FindTilesInCircle(int2 a, int r)

View File

@@ -111,7 +111,7 @@ namespace OpenRa.Game.Graphics
public void DrawSelectionBox(Actor selectedUnit, Color c, bool drawHealthBar)
{
var bounds = selectedUnit.Bounds;
var bounds = selectedUnit.GetBounds(true);
var xy = new float2(bounds.Left, bounds.Top);
var Xy = new float2(bounds.Right, bounds.Top);

View File

@@ -172,6 +172,7 @@
<Compile Include="Traits\AttackBase.cs" />
<Compile Include="Traits\AttackInfo.cs" />
<Compile Include="Traits\AttackTurreted.cs" />
<Compile Include="Traits\AutoHeal.cs" />
<Compile Include="Traits\AutoTarget.cs" />
<Compile Include="Traits\BelowUnits.cs" />
<Compile Include="Traits\Building.cs" />

View File

@@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace OpenRa.Game.Traits
{
class AutoHeal : ITick
{
public AutoHeal(Actor self) { }
void AttackTarget(Actor self, Actor target)
{
var attack = self.traits.WithInterface<AttackBase>().First();
if (target != null)
attack.ResolveOrder(self, new Order("Attack", self, target, int2.Zero, null));
else
self.CancelActivity();
}
float GetMaximumRange(Actor self)
{
return new[] { self.Info.Primary, self.Info.Secondary }
.Where(w => w != null)
.Max(w => Rules.WeaponInfo[w].Range);
}
bool NeedsNewTarget(Actor self)
{
var attack = self.traits.WithInterface<AttackBase>().First();
var range = GetMaximumRange(self);
if (attack.target == null)
return true; // he's dead.
if ((attack.target.Location - self.Location).LengthSquared > range * range + 2)
return true; // wandered off faster than we could follow
if (attack.target.Health == attack.target.Info.Strength)
return true; // fully healed
return false;
}
public void Tick(Actor self)
{
var attack = self.traits.WithInterface<AttackBase>().First();
var range = GetMaximumRange(self);
if (NeedsNewTarget(self))
AttackTarget(self, ChooseTarget(self, range));
}
Actor ChooseTarget(Actor self, float range)
{
var inRange = Game.FindUnitsInCircle(self.CenterLocation, Game.CellSize * range);
return inRange
.Where(a => a.Owner == self.Owner) /* todo: one day deal with friendly players */
.Where(a => Combat.HasAnyValidWeapons(self, a))
.Where(a => a.Health < a.Info.Strength)
.OrderBy(a => (a.Location - self.Location).LengthSquared)
.FirstOrDefault();
}
}
}

View File

@@ -16,16 +16,23 @@ namespace OpenRa.Game.Traits
attack.ResolveOrder(self, new Order("Attack", self, target, int2.Zero, null));
}
float GetMaximumRange(Actor self)
{
return new[] { self.Info.Primary, self.Info.Secondary }
.Where(w => w != null)
.Max(w => Rules.WeaponInfo[w].Range);
}
public void Tick(Actor self)
{
if (!self.IsIdle) return;
var attack = self.traits.WithInterface<AttackBase>().First();
var range = Rules.WeaponInfo[self.Info.Primary].Range;
var range = GetMaximumRange(self);
if (attack.target == null ||
(attack.target.Location - self.Location).LengthSquared > range * range + 2)
attack.target = ChooseTarget(self, range);
AttackTarget(self, ChooseTarget(self, range));
}
Actor ChooseTarget(Actor self, float range)

View File

@@ -35,7 +35,7 @@ namespace OpenRa.Game.Traits
{
if (doneBuilding) roof.Tick();
var b = self.Bounds;
var b = self.GetBounds(false);
if (isOpen && !Game.UnitInfluence.GetUnitsAt(((1/24f) * self.CenterLocation).ToInt2()).Any())
{
isOpen = false;