예제 #1
0
        public virtual void Vomiting(IntVec3 cell)
        {
            if (def.item == null)
            {
                return;
            }

            Thing thing = ThingMaker.MakeThing(def.item, null);

            thing.stackCount = def.count.RandomInRange;
            GenPlace.TryPlaceThing(thing, cell, pawn.Map, ThingPlaceMode.Direct, null, null);

            RadiologyEffectSpawnerDef.Spawn(def.effect, pawn);

            if (def.hurtParts == null)
            {
                return;
            }

            foreach (BodyPartDef partDef in def.hurtParts)
            {
                foreach (BodyPartRecord part in pawn.health.hediffSet.GetNotMissingParts().Where(x => def.hurtParts.Contains(x.def)))
                {
                    if (Rand.Value > def.hurtChance)
                    {
                        continue;
                    }

                    DamageInfo dinfo = new DamageInfo(DamageDefOf.Cut, def.damage.RandomInRange, 999999f, -1f, thing, part, null, DamageInfo.SourceCategory.ThingOrUnknown, null);
                    pawn.TakeDamage(dinfo);
                }
            }
        }
예제 #2
0
        public override void PostAdd(DamageInfo?dinfo)
        {
            base.PostAdd(dinfo);

            RadiologyEffectSpawnerDef.Spawn(def.SpawnEffect(pawn), pawn);

            CreateThingComps();
            CreateApparel();
        }
예제 #3
0
        public void ApplyDamage(DamageInfo dinfo, out bool absorbed)
        {
            absorbed = false;

            if (Mathf.Abs(MathHelper.AngleDifference(dinfo.Angle + 180, pawn.Rotation.AsAngle)) < 45)
            {
                return;
            }

            RadiologyEffectSpawnerDef.Spawn(def.effectReflect, pawn, dinfo.Angle + 180);
            dinfo.SetAmount(dinfo.Amount * def.ratio);
        }
예제 #4
0
        private void Blink(IntVec3 target)
        {
            cooldown = def.cooldownTicks;

            RadiologyEffectSpawnerDef.Spawn(def.effectOut, pawn);

            pawn.jobs.StartJob(new Job(RimWorld.JobDefOf.Wait, 1, false), JobCondition.InterruptForced, null, true, false);
            pawn.SetPositionDirect(target);
            pawn.Drawer.tweener.ResetTweenedPosToRoot();

            RadiologyEffectSpawnerDef.Spawn(def.effectIn, pawn);
        }
예제 #5
0
        public void RegenerateTick()
        {
            base.Tick();

            if (!pawn.IsHashIntervalTick(def.periodTicks))
            {
                return;
            }

            var injured   = pawn.health.hediffSet.GetInjuredParts();
            var missing   = pawn.health.hediffSet.GetMissingPartsCommonAncestors();
            var potential = missing.Where(x =>
                                          x.Part != null && (
                                              x.Part.parent == null || (
                                                  !injured.Contains(x.Part.parent) &&
                                                  !injured.Intersect(x.Part.parent.GetDirectChildParts()).Any()
                                                  )
                                              )
                                          );

            Hediff_MissingPart hediff = potential.RandomElementWithFallback();

            if (hediff == null)
            {
                return;
            }

            BodyPartRecord part = hediff.Part;

            pawn.health.hediffSet.hediffs.Remove(hediff);

            foreach (var subpart in part.GetDirectChildParts())
            {
                Hediff_MissingPart missingPart = HediffMaker.MakeHediff(RimWorld.HediffDefOf.MissingBodyPart, pawn, subpart) as Hediff_MissingPart;
                pawn.health.hediffSet.hediffs.Add(missingPart);
            }

            Hediff_Injury injury = HediffMaker.MakeHediff(RimWorld.HediffDefOf.Shredded, pawn, part) as Hediff_Injury;

            injury.Severity = part.def.hitPoints - 1;
            pawn.health.hediffSet.hediffs.Add(injury);

            pawn.health.hediffSet.DirtyCache();

            RadiologyEffectSpawnerDef.Spawn(def.effectRegeration, pawn);
        }
