153 lines
4.7 KiB
C#
153 lines
4.7 KiB
C#
using System;
|
|
using WeightedMonsterAbility = Server.Random.WeightedValue<Server.Mobiles.MonsterAbility>;
|
|
|
|
namespace Server.Mobiles;
|
|
|
|
public class MonsterAbilityGroup : MonsterAbility
|
|
{
|
|
private readonly WeightedMonsterAbility[] _weightedAbilities;
|
|
private readonly WeightedMonsterAbility[] _availableToTrigger;
|
|
private readonly MonsterAbilityTrigger _triggers;
|
|
private int _availableToTriggerCount;
|
|
|
|
public MonsterAbilityGroup(params WeightedMonsterAbility[] weightedAbilities)
|
|
{
|
|
_weightedAbilities = weightedAbilities;
|
|
_availableToTrigger = new WeightedMonsterAbility[weightedAbilities.Length];
|
|
|
|
for (var i = 0; i < _weightedAbilities.Length; i++)
|
|
{
|
|
_triggers |= _weightedAbilities[i].Value.AbilityTrigger;
|
|
}
|
|
}
|
|
|
|
public override MonsterAbilityTrigger AbilityTrigger => _triggers;
|
|
|
|
public bool HasAbility(MonsterAbility ability)
|
|
{
|
|
for (var i = 0; i < _weightedAbilities.Length; i++)
|
|
{
|
|
if (_weightedAbilities[i].Value == ability)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// Note: Does not get an ability randomly by weight
|
|
// This is used for passives or lookups
|
|
public MonsterAbility GetAbilityWithType(MonsterAbilityType type)
|
|
{
|
|
for (var i = 0; i < _weightedAbilities.Length; i++)
|
|
{
|
|
var ability = _weightedAbilities[i].Value;
|
|
if (ability.AbilityType == type)
|
|
{
|
|
return ability;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public override bool CanTrigger(BaseCreature source, MonsterAbilityTrigger trigger)
|
|
{
|
|
if (!base.CanTrigger(source, trigger))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
_availableToTriggerCount = 0;
|
|
|
|
for (var i = 0; i < _weightedAbilities.Length; i++)
|
|
{
|
|
var weightedAbility = _weightedAbilities[i];
|
|
if (weightedAbility.Value.CanTrigger(source, trigger))
|
|
{
|
|
_availableToTrigger[_availableToTriggerCount++] = weightedAbility;
|
|
}
|
|
}
|
|
|
|
return _availableToTriggerCount > 0;
|
|
}
|
|
|
|
// Note: Trigger will choose an ability at random by weight
|
|
public override void Trigger(MonsterAbilityTrigger trigger, BaseCreature source, Mobile target)
|
|
{
|
|
if (_availableToTriggerCount <= 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var slice = new ReadOnlySpan<WeightedMonsterAbility>(_availableToTrigger, 0, _availableToTriggerCount);
|
|
var chosenAbility = slice.RandomWeightedElement().Value;
|
|
|
|
// Just in case?
|
|
if (chosenAbility == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
base.Trigger(trigger, source, target);
|
|
chosenAbility.Trigger(trigger, source, target);
|
|
_availableToTriggerCount = 0; // Just in case trigger is called without CanTrigger
|
|
}
|
|
|
|
public override void AlterMeleeDamageFrom(BaseCreature source, Mobile target, ref int damage)
|
|
{
|
|
for (var i = 0; i < _weightedAbilities.Length; i++)
|
|
{
|
|
_weightedAbilities[i].Value.AlterMeleeDamageFrom(source, target, ref damage);
|
|
}
|
|
}
|
|
|
|
public override void AlterMeleeDamageTo(BaseCreature source, Mobile target, ref int damage)
|
|
{
|
|
for (var i = 0; i < _weightedAbilities.Length; i++)
|
|
{
|
|
_weightedAbilities[i].Value.AlterMeleeDamageTo(source, target, ref damage);
|
|
}
|
|
}
|
|
|
|
public override void AlterSpellDamageScalarFrom(BaseCreature source, Mobile target, ref double scalar)
|
|
{
|
|
for (var i = 0; i < _weightedAbilities.Length; i++)
|
|
{
|
|
_weightedAbilities[i].Value.AlterSpellDamageScalarFrom(source, target, ref scalar);
|
|
}
|
|
}
|
|
|
|
public override void AlterSpellDamageScalarTo(BaseCreature source, Mobile target, ref double scalar)
|
|
{
|
|
for (var i = 0; i < _weightedAbilities.Length; i++)
|
|
{
|
|
_weightedAbilities[i].Value.AlterSpellDamageScalarTo(source, target, ref scalar);
|
|
}
|
|
}
|
|
|
|
public override void AlterSpellDamageFrom(BaseCreature source, Mobile target, ref int damage)
|
|
{
|
|
for (var i = 0; i < _weightedAbilities.Length; i++)
|
|
{
|
|
_weightedAbilities[i].Value.AlterSpellDamageFrom(source, target, ref damage);
|
|
}
|
|
}
|
|
|
|
public override void AlterSpellDamageTo(BaseCreature source, Mobile target, ref int damage)
|
|
{
|
|
for (var i = 0; i < _weightedAbilities.Length; i++)
|
|
{
|
|
_weightedAbilities[i].Value.AlterSpellDamageTo(source, target, ref damage);
|
|
}
|
|
}
|
|
|
|
public override void Move(BaseCreature creature, Direction d)
|
|
{
|
|
for (var i = 0; i < _weightedAbilities.Length; i++)
|
|
{
|
|
_weightedAbilities[i].Value.Move(creature, d);
|
|
}
|
|
}
|
|
}
|