diff --git a/1.6/1.6/Defs/Thing_Misc/Weapons/ARA_Weapon_new.xml b/1.6/1.6/Defs/Thing_Misc/Weapons/ARA_Weapon_new.xml index ef51cd8..f55ffd8 100644 --- a/1.6/1.6/Defs/Thing_Misc/Weapons/ARA_Weapon_new.xml +++ b/1.6/1.6/Defs/Thing_Misc/Weapons/ARA_Weapon_new.xml @@ -87,4 +87,109 @@ 120 + + + + ARA_RW_Basic_Acid_Spreay_Gun + + 阿拉克涅虫群督虫使用基础远程武装器官,可以通过肌肉的瞬间加压喷出一团包含阿拉克涅酸液的液体团。这种酸液团的飞行速度很慢,但是能在目标地点炸开,并灼烧所有粘上酸液的敌人。 + Normal + Animal + + ARA_Cocoon_Weapon + + + ArachnaeSwarm/Weapon/ARA_RW_Basic_Acid_Bladder_Gun + Graphic_Single + 1.2 + + SpitterSpawn + + + ARA_Technology_7VXI + UnfinishedWeapon + + + 1300 + + 3.5 + 0.5 + 0.6 + 0.45 + 0.3 + 2.5 + + +
  • + ArachnaeSwarm.Verb_ShootSprayMulti + true + false + 1.0 + ARA_Proj_StrongSludgeSpray_Eco + false + false + 3 + 28 + 3 + 12 + SpitterSpit + + true + + 5 +
  • +
    + + 50 + + +
  • ARA_Armed_Organ
  • +
  • ARA_Armed_Organ_Ranged
  • +
  • ARA_Armed_Organ_T1
  • +
    + +
  • RewardStandardQualitySuper
  • +
    + +
  • + +
  • ARA_Weapon_Damage_Acid
  • + + + 1 + 1 + + +
    +
    + + + ARA_Proj_StrongSludgeSpray_Eco + + Projectile_Liquid + Projectile + Normal + Projectile + False + True + + Things/Projectile/SludgeSpray + Graphic_Random + MoteGlow + 0.85 + + + ARA_AcidBurn + 25 + 2 + 0.4 + 0.1 + 1 + 0 + 0.75 + Filth_SpentAcid + 1 + 0.25 + + \ No newline at end of file diff --git a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj index 458f602..b5ad875 100644 --- a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj +++ b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj @@ -202,6 +202,7 @@ + diff --git a/Source/ArachnaeSwarm/Pawn_Comps/ARA_Fighter_Invisible/CompFighterInvisible.cs b/Source/ArachnaeSwarm/Pawn_Comps/ARA_Fighter_Invisible/CompFighterInvisible.cs index fff5d3b..53d511c 100644 --- a/Source/ArachnaeSwarm/Pawn_Comps/ARA_Fighter_Invisible/CompFighterInvisible.cs +++ b/Source/ArachnaeSwarm/Pawn_Comps/ARA_Fighter_Invisible/CompFighterInvisible.cs @@ -16,9 +16,6 @@ namespace ArachnaeSwarm private int lastDetectedTick = -99999; - private static float lastNotified = -99999f; - - private const float NotifyCooldownSeconds = 60f; private Pawn Sightstealer => (Pawn)parent; public HediffDef GetTargetInvisibilityDef() diff --git a/Source/ArachnaeSwarm/Verbs/Verb_ShootSprayMulti.cs b/Source/ArachnaeSwarm/Verbs/Verb_ShootSprayMulti.cs new file mode 100644 index 0000000..32e73ad --- /dev/null +++ b/Source/ArachnaeSwarm/Verbs/Verb_ShootSprayMulti.cs @@ -0,0 +1,134 @@ +using RimWorld; +using System.Collections.Generic; +using UnityEngine; +using Verse; +using Verse.Sound; + +namespace ArachnaeSwarm +{ + public class Verb_ShootSprayMulti : Verb_Shoot + { + public VerbProperties_ShootSprayMulti SprayProps => verbProps as VerbProperties_ShootSprayMulti; + + protected override bool TryCastShot() + { + if (currentTarget.HasThing && currentTarget.Thing.Map != caster.Map) + { + return false; + } + + List cells = AffectedCells(currentTarget); + if (cells.Count == 0) + { + return false; + } + + // A single "shot" from the verb will fire projectiles at all affected cells. + // The base verb's burst fire mechanism will handle firing multiple "shots". + bool shotFired = false; + foreach (var cell in cells) + { + if (CanHitTarget(cell)) + { + ShootLine shootLine; + if (TryFindShootLineFromTo(caster.Position, cell, out shootLine)) + { + Projectile projectile = (Projectile)GenSpawn.Spawn(verbProps.defaultProjectile, shootLine.Source, caster.Map); + // Corrected Launch call without targetCover + projectile.Launch(caster, caster.DrawPos, cell, cell, ProjectileHitFlags.IntendedTarget, equipment: (caster as Pawn)?.equipment?.Primary); + shotFired = true; + } + } + } + + if (shotFired) + { + // Corrected sound calls based on MCP knowledge + if (verbProps.soundCast != null) + { + verbProps.soundCast.PlayOneShot(SoundInfo.InMap(new TargetInfo(caster.Position, caster.Map))); + } + if (verbProps.soundCastTail != null) + { + verbProps.soundCastTail.PlayOneShotOnCamera(); + } + if (caster is Pawn pawn) + { + if (pawn.records != null) + { + pawn.records.Increment(RecordDefOf.ShotsFired); + } + if (pawn.skills != null) + { + pawn.skills.Learn(SkillDefOf.Shooting, 0.5f); + } + } + } + + return shotFired; + } + + // This logic is adapted from CompAbilityEffect_SprayLiquidMulti + private List AffectedCells(LocalTargetInfo target) + { + List> tmpCellDots = new List>(); + List tmpCells = new List(); + + tmpCellDots.Clear(); + tmpCells.Clear(); + tmpCellDots.Add(new Pair(target.Cell, 999f)); + + int numCellsToHit = SprayProps?.numCellsToHit ?? 1; + if (numCellsToHit > 1) + { + Vector3 vector = caster.Position.ToVector3Shifted().Yto0(); + Vector3 vector2 = target.Cell.ToVector3Shifted().Yto0(); + IntVec3[] array; + int num; + if (numCellsToHit < 10) + { + array = GenAdj.AdjacentCells; + num = 8; + } + else + { + array = GenRadial.RadialPattern; + num = numCellsToHit + 5; + } + for (int i = 0; i < num; i++) + { + IntVec3 first = target.Cell + array[i]; + Vector3 vector3 = first.ToVector3Shifted().Yto0(); + float second = Vector3.Dot((vector3 - vector).normalized, (vector3 - vector2).normalized); + tmpCellDots.Add(new Pair(first, second)); + } + tmpCellDots.SortByDescending(x => x.Second); + } + + Map map = caster.Map; + int num2 = Mathf.Min(tmpCellDots.Count, numCellsToHit); + for (int j = 0; j < num2; j++) + { + IntVec3 first2 = tmpCellDots[j].First; + if (!first2.InBounds(map)) continue; + + if (first2.Filled(map)) + { + Building_Door door = first2.GetDoor(map); + if (door == null || !door.Open) continue; + } + + if (TryFindShootLineFromTo(caster.Position, first2, out var _)) + { + tmpCells.Add(first2); + } + } + return tmpCells; + } + } + + public class VerbProperties_ShootSprayMulti : VerbProperties + { + public int numCellsToHit = 1; + } +} \ No newline at end of file