Skip to content

Instantly share code, notes, and snippets.

@phrohdoh
Created July 12, 2014 22:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save phrohdoh/6d8ad9a2b1a5592bf76f to your computer and use it in GitHub Desktop.
Save phrohdoh/6d8ad9a2b1a5592bf76f to your computer and use it in GitHub Desktop.
#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.Collections;
using System.Linq;
using OpenRA.Traits;
namespace OpenRA.Mods.RA
{
// Order is important here!
public enum ChainAttackModel
{
Multiplicative,
Additive
}
[Desc("Actor can fire weapon at another ChainAttacks actor to increase the total damage output.")]
public class ChainAttacksInfo : ITraitInfo, Requires<ArmamentInfo>
{
[Desc("Number of chained \"jumps\" our attack can perform.")]
public readonly int MaximumChains = 1;
[Desc("Actor receiving support classifications:")]
public readonly string[] ReceiverTypes = { };
[Desc("Actor sending support classification:")]
public readonly string SenderType = null;
[Desc("Defaults to primary Armament entry.")]
public readonly string ArmamentName = "primary";
[Desc("Range (in cells) that actor can scan for supporting ChainAttacks actors.")]
public readonly WRange Range = WRange.FromCells(5);
[Desc("Increase damage in a linear (Additive) or exponention (Multiplicative) fashion?")]
public readonly ChainAttackModel DamageType = ChainAttackModel.Additive;
[Desc("Amount of damage to add to total damage. Default is 0 which means \"add our weapon's default damage value.\"",
"Only used if DamageType is Additive")]
public readonly int LinearDamageAdded = 0;
[Desc("Amount of damage to add to total damage. Default is 2.0 which doubles damage on each iteration.",
"Only used if DamageType is Multiplicative")]
public readonly float DamageMultiplier = 2.0f;
public object Create(ActorInitializer init) { return new ChainAttacks(init.self, this); }
}
public class ChainAttacks : INotifyAttack, INotifyAppliedDamage
{
ChainAttacksInfo info;
Armament weaponToUse;
public ChainAttacks(Actor self, ChainAttacksInfo info)
{
this.info = info;
weaponToUse = self.TraitsImplementing<Armament>()
.FirstOrDefault(a => a.Info.Name == info.ArmamentName);
}
public void Attacking(Actor self, Target target, Armament a, Barrel barrel)
{
var supporters = self.World.FindActorsInCircle(self.CenterPosition, info.Range)
.Where(s => s.SharesOwnerWith(self) && s.HasTrait<ChainAttacks>())
.OrderBy(x => x.Trait<ChainAttacksInfo>().DamageType);
var damageToAdd = 0;
foreach (var supporter in supporters)
{
var cai = supporter.Info.Traits.Get<ChainAttacksInfo>();
for (var i = 0; i < info.MaximumChains; i++)
damageToAdd += RequestSupport(supporter, weaponToUse, cai.DamageType);
Game.Debug("DamageToAdd: {0}.".F(damageToAdd));
}
// TODO: add `damageToAdd` to real damage output
}
int RequestSupport(Actor supporter, Armament arm, ChainAttackModel model)
{
var cai = supporter.Info.Traits.Get<ChainAttacksInfo>();
if (!info.ReceiverTypes.Contains(cai.SenderType))
return 0;
var baseDamage = arm.Weapon.Warheads.First().Damage;
return model == ChainAttackModel.Multiplicative ? (int)(baseDamage * info.DamageMultiplier) :
(info.LinearDamageAdded == 0 ? baseDamage : info.LinearDamageAdded);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment