protected virtual void Explode() { Map map = base.Map; //this.Destroy(DestroyMode.Vanish); ProjectilePropertiesCE propsCE = def.projectile as ProjectilePropertiesCE; GenExplosion.DoExplosion(ExactPosition.ToIntVec3(), map, this.def.projectile.explosionRadius, this.def.projectile.damageDef, this.launcher, this.def.projectile.soundExplode, this.def, this.equipmentDef, this.def.projectile.postExplosionSpawnThingDef, this.def.projectile.explosionSpawnChance, 1, propsCE != null && propsCE.damageAdjacentTiles, this.def.projectile.preExplosionSpawnThingDef, this.def.projectile.explosionSpawnChance, 1); //This code was disabled because it didn't run under previous circumstances. Could be enabled if necessary /* * if (map != null && base.ExactPosition.ToIntVec3().IsValid) * { * ThrowBigExplode(base.ExactPosition + Gen.RandomHorizontalVector(def.projectile.explosionRadius * 0.5f), base.Map, def.projectile.explosionRadius * 0.4f); * } */ base.Impact(null); // base.Impact() handles this.Destroy() and comp.Explode() }
protected virtual void Explode() { ExplosionCE explosion = GenSpawn.Spawn(CE_ThingDefOf.ExplosionCE, ExactPosition.ToIntVec3(), Map) as ExplosionCE; explosion.height = ExactPosition.y; explosion.radius = def.projectile.explosionRadius; explosion.damType = def.projectile.damageDef; explosion.instigator = launcher; explosion.damAmount = def.projectile.GetDamageAmount(1); explosion.weapon = equipmentDef; explosion.projectile = def; explosion.preExplosionSpawnThingDef = def.projectile.preExplosionSpawnThingDef; explosion.preExplosionSpawnChance = def.projectile.preExplosionSpawnChance; explosion.preExplosionSpawnThingCount = def.projectile.preExplosionSpawnThingCount; explosion.postExplosionSpawnThingDef = def.projectile.postExplosionSpawnThingDef; explosion.postExplosionSpawnChance = def.projectile.postExplosionSpawnChance; explosion.postExplosionSpawnThingCount = def.projectile.postExplosionSpawnThingCount; explosion.applyDamageToExplosionCellsNeighbors = def.projectile.applyDamageToExplosionCellsNeighbors; explosion.chanceToStartFire = def.projectile.explosionChanceToStartFire; explosion.damageFalloff = def.projectile.explosionDamageFalloff; explosion.StartExplosion(def.projectile.soundExplode); explosion.armorPenetration = explosion.damAmount * 0.1f; //This code was disabled because it didn't run under previous circumstances. Could be enabled if necessary /* * if (map != null && base.ExactPosition.ToIntVec3().IsValid) * { * ThrowBigExplode(base.ExactPosition + Gen.RandomHorizontalVector(def.projectile.explosionRadius * 0.5f), base.Map, def.projectile.explosionRadius * 0.4f); * } */ base.Impact(null); // base.Impact() handles this.Destroy() and comp.Explode() }
public override void Tick() { base.Tick(); if (outRange()) { hitThings.Clear(); Destroy(); return; } var ts = Map.thingGrid.ThingsAt(ExactPosition.ToIntVec3()); foreach (var t in ts) { if ((t is not Pawn || t == launcher) && t is not Building) { continue; } if (hitThings.Contains(t)) { continue; } // Log.Warning(this.hitThings+" not contains "+t); aImpact(t); hitThings.Add(t); } }
//Unmodified public override void Tick() { base.Tick(); if (landed) { return; } Vector3 exactPosition = ExactPosition; ticksToImpact--; if (!ExactPosition.InBounds(base.Map)) { ticksToImpact++; Position = ExactPosition.ToIntVec3(); Destroy(DestroyMode.Vanish); return; } Vector3 exactPosition2 = ExactPosition; if (!def.projectile.flyOverhead && canFreeIntercept && CheckForFreeInterceptBetween(exactPosition, exactPosition2)) { return; } Position = ExactPosition.ToIntVec3(); if (ticksToImpact == 60f && Find.TickManager.CurTimeSpeed == TimeSpeed.Normal && def.projectile.soundImpactAnticipate != null) { def.projectile.soundImpactAnticipate.PlayOneShot(this); } if (ticksToImpact <= 0) { if (DestinationCell.InBounds(base.Map)) { Position = DestinationCell; } ImpactSomething(); return; } if (ambientSustainer != null) { ambientSustainer.Maintain(); } // attack shooting expression if (this.launcher is Building_TurretGunCR == false) { if (Rand.Value > 0.7 && this.launcher.def.race.Humanlike && !robotBodyList.Contains(this.launcher.def.race.body.defName) && Gen.IsHashIntervalTick(launcher, Rand.Range(280, 700))) { AGAIN : string rndswear = RulePackDef.Named("AttackMote").Rules.RandomElement().Generate(); if (rndswear == "[swear]" || rndswear == "" || rndswear == " ") { goto AGAIN; } MoteMaker.ThrowText(launcher.Position.ToVector3Shifted(), this.launcher.Map, rndswear); } } }
//Modified collision with downed pawns private void ImpactSomething() { if (BlockerRegistry.ImpactSomethingCallback(this, launcher)) { this.Destroy(); return; } var pos = ExactPosition.ToIntVec3(); //Not modified, just mortar code if (def.projectile.flyOverhead) { var roofDef = Map.roofGrid.RoofAt(pos); if (roofDef != null) { if (roofDef.isThickRoof) { def.projectile.soundHitThickRoof.PlayOneShot(new TargetInfo(pos, Map)); Destroy(); return; } if (pos.GetEdifice(Map) == null || pos.GetEdifice(Map).def.Fillage != FillCategory.Full) { RoofCollapserImmediate.DropRoofInCells(pos, Map); } } } // FIXME : Early opt-out Thing thing = pos.GetFirstPawn(Map); if (thing != null && TryCollideWith(thing)) { return; } var list = Map.thingGrid.ThingsListAt(pos).Where(t => t is Pawn || t.def.Fillage != FillCategory.None).ToList(); if (list.Count > 0) { foreach (var thing2 in list) { if (TryCollideWith(thing2)) { return; } } } ExactPosition = ExactPosition; landed = true; Impact(null); }
//Removed minimum collision distance private bool CheckForCollisionBetween() { var lastPosIV3 = LastPos.ToIntVec3(); var newPosIV3 = ExactPosition.ToIntVec3(); List <Thing> list = base.Map.listerThings.ThingsInGroup(ThingRequestGroup.ProjectileInterceptor); for (int i = 0; i < list.Count; i++) { if (CheckIntercept(list[i], list[i].TryGetComp <CompProjectileInterceptor>())) { this.Destroy(DestroyMode.Vanish); return(true); } } #region Sanity checks if (ticksToImpact == 0 || def.projectile.flyOverhead) { return(false); } if (!lastPosIV3.InBounds(Map) || !newPosIV3.InBounds(Map)) { return(false); } if (Controller.settings.DebugDrawInterceptChecks) { Map.debugDrawer.FlashLine(lastPosIV3, newPosIV3); } #endregion // Iterate through all cells between the last and the new position // INCLUDING[!!!] THE LAST AND NEW POSITIONS! var cells = GenSight.PointsOnLineOfSight(lastPosIV3, newPosIV3).Union(new[] { lastPosIV3, newPosIV3 }).Distinct().OrderBy(x => (x.ToVector3Shifted() - LastPos).MagnitudeHorizontalSquared()); //Order cells by distance from the last position foreach (var cell in cells) { if (CheckCellForCollision(cell)) { return(true); } if (Controller.settings.DebugDrawInterceptChecks) { Map.debugDrawer.FlashCell(cell, 1, "o"); } } return(false); }
protected virtual void Impact(Thing hitThing) { CompExplosiveCE comp = this.TryGetComp <CompExplosiveCE>(); if (comp != null && ExactPosition.ToIntVec3().IsValid) { comp.Explode(launcher, ExactPosition, Find.CurrentMap); } //Spawn things if not an explosive but preExplosionSpawnThingDef != null if (Controller.settings.EnableAmmoSystem && Controller.settings.ReuseNeolithicProjectiles && comp == null && Position.IsValid && def.projectile.preExplosionSpawnChance > 0 && def.projectile.preExplosionSpawnThingDef != null && Rand.Value < def.projectile.preExplosionSpawnChance) { var thingDef = def.projectile.preExplosionSpawnThingDef; if (thingDef.IsFilth && Position.Walkable(this.Map)) { FilthMaker.MakeFilth(Position, Map, thingDef, 1); } else { Thing reusableAmmo = ThingMaker.MakeThing(thingDef, null); reusableAmmo.stackCount = 1; reusableAmmo.SetForbidden(true, false); GenPlace.TryPlaceThing(reusableAmmo, Position, Map, ThingPlaceMode.Near, null); LessonAutoActivator.TeachOpportunity(CE_ConceptDefOf.CE_ReusableNeolithicProjectiles, reusableAmmo, OpportunityType.GoodToKnow); } } // Opt-out for things without explosionRadius if (def.projectile.explosionRadius > 0 && ExactPosition.y < SuppressionRadius) { // Apply suppression around impact area var suppressThings = GenRadial.RadialDistinctThingsAround(ExactPosition.ToIntVec3(), Map, SuppressionRadius + def.projectile.explosionRadius, true); foreach (Thing thing in suppressThings) { Pawn pawn = thing as Pawn; if (pawn != null) { ApplySuppression(pawn); } } } Destroy(); }
public override void Tick() { if (AllComps != null) { int i = 0; int count = AllComps.Count; while (i < count) { AllComps[i].CompTick(); i++; } } if (landed) { return; } Vector3 exactPosition = ExactPosition; ticksToImpact--; if (!ExactPosition.InBounds(Map)) { ticksToImpact++; Position = ExactPosition.ToIntVec3(); Destroy(DestroyMode.Vanish); return; } Vector3 exactPosition2 = ExactPosition; if (CheckForFreeInterceptBetween(exactPosition, exactPosition2)) { return; } Position = ExactPosition.ToIntVec3(); if (ticksToImpact == 60 && Find.TickManager.CurTimeSpeed == TimeSpeed.Normal && this.def.projectile.soundImpactAnticipate != null) { def.projectile.soundImpactAnticipate.PlayOneShot(this); } if (ticksToImpact <= 0) { if (DestinationCell.InBounds(Map)) { Position = DestinationCell; } ImpactSomething(); return; } if (ambientSustainer != null) { ambientSustainer.Maintain(); } }
public override void Tick() { base.Tick(); if (landed) { return; } LastPos = ExactPosition; ticksToImpact--; if (!ExactPosition.InBounds(Map)) { Position = LastPos.ToIntVec3(); Destroy(); return; } if (CheckForCollisionBetween()) { return; } Position = ExactPosition.ToIntVec3(); if (ticksToImpact == 60 && Find.TickManager.CurTimeSpeed == TimeSpeed.Normal && def.projectile.soundImpactAnticipate != null) { def.projectile.soundImpactAnticipate.PlayOneShot(this); } //TODO : It appears that the final steps in the arc (past ticksToImpact == 0) don't CheckForCollisionBetween. if (ticksToImpact <= 0) { ImpactSomething(); return; } if (ambientSustainer != null) { ambientSustainer.Maintain(); } if (def.HasModExtension <TrailerProjectileExtension>()) { var trailer = def.GetModExtension <TrailerProjectileExtension>(); if (trailer != null) { if (ticksToImpact % trailer.trailerMoteInterval == 0) { for (int i = 0; i < trailer.motesThrown; i++) { TrailThrower.ThrowSmoke(DrawPos, trailer.trailMoteSize, Map, trailer.trailMoteDef); } } } } }
// Token: 0x060026E7 RID: 9959 RVA: 0x00127F60 File Offset: 0x00126360 protected override void Impact(Thing hitThing) { var map = Map; base.Impact(hitThing); var battleLogEntry_RangedImpact = new BattleLogEntry_RangedImpact(launcher, hitThing, intendedTarget.Thing, equipmentDef, def, targetCoverDef); Find.BattleLog.Add(battleLogEntry_RangedImpact); if (hitThing != null) { var damageDef = def.projectile.damageDef; float amount = DamageAmount; var armorPenetration = ArmorPenetration; var y = ExactRotation.eulerAngles.y; var instigator = launcher; var thingDef = equipmentDef; var dinfo = new DamageInfo(damageDef, amount, armorPenetration, y, instigator, null, thingDef, DamageInfo.SourceCategory.ThingOrUnknown, intendedTarget.Thing); hitThing.TakeDamage(dinfo).AssociateWithLog(battleLogEntry_RangedImpact); if (hitThing is Pawn { stances : { } } pawn&& pawn.BodySize <= def.projectile.StoppingPower + 0.001f) { pawn.stances.StaggerFor(95); } } //else //{ var fire = (Fire)ThingMaker.MakeThing(ThingDefOf.Fire); fire.fireSize = 0.1f; if (map.thingGrid.ThingAt(ExactPosition.ToIntVec3(), ThingDefOf.Fire) != null) { ((Fire)map.thingGrid.ThingAt(ExactPosition.ToIntVec3(), ThingDefOf.Fire)).fireSize += 0.1f; } else { GenSpawn.Spawn(fire, ExactPosition.ToIntVec3(), map, Rot4.North); } // } }
protected override void Impact(Thing hitThing) { // Snap to target so we hit multi-tile pawns with our explosion if (hitThing is Pawn) { var newPos = hitThing.DrawPos; newPos.y = ExactPosition.y; ExactPosition = newPos; Position = ExactPosition.ToIntVec3(); } if (def.projectile.explosionDelay == 0) { Explode(); return; } landed = true; ticksToDetonation = def.projectile.explosionDelay; GenExplosion.NotifyNearbyPawnsOfDangerousExplosive(this, this.def.projectile.damageDef, this.launcher?.Faction); }
public override void Tick() { base.Tick(); if (landed) { return; } Vector3 exactPosition = ExactPosition; ticksToImpact--; if (!ExactPosition.InBounds(base.Map)) { ticksToImpact++; base.Position = ExactPosition.ToIntVec3(); Destroy(); return; } Vector3 exactPosition2 = ExactPosition; if (CheckForFreeInterceptBetween(exactPosition, exactPosition2)) { return; } base.Position = ExactPosition.ToIntVec3(); if (ticksToImpact == 60 && Find.TickManager.CurTimeSpeed == TimeSpeed.Normal && def.projectile.soundImpactAnticipate != null) { def.projectile.soundImpactAnticipate.PlayOneShot(this); } if (ticksToImpact <= 0) { if (DestinationCell.InBounds(base.Map)) { base.Position = DestinationCell; } ImpactSomething(); } else if (ambientSustainer != null) { ambientSustainer.Maintain(); } }
public override void Tick() { base.Tick(); if (!Spawned) { return; } if (!ExactPosition.InBounds(Map)) { return; } foreach (var th in Map.thingGrid.ThingsAt(ExactPosition.ToIntVec3())) { if (th is Pawn) { aImpact(th); } } }
//Unmodified public override void Tick() { base.Tick(); if (landed) { return; } Vector2 lastExactPosition = Vec2Position; ticksToImpact--; if (!ExactPosition.InBounds(base.Map)) { ticksToImpact++; Position = ExactPosition.ToIntVec3(); Destroy(DestroyMode.Vanish); return; } heightOutdated = true; if (ticksToImpact >= 0 && !def.projectile.flyOverhead && CheckForCollisionBetween(lastExactPosition, Vec2Position)) { return; } Position = ExactPosition.ToIntVec3(); if (ticksToImpact == 60 && Find.TickManager.CurTimeSpeed == TimeSpeed.Normal && def.projectile.soundImpactAnticipate != null) { def.projectile.soundImpactAnticipate.PlayOneShot(this); } if (ticksToImpact <= 0) { ImpactSomething(); return; } if (ambientSustainer != null) { ambientSustainer.Maintain(); } }
public override void Tick() { base.Tick(); if (landed) { return; } LastPos = ExactPosition; ticksToImpact--; if (!ExactPosition.InBounds(base.Map)) { Position = LastPos.ToIntVec3(); Destroy(DestroyMode.Vanish); return; } if (ticksToImpact >= 0 && !def.projectile.flyOverhead && CheckForCollisionBetween()) { return; } Position = ExactPosition.ToIntVec3(); if (ticksToImpact == 60 && Find.TickManager.CurTimeSpeed == TimeSpeed.Normal && def.projectile.soundImpactAnticipate != null) { def.projectile.soundImpactAnticipate.PlayOneShot(this); } //TODO : It appears that the final steps in the arc (past ticksToImpact == 0) don't CheckForCollisionBetween. if (ticksToImpact <= 0) { ImpactSomething(); return; } if (ambientSustainer != null) { ambientSustainer.Maintain(); } }
//Removed minimum collision distance private bool CheckForCollisionBetween() { var lastPosIV3 = LastPos.ToIntVec3(); var newPosIV3 = ExactPosition.ToIntVec3(); #region Sanity checks if (!lastPosIV3.InBounds(base.Map) || !newPosIV3.InBounds(base.Map)) { return(false); } if (DebugViewSettings.drawInterceptChecks) { Map.debugDrawer.FlashLine(lastPosIV3, newPosIV3); } #endregion // Iterate through all cells between the last and the new position // INCLUDING[!!!] THE LAST AND NEW POSITIONS! var cells = GenSight.PointsOnLineOfSight(lastPosIV3, newPosIV3).Union(new [] { lastPosIV3, newPosIV3 }).Distinct().OrderBy(x => (x.ToVector3Shifted() - LastPos).MagnitudeHorizontalSquared()); //Order cells by distance from the last position foreach (IntVec3 cell in cells) { if (CheckCellForCollision(cell)) { return(true); } if (DebugViewSettings.drawInterceptChecks) { Map.debugDrawer.FlashCell(cell, 1, "o"); } } return(false); }
protected virtual void Explode() { Map map = base.Map; //this.Destroy(DestroyMode.Vanish); ProjectilePropertiesCE propsCE = def.projectile as ProjectilePropertiesCE; GenExplosion.DoExplosion(ExactPosition.ToIntVec3(), map, def.projectile.explosionRadius, def.projectile.damageDef, launcher, def.projectile.damageAmountBase, def.projectile.soundExplode, equipmentDef, def, def.projectile.postExplosionSpawnThingDef, def.projectile.postExplosionSpawnChance, def.projectile.postExplosionSpawnThingCount, def.projectile.applyDamageToExplosionCellsNeighbors, def.projectile.preExplosionSpawnThingDef, def.projectile.preExplosionSpawnChance, def.projectile.preExplosionSpawnThingCount, def.projectile.explosionChanceToStartFire, def.projectile.explosionDealMoreDamageAtCenter); //This code was disabled because it didn't run under previous circumstances. Could be enabled if necessary /* * if (map != null && base.ExactPosition.ToIntVec3().IsValid) * { * ThrowBigExplode(base.ExactPosition + Gen.RandomHorizontalVector(def.projectile.explosionRadius * 0.5f), base.Map, def.projectile.explosionRadius * 0.4f); * } */ base.Impact(null); // base.Impact() handles this.Destroy() and comp.Explode() }
public virtual void RayCast(Thing launcher, VerbProperties verbProps, Vector2 origin, float shotAngle, float shotRotation, float shotHeight = 0f, float shotSpeed = -1f, float spreadDegrees = 0f, float aperatureSize = 0.03f, Thing equipment = null) { float magicSpreadFactor = Mathf.Sin(0.06f / 2 * Mathf.Deg2Rad) + aperatureSize; float magicLaserDamageConstant = 1 / (magicSpreadFactor * magicSpreadFactor * 3.14159f); ProjectilePropertiesCE pprops = def.projectile as ProjectilePropertiesCE; shotRotation = Mathf.Deg2Rad * shotRotation + (float)(3.14159 / 2.0f); Vector3 direction = new Vector3(Mathf.Cos(shotRotation) * Mathf.Cos(shotAngle), Mathf.Sin(shotAngle), Mathf.Sin(shotRotation) * Mathf.Cos(shotAngle)); Vector3 origin3 = new Vector3(origin.x, shotHeight, origin.y); Map map = launcher.Map; Vector3 destination = direction * verbProps.range + origin3; this.shotAngle = shotAngle; this.shotHeight = shotHeight; this.shotRotation = shotRotation; this.launcher = launcher; this.origin = origin; equipmentDef = equipment?.def ?? null; Ray ray = new Ray(origin3, direction); var lbce = this as LaserBeamCE; float spreadRadius = Mathf.Sin(spreadDegrees / 2.0f * Mathf.Deg2Rad); LaserGunDef defWeapon = equipmentDef as LaserGunDef; Vector3 muzzle = ray.GetPoint((defWeapon == null ? 0.9f : defWeapon.barrelLength)); var it_bounds = CE_Utility.GetBoundsFor(intendedTarget); for (int i = 1; i < verbProps.range; i++) { float spreadArea = (i * spreadRadius + aperatureSize) * (i * spreadRadius + aperatureSize) * 3.14159f; if (pprops.damageFalloff) { lbce.DamageModifier = 1 / (magicLaserDamageConstant * spreadArea); } Vector3 tp = ray.GetPoint(i); if (tp.y > CollisionVertical.WallCollisionHeight) { break; } if (tp.y < 0) { destination = tp; landed = true; ExactPosition = tp; Position = ExactPosition.ToIntVec3(); break; } foreach (Thing thing in Map.thingGrid.ThingsListAtFast(tp.ToIntVec3())) { if (this == thing) { continue; } var bounds = CE_Utility.GetBoundsFor(thing); if (!bounds.IntersectRay(ray, out var dist)) { continue; } if (i < 2 && thing != intendedTarget) { continue; } if (thing is Plant plant) { if (!Rand.Chance(thing.def.fillPercent * plant.Growth)) { continue; } } else if (thing is Building) { if (!Rand.Chance(thing.def.fillPercent)) { continue; } } ExactPosition = tp; destination = tp; landed = true; LastPos = destination; ExactPosition = destination; Position = ExactPosition.ToIntVec3(); lbce.SpawnBeam(muzzle, destination); lbce.Impact(thing, muzzle); return; } } if (lbce != null) { lbce.SpawnBeam(muzzle, destination); Destroy(DestroyMode.Vanish); return; } }