예제 #6
0
        public void ApplyBurn(Pawn pawn, HediffRadiation radiation)
        {
            float burnAmount = def.burnThreshold.RandomInRange;

            if (radiation.burn < burnAmount)
            {
                return;
            }

            radiation.burn -= burnAmount;

            DamageInfo dinfo = new DamageInfo(DamageDefOf.Burn, burnAmount, 999999f, -1f, this, radiation.Part, null, DamageInfo.SourceCategory.ThingOrUnknown, null);

            pawn.TakeDamage(dinfo);

            RadiologyEffectSpawnerDef.Spawn(def.burnEffect, pawn);
        }
예제 #7
0
        public void Drain()
        {
            Building building = null;

            if (previousBuilding != null && previousBuilding.Position.DistanceTo(pawn.Position) < def.range)
            {
                building = previousBuilding;
            }
            if (building == null)
            {
                building = pawn.Map.listerBuildings.allBuildingsColonistElecFire.FirstOrDefault(x => x.Position.DistanceTo(pawn.Position) < def.range);
            }
            previousBuilding = building;

            if (building == null)
            {
                return;
            }

            CompPower power = building.GetComp <CompPower>();

            if (power == null || power.PowerNet == null)
            {
                return;
            }

            float amount  = Mathf.Min(power.PowerNet.AvailablePower(), def.drain);
            float canTake = def.efficiency < 0.0001 ? def.capacity : (def.capacity - charge) / def.efficiency;

            if (amount > canTake)
            {
                amount = canTake;
            }
            if (amount < def.drain / 2)
            {
                return;
            }

            power.PowerNet.Drain(amount);
            charge += amount * def.efficiency;

            RadiologyEffectSpawnerDef.Spawn(def.effectDraining, pawn.Map, pawn.TrueCenter(), (building.Position - pawn.Position).AngleFlat);
            RadiologyEffectSpawnerDef.Spawn(def.effectDrained, pawn.Map, building.RandomPointNearTrueCenter(), (pawn.Position - building.Position).AngleFlat);
        }
예제 #8
0
        public override void Tick()
        {
            base.Tick();

            if (regenerationDelay > 0)
            {
                regenerationDelay--;
            }
            else
            {
                if (health == 0 && def.health != 0 && def.regenratedPerSecond != 0)
                {
                    RadiologyEffectSpawnerDef.Spawn(def.effectRestored, pawn);
                }

                health += def.regenratedPerSecond / 60;
                if (health > def.health)
                {
                    health = def.health;
                }
            }
        }
예제 #9
0
        public void ApplyDamage(DamageInfo dinfo, out bool absorbed)
        {
            absorbed = false;

            if (def.protectsAgainst != null && !def.protectsAgainst.Contains(dinfo.Def))
            {
                return;
            }
            if (def.uselessAgainst != null && def.uselessAgainst.Contains(dinfo.Def))
            {
                return;
            }

            regenerationDelay = def.regenerationDelayTicks;

            if (health == 0 && def.health != 0)
            {
                return;
            }

            if (dinfo.Amount <= health || def.health == 0)
            {
                health  -= dinfo.Amount;
                absorbed = true;

                RadiologyEffectSpawnerDef.Spawn(def.effectAbsorbed, pawn, dinfo.Angle + 180);
            }
            else
            {
                dinfo.SetAmount(dinfo.Amount - health);
                health = 0;
            }

            if (health == 0 && def.health != 0)
            {
                RadiologyEffectSpawnerDef.Spawn(def.effectBroken, pawn, dinfo.Angle + 180);
            }
        }
예제 #10
0
        public bool RegenerateInjury(Pawn pawn, float amount)
        {
            var           injuries = pawn.health.hediffSet.hediffs.OfType <Hediff_Injury>().Where(x => x.Severity > 0 && x.Part != null);
            Hediff_Injury injury   = injuries.RandomElementWithFallback();

            if (injury == null)
            {
                return(false);
            }

            HediffComp_GetsPermanent hediffComp_GetsPermanent = injury.TryGetComp <HediffComp_GetsPermanent>();

            if (hediffComp_GetsPermanent != null)
            {
                hediffComp_GetsPermanent.IsPermanent = false;
            }

            injury.Severity = Mathf.Max(injury.Severity - amount);
            pawn.health.hediffSet.DirtyCache();

            RadiologyEffectSpawnerDef.Spawn(effectRegeneration, pawn);
            return(true);
        }
        public bool RegenerateInjury()
        {
            var           permanentInjuries = pawn.health.hediffSet.hediffs.OfType <Hediff_Injury>().Where(x => x.IsPermanent() && x.Part != null);
            Hediff_Injury injury            = permanentInjuries.RandomElementWithFallback();

            if (injury == null)
            {
                return(false);
            }

            HediffComp_GetsPermanent hediffComp_GetsPermanent = injury.TryGetComp <HediffComp_GetsPermanent>();

            if (hediffComp_GetsPermanent == null)
            {
                return(false);
            }

            hediffComp_GetsPermanent.IsPermanent = false;
            injury.Severity = injury.Part.def.hitPoints - 1;
            pawn.health.hediffSet.DirtyCache();

            RadiologyEffectSpawnerDef.Spawn(def.effectRegeneration, pawn);
            return(true);
        }
예제 #12
0
        public void Irradiate(RadiationInfo info, int ticks)
        {
            Chamber chamber = parent.Linked <Chamber>();

            SoundDefOf.RadiologyIrradiateBasic.PlayOneShot(new TargetInfo(parent.Position, parent.Map, false));
            ticksCooldown = ticks;

            if (info.pawn.IsShielded())
            {
                return;
            }

            info.part   = GetBodyPart(info.chamber, info.pawn);
            info.burn   = props.burn.perSecond.RandomInRange;
            info.normal = props.mutate.perSecond.RandomInRange;
            info.rare   = props.mutateRare.perSecond.RandomInRange;
            if (info.secondHand)
            {
                info.rare /= 2;
            }

            motesReflectAt.Clear();
            foreach (ThingComp comp in GetModifiers <ThingComp, IRadiationModifier>(info.chamber))
            {
                if (comp is CompBlocker)
                {
                    motesReflectAt.Add((parent.Rotation.IsHorizontal ? comp.parent.Position.x : comp.parent.Position.z) + 0.5f);
                }

                if (info.secondHand)
                {
                    continue;
                }

                IRadiationModifier modifier = comp as IRadiationModifier;
                modifier.Modify(ref info);
            }

            if (info.burn <= 0 && info.normal <= 0 && info.rare <= 0)
            {
                return;
            }

            HediffRadiation radiation = GetHediffRadition(info.part, info.chamber, info.pawn);

            if (radiation == null)
            {
                return;
            }

            radiation.burn   += info.burn;
            radiation.normal += info.normal;
            radiation.rare   += info.rare;

            float burnThreshold = info.chamber.def.burnThreshold.RandomInRange;
            float burnAmount    = radiation.burn - burnThreshold;

            if (burnAmount > 0)
            {
                radiation.burn -= info.chamber.def.burnThreshold.min;

                DamageInfo dinfo = new DamageInfo(DamageDefOf.Burn, burnAmount * props.burn.multiplier, 999999f, -1f, info.chamber, radiation.Part, null, DamageInfo.SourceCategory.ThingOrUnknown, null);
                info.pawn.TakeDamage(dinfo);

                if (chamber != null)
                {
                    RadiologyEffectSpawnerDef.Spawn(chamber.def.burnEffect, info.pawn);
                }
            }

            float mutateThreshold = info.chamber.def.mutateThreshold.RandomInRange;
            float mutateAmount    = radiation.normal + radiation.rare - mutateThreshold;

            if (mutateAmount > 0)
            {
                float ratio = radiation.rare / (radiation.normal + radiation.rare);
                radiation.rare   -= info.chamber.def.mutateThreshold.min * ratio;
                radiation.normal -= info.chamber.def.mutateThreshold.min * (1f - ratio);

                Mutation mutation;
                var      mutatedParts = RadiationHelper.MutatePawn(info.pawn, radiation, mutateAmount * props.mutate.multiplier, ratio, out mutation);
                if (mutatedParts != null)
                {
                    foreach (var anotherRadiation in info.pawn.health.hediffSet.GetHediffs <HediffRadiation>())
                    {
                        if (mutatedParts.Contains(anotherRadiation.Part) && radiation != anotherRadiation)
                        {
                            anotherRadiation.normal -= info.chamber.def.mutateThreshold.min * (1f - ratio);
                            anotherRadiation.rare   -= info.chamber.def.mutateThreshold.min * ratio;
                        }
                    }
                }
            }
        }