Пример #1
0
 public static void Postfix(WeatherManager __instance, Map map)
 {
     if (map.weatherManager.curWeather.defName == "LotRW_HealingRainWD")
     {
         if (Find.TickManager.TicksGame % 10 == 0)
         {
             Pawn pawn = map.mapPawns.AllPawnsSpawned.RandomElement();
             if (!pawn.Position.Roofed(map))
             {
                 IEnumerable <Hediff_Injury> injuries = pawn.health.hediffSet.GetHediffs <Hediff_Injury>();
                 if (injuries != null && injuries.Count() > 0)
                 {
                     Hediff_Injury injury = injuries.RandomElement();
                     if (injury.CanHealNaturally() && !injury.IsPermanent())
                     {
                         injury.Heal(Rand.Range(.2f, 2f));
                         if (Rand.Chance(.5f))
                         {
                             EffectMaker.MakeEffect(ThingDef.Named("Mote_HealingWaves"), pawn.DrawPos, map, Rand.Range(.4f, .6f), 180, 1f, 0);
                         }
                         else
                         {
                             EffectMaker.MakeEffect(ThingDef.Named("Mote_HealingWaves"), pawn.DrawPos, map, Rand.Range(.4f, .6f), 180, 1f, 0, 180, .1f, .02f, .19f, false);
                         }
                     }
                 }
             }
         }
     }
 }
        public override void Destroy(DestroyMode mode = DestroyMode.Vanish)
        {
            bool flag = this.age <= this.duration;

            if (!flag)
            {
                Building structure = null;
                for (int j = 0; j < this.wallPositions.Count(); j++)
                {
                    structure = this.wallPositions[j].GetFirstBuilding(this.Map);
                    if (structure != null)
                    {
                        structure.Destroy();
                        EffectMaker.MakeEffect(ThingDef.Named("Mote_ThickDust"), this.wallPositions[j].ToVector3Shifted(), this.Map, Rand.Range(.6f, .8f), Rand.Range(0, 360), Rand.Range(.8f, 1.6f), Rand.Range(-20, 20), 0, Rand.Range(.2f, .3f), .05f, Rand.Range(.4f, .6f), false);
                    }
                    structure = null;
                }

                for (int i = 0; i < this.despawnedThingList.Count(); i++)
                {
                    GenSpawn.Spawn(this.despawnedThingList[i], this.despawnedThingList[i].Position, this.Map);
                }
                base.Destroy(mode);
            }
        }
        private void Initialize()
        {
            radius     = (int)def.projectile.explosionRadius;
            inDarkness = GenRadial.RadialCellsAround(Position, radius, false).ToList();
            for (var i = 0; i < inDarkness.Count; i++)
            {
                if (inDarkness[i].IsValid && inDarkness[i].InBounds(Map))
                {
                    var darkness = ThingDef.Named("Mandos_BlackSmoke");
                    GenSpawn.Spawn(darkness, inDarkness[i], Map);
                    //GenExplosion.DoExplosion(inDarkness[i], base.Map, 1, DamageDefOf.Smoke, this.launcher, -1, -1, null, null, null, null, darkness, 1);
                    EffectMaker.MakeEffect(ThingDef.Named("Mote_BlackSmoke"), inDarkness[i].ToVector3Shifted(), Map,
                                           Rand.Range(1f, 2f), Rand.Range(0, 360), Rand.Range(.1f, .2f), Rand.Range(-20, 20),
                                           (float)duration / 240, Rand.Range(.5f, 1.5f), Rand.Range(2f, 3f), true);
                    //EffectMaker.MakeEffect(ThingDef.Named("Mote_BlackSmoke"), this.inDarkness[i].ToVector3Shifted(), base.Map, Rand.Range(1f, 2f), Rand.Range(0, 360), Rand.Range(.1f, .2f), Rand.Range(-20, 20), this.duration / 60, Rand.Range(.5f, 1.5f), Rand.Range(2f, 3f), true);
                    var victim = inDarkness[i].GetFirstPawn(Map);
                    if (victim != null)
                    {
                        HealthUtility.AdjustSeverity(victim, HediffDef.Named("LotRW_DarknessHD"), 1);
                    }
                }
                else
                {
                    inDarkness.Remove(inDarkness[i]);
                }
            }

            initialized = true;
        }
Пример #4
0
        public override void Destroy(DestroyMode mode = DestroyMode.Vanish)
        {
            if (age <= duration)
            {
                return;
            }

            for (var j = 0; j < wallPositions.Count; j++)
            {
                var structure = wallPositions[j].GetFirstBuilding(Map);
                if (structure == null)
                {
                    continue;
                }

                structure.Destroy();
                EffectMaker.MakeEffect(ThingDef.Named("Mote_ThickDust"), wallPositions[j].ToVector3Shifted(),
                                       Map, Rand.Range(.6f, .8f), Rand.Range(0, 360), Rand.Range(.8f, 1.6f), Rand.Range(-20, 20),
                                       0, Rand.Range(.2f, .3f), .05f, Rand.Range(.4f, .6f), false);
            }

            foreach (var newThing in despawnedThingList)
            {
                GenSpawn.Spawn(newThing, newThing.Position, Map);
            }

            base.Destroy(mode);
        }
        protected override void Impact(Thing hitThing)
        {
            base.Impact(hitThing);
            if (!initialized)
            {
                Initialize();
            }

            if (Find.TickManager.TicksGame % hediffFrequency != 0)
            {
                return;
            }

            for (var i = 0; i < inDarkness.Count; i++)
            {
                var victim = inDarkness[i].GetFirstPawn(Map);
                if (victim == null)
                {
                    continue;
                }

                HealthUtility.AdjustSeverity(victim, HediffDef.Named("LotRW_DarknessHD"), 1);
                EffectMaker.MakeEffect(ThingDef.Named("Mote_BodyOutline"), victim.DrawPos, victim.Map, 1f, 0, 0,
                                       0, 0, .05f, .2f, .2f, false);
            }
        }
