暂存
This commit is contained in:
Binary file not shown.
@@ -50,8 +50,7 @@
|
|||||||
<consumeFuelOnlyWhenUsed>true</consumeFuelOnlyWhenUsed>
|
<consumeFuelOnlyWhenUsed>true</consumeFuelOnlyWhenUsed>
|
||||||
</li>
|
</li>
|
||||||
<li Class="CompProperties_Forbiddable"/>
|
<li Class="CompProperties_Forbiddable"/>
|
||||||
<li Class="CompProperties_Breakdownable"/>
|
<li Class="CompProperties_Breakdownable"/>
|
||||||
<li Class="ArachnaeSwarm.CompProperties_ForceTargetable" />
|
|
||||||
</comps>
|
</comps>
|
||||||
<building>
|
<building>
|
||||||
<turretGunDef>CatastropheMissile_Weapon</turretGunDef>
|
<turretGunDef>CatastropheMissile_Weapon</turretGunDef>
|
||||||
@@ -60,7 +59,7 @@
|
|||||||
<li>Artillery</li>
|
<li>Artillery</li>
|
||||||
</buildingTags>
|
</buildingTags>
|
||||||
</building>
|
</building>
|
||||||
<designationCategory>Security</designationCategory>
|
<designationCategory>ARA_Buildings</designationCategory>
|
||||||
<constructionSkillPrerequisite>8</constructionSkillPrerequisite>
|
<constructionSkillPrerequisite>8</constructionSkillPrerequisite>
|
||||||
<researchPrerequisites>
|
<researchPrerequisites>
|
||||||
<li>ShipbuildingBasics</li>
|
<li>ShipbuildingBasics</li>
|
||||||
|
|||||||
@@ -6,16 +6,26 @@
|
|||||||
<label>“天灾”巡航导弹</label>
|
<label>“天灾”巡航导弹</label>
|
||||||
<thingClass>ArachnaeSwarm.Projectile_CruiseMissile</thingClass>
|
<thingClass>ArachnaeSwarm.Projectile_CruiseMissile</thingClass>
|
||||||
<graphicData>
|
<graphicData>
|
||||||
<texPath>Wula/Projectile/WULA_Loitering_Munition</texPath>
|
<graphicClass>Graphic_Single_AgeSecs</graphicClass>
|
||||||
<graphicClass>Graphic_Single</graphicClass>
|
<texPath>Things/Projectile/FleshmassSpitterProjectileSheet</texPath>
|
||||||
|
<drawSize>(3,3)</drawSize>
|
||||||
|
<shaderType>MoteGlow</shaderType>
|
||||||
</graphicData>
|
</graphicData>
|
||||||
<projectile>
|
<projectile>
|
||||||
|
<useGraphicClass>True</useGraphicClass>
|
||||||
|
<shadowSize>1</shadowSize>
|
||||||
<damageDef>ARA_AcidBurn</damageDef>
|
<damageDef>ARA_AcidBurn</damageDef>
|
||||||
<damageAmountBase>200</damageAmountBase>
|
<damageAmountBase>200</damageAmountBase>
|
||||||
<speed>50</speed>
|
<speed>80</speed>
|
||||||
|
<spinRate>15</spinRate>
|
||||||
|
<flyOverhead>true</flyOverhead>0
|
||||||
|
<filth>Filth_SpentAcid</filth>
|
||||||
|
<filthCount>4</filthCount>
|
||||||
|
<explosionEffect>Shell_AcidSpitImpact</explosionEffect>
|
||||||
|
<explosionEffectLifetimeTicks>60</explosionEffectLifetimeTicks>
|
||||||
|
<doExplosionVFX>false</doExplosionVFX>
|
||||||
<explosionRadius>5.9</explosionRadius>
|
<explosionRadius>5.9</explosionRadius>
|
||||||
<soundExplode>MortarBomb_Explode</soundExplode>
|
<soundExplode>MortarBomb_Explode</soundExplode>
|
||||||
<flyOverhead>true</flyOverhead>
|
|
||||||
</projectile>
|
</projectile>
|
||||||
<modExtensions>
|
<modExtensions>
|
||||||
<li Class="ArachnaeSwarm.CruiseMissileProperties">
|
<li Class="ArachnaeSwarm.CruiseMissileProperties">
|
||||||
@@ -38,6 +48,49 @@
|
|||||||
<bezierRandomOffsetScale>0.5</bezierRandomOffsetScale>
|
<bezierRandomOffsetScale>0.5</bezierRandomOffsetScale>
|
||||||
</li>
|
</li>
|
||||||
</modExtensions>
|
</modExtensions>
|
||||||
|
<comps>
|
||||||
|
<li Class="CompProperties_ProjectileEffecter">
|
||||||
|
<effecterDef>Shell_AcidSpitStream</effecterDef>
|
||||||
|
</li>
|
||||||
|
<li Class="CompProperties_ProjectileEffecter">
|
||||||
|
<effecterDef>Shell_AcidSpitLaunched</effecterDef>
|
||||||
|
</li>
|
||||||
|
</comps>
|
||||||
|
</ThingDef>
|
||||||
|
|
||||||
|
<ThingDef ParentName="BaseBullet">
|
||||||
|
<defName>Projectile_CatastropheMissile_Fake</defName>
|
||||||
|
<label>“天灾”巡航导弹</label>
|
||||||
|
<thingClass>ArachnaeSwarm.Projectile_CruiseMissile</thingClass>
|
||||||
|
<graphicData>
|
||||||
|
<graphicClass>Graphic_Single_AgeSecs</graphicClass>
|
||||||
|
<texPath>Things/Projectile/FleshmassSpitterProjectileSheet</texPath>
|
||||||
|
<drawSize>(3,3)</drawSize>
|
||||||
|
<shaderType>MoteGlow</shaderType>
|
||||||
|
</graphicData>
|
||||||
|
<projectile>
|
||||||
|
<useGraphicClass>True</useGraphicClass>
|
||||||
|
<shadowSize>1</shadowSize>
|
||||||
|
<damageDef>ARA_AcidBurn</damageDef>
|
||||||
|
<damageAmountBase>0</damageAmountBase>
|
||||||
|
<speed>50</speed>
|
||||||
|
<spinRate>15</spinRate>
|
||||||
|
<flyOverhead>true</flyOverhead>
|
||||||
|
</projectile>
|
||||||
|
<modExtensions>
|
||||||
|
<li Class="ArachnaeSwarm.CruiseMissileProperties">
|
||||||
|
<isDummy>true</isDummy>
|
||||||
|
<useSubExplosions>false</useSubExplosions>
|
||||||
|
</li>
|
||||||
|
</modExtensions>
|
||||||
|
<comps>
|
||||||
|
<li Class="CompProperties_ProjectileEffecter">
|
||||||
|
<effecterDef>Shell_AcidSpitStream</effecterDef>
|
||||||
|
</li>
|
||||||
|
<li Class="CompProperties_ProjectileEffecter">
|
||||||
|
<effecterDef>Shell_AcidSpitLaunched</effecterDef>
|
||||||
|
</li>
|
||||||
|
</comps>
|
||||||
</ThingDef>
|
</ThingDef>
|
||||||
|
|
||||||
<ThingDef ParentName="BaseWeapon">
|
<ThingDef ParentName="BaseWeapon">
|
||||||
@@ -77,7 +130,7 @@
|
|||||||
<li>
|
<li>
|
||||||
<verbClass>ArachnaeSwarm.Verb_LaunchCatastropheMissile</verbClass>
|
<verbClass>ArachnaeSwarm.Verb_LaunchCatastropheMissile</verbClass>
|
||||||
<hasStandardCommand>true</hasStandardCommand>
|
<hasStandardCommand>true</hasStandardCommand>
|
||||||
<defaultProjectile>Projectile_CatastropheMissile</defaultProjectile> <!-- Placeholder local projectile -->
|
<defaultProjectile>Projectile_CatastropheMissile</defaultProjectile> <!-- Placeholder local projectile -->
|
||||||
<warmupTime>3.0</warmupTime>
|
<warmupTime>3.0</warmupTime>
|
||||||
<forcedMissRadius>1</forcedMissRadius>
|
<forcedMissRadius>1</forcedMissRadius>
|
||||||
<isMortar>true</isMortar>
|
<isMortar>true</isMortar>
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<LanguageData>
|
||||||
|
|
||||||
|
<CommandFireGlobal>发射远程打击</CommandFireGlobal>
|
||||||
|
<CommandFireGlobalDesc>选择一个世界地图上的目标进行远程打击。</CommandFireGlobalDesc>
|
||||||
|
|
||||||
|
<CommandFireLocal>发射本地打击</CommandFireLocal>
|
||||||
|
<CommandFireLocalDesc>手动命令炮塔攻击一个本地地图上的目标。</CommandFireLocalDesc>
|
||||||
|
|
||||||
|
<RemoteTargetSet>远程目标已设定:{0}</RemoteTargetSet>
|
||||||
|
<MessageTargetMustBeMap>远程打击的目标必须是一个已探索的地点。</MessageTargetMustBeMap>
|
||||||
|
<NoMissileToLaunch>没有可用的导弹。</NoMissileToLaunch>
|
||||||
|
|
||||||
|
<CommandClearAllTargets>取消所有目标</CommandClearAllTargets>
|
||||||
|
<CommandClearAllTargetsDesc>取消当前设定的所有本地和远程目标。</CommandClearAllTargetsDesc>
|
||||||
|
|
||||||
|
</LanguageData>
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
|
||||||
<LanguageData>
|
|
||||||
|
|
||||||
<!-- Commands & Messages -->
|
|
||||||
<CommandDeployWormholePortalB_Pilot>部署虫洞传送门</CommandDeployWormholePortalB_Pilot>
|
|
||||||
<CommandDeployWormholePortalB_PilotDesc>选择一名驾驶员来启动一个B端传送门。</CommandDeployWormholePortalB_PilotDesc>
|
|
||||||
<NoPilotAvailable>没有可用的驾驶员</NoPilotAvailable>
|
|
||||||
|
|
||||||
</LanguageData>
|
|
||||||
@@ -1,58 +1,160 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using RimWorld;
|
using System.Text;
|
||||||
using RimWorld.Planet;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using Verse;
|
using Verse;
|
||||||
using Verse.AI;
|
using Verse.AI;
|
||||||
using Verse.Sound;
|
using Verse.Sound;
|
||||||
|
using RimWorld;
|
||||||
|
using RimWorld.Planet;
|
||||||
|
|
||||||
namespace ArachnaeSwarm
|
namespace ArachnaeSwarm
|
||||||
{
|
{
|
||||||
[StaticConstructorOnStartup]
|
[StaticConstructorOnStartup]
|
||||||
public class Building_CatastropheMissileSilo : Building_TurretGun
|
public class Building_CatastropheMissileSilo : Building_TurretGun
|
||||||
{
|
{
|
||||||
|
public GlobalTargetInfo longTarget;
|
||||||
public static readonly Texture2D FireMissionTex = ContentFinder<Texture2D>.Get("UI/Commands/Attack", true);
|
public static readonly Texture2D FireMissionTex = ContentFinder<Texture2D>.Get("UI/Commands/Attack", true);
|
||||||
|
|
||||||
|
public override void SpawnSetup(Map map, bool respawningAfterLoad)
|
||||||
|
{
|
||||||
|
base.SpawnSetup(map, respawningAfterLoad);
|
||||||
|
// This is the definitive fix for the default target issue on spawn.
|
||||||
|
// It runs only once when the building is first created, not on game load.
|
||||||
|
if (!respawningAfterLoad)
|
||||||
|
{
|
||||||
|
this.longTarget = GlobalTargetInfo.Invalid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void ExposeData()
|
public override void ExposeData()
|
||||||
{
|
{
|
||||||
base.ExposeData();
|
base.ExposeData();
|
||||||
|
// We no longer save/load longTarget here. It is only set by player action.
|
||||||
|
// Scribe_TargetInfo.Look(ref this.longTarget, "longTarget"); // REMOVED
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Tick()
|
protected override void Tick()
|
||||||
{
|
{
|
||||||
base.Tick();
|
// --- Attack Priority Logic ---
|
||||||
|
// Prio 1: Forced Local Target. Let the base class handle it.
|
||||||
|
if (this.forcedTarget.IsValid)
|
||||||
|
{
|
||||||
|
base.Tick();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Prio 2: Remote Target
|
||||||
|
if (this.longTarget.IsValid)
|
||||||
|
{
|
||||||
|
if (base.Active && this.burstCooldownTicksLeft <= 0 && CanFireGlobal(out _))
|
||||||
|
{
|
||||||
|
this.FireMission(this.longTarget);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Manually tick cooldown and turret top rotation when in remote mode to prevent auto-targeting
|
||||||
|
if(this.burstCooldownTicksLeft > 0) this.burstCooldownTicksLeft--;
|
||||||
|
this.top.TurretTopTick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Prio 3: No manual target, fall back to base auto-targeting.
|
||||||
|
else
|
||||||
|
{
|
||||||
|
base.Tick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string GetInspectString()
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder(base.GetInspectString());
|
||||||
|
if (this.longTarget.IsValid)
|
||||||
|
{
|
||||||
|
sb.AppendLine();
|
||||||
|
sb.Append("RemoteTargetSet".Translate(this.longTarget.Label));
|
||||||
|
}
|
||||||
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<Gizmo> GetGizmos()
|
public override IEnumerable<Gizmo> GetGizmos()
|
||||||
{
|
{
|
||||||
// Add the default turret gizmos (like "Set forced target")
|
// Yield base gizmos first, which includes "Set forced target"
|
||||||
foreach (Gizmo c in base.GetGizmos())
|
foreach (var g in base.GetGizmos())
|
||||||
{
|
{
|
||||||
yield return c;
|
yield return g;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add our custom global strike gizmo
|
// Then add our custom "Global Strike" gizmo
|
||||||
Command_Action launch = new Command_Action
|
Command_Action fireGlobal = new Command_Action
|
||||||
{
|
{
|
||||||
defaultLabel = "CommandFireGlobal".Translate(),
|
defaultLabel = "CommandFireGlobal".Translate(),
|
||||||
defaultDesc = "CommandFireGlobalDesc".Translate(),
|
defaultDesc = "CommandFireGlobalDesc".Translate(),
|
||||||
icon = FireMissionTex,
|
icon = FireMissionTex,
|
||||||
action = new Action(this.StartChoosingDestination)
|
action = new Action(StartChoosingDestination)
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!CanFireGlobal(out string reason))
|
if (!CanFireGlobal(out string reason))
|
||||||
{
|
{
|
||||||
launch.Disable(reason);
|
fireGlobal.Disable(reason);
|
||||||
|
}
|
||||||
|
// Disable if a local forced target is already set
|
||||||
|
if (this.forcedTarget.IsValid)
|
||||||
|
{
|
||||||
|
fireGlobal.Disable("LocalTargetForced".Translate());
|
||||||
|
}
|
||||||
|
yield return fireGlobal;
|
||||||
|
|
||||||
|
// Add a specific button to clear the remote target
|
||||||
|
if (this.longTarget.IsValid)
|
||||||
|
{
|
||||||
|
Command_Action clearRemote = new Command_Action
|
||||||
|
{
|
||||||
|
defaultLabel = "CommandClearRemoteTarget".Translate(),
|
||||||
|
defaultDesc = "CommandClearRemoteTargetDesc".Translate(),
|
||||||
|
icon = ContentFinder<Texture2D>.Get("UI/Designators/Cancel"),
|
||||||
|
action = () =>
|
||||||
|
{
|
||||||
|
this.longTarget = GlobalTargetInfo.Invalid;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
yield return clearRemote;
|
||||||
}
|
}
|
||||||
yield return launch;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void FireMission(GlobalTargetInfo target)
|
||||||
|
{
|
||||||
|
if (!CanFireGlobal(out _)) return;
|
||||||
|
|
||||||
|
WorldObject_CatastropheMissile missile = (WorldObject_CatastropheMissile)WorldObjectMaker.MakeWorldObject(
|
||||||
|
DefDatabase<WorldObjectDef>.GetNamed("CatastropheMissile_Flying")
|
||||||
|
);
|
||||||
|
missile.Tile = this.Map.Tile;
|
||||||
|
missile.destinationTile = target.Tile;
|
||||||
|
missile.destinationCell = target.Cell;
|
||||||
|
missile.Projectile = DefDatabase<ThingDef>.GetNamed("Projectile_CatastropheMissile");
|
||||||
|
Find.WorldObjects.Add(missile);
|
||||||
|
|
||||||
|
if (CellFinder.TryFindRandomEdgeCellWith(c => this.Map.reachability.CanReach(this.Position, c, PathEndMode.OnCell, TraverseParms.For(TraverseMode.NoPassClosedDoors, Danger.Deadly)), this.Map, 0f, out IntVec3 edgeCell))
|
||||||
|
{
|
||||||
|
Projectile_CruiseMissile dummy = (Projectile_CruiseMissile)GenSpawn.Spawn(DefDatabase<ThingDef>.GetNamed("Projectile_CatastropheMissile_Fake"), this.Position, this.Map);
|
||||||
|
dummy?.Launch(this, this.DrawPos, new LocalTargetInfo(edgeCell), new LocalTargetInfo(edgeCell), ProjectileHitFlags.None);
|
||||||
|
}
|
||||||
|
|
||||||
|
var refuelableComp = this.TryGetComp<CompRefuelable>();
|
||||||
|
if(refuelableComp != null)
|
||||||
|
{
|
||||||
|
refuelableComp.ConsumeFuel(1);
|
||||||
|
}
|
||||||
|
SoundDef.Named("RocketLaunch").PlayOneShot(new TargetInfo(this.Position, this.Map));
|
||||||
|
|
||||||
|
// Manually reset cooldown.
|
||||||
|
this.BurstComplete();
|
||||||
|
}
|
||||||
|
|
||||||
private bool CanFireGlobal(out string reason)
|
private bool CanFireGlobal(out string reason)
|
||||||
{
|
{
|
||||||
var refuelableComp = this.TryGetComp<CompRefuelable>();
|
var refuelableComp = this.TryGetComp<CompRefuelable>();
|
||||||
if (refuelableComp != null && !refuelableComp.HasFuel)
|
if (refuelableComp != null && !refuelableComp.HasFuel)
|
||||||
{
|
{
|
||||||
reason = "NoFuel".Translate().CapitalizeFirst();
|
reason = "NoFuel".Translate().CapitalizeFirst();
|
||||||
return false;
|
return false;
|
||||||
@@ -65,13 +167,12 @@ namespace ArachnaeSwarm
|
|||||||
{
|
{
|
||||||
CameraJumper.TryJump(CameraJumper.GetWorldTarget(this), CameraJumper.MovementMode.Pan);
|
CameraJumper.TryJump(CameraJumper.GetWorldTarget(this), CameraJumper.MovementMode.Pan);
|
||||||
Find.WorldSelector.ClearSelection();
|
Find.WorldSelector.ClearSelection();
|
||||||
|
|
||||||
Find.WorldTargeter.BeginTargeting(
|
Find.WorldTargeter.BeginTargeting(
|
||||||
new Func<GlobalTargetInfo, bool>(this.ChoseWorldTarget),
|
new Func<GlobalTargetInfo, bool>(this.ChoseWorldTarget),
|
||||||
true,
|
true,
|
||||||
FireMissionTex,
|
FireMissionTex,
|
||||||
true,
|
true,
|
||||||
() => GenDraw.DrawWorldRadiusRing(this.Map.Tile, 99999),
|
() => GenDraw.DrawWorldRadiusRing(this.Map.Tile, 99999),
|
||||||
null, null, null, true);
|
null, null, null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,12 +183,13 @@ namespace ArachnaeSwarm
|
|||||||
Messages.Message("MessageTargetInvalid".Translate(), MessageTypeDefOf.RejectInput, true);
|
Messages.Message("MessageTargetInvalid".Translate(), MessageTypeDefOf.RejectInput, true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (target.Map == this.Map)
|
if (target.Tile == this.Map.Tile)
|
||||||
{
|
{
|
||||||
Messages.Message("Cannot target own map for global strike.", MessageTypeDefOf.RejectInput, true);
|
Messages.Message("Cannot target own map for global strike.", MessageTypeDefOf.RejectInput, true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allow targeting Pawns and Buildings on the world map
|
||||||
if (target.WorldObject is MapParent mapParent && mapParent.HasMap)
|
if (target.WorldObject is MapParent mapParent && mapParent.HasMap)
|
||||||
{
|
{
|
||||||
var originalMap = this.Map;
|
var originalMap = this.Map;
|
||||||
@@ -96,53 +198,33 @@ namespace ArachnaeSwarm
|
|||||||
};
|
};
|
||||||
|
|
||||||
Current.Game.CurrentMap = mapParent.Map;
|
Current.Game.CurrentMap = mapParent.Map;
|
||||||
Find.Targeter.BeginTargeting(new TargetingParameters { canTargetLocations = true },
|
Find.Targeter.BeginTargeting(new TargetingParameters
|
||||||
|
{
|
||||||
|
canTargetLocations = true,
|
||||||
|
canTargetPawns = true, // Allow targeting pawns
|
||||||
|
canTargetBuildings = true // Allow targeting buildings
|
||||||
|
},
|
||||||
(LocalTargetInfo localTarget) =>
|
(LocalTargetInfo localTarget) =>
|
||||||
{
|
{
|
||||||
this.FireMission(new GlobalTargetInfo(localTarget.Cell, mapParent.Map));
|
// Convert LocalTargetInfo to GlobalTargetInfo, handling Thing targets.
|
||||||
},
|
if (localTarget.HasThing)
|
||||||
|
{
|
||||||
|
this.longTarget = new GlobalTargetInfo(localTarget.Thing);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.longTarget = new GlobalTargetInfo(localTarget.Cell, mapParent.Map);
|
||||||
|
}
|
||||||
|
},
|
||||||
null, onFinished, FireMissionTex, true);
|
null, onFinished, FireMissionTex, true);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Messages.Message("MessageTargetMustBeMap".Translate(), MessageTypeDefOf.RejectInput, true);
|
Messages.Message("MessageTargetMustBeMap".Translate(), MessageTypeDefOf.RejectInput, true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void FireMission(GlobalTargetInfo target)
|
|
||||||
{
|
|
||||||
if (!CanFireGlobal(out _)) return;
|
|
||||||
|
|
||||||
var refuelableComp = this.TryGetComp<CompRefuelable>();
|
|
||||||
|
|
||||||
// --- Launch Logic starts here ---
|
|
||||||
|
|
||||||
// 1. Create the world-traveling object immediately
|
|
||||||
WorldObject_CatastropheMissile missile = (WorldObject_CatastropheMissile)WorldObjectMaker.MakeWorldObject(
|
|
||||||
DefDatabase<WorldObjectDef>.GetNamed("CatastropheMissile_Flying")
|
|
||||||
);
|
|
||||||
missile.Tile = this.Map.Tile;
|
|
||||||
missile.destinationTile = target.Tile;
|
|
||||||
missile.destinationCell = target.Cell;
|
|
||||||
missile.Projectile = DefDatabase<ThingDef>.GetNamed("Projectile_CatastropheMissile");
|
|
||||||
Find.WorldObjects.Add(missile);
|
|
||||||
|
|
||||||
// 2. Launch a local dummy projectile for visual effect, that will never impact.
|
|
||||||
if (CellFinder.TryFindRandomEdgeCellWith(c => this.Map.reachability.CanReach(this.Position, c, PathEndMode.OnCell, TraverseParms.For(TraverseMode.NoPassClosedDoors, Danger.Deadly)), this.Map, 0f, out IntVec3 edgeCell))
|
|
||||||
{
|
|
||||||
Projectile dummy = (Projectile)GenSpawn.Spawn(DefDatabase<ThingDef>.GetNamed("Projectile_CatastropheMissile"), this.Position, this.Map);
|
|
||||||
dummy.Launch(this, this.DrawPos, new LocalTargetInfo(edgeCell), new LocalTargetInfo(edgeCell), ProjectileHitFlags.None);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. Consume resources and start cooldown
|
|
||||||
if(refuelableComp != null)
|
|
||||||
{
|
|
||||||
refuelableComp.ConsumeFuel(1);
|
|
||||||
}
|
|
||||||
SoundDef.Named("RocketLaunch").PlayOneShot(new TargetInfo(this.Position, this.Map));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,6 +8,7 @@ namespace ArachnaeSwarm
|
|||||||
{
|
{
|
||||||
public class CruiseMissileProperties : DefModExtension
|
public class CruiseMissileProperties : DefModExtension
|
||||||
{
|
{
|
||||||
|
public bool isDummy = false;
|
||||||
public DamageDef customDamageDef;
|
public DamageDef customDamageDef;
|
||||||
public int customDamageAmount = 5;
|
public int customDamageAmount = 5;
|
||||||
public float customExplosionRadius = 1.1f;
|
public float customExplosionRadius = 1.1f;
|
||||||
@@ -38,11 +39,19 @@ namespace ArachnaeSwarm
|
|||||||
private Vector3 Randdd;
|
private Vector3 Randdd;
|
||||||
private Vector3 position2;
|
private Vector3 position2;
|
||||||
public Vector3 ExPos;
|
public Vector3 ExPos;
|
||||||
|
public bool isDummy = false;
|
||||||
|
|
||||||
|
public override void ExposeData()
|
||||||
|
{
|
||||||
|
base.ExposeData();
|
||||||
|
Scribe_Values.Look(ref isDummy, "isDummy", false);
|
||||||
|
}
|
||||||
|
|
||||||
public override void SpawnSetup(Map map, bool respawningAfterLoad)
|
public override void SpawnSetup(Map map, bool respawningAfterLoad)
|
||||||
{
|
{
|
||||||
base.SpawnSetup(map, respawningAfterLoad);
|
base.SpawnSetup(map, respawningAfterLoad);
|
||||||
settings = def.GetModExtension<CruiseMissileProperties>() ?? new CruiseMissileProperties();
|
settings = def.GetModExtension<CruiseMissileProperties>() ?? new CruiseMissileProperties();
|
||||||
|
this.isDummy = settings.isDummy;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RandFactor()
|
private void RandFactor()
|
||||||
@@ -113,6 +122,11 @@ namespace ArachnaeSwarm
|
|||||||
var map = base.Map;
|
var map = base.Map;
|
||||||
base.Impact(hitThing, blockedByShield);
|
base.Impact(hitThing, blockedByShield);
|
||||||
|
|
||||||
|
if (isDummy)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
DoExplosion(
|
DoExplosion(
|
||||||
base.Position,
|
base.Position,
|
||||||
map,
|
map,
|
||||||
|
|||||||
Reference in New Issue
Block a user