#117 emit infantry on sell

This commit is contained in:
Chris Forbes
2010-04-09 19:27:45 +12:00
parent 7ade8e5ef8
commit 982c9518ac
6 changed files with 61 additions and 3 deletions

View File

@@ -42,7 +42,7 @@ namespace OpenRA.GameRules
return TilesWhere( name, dim, footprint.ToArray(), a => a != '_' ).Select( t => t + topLeft );
}
public static IEnumerable<int2> Tiles(Actor a, Traits.Building building)
public static IEnumerable<int2> Tiles(Actor a)
{
return Tiles( a.Info.Name, a.Info.Traits.Get<BuildingInfo>(), a.Location );
}

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -78,6 +78,7 @@
<Compile Include="Chat.cs" />
<Compile Include="Chrome.cs" />
<Compile Include="GameRules\WeaponInfo.cs" />
<Compile Include="Traits\AI\EmitInfantryOnSell.cs" />
<Compile Include="Traits\AI\ReturnOnIdle.cs" />
<Compile Include="Traits\Render\HiddenUnderFog.cs" />
<Compile Include="Traits\World\Shroud.cs" />

View File

@@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenRA.GameRules;
namespace OpenRA.Traits.AI
{
class EmitInfantryOnSellInfo : StatelessTraitInfo<EmitInfantryOnSell>
{
public readonly float ValueFraction = .4f;
public readonly float MinHpFraction = .3f;
public readonly string[] ActorTypes = { "e1" }; // todo: cN as well
}
class EmitInfantryOnSell : INotifySold, INotifyDamage
{
public void Selling(Actor self) { }
void Emit(Actor self)
{
var info = self.Info.Traits.Get<EmitInfantryOnSellInfo>();
var csv = self.Info.Traits.GetOrDefault<CustomSellValueInfo>();
var cost = csv != null ? csv.Value : self.Info.Traits.Get<BuildableInfo>().Cost;
var hp = self.Info.Traits.Get<OwnedActorInfo>().HP;
var hpFraction = Math.Max(info.MinHpFraction, hp / self.GetMaxHP());
var dudesValue = (int)(hpFraction * info.ValueFraction * cost);
var eligibleLocations = Footprint.Tiles(self).ToList();
// todo: fix this for unbuildables in ActorTypes, like civilians.
var actorTypes = info.ActorTypes.Select(a => new { Name = a, Cost = Rules.Info[a].Traits.Get<BuildableInfo>().Cost }).ToArray();
while (eligibleLocations.Count > 0 && actorTypes.Any(a => a.Cost <= dudesValue))
{
var at = actorTypes.Where(a => a.Cost <= dudesValue).Random(self.World.SharedRandom);
var loc = eligibleLocations.Random(self.World.SharedRandom);
eligibleLocations.Remove(loc);
dudesValue -= at.Cost;
self.World.AddFrameEndTask(w => w.CreateActor(at.Name, loc, self.Owner));
}
}
public void Sold(Actor self) { Emit(self); }
public void Damaged(Actor self, AttackInfo e)
{
if (e.DamageStateChanged && e.DamageState == DamageState.Dead)
Emit(self);
}
}
}

View File

@@ -34,7 +34,7 @@ namespace OpenRA.Traits
static int2? FindAdjacentTile(Actor self, bool waterBound)
{
var tiles = Footprint.Tiles(self, self.traits.Get<Traits.Building>());
var tiles = Footprint.Tiles(self);
var min = tiles.Aggregate(int2.Min) - new int2(1, 1);
var max = tiles.Aggregate(int2.Max) + new int2(1, 1);

View File

@@ -49,6 +49,7 @@
Dimensions: 1,1
Footprint: x
RenderBuilding:
EmitInfantryOnSell:
^Wall:
Category: Building

View File

@@ -66,6 +66,7 @@ SPEN:
ProductionSurround:
Produces: Ship
IronCurtainable:
-EmitInfantryOnSell:
SYRD:
InfiltrateForSonarPulse:
@@ -92,6 +93,7 @@ SYRD:
ProductionSurround:
Produces: Ship
IronCurtainable:
-EmitInfantryOnSell:
IRON:
RequiresPower:
@@ -743,6 +745,7 @@ SYRF:
RenderBuilding:
Image: SYRD
Fake:
-EmitInfantryOnSell:
SPEF:
Inherits: ^Building
@@ -759,6 +762,7 @@ SPEF:
RenderBuilding:
Image: SPEN
Fake:
-EmitInfantryOnSell:
DOMF:
Inherits: ^Building