Пример #6
0
        protected override void Impact(Thing hitThing)
        {
            Map map = base.Map;

            base.Impact(hitThing);
            ThingDef def = this.def;
            IntVec3  impactPos;

            if (!initialized)
            {
                Initialize(map);
            }

            impactPos = cellRect.RandomCell;
            if (this.age > (lastStrike + strikeDelay) && impactPos.Standable(map) && impactPos.InBounds(map))
            {
                this.lastStrike  = this.age;
                this.strikeDelay = Rand.Range(45, 90);
                skyfallers.Add(SkyfallerMaker.SpawnSkyfaller(ThingDef.Named("Skyfaller_RainOfFire"), impactPos, map));
                skyfallers[skyfallers.Count - 1].angle = Rand.Range(-40, 0);
            }
            else if (this.age > (lastStrikeSmall + smallStrikeDelay) && this.age > smallStartDelay)
            {
                this.lastStrikeSmall = this.age;
                skyfallersSmall.Add(SkyfallerMaker.SpawnSkyfaller(ThingDef.Named("Skyfaller_RainOfFire_Small"), impactPos, map));
                skyfallersSmall[skyfallersSmall.Count - 1].angle = Rand.Range(-40, 0);
            }

            for (int i = 0; i < skyfallers.Count(); i++)
            {
                if (skyfallers[i].ticksToImpact == 0)
                {
                    this.expandingTick++;
                    IntVec3 centerCell = skyfallers[i].Position;
                    IntVec3 curCell;
                    IEnumerable <IntVec3> oldExplosionCells = GenRadial.RadialCellsAround(centerCell, expandingTick - 1, true);
                    IEnumerable <IntVec3> newExplosionCells = GenRadial.RadialCellsAround(centerCell, expandingTick, true);
                    IEnumerable <IntVec3> explosionCells    = newExplosionCells.Except(oldExplosionCells);
                    for (int j = 0; j < explosionCells.Count(); j++)
                    {
                        curCell = explosionCells.ToArray <IntVec3>()[j];
                        if (curCell.InBounds(map) && curCell.IsValid)
                        {
                            Vector3 heading   = (curCell - centerCell).ToVector3();
                            float   distance  = heading.magnitude;
                            Vector3 direction = heading / distance;
                            EffectMaker.MakeEffect(WizardryDefOf.Mote_ExpandingFlame, curCell.ToVector3(), this.Map, .8f, (Quaternion.AngleAxis(90, Vector3.up) * direction).ToAngleFlat(), 4f, Rand.Range(100, 200));
                            EffectMaker.MakeEffect(WizardryDefOf.Mote_RecedingFlame, curCell.ToVector3(), this.Map, .7f, (Quaternion.AngleAxis(90, Vector3.up) * direction).ToAngleFlat(), 1f, 0);
                        }
                    }
                    if (expandingTick == 3)
                    {
                        this.expandingTick = 0;
                        skyfallers.Remove(skyfallers[i]);
                    }
                }
            }
        }
        public override void Tick()
        {
            base.Tick();
            Vector3 exactPosition = this.ExactPosition;

            this.ticksToImpact--;
            bool flag = !this.ExactPosition.InBounds(base.Map);

            if (flag)
            {
                this.ticksToImpact++;
                base.Position = this.ExactPosition.ToIntVec3();
                this.Destroy(DestroyMode.Vanish);
            }
            else
            {
                base.Position = this.ExactPosition.ToIntVec3();
                if (Find.TickManager.TicksGame % rotationRate == 0)
                {
                    this.rotation++;
                    if (this.rotation >= 4)
                    {
                        this.rotation = 0;
                    }
                    EffectMaker.MakeEffect(WizardryDefOf.Mote_Sparks, this.DrawPos, this.Map, Rand.Range(.3f, .5f), (this.rotation * 90) + Rand.Range(-45, 45), Rand.Range(2, 3), Rand.Range(100, 200));
                }

                bool flag2 = this.ticksToImpact <= 0;
                if (flag2)
                {
                    bool flag3 = this.DestinationCell.InBounds(base.Map);
                    if (flag3)
                    {
                        base.Position = this.DestinationCell;
                    }

                    if (midPoint)
                    {
                        this.ImpactSomething();
                    }
                    else
                    {
                        this.ChangeDirection();
                        if (!rainStarted)
                        {
                            StartWeatherEffects();
                        }
                    }
                }
            }
        }
        public override void Tick()
        {
            base.Tick();
            var unused = ExactPosition;

            ticksToImpact--;
            if (!ExactPosition.InBounds(Map))
            {
                ticksToImpact++;
                Position = ExactPosition.ToIntVec3();
                Destroy();
            }
            else
            {
                Position = ExactPosition.ToIntVec3();
                if (Find.TickManager.TicksGame % rotationRate == 0)
                {
                    rotation++;
                    if (rotation >= 4)
                    {
                        rotation = 0;
                    }

                    EffectMaker.MakeEffect(WizardryDefOf.Mote_Sparks, DrawPos, Map, Rand.Range(.3f, .5f),
                                           (rotation * 90) + Rand.Range(-45, 45), Rand.Range(2, 3), Rand.Range(100, 200));
                }

                if (ticksToImpact > 0)
                {
                    return;
                }

                if (DestinationCell.InBounds(Map))
                {
                    Position = DestinationCell;
                }

                if (midPoint)
                {
                    ImpactSomething();
                }
                else
                {
                    ChangeDirection();
                    if (!rainStarted)
                    {
                        StartWeatherEffects();
                    }
                }
            }
        }
        public override void Tick()
        {
            base.Tick();
            this.age++;
            Vector3 exactPosition = this.ExactPosition;

            this.ticksToImpact--;
            bool flag = !this.ExactPosition.InBounds(base.Map);

            if (flag)
            {
                this.ticksToImpact++;
                base.Position = this.ExactPosition.ToIntVec3();
                this.Destroy(DestroyMode.Vanish);
            }
            else if (!this.ExactPosition.ToIntVec3().Walkable(base.Map))
            {
                this.impactForce = (this.DestinationCell - this.ExactPosition.ToIntVec3()).LengthHorizontal + (this.speed * .2f);
                this.ImpactSomething();
            }
            else
            {
                base.Position = this.ExactPosition.ToIntVec3();
                if (Find.TickManager.TicksGame % 3 == 0)
                {
                    EffectMaker.MakeEffect(WizardryDefOf.Mote_RecedingFlame, this.ExactPosition, this.Map, .8f, (Quaternion.AngleAxis(90, Vector3.up) * flyingDirection).ToAngleFlat(), 2f, 0);
                    this.rotation++;
                    if (this.rotation >= 4)
                    {
                        this.rotation = 0;
                    }
                }

                if (Find.TickManager.TicksGame % 12 == 0)
                {
                    DoFlyingObjectDamage();
                }

                bool flag2 = this.ticksToImpact <= 0;
                if (flag2)
                {
                    bool flag3 = this.DestinationCell.InBounds(base.Map);
                    if (flag3)
                    {
                        base.Position = this.DestinationCell;
                    }
                    this.ImpactSomething();
                }
            }
        }
        public override void Tick()
        {
            base.Tick();
            age++;
            var unused = ExactPosition;

            ticksToImpact--;
            if (!ExactPosition.InBounds(Map))
            {
                ticksToImpact++;
                Position = ExactPosition.ToIntVec3();
                Destroy();
            }
            else if (!ExactPosition.ToIntVec3().Walkable(Map))
            {
                impactForce = (DestinationCell - ExactPosition.ToIntVec3()).LengthHorizontal + (speed * .2f);
                ImpactSomething();
            }
            else
            {
                Position = ExactPosition.ToIntVec3();
                if (Find.TickManager.TicksGame % 3 == 0)
                {
                    EffectMaker.MakeEffect(WizardryDefOf.Mote_RecedingFlame, ExactPosition, Map, .8f,
                                           (Quaternion.AngleAxis(90, Vector3.up) * flyingDirection).ToAngleFlat(), 2f, 0);
                    rotation++;
                    if (rotation >= 4)
                    {
                        rotation = 0;
                    }
                }

                if (Find.TickManager.TicksGame % 12 == 0)
                {
                    DoFlyingObjectDamage();
                }

                if (ticksToImpact > 0)
                {
                    return;
                }

                if (DestinationCell.InBounds(Map))
                {
                    Position = DestinationCell;
                }

                ImpactSomething();
            }
        }
        protected override bool TryCastShot()
        {
            if (currentTarget.Thing is Pawn targetPawn)
            {
                HealthUtility.AdjustSeverity(targetPawn, HediffDef.Named("LotRW_DoomHD"), 1f);
                for (var i = 0; i < 4; i++)
                {
                    EffectMaker.MakeEffect(ThingDef.Named("Mote_BlackSmoke"), targetPawn.DrawPos, targetPawn.Map,
                                           Rand.Range(.4f, .6f), Rand.Range(0, 360), Rand.Range(2, 3), Rand.Range(-200, 200), .15f, 0f,
                                           Rand.Range(.2f, .3f), true);
                }
            }

            base.PostCastShot(true, out var didShoot);
            return(didShoot);
        }
        public void DestroyProjectiles()
        {
            List <Thing> cellList = this.Position.GetThingList(this.Map);

            for (int i = 0; i < cellList.Count; i++)
            {
                if (cellList[i] is Projectile && cellList[i].def.defName != "LotRW_Projectile_AirWall")
                {
                    Vector3 displayEffect = this.DrawPos;
                    displayEffect.x += Rand.Range(-.3f, .3f);
                    displayEffect.y += Rand.Range(-.3f, .3f);
                    displayEffect.z += Rand.Range(-.3f, .3f);
                    EffectMaker.MakeEffect(ThingDef.Named("Mote_LightningGlow"), displayEffect, this.Map, cellList[i].def.projectile.GetDamageAmount(1, null) / 8f);
                    cellList[i].Destroy(DestroyMode.Vanish);
                }
            }
        }
        protected override void Impact(Thing hitThing)
        {
            base.Impact(hitThing);
            if (!initialized)
            {
                Initialize();
            }

            var unused = def;
            var map    = caster.Map;

            expandingTick++;
            var centerCell        = Position;
            var oldExplosionCells = GenRadial.RadialCellsAround(centerCell, expandingTick - 1, true);
            var newExplosionCells = GenRadial.RadialCellsAround(centerCell, expandingTick, true);
            var explosionCells    = newExplosionCells.Except(oldExplosionCells);

            for (var i = 0; i < explosionCells.Count(); i++)
            {
                var curCell = explosionCells.ToArray()[i];
                if (!curCell.InBounds(map) || !curCell.IsValid)
                {
                    continue;
                }

                var heading   = (curCell - centerCell).ToVector3();
                var distance  = heading.magnitude;
                var direction = heading / distance;
                EffectMaker.MakeEffect(WizardryDefOf.Mote_ExpandingFlame, curCell.ToVector3(), map, .8f,
                                       (Quaternion.AngleAxis(90, Vector3.up) * direction).ToAngleFlat(), 4f, Rand.Range(100, 200));
                EffectMaker.MakeEffect(WizardryDefOf.Mote_RecedingFlame, curCell.ToVector3(), map, .7f,
                                       (Quaternion.AngleAxis(90, Vector3.up) * direction).ToAngleFlat(), 1f, 0);
                var hitList = curCell.GetThingList(map);
                foreach (var burnThing in hitList)
                {
                    DamageEntities(burnThing);
                }

                //GenExplosion.DoExplosion(this.currentPos.ToIntVec3(), this.Map, .4f, DamageDefOf.Flame, this.launcher, 10, SoundDefOf.ArtilleryShellLoaded, def, this.equipmentDef, null, 0f, 1, false, null, 0f, 1, 0f, false);
                if (Rand.Chance(fireStartChance))
                {
                    FireUtility.TryStartFireIn(curCell, map, Rand.Range(.1f, .35f));
                }
            }
        }
Пример #14
0
        protected override bool TryCastShot()
        {
            bool flag = true;

            if (this.currentTarget.Thing != null)
            {
                Pawn targetPawn = this.currentTarget.Thing as Pawn;
                if (targetPawn != null)
                {
                    HealthUtility.AdjustSeverity(targetPawn, HediffDef.Named("LotRW_DoomHD"), 1f);
                    for (int i = 0; i < 4; i++)
                    {
                        EffectMaker.MakeEffect(ThingDef.Named("Mote_BlackSmoke"), targetPawn.DrawPos, targetPawn.Map, Rand.Range(.4f, .6f), Rand.Range(0, 360), Rand.Range(2, 3), Rand.Range(-200, 200), .15f, 0f, Rand.Range(.2f, .3f), true);
                    }
                }
            }
            base.PostCastShot(flag, out flag);
            return(flag);
        }
        protected override void Impact(Thing hitThing)
        {
            base.Impact(hitThing);
            if (!initialized)
            {
                Initialize();
            }
            ThingDef def = this.def;
            Map      map = caster.Map;

            this.expandingTick++;
            IntVec3 centerCell = base.Position;
            IntVec3 curCell;
            IEnumerable <IntVec3> oldExplosionCells = GenRadial.RadialCellsAround(centerCell, expandingTick - 1, true);
            IEnumerable <IntVec3> newExplosionCells = GenRadial.RadialCellsAround(centerCell, expandingTick, true);
            IEnumerable <IntVec3> explosionCells    = newExplosionCells.Except(oldExplosionCells);

            for (int i = 0; i < explosionCells.Count(); i++)
            {
                curCell = explosionCells.ToArray <IntVec3>()[i];
                if (curCell.InBounds(map) && curCell.IsValid)
                {
                    Vector3 heading   = (curCell - centerCell).ToVector3();
                    float   distance  = heading.magnitude;
                    Vector3 direction = heading / distance;
                    EffectMaker.MakeEffect(WizardryDefOf.Mote_ExpandingFlame, curCell.ToVector3(), map, .8f, (Quaternion.AngleAxis(90, Vector3.up) * direction).ToAngleFlat(), 4f, Rand.Range(100, 200));
                    EffectMaker.MakeEffect(WizardryDefOf.Mote_RecedingFlame, curCell.ToVector3(), map, .7f, (Quaternion.AngleAxis(90, Vector3.up) * direction).ToAngleFlat(), 1f, 0);
                    List <Thing> hitList   = curCell.GetThingList(map);
                    Thing        burnThing = null;
                    for (int j = 0; j < hitList.Count; j++)
                    {
                        burnThing = hitList[j];
                        DamageEntities(burnThing);
                    }
                    //GenExplosion.DoExplosion(this.currentPos.ToIntVec3(), this.Map, .4f, DamageDefOf.Flame, this.launcher, 10, SoundDefOf.ArtilleryShellLoaded, def, this.equipmentDef, null, 0f, 1, false, null, 0f, 1, 0f, false);
                    if (Rand.Chance(this.fireStartChance))
                    {
                        FireUtility.TryStartFireIn(curCell, map, Rand.Range(.1f, .35f));
                    }
                }
            }
        }
Пример #16
0
 private void DrawEffects(Vector3 effectVec)
 {
     effectVec.x += Rand.Range(-0.4f, 0.4f);
     effectVec.z += Rand.Range(-0.4f, 0.4f);
     if (isCircling)
     {
         if (this.shiftRight)
         {
             EffectMaker.MakeEffect(this.moteDef, effectVec, this.Map, Rand.Range(.2f, .3f), this.ExactRotationAngle + 90, Rand.Range(1, 1.5f), Rand.Range(-200, 200), .1f, 0f, Rand.Range(.2f, .25f), false);
         }
         else
         {
             EffectMaker.MakeEffect(this.moteDef, effectVec, this.Map, Rand.Range(.2f, .3f), this.ExactRotationAngle - 90, Rand.Range(1, 1.5f), Rand.Range(-200, 200), .1f, 0f, Rand.Range(.2f, .25f), false);
         }
     }
     else
     {
         EffectMaker.MakeEffect(this.moteDef, effectVec, this.Map, Rand.Range(.1f, .2f), this.ExactRotationAngle, Rand.Range(10, 15), Rand.Range(-100, 100), .15f, 0f, Rand.Range(.2f, .3f), false);
     }
 }
Пример #17
0
        public void DestroyProjectiles()
        {
            var cellList = Position.GetThingList(Map);

            foreach (var thing in cellList)
            {
                if (thing is not Projectile || thing.def.defName == "LotRW_Projectile_AirWall")
                {
                    continue;
                }

                var displayEffect = DrawPos;
                displayEffect.x += Rand.Range(-.3f, .3f);
                displayEffect.y += Rand.Range(-.3f, .3f);
                displayEffect.z += Rand.Range(-.3f, .3f);
                EffectMaker.MakeEffect(ThingDef.Named("Mote_LightningGlow"), displayEffect, Map,
                                       thing.def.projectile.GetDamageAmount(1) / 8f);
                thing.Destroy();
            }
        }
Пример #18
0
        public static void MakeRadialEffects(float radius, ThingDef mote, Vector3 loc, Map map, float scale, float directionAngle, float velocity, float rotationRate, float lookAngle, float solidTime, float fadeIn, float fadeOut, bool colorShift)
        {
            int num = GenRadial.NumCellsInRadius(radius);

            for (int i = 0; i < num; i++)
            {
                IntVec3 intVec = loc.ToIntVec3() + GenRadial.RadialPattern[i];
                if (intVec.IsValid && intVec.InBounds(map))
                {
                    //-1 denotes "outward" from center
                    if (directionAngle == -1)
                    {
                        directionAngle = (Quaternion.AngleAxis(90, Vector3.up) * GetVector(loc.ToIntVec3(), intVec)).ToAngleFlat();
                    }
                    if (lookAngle == -1)
                    {
                        lookAngle = (Quaternion.AngleAxis(90, Vector3.up) * GetVector(loc.ToIntVec3(), intVec)).ToAngleFlat();
                    }
                    EffectMaker.MakeEffect(mote, intVec.ToVector3Shifted(), map, scale, directionAngle, velocity, rotationRate, lookAngle, solidTime, fadeIn, fadeOut, false);
                }
            }
        }
Пример #19
0
        protected override void Impact(Thing hitThing)
        {
            base.Impact(hitThing);
            if (!initialized)
            {
                Initialize();
            }

            if (Find.TickManager.TicksGame % this.hediffFrequency == 0)
            {
                for (int i = 0; i < this.inDarkness.Count(); i++)
                {
                    Pawn victim = null;
                    victim = this.inDarkness[i].GetFirstPawn(base.Map);
                    if (victim != null)
                    {
                        HealthUtility.AdjustSeverity(victim, HediffDef.Named("LotRW_DarknessHD"), 1);
                        EffectMaker.MakeEffect(ThingDef.Named("Mote_BodyOutline"), victim.DrawPos, victim.Map, 1f, 0, 0, 0, 0, .05f, .2f, .2f, false);
                    }
                }
            }
        }
