diff --git a/1.6/1.6/Assemblies/WulaFallenEmpire.dll b/1.6/1.6/Assemblies/WulaFallenEmpire.dll index c5b8fe3c..5e4a5b1b 100644 Binary files a/1.6/1.6/Assemblies/WulaFallenEmpire.dll and b/1.6/1.6/Assemblies/WulaFallenEmpire.dll differ diff --git a/1.6/1.6/Defs/HediffDefs/Hediffs_BodyParts_Turret.xml b/1.6/1.6/Defs/HediffDefs/Hediffs_BodyParts_Turret.xml new file mode 100644 index 00000000..f3232607 --- /dev/null +++ b/1.6/1.6/Defs/HediffDefs/Hediffs_BodyParts_Turret.xml @@ -0,0 +1,83 @@ + + + + + + + Gun_WULA_MiniTurretGun_ForHediff + + A simple automatic gun made to be mounted on a turret. + + Things/Building/TacticalTurret/TacticalTurret_Top + Graphic_Single + + + 0.77 + 0.70 + 0.45 + 0.24 + 4.8 + 0 + 5 + 0 + + +
  • + Verb_Shoot + Bullet_TacticalTurret + 0 + 19.9 + 8 + 2 + GunShotA + GunTail_Light + 9 + 1 +
  • +
    +
    + + + + WULA_ShoulderCannon + + A shoulder-mounted automated cannon that tracks and fires upon hostiles. + Steel + Hediff_Implant + (0.6, 0.6, 0.6) + false + + + +
  • + + Gun_WULA_MiniTurretGun_ForHediff + + + 0 + + + true +
  • +
    + + +
  • + +
  • +
    +
    + +
    diff --git a/Source/WulaFallenEmpire/HediffComp_TopTurret.cs b/Source/WulaFallenEmpire/HediffComp_TopTurret.cs new file mode 100644 index 00000000..37b2de23 --- /dev/null +++ b/Source/WulaFallenEmpire/HediffComp_TopTurret.cs @@ -0,0 +1,268 @@ +using System; +using System.Collections.Generic; +using UnityEngine; +using Verse; +using Verse.AI; +using RimWorld; + +namespace WulaFallenEmpire +{ + public class HediffCompProperties_TopTurret : HediffCompProperties + { + public HediffCompProperties_TopTurret() + { + this.compClass = typeof(HediffComp_TopTurret); + } + + public ThingDef turretDef; + + public float angleOffset; + + public bool autoAttack = true; + } + + [StaticConstructorOnStartup] + public class HediffComp_TopTurret : HediffComp, IAttackTargetSearcher + { + public Thing Thing + { + get + { + return this.Pawn; + } + } + + private HediffCompProperties_TopTurret Props + { + get + { + return (HediffCompProperties_TopTurret)this.props; + } + } + + public Verb CurrentEffectiveVerb + { + get + { + return this.AttackVerb; + } + } + + public LocalTargetInfo LastAttackedTarget + { + get + { + return this.lastAttackedTarget; + } + } + + public int LastAttackTargetTick + { + get + { + return this.lastAttackTargetTick; + } + } + + public CompEquippable GunCompEq + { + get + { + return this.gun.TryGetComp(); + } + } + + public Verb AttackVerb + { + get + { + return this.GunCompEq.PrimaryVerb; + } + } + + private bool WarmingUp + { + get + { + return this.burstWarmupTicksLeft > 0; + } + } + + private bool CanShoot + { + get + { + Pawn pawn; + if ((pawn = (this.Pawn)) != null) + { + if (!pawn.Spawned || pawn.Downed || pawn.Dead || !pawn.Awake()) + { + return false; + } + if (pawn.stances.stunner.Stunned) + { + return false; + } + if (this.TurretDestroyed) + { + return false; + } + if (pawn.IsColonyMechPlayerControlled && !this.fireAtWill) + { + return false; + } + } + CompCanBeDormant compCanBeDormant = this.Pawn.TryGetComp(); + return compCanBeDormant == null || compCanBeDormant.Awake; + } + } + + public bool TurretDestroyed + { + get + { + Pawn pawn; + return (pawn = (this.Pawn)) != null && this.AttackVerb.verbProps.linkedBodyPartsGroup != null && this.AttackVerb.verbProps.ensureLinkedBodyPartsGroupAlwaysUsable && PawnCapacityUtility.CalculateNaturalPartsAverageEfficiency(pawn.health.hediffSet, this.AttackVerb.verbProps.linkedBodyPartsGroup) <= 0f; + } + } + + private Material TurretMat + { + get + { + if (this.turretMat == null) + { + this.turretMat = MaterialPool.MatFrom(this.Props.turretDef.graphicData.texPath); + } + return this.turretMat; + } + } + + public bool AutoAttack + { + get + { + return this.Props.autoAttack; + } + } + + public override void CompPostMake() + { + base.CompPostMake(); + this.MakeGun(); + } + + private void MakeGun() + { + this.gun = ThingMaker.MakeThing(this.Props.turretDef, null); + this.UpdateGunVerbs(); + } + + private void UpdateGunVerbs() + { + List allVerbs = this.gun.TryGetComp().AllVerbs; + for (int i = 0; i < allVerbs.Count; i++) + { + Verb verb = allVerbs[i]; + verb.caster = this.Pawn; + verb.castCompleteCallback = delegate () + { + this.burstCooldownTicksLeft = this.AttackVerb.verbProps.defaultCooldownTime.SecondsToTicks(); + }; + } + } + public override void CompPostTick(ref float severityAdjustment) + { + base.CompPostTick(ref severityAdjustment); + if (!this.CanShoot) + { + return; + } + if (this.currentTarget.IsValid) + { + this.curRotation = (this.currentTarget.Cell.ToVector3Shifted() - this.Pawn.DrawPos).AngleFlat() + this.Props.angleOffset; + } + this.AttackVerb.VerbTick(); + if (this.AttackVerb.state != VerbState.Bursting) + { + if (this.WarmingUp) + { + this.burstWarmupTicksLeft--; + if (this.burstWarmupTicksLeft == 0) + { + this.AttackVerb.TryStartCastOn(this.currentTarget, false, true, false, true); + this.lastAttackTargetTick = Find.TickManager.TicksGame; + this.lastAttackedTarget = this.currentTarget; + return; + } + } + else + { + if (this.burstCooldownTicksLeft > 0) + { + this.burstCooldownTicksLeft--; + } + if (this.burstCooldownTicksLeft <= 0 && this.Pawn.IsHashIntervalTick(10)) + { + this.currentTarget = (Thing)AttackTargetFinder.BestShootTargetFromCurrentPosition(this, TargetScanFlags.NeedThreat | TargetScanFlags.NeedAutoTargetable, null, 0f, 9999f); + if (this.currentTarget.IsValid) + { + this.burstWarmupTicksLeft = 1; + return; + } + this.ResetCurrentTarget(); + } + } + } + } + + private void ResetCurrentTarget() + { + this.currentTarget = LocalTargetInfo.Invalid; + this.burstWarmupTicksLeft = 0; + } + + public override void CompExposeData() + { + base.CompExposeData(); + Scribe_Values.Look(ref this.burstCooldownTicksLeft, "burstCooldownTicksLeft", 0, false); + Scribe_Values.Look(ref this.burstWarmupTicksLeft, "burstWarmupTicksLeft", 0, false); + Scribe_TargetInfo.Look(ref this.currentTarget, "currentTarget"); + Scribe_Deep.Look(ref this.gun, "gun", Array.Empty()); + Scribe_Values.Look(ref this.fireAtWill, "fireAtWill", true, false); + if (Scribe.mode == LoadSaveMode.PostLoadInit) + { + if (this.gun == null) + { + Log.Error("CompTurrentGun had null gun after loading. Recreating."); + this.MakeGun(); + return; + } + this.UpdateGunVerbs(); + } + } + + private const int StartShootIntervalTicks = 10; + + private static readonly CachedTexture ToggleTurretIcon = new CachedTexture("UI/Gizmos/ToggleTurret"); + + public Thing gun; + + protected int burstCooldownTicksLeft; + + protected int burstWarmupTicksLeft; + + protected LocalTargetInfo currentTarget = LocalTargetInfo.Invalid; + + private bool fireAtWill = true; + + private LocalTargetInfo lastAttackedTarget = LocalTargetInfo.Invalid; + + private int lastAttackTargetTick; + + private float curRotation; + + [Unsaved(false)] + public Material turretMat; + } +} \ No newline at end of file diff --git a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj index 3832c8f1..88df74d4 100644 --- a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj +++ b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj @@ -192,6 +192,7 @@ +