160 lines
5.2 KiB
C#
160 lines
5.2 KiB
C#
using RimWorld;
|
|
using Verse;
|
|
using System.Text;
|
|
|
|
namespace ArachnaeSwarm
|
|
{
|
|
public class CompAbilityEffect_GiveHediffWithSkillDuration : CompAbilityEffect_WithDuration
|
|
{
|
|
public new CompProperties_AbilityGiveHediffWithSkillDuration Props => (CompProperties_AbilityGiveHediffWithSkillDuration)props;
|
|
|
|
public override void Apply(LocalTargetInfo target, LocalTargetInfo dest)
|
|
{
|
|
base.Apply(target, dest);
|
|
|
|
if (!Props.ignoreSelf || target.Pawn != parent.pawn)
|
|
{
|
|
if (!Props.onlyApplyToSelf && Props.applyToTarget)
|
|
{
|
|
ApplyToTarget(target.Pawn, parent.pawn);
|
|
}
|
|
if (Props.applyToSelf || Props.onlyApplyToSelf)
|
|
{
|
|
ApplyToTarget(parent.pawn, target.Pawn);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ApplyToTarget(Pawn target, Pawn other)
|
|
{
|
|
if (target == null) return;
|
|
|
|
if (TryResist(target))
|
|
{
|
|
MoteMaker.ThrowText(target.DrawPos, target.Map, "Resisted".Translate());
|
|
return;
|
|
}
|
|
|
|
if (Props.replaceExisting)
|
|
{
|
|
Hediff existingHediff = target.health.hediffSet.GetFirstHediffOfDef(Props.hediffDef);
|
|
if (existingHediff != null)
|
|
{
|
|
target.health.RemoveHediff(existingHediff);
|
|
}
|
|
}
|
|
|
|
Hediff hediff = HediffMaker.MakeHediff(Props.hediffDef, target, Props.onlyBrain ? target.health.hediffSet.GetBrain() : null);
|
|
HediffComp_Disappears disappearsComp = hediff.TryGetComp<HediffComp_Disappears>();
|
|
|
|
if (disappearsComp != null)
|
|
{
|
|
disappearsComp.ticksToDisappear = GetDurationWithSkillBonus(target).SecondsToTicks();
|
|
}
|
|
|
|
if (Props.severity >= 0f)
|
|
{
|
|
hediff.Severity = Props.severity;
|
|
}
|
|
|
|
HediffComp_Link linkComp = hediff.TryGetComp<HediffComp_Link>();
|
|
if (linkComp != null)
|
|
{
|
|
linkComp.other = other;
|
|
linkComp.drawConnection = target == parent.pawn;
|
|
}
|
|
|
|
target.health.AddHediff(hediff);
|
|
}
|
|
|
|
private float GetDurationWithSkillBonus(Pawn target)
|
|
{
|
|
// 使用基类的durationSeconds作为基础值
|
|
float baseDuration = Props.ActualBaseDurationSeconds;
|
|
|
|
if (Props.skillDef != null && parent.pawn != null && parent.pawn.skills != null)
|
|
{
|
|
SkillRecord skill = parent.pawn.skills.GetSkill(Props.skillDef);
|
|
if (skill != null)
|
|
{
|
|
int effectiveLevel = skill.Level;
|
|
if (Props.maxBonusLevels > 0 && effectiveLevel > Props.maxBonusLevels)
|
|
{
|
|
effectiveLevel = Props.maxBonusLevels;
|
|
}
|
|
|
|
return baseDuration + (effectiveLevel * Props.extraSecondsPerSkillLevel);
|
|
}
|
|
}
|
|
|
|
return baseDuration;
|
|
}
|
|
|
|
protected virtual bool TryResist(Pawn pawn)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// 在工具提示中显示技能加成信息
|
|
public override string ExtraTooltipPart()
|
|
{
|
|
StringBuilder stringBuilder = new StringBuilder();
|
|
|
|
// 先添加基类的工具提示
|
|
string baseTooltip = base.ExtraTooltipPart();
|
|
if (!string.IsNullOrEmpty(baseTooltip))
|
|
{
|
|
stringBuilder.AppendLine(baseTooltip);
|
|
}
|
|
|
|
// 添加技能加成信息
|
|
if (Props.showSkillBonusInTooltip && Props.skillDef != null && parent.pawn != null)
|
|
{
|
|
SkillRecord skill = parent.pawn.skills?.GetSkill(Props.skillDef);
|
|
if (skill != null)
|
|
{
|
|
stringBuilder.AppendLine("AbilitySkillDurationBonus".Translate(
|
|
Props.skillDef.LabelCap,
|
|
skill.Level,
|
|
GetSkillBonusDuration(),
|
|
GetTotalDuration()
|
|
));
|
|
}
|
|
}
|
|
|
|
return stringBuilder.ToString().TrimEndNewlines();
|
|
}
|
|
|
|
// 获取技能加成的持续时间
|
|
private float GetSkillBonusDuration()
|
|
{
|
|
if (Props.skillDef == null || parent.pawn == null) return 0f;
|
|
|
|
SkillRecord skill = parent.pawn.skills.GetSkill(Props.skillDef);
|
|
if (skill == null) return 0f;
|
|
|
|
int effectiveLevel = skill.Level;
|
|
if (Props.maxBonusLevels > 0 && effectiveLevel > Props.maxBonusLevels)
|
|
{
|
|
effectiveLevel = Props.maxBonusLevels;
|
|
}
|
|
|
|
return effectiveLevel * Props.extraSecondsPerSkillLevel;
|
|
}
|
|
|
|
// 获取总持续时间
|
|
private float GetTotalDuration()
|
|
{
|
|
return Props.ActualBaseDurationSeconds + GetSkillBonusDuration();
|
|
}
|
|
|
|
public override bool AICanTargetNow(LocalTargetInfo target)
|
|
{
|
|
if (parent.pawn.Faction == Faction.OfPlayer)
|
|
{
|
|
return false;
|
|
}
|
|
return target.Pawn != null;
|
|
}
|
|
}
|
|
} |