Пример #20
0
        protected override void Impact(Thing hitThing)
        {
            base.Impact(hitThing);

            var unused = def;

            if (!initialized)
            {
                pawn        = launcher as Pawn;
                radius      = def.projectile.explosionRadius;
                initialized = true;
                if (pawn != null)
                {
                    direction = GetVector(pawn.Position, Position);
                }

                realPosition = Position.ToVector3();
                targets      = GenRadial.RadialCellsAround(Position, strikeNum, false);
                cellList     = targets.ToList();
                CreateSustainer();
            }

            if (sustainer == null)
            {
                Log.Error("Vortex sustainer is null.");
                CreateSustainer();
            }

            sustainer.Maintain();
            UpdateSustainerVolume();

            realPosition += direction * .1f;
            if (Map == null)
            {
                return;
            }

            if (!realPosition.ToIntVec3().Walkable(Map))
            {
                age = duration;
            }

            FleckMaker.ThrowTornadoDustPuff(realPosition, Map, Rand.Range(.6f, .9f), Color.white);
            //EffectMaker.MakeEffect(FleckDefOf.TornadoDustPuff, realPosition, Map, Rand.Range(.6f, .9f), Rand.Range(0, 360), Rand.Range(4f, 5f), Rand.Range(100, 200));
            IntVec3 curCell;
            Vector3 moteVector;

            for (var i = 0; i < 5; i++)
            {
                curCell = cellList.RandomElement();
                if (!curCell.IsValid || !curCell.InBounds(Map))
                {
                    continue;
                }

                moteVector = GetVector(realPosition.ToIntVec3(), curCell);
                EffectMaker.MakeEffect(ThingDef.Named("Mote_Tornado"), curCell.ToVector3(), Map,
                                       Rand.Range(.4f, .8f),
                                       (Quaternion.AngleAxis(Rand.Range(-35, -55), Vector3.up) * moteVector).ToAngleFlat(),
                                       Rand.Range(1f, 3f), Rand.Range(-200, -500),
                                       (Quaternion.AngleAxis(Rand.Range(-35, -55), Vector3.up) * moteVector).ToAngleFlat(),
                                       Rand.Range(.2f, .3f), .1f, Rand.Range(.05f, .2f), true);
            }

            if (Find.TickManager.TicksGame % 50 == 0)
            {
                direction.x = Rand.Range(-.6f, .6f);
                direction.z = Rand.Range(-.6f, .6f);
            }

            if (Find.TickManager.TicksGame % strikeDelay == 0)
            {
                foreach (var intVec3 in cellList)
                {
                    curCell = intVec3;
                    if (!curCell.IsValid || !curCell.InBounds(Map))
                    {
                        continue;
                    }

                    fireVortexValue += CalculateFireAmountInArea(curCell, .4f);
                    var force   = (10f / (curCell.ToVector3() - realPosition).magnitude) + 10f;
                    var hitList = curCell.GetThingList(Map);
                    for (var index = 0; index < hitList.Count; index++)
                    {
                        var dmgThing          = hitList[index];
                        var launchVector      = GetVector(dmgThing.Position, realPosition.ToIntVec3());
                        var projectedPosition = dmgThing.Position + (force * launchVector).ToIntVec3();
                        if (dmgThing is Pawn victim)
                        {
                            if (!projectedPosition.IsValid || !projectedPosition.InBounds(Map) || victim.Dead)
                            {
                                continue;
                            }

                            if (fireVortexValue > 0)
                            {
                                DamageEntities(victim,
                                               Mathf.RoundToInt(def.projectile.GetDamageAmount(1) * force),
                                               DamageDefOf.Flame);
                                fireVortexValue -= .2f;
                            }

                            LaunchFlyingObect(projectedPosition, victim);
                        }
                        else if (dmgThing is Building)
                        {
                            if (!(fireVortexValue > 0))
                            {
                                continue;
                            }

                            DamageEntities(dmgThing,
                                           Mathf.RoundToInt(def.projectile.GetDamageAmount(1) * force * 2),
                                           DamageDefOf.Flame);
                            fireVortexValue -= .2f;
                        }
                        else if (dmgThing.def.EverHaulable && !(dmgThing is Corpse))
                        {
                            if (projectedPosition.IsValid && projectedPosition.InBounds(Map))
                            {
                                LaunchFlyingObect(projectedPosition, dmgThing);
                            }
                        }
                    }
                }

                targets  = GenRadial.RadialCellsAround(realPosition.ToIntVec3(), strikeNum, true);
                cellList = targets.ToList();
            }

            if (!(fireVortexValue > 0))
            {
                return;
            }

            if (Find.TickManager.TicksGame % fireDelay != 0)
            {
                return;
            }

            curCell    = cellList.RandomElement();
            moteVector = GetVector(realPosition.ToIntVec3(), curCell);
            EffectMaker.MakeEffect(ThingDef.Named("Mote_MicroSparks"),
                                   cellList.RandomElement().ToVector3Shifted(), Map, Rand.Range(.5f, 1f),
                                   (Quaternion.AngleAxis(Rand.Range(-35, -50), Vector3.up) * moteVector).ToAngleFlat(),
                                   Rand.Range(2, 3), Rand.Range(50, 200));
            EffectMaker.MakeEffect(ThingDef.Named("Mote_MicroSparks"),
                                   cellList.RandomElement().ToVector3Shifted(), Map, Rand.Range(.5f, 1f),
                                   (Quaternion.AngleAxis(Rand.Range(35, 50), Vector3.up) * moteVector).ToAngleFlat(),
                                   Rand.Range(1, 2), Rand.Range(50, 200));
            DoFireVortex();
        }
Пример #21
0
        protected override void Impact(Thing hitThing)
        {
            var map = Map;

            base.Impact(hitThing);
            var unused = def;

            if (!initialized)
            {
                Initialize(map);
            }

            var impactPos = cellRect.RandomCell;

            if (age > lastStrike + strikeDelay && impactPos.Standable(map) && impactPos.InBounds(map))
            {
                lastStrike  = age;
                strikeDelay = Rand.Range(45, 90);
                skyfallers.Add(SkyfallerMaker.SpawnSkyfaller(ThingDef.Named("Skyfaller_RainOfFire"), impactPos, map));
                skyfallers[skyfallers.Count - 1].angle = Rand.Range(-40, 0);
            }
            else if (age > lastStrikeSmall + smallStrikeDelay && age > smallStartDelay)
            {
                lastStrikeSmall = age;
                skyfallersSmall.Add(SkyfallerMaker.SpawnSkyfaller(ThingDef.Named("Skyfaller_RainOfFire_Small"),
                                                                  impactPos, map));
                skyfallersSmall[skyfallersSmall.Count - 1].angle = Rand.Range(-40, 0);
            }

            for (var i = 0; i < skyfallers.Count; i++)
            {
                if (skyfallers[i].ticksToImpact != 0)
                {
                    continue;
                }

                expandingTick++;
                var centerCell        = skyfallers[i].Position;
                var oldExplosionCells = GenRadial.RadialCellsAround(centerCell, expandingTick - 1, true);
                var newExplosionCells = GenRadial.RadialCellsAround(centerCell, expandingTick, true);
                var explosionCells    = newExplosionCells.Except(oldExplosionCells);
                for (var j = 0; j < explosionCells.Count(); j++)
                {
                    var curCell = explosionCells.ToArray()[j];
                    if (!curCell.InBounds(map) || !curCell.IsValid)
                    {
                        continue;
                    }

                    var heading   = (curCell - centerCell).ToVector3();
                    var distance  = heading.magnitude;
                    var direction = heading / distance;
                    EffectMaker.MakeEffect(WizardryDefOf.Mote_ExpandingFlame, curCell.ToVector3(), Map, .8f,
                                           (Quaternion.AngleAxis(90, Vector3.up) * direction).ToAngleFlat(), 4f,
                                           Rand.Range(100, 200));
                    EffectMaker.MakeEffect(WizardryDefOf.Mote_RecedingFlame, curCell.ToVector3(), Map, .7f,
                                           (Quaternion.AngleAxis(90, Vector3.up) * direction).ToAngleFlat(), 1f, 0);
                }

                if (expandingTick != 3)
                {
                    continue;
                }

                expandingTick = 0;
                skyfallers.Remove(skyfallers[i]);
            }
        }
        protected override void Impact(Thing hitThing)
        {
            Map map = base.Map;

            base.Impact(hitThing);
            ThingDef def = this.def;

            if (!this.initialized)
            {
                caster = this.launcher as Pawn;
                GetSecondTarget();
                //todo: determine thingdef based on ground type, not random
                float rnd = Rand.Range(0f, 3f);
                if (rnd < 1)
                {
                    spawnDef = ThingDef.Named("Sandstone");
                }
                else if (rnd < 2)
                {
                    spawnDef = ThingDef.Named("Granite");
                }
                else if (rnd < 3)
                {
                    spawnDef = ThingDef.Named("Slate");
                }
                else if (rnd < 4)
                {
                    spawnDef = ThingDef.Named("Limestone");
                }
                else
                {
                    spawnDef = ThingDef.Named("Marble");
                }
                this.initialized = true;
            }

            CompWizardry comp = caster.GetComp <CompWizardry>();

            if (!this.wallActive && comp.SecondTarget != null)
            {
                this.age          = 0;
                this.duration     = 2400;
                this.wallActive   = true;
                this.wallPos      = base.Position.ToVector3Shifted();
                this.wallDir      = GetVector(base.Position.ToVector3Shifted(), comp.SecondTarget.Cell.ToVector3Shifted());
                this.wallEnd      = comp.SecondTarget.Cell;
                comp.SecondTarget = null;
            }

            if (!wallActive)
            {
                if (Find.TickManager.TicksGame % 6 == 0)
                {
                    EffectMaker.MakeEffect(ThingDef.Named("Mote_ThickDust"), base.Position.ToVector3Shifted(), this.Map, Rand.Range(.4f, .6f), Rand.Range(0, 360), Rand.Range(.8f, 1.6f), Rand.Range(-20, 20), 0, Rand.Range(.2f, .3f), .05f, Rand.Range(.4f, .6f), false);
                }
            }
            else
            {
                if (wallLength < wallLengthMax)
                {
                    float magnitude = (base.Position.ToVector3Shifted() - Find.Camera.transform.position).magnitude;
                    Find.CameraDriver.shaker.DoShake(10 / magnitude);
                    for (int k = 0; k < wallLengthMax; k++)
                    {
                        List <Thing> cellList = this.wallPos.ToIntVec3().GetThingList(caster.Map);
                        bool         hasWall  = false;
                        for (int i = 0; i < cellList.Count(); i++)
                        {
                            if (cellList[i].def.designationCategory == DesignationCategoryDefOf.Structure)
                            {
                                hasWall = true;
                            }
                        }

                        if (!hasWall)
                        {
                            bool spawnWall = true;
                            for (int i = 0; i < cellList.Count(); i++)
                            {
                                if (!cellList[i].def.EverHaulable && !(cellList[i] is Pawn))
                                {
                                    if (cellList[i].def.altitudeLayer == AltitudeLayer.Building || cellList[i].def.altitudeLayer == AltitudeLayer.Item || cellList[i].def.altitudeLayer == AltitudeLayer.ItemImportant)
                                    {
                                        //Log.Message("bypassing object and setting wall spawn to false");
                                        spawnWall = false;
                                    }
                                    else
                                    {
                                        if (cellList[i].def.defName.Contains("Mote") || (cellList[i].def.defName == "LotRW_Projectile_RockWall"))
                                        {
                                            //Log.Message("avoided storing " + cellList[i].def.defName);
                                        }
                                        else
                                        {
                                            this.despawnedThingList.Add(cellList[i]);
                                            cellList[i].DeSpawn();
                                        }
                                    }
                                }
                                else
                                {
                                    int launchDir = -90;
                                    if (Rand.Chance(.5f))
                                    {
                                        launchDir = 90;
                                    }
                                    LaunchFlyingObect(cellList[i].Position + (Quaternion.AngleAxis(launchDir, Vector3.up) * wallDir).ToIntVec3(), cellList[i]);
                                }
                            }
                            if (spawnWall && Rand.Chance(this.wallSpawnChance))
                            {
                                AbilityUser.SpawnThings tempSpawn = new SpawnThings()
                                {
                                    def        = spawnDef,
                                    spawnCount = 1
                                };
                                SingleSpawnLoop(tempSpawn, wallPos.ToIntVec3(), caster.Map);
                                this.wallLength++;
                                this.wallPositions.Add(wallPos.ToIntVec3());
                                EffectMaker.MakeEffect(ThingDef.Named("Mote_ThickDust"), this.wallPos, this.Map, Rand.Range(.6f, .8f), Rand.Range(0, 360), Rand.Range(1f, 2f), Rand.Range(-20, 20), 0, Rand.Range(.2f, .3f), .05f, Rand.Range(.4f, .6f), false);
                            }
                        }

                        this.wallPos += this.wallDir;
                        EffectMaker.MakeEffect(ThingDef.Named("Mote_ThickDust"), this.wallPos, this.Map, Rand.Range(.6f, 1f), Rand.Range(0, 360), Rand.Range(.6f, 1f), Rand.Range(-20, 20), 0, Rand.Range(.4f, .6f), Rand.Range(.05f, .3f), Rand.Range(.4f, 1f), false);

                        if (this.wallPos.ToIntVec3() == this.wallEnd)
                        {
                            this.wallPos   -= this.wallDir;
                            this.wallLength = this.wallLengthMax;
                        }
                    }
                }
            }
        }
Пример #23
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            var commandStorm = new Toil
            {
                initAction = delegate
                {
                    if (age > duration)
                    {
                        EndJobWith(JobCondition.Succeeded);
                    }

                    var map = pawn.Map;
                    if (!(map.weatherManager.curWeather.defName == "Rain" ||
                          map.weatherManager.curWeather.defName == "RainyThunderstorm" ||
                          map.weatherManager.curWeather.defName == "FoggyRain" ||
                          map.weatherManager.curWeather.defName == "SnowHard" ||
                          map.weatherManager.curWeather.defName == "SnowGentle" ||
                          map.weatherManager.curWeather.defName == "DryThunderstorm"))
                    {
                        EndJobWith(JobCondition.Succeeded);
                    }

                    GetTargetList();
                    if (targetList.Count < 1)
                    {
                        EndJobWith(JobCondition.Succeeded);
                    }
                },
                tickAction = delegate
                {
                    if (age > lastStrike + ticksTillNextStrike)
                    {
                        DoWeatherEffect();
                        ticksTillNextStrike = Rand.Range(20, 200);
                        lastStrike          = age;
                    }

                    if (Find.TickManager.TicksGame % 4 == 0)
                    {
                        float direction = Rand.Range(0, 360);
                        EffectMaker.MakeEffect(WizardryDefOf.Mote_CastingBeam, pawn.DrawPos, pawn.Map,
                                               Rand.Range(.1f, .4f),
                                               direction, Rand.Range(8, 10), 0, direction, 0.2f, .02f, .1f, false);
                    }

                    age++;
                    ticksLeftThisToil = duration - age;
                    if (age > duration)
                    {
                        EndJobWith(JobCondition.Succeeded);
                    }

                    if (Map.weatherManager.curWeather.defName == "Clear")
                    {
                        EndJobWith(JobCondition.Succeeded);
                    }
                },
                defaultCompleteMode = ToilCompleteMode.Delay,
                defaultDuration     = duration
            };

            commandStorm.WithProgressBar(TargetIndex.A, delegate
            {
                if (pawn.DestroyedOrNull() || pawn.Dead || pawn.Downed)
                {
                    return(1f);
                }

                return(1f - ((float)commandStorm.actor.jobs.curDriver.ticksLeftThisToil / duration));
            }, false, 0f);
            commandStorm.AddFinishAction(delegate
            {
                //Log.Message("ending storm calling");
                //do soemthing?
            });
            yield return(commandStorm);
        }
        public static bool Projectile_Launch_Prefix(Projectile __instance, Thing launcher, Vector3 origin,
                                                    ref LocalTargetInfo usedTarget, ref LocalTargetInfo intendedTarget)
        {
            if (launcher is not Pawn launcherPawn)
            {
                return(true);
            }

            if (!launcherPawn.health.hediffSet.HasHediff(HediffDef.Named("LotRW_DoomHD")))
            {
                return(true);
            }

            if (launcherPawn.equipment.PrimaryEq == null || !launcherPawn.equipment.Primary.def.IsRangedWeapon)
            {
                return(true);
            }

            var maxRange    = launcherPawn.equipment.Primary.def.Verbs.FirstOrDefault().range;
            var doomTargets = new List <Pawn>();
            var mapPawns    = launcherPawn.Map.mapPawns.AllPawnsSpawned;

            doomTargets.Clear();
            foreach (var pawn in mapPawns)
            {
                if (pawn.Faction == launcherPawn.Faction &&
                    (pawn.Position - launcherPawn.Position).LengthHorizontal < maxRange)
                {
                    doomTargets.Add(pawn);
                }
            }

            if (doomTargets.Count <= 0)
            {
                return(true);
            }

            LocalTargetInfo doomTarget = doomTargets.RandomElement();

            if (doomTarget == launcherPawn)
            {
                doomTarget = usedTarget;
            }
            else
            {
                if (Rand.Chance(.5f))
                {
                    HealthUtility.AdjustSeverity(doomTarget.Thing as Pawn,
                                                 HediffDef.Named("LotRW_DoomHD"), 1f);
                    for (var i = 0; i < 4; i++)
                    {
                        EffectMaker.MakeEffect(ThingDef.Named("Mote_BlackSmoke"),
                                               doomTarget.Thing.DrawPos, doomTarget.Thing.Map, Rand.Range(.4f, .6f),
                                               Rand.Range(0, 360), Rand.Range(.2f, .4f), Rand.Range(-200, 200), .15f, 2f,
                                               Rand.Range(.2f, .3f), true);
                    }
                }
            }

            var      drawPos = launcherPawn.DrawPos;
            ThingDef moteDef;

            if (doomTarget.Cell.x < launcherPawn.Position.x)
            {
                drawPos.x += .6f;
                moteDef    = ThingDef.Named("Mote_ReaperWest");
            }
            else
            {
                drawPos.x -= .6f;
                moteDef    = ThingDef.Named("Mote_ReaperEast");
            }

            drawPos.z     += .5f;
            usedTarget     = doomTarget;
            intendedTarget = doomTarget;
            EffectMaker.MakeEffect(moteDef, drawPos, launcherPawn.Map, .8f, 0, 0, 0, .2f, .1f, .4f,
                                   false);

            return(true);
        }
Пример #25
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            Pawn patient     = TargetA.Thing as Pawn;
            Toil gotoPatient = new Toil()
            {
                initAction = () =>
                {
                    pawn.pather.StartPath(TargetA, PathEndMode.Touch);
                },
                defaultCompleteMode = ToilCompleteMode.PatherArrival
            };

            yield return(gotoPatient);

            Toil doHealing = new Toil();

            doHealing.initAction = delegate
            {
                if (age > duration)
                {
                    this.EndJobWith(JobCondition.Succeeded);
                }
                if (patient.DestroyedOrNull() || patient.Dead)
                {
                    this.EndJobWith(JobCondition.Incompletable);
                }
            };
            doHealing.tickAction = delegate
            {
                if (patient.DestroyedOrNull() || patient.Dead)
                {
                    this.EndJobWith(JobCondition.Incompletable);
                }
                if (Find.TickManager.TicksGame % 1 == 0)
                {
                    EffectMaker.MakeEffect(ThingDef.Named("Mote_HealingMote"), this.pawn.DrawPos, this.Map, Rand.Range(.3f, .5f), (Quaternion.AngleAxis(90, Vector3.up) * GetVector(this.pawn.Position, patient.Position)).ToAngleFlat() + Rand.Range(-10, 10), 5f, 0);
                }
                if (age > (lastHeal + ticksTillNextHeal))
                {
                    DoHealingEffect(patient);
                    EffectMaker.MakeEffect(ThingDef.Named("Mote_HealingCircles"), patient.DrawPos, this.Map, Rand.Range(.3f, .4f), 0, 0, Rand.Range(400, 500), Rand.Range(0, 360), .08f, .01f, .24f, false);
                    lastHeal = age;
                    if (this.injuryCount == 0)
                    {
                        this.EndJobWith(JobCondition.Succeeded);
                    }
                }
                if (!patient.Drafted && patient.CurJobDef != JobDefOf.Wait)
                {
                    if (patient.jobs.posture == PawnPosture.Standing)
                    {
                        Job job = new Job(JobDefOf.Wait, patient);
                        patient.jobs.TryTakeOrderedJob(job, JobTag.Misc);
                    }
                }
                age++;
                ticksLeftThisToil = duration - age;
                if (age > duration)
                {
                    this.EndJobWith(JobCondition.Succeeded);
                }
            };
            doHealing.defaultCompleteMode = ToilCompleteMode.Delay;
            doHealing.defaultDuration     = this.duration;
            doHealing.WithProgressBar(TargetIndex.B, delegate
            {
                if (this.pawn.DestroyedOrNull() || this.pawn.Dead)
                {
                    return(1f);
                }
                return(1f - (float)doHealing.actor.jobs.curDriver.ticksLeftThisToil / this.duration);
            }, false, 0f);
            doHealing.AddFinishAction(delegate
            {
                CompWizardry comp       = pawn.GetComp <CompWizardry>();
                PawnAbility pawnAbility = comp.AbilityData.Powers.FirstOrDefault((PawnAbility x) => x.Def == WizardryDefOf.LotRW_Nienna_HealingTouch);
                pawnAbility.PostAbilityAttempt();
                patient.jobs.EndCurrentJob(JobCondition.Succeeded, true);
            });
            yield return(doHealing);
        }
        protected virtual void Impact(Thing hitThing)
        {
            bool flag = hitThing == null;

            if (flag)
            {
                Pawn pawn;
                bool flag2 = (pawn = (base.Position.GetThingList(base.Map).FirstOrDefault((Thing x) => x == this.assignedTarget) as Pawn)) != null;
                if (flag2)
                {
                    hitThing = pawn;
                }
            }
            bool hasValue = this.impactDamage.HasValue;

            if (hasValue)
            {
                hitThing.TakeDamage(this.impactDamage.Value);
            }
            try
            {
                SoundDefOf.Ambient_AltitudeWind.sustainFadeoutTime.Equals(30.0f);

                GenSpawn.Spawn(this.flyingThing, base.Position, base.Map);
                if (this.flyingThing is Pawn)
                {
                    Pawn p = this.flyingThing as Pawn;
                    if (this.earlyImpact)
                    {
                        DamageEntities(p, this.impactForce, DamageDefOf.Blunt);
                        DamageEntities(p, 2 * this.impactForce, DamageDefOf.Stun);
                    }
                }
                else if (flyingThing.def.thingCategories != null && (flyingThing.def.thingCategories.Contains(ThingCategoryDefOf.Chunks) || flyingThing.def.thingCategories.Contains(ThingCategoryDef.Named("StoneChunks"))))
                {
                    float   radius = 3f;
                    Vector3 center = this.ExactPosition;
                    if (this.earlyImpact)
                    {
                        bool    wallFlag90neg = false;
                        IntVec3 wallCheck     = (center + (Quaternion.AngleAxis(-90, Vector3.up) * this.flyingDirection)).ToIntVec3();
                        MoteMaker.ThrowMicroSparks(wallCheck.ToVector3Shifted(), base.Map);
                        wallFlag90neg = wallCheck.Walkable(base.Map);

                        wallCheck = (center + (Quaternion.AngleAxis(90, Vector3.up) * this.flyingDirection)).ToIntVec3();
                        MoteMaker.ThrowMicroSparks(wallCheck.ToVector3Shifted(), base.Map);
                        bool wallFlag90 = wallCheck.Walkable(base.Map);

                        if ((!wallFlag90 && !wallFlag90neg) || (wallFlag90 && wallFlag90neg))
                        {
                            //fragment energy bounces in reverse direction of travel
                            center = center + ((Quaternion.AngleAxis(180, Vector3.up) * this.flyingDirection) * 3);
                        }
                        else if (wallFlag90)
                        {
                            center = center + ((Quaternion.AngleAxis(90, Vector3.up) * this.flyingDirection) * 3);
                        }
                        else if (wallFlag90neg)
                        {
                            center = center + ((Quaternion.AngleAxis(-90, Vector3.up) * this.flyingDirection) * 3);
                        }
                    }

                    int num = GenRadial.NumCellsInRadius(radius);
                    for (int i = 0; i < num / 2; i++)
                    {
                        IntVec3 intVec = center.ToIntVec3() + GenRadial.RadialPattern[Rand.Range(1, num)];
                        if (intVec.IsValid && intVec.InBounds(base.Map))
                        {
                            Vector3 moteDirection = GetVector(this.ExactPosition.ToIntVec3(), intVec);
                            EffectMaker.MakeEffect(ThingDef.Named("Mote_Rubble"), this.ExactPosition, base.Map, Rand.Range(.3f, .5f), (Quaternion.AngleAxis(90, Vector3.up) * moteDirection).ToAngleFlat(), 12f, 0);
                            GenExplosion.DoExplosion(intVec, base.Map, .4f, WizardryDefOf.LotRW_RockFragments, pawn, Rand.Range(6, 16), 0, SoundDefOf.Pawn_Melee_Punch_HitBuilding, null, null, null, ThingDef.Named("Filth_RubbleRock"), .6f, 1, false, null, 0f, 1, 0, false);
                            MoteMaker.ThrowSmoke(intVec.ToVector3Shifted(), base.Map, Rand.Range(.6f, 1f));
                        }
                    }
                    Thing p = this.flyingThing;
                    DamageEntities(p, 305, DamageDefOf.Blunt);
                }

                this.Destroy(DestroyMode.Vanish);
            }
            catch
            {
                if (!this.flyingThing.Spawned)
                {
                    GenSpawn.Spawn(this.flyingThing, base.Position, base.Map);
                }

                this.Destroy(DestroyMode.Vanish);
            }
        }
        protected override void Impact(Thing hitThing)
        {
            base.Impact(hitThing);

            ThingDef def    = this.def;
            Pawn     victim = null;

            if (!this.initialized)
            {
                this.pawn         = this.launcher as Pawn;
                this.radius       = this.def.projectile.explosionRadius;
                this.initialized  = true;
                this.direction    = GetVector(pawn.Position, base.Position);
                this.realPosition = base.Position.ToVector3();
                this.targets      = GenRadial.RadialCellsAround(base.Position, strikeNum, false);
                cellList          = targets.ToList <IntVec3>();
                this.CreateSustainer();
            }

            if (this.sustainer == null)
            {
                Log.Error("Vortex sustainer is null.");
                this.CreateSustainer();
            }
            this.sustainer.Maintain();
            this.UpdateSustainerVolume();

            this.realPosition += this.direction * .1f;
            if (this.Map != null)
            {
                if (!this.realPosition.ToIntVec3().Walkable(this.Map))
                {
                    this.age = this.duration;
                }
                EffectMaker.MakeEffect(ThingDefOf.Mote_TornadoDustPuff, this.realPosition, this.Map, Rand.Range(.6f, .9f), Rand.Range(0, 360), Rand.Range(4f, 5f), Rand.Range(100, 200));
                IntVec3 curCell;
                for (int i = 0; i < 5; i++)
                {
                    curCell = cellList.RandomElement();
                    if (curCell.IsValid && curCell.InBounds(this.Map))
                    {
                        Vector3 moteVector = GetVector(this.realPosition.ToIntVec3(), curCell);
                        EffectMaker.MakeEffect(ThingDef.Named("Mote_Tornado"), curCell.ToVector3(), this.Map, Rand.Range(.4f, .8f), (Quaternion.AngleAxis(Rand.Range(-35, -55), Vector3.up) * moteVector).ToAngleFlat(), Rand.Range(1f, 3f), Rand.Range(-200, -500), (Quaternion.AngleAxis(Rand.Range(-35, -55), Vector3.up) * moteVector).ToAngleFlat(), Rand.Range(.2f, .3f), .1f, Rand.Range(.05f, .2f), true);
                    }
                }

                if (Find.TickManager.TicksGame % 50 == 0)
                {
                    this.direction.x = (Rand.Range(-.6f, .6f));
                    this.direction.z = (Rand.Range(-.6f, .6f));
                }

                if (Find.TickManager.TicksGame % this.strikeDelay == 0)
                {
                    for (int i = 0; i < cellList.Count(); i++)
                    {
                        curCell = cellList[i];
                        if (curCell.IsValid && curCell.InBounds(this.Map))
                        {
                            this.fireVortexValue += this.CalculateFireAmountInArea(curCell, .4f);
                            float        force = (10f / (curCell.ToVector3() - this.realPosition).magnitude + 10f);
                            Thing        dmgThing;
                            List <Thing> hitList = curCell.GetThingList(this.Map);
                            for (int j = 0; j < hitList.Count; j++)
                            {
                                dmgThing = hitList[j];
                                Vector3 launchVector      = GetVector(dmgThing.Position, this.realPosition.ToIntVec3());
                                IntVec3 projectedPosition = dmgThing.Position + (force * launchVector).ToIntVec3();
                                if (dmgThing is Pawn)
                                {
                                    victim = dmgThing as Pawn;
                                    int mass = 10; // victim.mass possible calculation, currently not used
                                    if (projectedPosition.IsValid && projectedPosition.InBounds(this.Map) && !victim.Dead)
                                    {
                                        if (this.fireVortexValue > 0)
                                        {
                                            DamageEntities(dmgThing, Mathf.RoundToInt(this.def.projectile.GetDamageAmount(1, null) * force), DamageDefOf.Flame);
                                            this.fireVortexValue -= .2f;
                                        }
                                        LaunchFlyingObect(projectedPosition, victim);
                                    }
                                }
                                else if (dmgThing is Building)
                                {
                                    if (this.fireVortexValue > 0)
                                    {
                                        DamageEntities(dmgThing, Mathf.RoundToInt(this.def.projectile.GetDamageAmount(1, null) * force * 2), DamageDefOf.Flame);
                                        this.fireVortexValue -= .2f;
                                    }
                                }
                                else if (dmgThing.def.EverHaulable && !(dmgThing is Corpse))
                                {
                                    if (projectedPosition.IsValid && projectedPosition.InBounds(this.Map))
                                    {
                                        LaunchFlyingObect(projectedPosition, dmgThing);
                                    }
                                }
                            }
                        }
                    }
                    targets  = GenRadial.RadialCellsAround(this.realPosition.ToIntVec3(), strikeNum, true);
                    cellList = targets.ToList <IntVec3>();
                }
                if (this.fireVortexValue > 0)
                {
                    if (Find.TickManager.TicksGame % this.fireDelay == 0)
                    {
                        curCell = this.cellList.RandomElement();
                        Vector3 moteVector = GetVector(this.realPosition.ToIntVec3(), curCell);
                        EffectMaker.MakeEffect(ThingDef.Named("Mote_MicroSparks"), this.cellList.RandomElement().ToVector3Shifted(), this.Map, Rand.Range(.5f, 1f), (Quaternion.AngleAxis(Rand.Range(-35, -50), Vector3.up) * moteVector).ToAngleFlat(), Rand.Range(2, 3), Rand.Range(50, 200));
                        EffectMaker.MakeEffect(ThingDef.Named("Mote_MicroSparks"), this.cellList.RandomElement().ToVector3Shifted(), this.Map, Rand.Range(.5f, 1f), (Quaternion.AngleAxis(Rand.Range(35, 50), Vector3.up) * moteVector).ToAngleFlat(), Rand.Range(1, 2), Rand.Range(50, 200));
                        DoFireVortex();
                    }
                }
            }
        }
        protected override void Impact(Thing hitThing)
        {
            base.Impact(hitThing);
            caster = launcher as Pawn;
            var map = caster?.Map;

            if (!initialized)
            {
                if (caster != null)
                {
                    centerCell = caster.Position;
                    direction  = GetVector(Position, false);
                    nextStrike = age + ticksPerStrike;
                    currentPos = caster.Position.ToVector3();
                }

                currentPos.y = 0;
                initialized  = true;
            }

            if (age <= nextStrike || !(fireAmount > 0))
            {
                return;
            }

            currentPos += direction;
            nextStrike  = age + ticksPerStrike;
            if (currentPos.ToIntVec3().GetTerrain(map).passability != Traversability.Impassable &&
                currentPos.ToIntVec3().Walkable(map))
            {
                if (caster != null && (currentPos.ToIntVec3() == caster.Position || Map == null))
                {
                    return;
                }

                EffectMaker.MakeEffect(WizardryDefOf.Mote_ExpandingFlame, currentPos, Map, 1f,
                                       (Quaternion.AngleAxis(90, Vector3.up) * direction).ToAngleFlat(), 3f, Rand.Range(200, 500));
                EffectMaker.MakeEffect(WizardryDefOf.Mote_RecedingFlame, currentPos, Map, .8f,
                                       (Quaternion.AngleAxis(90, Vector3.up) * direction).ToAngleFlat(), 1f, 0);
                var   hitList = currentPos.ToIntVec3().GetThingList(map);
                Thing burnThing;
                foreach (var thing in hitList)
                {
                    burnThing = thing;
                    DamageEntities(burnThing);
                }

                //GenExplosion.DoExplosion(this.currentPos.ToIntVec3(), this.Map, .4f, DamageDefOf.Flame, this.launcher, 10, SoundDefOf.ArtilleryShellLoaded, def, this.equipmentDef, null, 0f, 1, false, null, 0f, 1, 0f, false);
                if (Rand.Chance(fireStartChance))
                {
                    FireUtility.TryStartFireIn(currentPos.ToIntVec3(), map, .2f);
                }

                fireAmount -= mainFlameDropoff;
                strikeInt++;
                var     tempVec1    = currentPos;
                IntVec3 lastVec1Pos = default;
                var     tempVec2    = currentPos;
                IntVec3 lastVec2Pos = default;
                distance = Mathf.Max(5f, distance);
                for (var i = strikeInt / distance; i > .3f; i -= .5f)
                {
                    tempVec1 += directionP;
                    if (tempVec1.ToIntVec3() != currentPos.ToIntVec3() && tempVec1.ToIntVec3() != lastVec1Pos)
                    {
                        lastVec1Pos = tempVec1.ToIntVec3();
                        EffectMaker.MakeEffect(WizardryDefOf.Mote_ExpandingFlame, tempVec1, Map, .8f,
                                               (Quaternion.AngleAxis(90, Vector3.up) * direction).ToAngleFlat(), 2f,
                                               Rand.Range(200, 500));
                        EffectMaker.MakeEffect(WizardryDefOf.Mote_RecedingFlame, tempVec1, Map, .7f,
                                               (Quaternion.AngleAxis(90, Vector3.up) * direction).ToAngleFlat(), 1f, 0);
                        hitList = lastVec1Pos.GetThingList(map);
                        foreach (var thing in hitList)
                        {
                            burnThing = thing;
                            DamageEntities(burnThing);
                        }

                        if (Rand.Chance(fireStartChance))
                        {
                            FireUtility.TryStartFireIn(lastVec1Pos, map, .2f);
                        }

                        fireAmount -= branchingFlameDropoff;
                        //GenExplosion.DoExplosion(lastVec1Pos, this.Map, .4f, DamageDefOf.Flame, this.launcher, 10, SoundDefOf.ArtilleryShellLoaded, def, this.equipmentDef, null, 0f, 1, false, null, 0f, 1, 0f, false);
                    }

                    tempVec2 -= directionP;
                    if (tempVec2.ToIntVec3() != currentPos.ToIntVec3() && tempVec2.ToIntVec3() != lastVec2Pos)
                    {
                        lastVec2Pos = tempVec2.ToIntVec3();
                        EffectMaker.MakeEffect(WizardryDefOf.Mote_ExpandingFlame, tempVec2, Map, .8f,
                                               (Quaternion.AngleAxis(90, Vector3.up) * direction).ToAngleFlat(), 2f,
                                               Rand.Range(200, 500));
                        EffectMaker.MakeEffect(WizardryDefOf.Mote_RecedingFlame, tempVec2, Map, .7f,
                                               (Quaternion.AngleAxis(90, Vector3.up) * direction).ToAngleFlat(), 1f, 0);
                        hitList = lastVec2Pos.GetThingList(map);
                        foreach (var thing in hitList)
                        {
                            burnThing = thing;
                            DamageEntities(burnThing);
                        }

                        if (Rand.Chance(fireStartChance))
                        {
                            FireUtility.TryStartFireIn(lastVec2Pos, map, .2f);
                        }

                        fireAmount -= branchingFlameDropoff;
                        //GenExplosion.DoExplosion(lastVec2Pos, this.Map, .4f, DamageDefOf.Flame, this.launcher, 10, SoundDefOf.ArtilleryShellLoaded, def, this.equipmentDef, null, 0f, 1, false, null, 0f, 1, 0f, false);
                    }

                    if (fireAmount < 0)
                    {
                        i = 0;
                    }
                }
            }
            else
            {
                //main branch of fire cone hit impassable or unwalkable terrain
                age = duration;
            }
        }
Пример #29
0
        private void DoQuakeDamages(float radius, IntVec3 location)
        {
            var num = GenRadial.NumCellsInRadius(radius);

            for (var i = 0; i < num; i++)
            {
                var intVec = location + GenRadial.RadialPattern[i];
                if (!intVec.IsValid || !intVec.InBounds(Map))
                {
                    continue;
                }

                if (Rand.Chance(.4f))
                {
                    EffectMaker.MakeEffect(ThingDef.Named("Mote_ThickDust"), intVec.ToVector3Shifted(), Map,
                                           Rand.Range(.2f, 2f), Rand.Range(0, 360), Rand.Range(.5f, 1f), Rand.Range(10, 250), 0,
                                           Rand.Range(.3f, .9f), Rand.Range(.05f, .3f), Rand.Range(.6f, 2.4f), true);
                }

                var structure = intVec.GetFirstBuilding(Map);
                if (structure != null)
                {
                    if (structure.def.designationCategory == DesignationCategoryDefOf.Structure)
                    {
                        DamageEntities(structure, structure.def.BaseMaxHitPoints, DamageDefOf.Crush);
                        var moteDirection = GetVector(origin.ToIntVec3(), intVec);
                        EffectMaker.MakeEffect(ThingDef.Named("Mote_Rubble"), intVec.ToVector3Shifted(), Map,
                                               Rand.Range(.3f, .5f),
                                               (Quaternion.AngleAxis(90, Vector3.up) * moteDirection).ToAngleFlat(), 8f, 0);
                        EffectMaker.MakeEffect(ThingDef.Named("Mote_Rubble"), intVec.ToVector3Shifted(), Map,
                                               Rand.Range(.3f, .6f),
                                               (Quaternion.AngleAxis(Rand.Range(-70, -110), Vector3.up) * moteDirection).ToAngleFlat(),
                                               6f, 0);
                        GenExplosion.DoExplosion(intVec, Map, .4f, WizardryDefOf.LotRW_RockFragments, launcher,
                                                 Rand.Range(6, 16), 0, SoundDefOf.Pawn_Melee_Punch_HitBuilding, null, null, null,
                                                 ThingDef.Named("Filth_RubbleRock"), .4f);
                        FleckMaker.ThrowSmoke(intVec.ToVector3Shifted(), Map, Rand.Range(.6f, 1f));
                        if (intVec == boltPosition)
                        {
                            wallImpact = true;
                            duration   = approximateDuration;
                        }
                    }
                    else if (structure.def.building.isResourceRock)
                    {
                        var yieldThing  = structure.def.building.mineableThing;
                        var yieldAmount = (int)(structure.def.building.mineableYield * Rand.Range(.7f, .9f));
                        DamageEntities(structure, structure.def.BaseMaxHitPoints, DamageDefOf.Crush);
                        var moteDirection = GetVector(origin.ToIntVec3(), intVec);
                        EffectMaker.MakeEffect(ThingDef.Named("Mote_Rubble"), intVec.ToVector3Shifted(), Map,
                                               Rand.Range(.3f, .5f),
                                               (Quaternion.AngleAxis(90, Vector3.up) * moteDirection).ToAngleFlat(), 8f, 0);
                        EffectMaker.MakeEffect(ThingDef.Named("Mote_Rubble"), intVec.ToVector3Shifted(), Map,
                                               Rand.Range(.3f, .6f),
                                               (Quaternion.AngleAxis(Rand.Range(-70, -110), Vector3.up) * moteDirection).ToAngleFlat(),
                                               6f, 0);
                        GenExplosion.DoExplosion(intVec, Map, .4f, WizardryDefOf.LotRW_RockFragments, launcher,
                                                 Rand.Range(6, 16), 0, SoundDefOf.Crunch, null, null, null, yieldThing, 1f, yieldAmount);
                        FleckMaker.ThrowSmoke(intVec.ToVector3Shifted(), Map, Rand.Range(.6f, 1f));
                        if (intVec == boltPosition)
                        {
                            wallImpact = true;
                            duration   = approximateDuration;
                        }
                    }
                    else if (structure.def.building.isNaturalRock)
                    {
                        var yieldThing = structure.def.building.mineableThing;
                        DamageEntities(structure, structure.def.BaseMaxHitPoints, DamageDefOf.Crush);
                        var moteDirection = GetVector(origin.ToIntVec3(), intVec);
                        EffectMaker.MakeEffect(ThingDef.Named("Mote_Rubble"), intVec.ToVector3Shifted(), Map,
                                               Rand.Range(.3f, .5f),
                                               (Quaternion.AngleAxis(90, Vector3.up) * moteDirection).ToAngleFlat(), 8f, 0);
                        EffectMaker.MakeEffect(ThingDef.Named("Mote_Rubble"), intVec.ToVector3Shifted(), Map,
                                               Rand.Range(.3f, .6f),
                                               (Quaternion.AngleAxis(Rand.Range(-70, -110), Vector3.up) * moteDirection).ToAngleFlat(),
                                               6f, 0);
                        GenExplosion.DoExplosion(intVec, Map, .4f, WizardryDefOf.LotRW_RockFragments, launcher,
                                                 Rand.Range(6, 16), 0, SoundDefOf.Crunch, null, null, null, yieldThing, .2f);
                        FleckMaker.ThrowSmoke(intVec.ToVector3Shifted(), Map, Rand.Range(.6f, 1f));
                        if (intVec == boltPosition)
                        {
                            wallImpact = true;
                            duration   = approximateDuration;
                        }
                    }
                    else
                    {
                        DamageEntities(structure, Rand.Range(40, 50), DamageDefOf.Crush);
                        EffectMaker.MakeEffect(ThingDef.Named("Mote_Rubble"), intVec.ToVector3Shifted(), Map,
                                               Rand.Range(.3f, .6f), Rand.Range(0, 359), 6f, 0);
                        EffectMaker.MakeEffect(ThingDef.Named("Mote_Rubble"), intVec.ToVector3Shifted(), Map,
                                               Rand.Range(.3f, .6f), Rand.Range(0, 359), 4f, 0);
                        FleckMaker.ThrowSmoke(intVec.ToVector3Shifted(), Map, Rand.Range(.6f, 1f));
                    }
                }

                var pawn = intVec.GetFirstPawn(Map);
                if (pawn == null || pawn == caster)
                {
                    continue;
                }

                if (Rand.Chance(.2f))
                {
                    DamageEntities(pawn, Rand.Range(4, 6), DamageDefOf.Crush);
                }

                HealthUtility.AdjustSeverity(pawn, HediffDef.Named("LotRW_Quake"), Rand.Range(1f, 2f));
            }
        }
        protected override void Impact(Thing hitThing)
        {
            Map map = base.Map;

            base.Impact(hitThing);
            ThingDef def = this.def;

            if (!this.initialized)
            {
                caster = this.launcher as Pawn;
                GetSecondTarget();
                this.initialized = true;
            }

            CompWizardry comp = caster.GetComp <CompWizardry>();

            if (!this.wallActive && comp.SecondTarget != null)
            {
                this.age          = 0;
                this.duration     = 1200;
                this.wallActive   = true;
                this.wallPos      = base.Position.ToVector3Shifted();
                this.wallDir      = GetVector(base.Position.ToVector3Shifted(), comp.SecondTarget.Cell.ToVector3Shifted());
                this.wallEnd      = comp.SecondTarget.Cell;
                comp.SecondTarget = null;
            }

            if (!wallActive)
            {
                if (Find.TickManager.TicksGame % 6 == 0)
                {
                    MoteMaker.ThrowDustPuff(base.Position, caster.Map, Rand.Range(.6f, .9f));
                }
            }
            else
            {
                if (Find.TickManager.TicksGame % 3 == 0)
                {
                    if (wallLength < wallLengthMax)
                    {
                        List <Thing> cellList = this.wallPos.ToIntVec3().GetThingList(caster.Map);
                        bool         hasWall  = false;
                        for (int i = 0; i < cellList.Count(); i++)
                        {
                            if (cellList[i].def.defName == "LotRW_WindWall")
                            {
                                hasWall = true;
                            }
                        }

                        if (!hasWall)
                        {
                            bool spawnWall = true;
                            for (int i = 0; i < cellList.Count(); i++)
                            {
                                if (!cellList[i].def.EverHaulable)
                                {
                                    if (cellList[i].def.altitudeLayer == AltitudeLayer.Building || cellList[i].def.altitudeLayer == AltitudeLayer.Item || cellList[i].def.altitudeLayer == AltitudeLayer.ItemImportant)
                                    {
                                        //Log.Message("bypassing object and setting wall spawn to false");
                                        spawnWall = false;
                                    }
                                    else
                                    {
                                        if (cellList[i].def.defName.Contains("Mote") || (cellList[i].def.defName == "LotRW_Projectile_AirWall"))
                                        {
                                            //Log.Message("avoided storing " + cellList[i].def.defName);
                                        }
                                        else
                                        {
                                            this.despawnedThingList.Add(cellList[i]);
                                            cellList[i].DeSpawn();
                                        }
                                    }
                                }
                                else
                                {
                                    int launchDir = -90;
                                    if (Rand.Chance(.5f))
                                    {
                                        launchDir = 90;
                                    }
                                    LaunchFlyingObect(cellList[i].Position + (Quaternion.AngleAxis(launchDir, Vector3.up) * wallDir).ToIntVec3(), cellList[i]);
                                }
                            }
                            if (spawnWall)
                            {
                                AbilityUser.SpawnThings tempSpawn = new SpawnThings()
                                {
                                    def        = ThingDef.Named("LotRW_WindWall"),
                                    spawnCount = 1
                                };
                                SingleSpawnLoop(tempSpawn, wallPos.ToIntVec3(), caster.Map);
                                this.wallLength++;
                                this.wallPositions.Add(wallPos.ToIntVec3());
                            }
                        }

                        this.wallPos += this.wallDir;

                        if (!this.wallPos.ToIntVec3().Walkable(caster.Map) || this.wallPos.ToIntVec3() == this.wallEnd)
                        {
                            this.wallPos   -= this.wallDir;
                            this.wallLength = this.wallLengthMax;
                        }
                    }

                    for (int j = 0; j < this.wallPositions.Count(); j++)
                    {
                        int launchDir = Rand.Range(-100, -80);
                        if (Rand.Chance(.5f))
                        {
                            launchDir = Rand.Range(80, 100);
                        }
                        EffectMaker.MakeEffect(ThingDef.Named("Mote_DustPuff"), this.wallPositions.RandomElement().ToVector3Shifted(), caster.Map, Rand.Range(.6f, .8f), (Quaternion.AngleAxis(launchDir, Vector3.up) * wallDir).ToAngleFlat(), Rand.Range(2f, 5f), Rand.Range(100, 200), .04f, .03f, .8f, false);
                    }
                }
            }
        }