public void Clear() { def = null; targetA = LocalTargetInfo.Invalid; targetB = LocalTargetInfo.Invalid; targetC = LocalTargetInfo.Invalid; targetQueueA = null; targetQueueB = null; count = -1; countQueue = null; loadID = -1; startTick = -1; expiryInterval = -1; checkOverrideOnExpire = false; playerForced = false; placedThings = null; maxNumMeleeAttacks = int.MaxValue; maxNumStaticAttacks = int.MaxValue; locomotionUrgency = LocomotionUrgency.Jog; haulMode = HaulMode.Undefined; bill = null; commTarget = null; plantDefToSow = null; verbToUse = null; haulOpportunisticDuplicates = false; exitMapOnArrival = false; failIfCantJoinOrCreateCaravan = false; killIncappedTarget = false; ignoreForbidden = false; ignoreDesignations = false; canBash = false; canUseRangedWeapon = true; haulDroppedApparel = false; restUntilHealed = false; ignoreJoyTimeAssignment = false; doUntilGatheringEnded = false; overeat = false; attackDoorIfTargetLost = false; takeExtraIngestibles = 0; expireRequiresEnemiesNearby = false; lord = null; collideWithPawns = false; forceSleep = false; interaction = null; endIfCantShootTargetFromCurPos = false; endIfCantShootInMelee = false; checkEncumbrance = false; followRadius = 0f; endAfterTendedOnce = false; quest = null; mote = null; jobGiverThinkTree = null; jobGiver = null; workGiverDef = null; if (cachedDriver != null) { cachedDriver.job = null; } cachedDriver = null; }
// Token: 0x060050F1 RID: 20721 RVA: 0x002A45C0 File Offset: 0x002A29C0 public void DrawMoteInternal(Vector3 loc, Rot4 rot, ThingDef thingDef, Thing thing, int layer) { Mote mote = (Mote)thing; float alpha = mote.Alpha; if (alpha > 0f) { Color color = base.Color * mote.instanceColor; color.a *= alpha; Vector3 exactScale = mote.exactScale; exactScale.x *= this.data.drawSize.x; exactScale.z *= this.data.drawSize.y; Matrix4x4 matrix = default(Matrix4x4); matrix.SetTRS(mote.DrawPos, Quaternion.AngleAxis(mote.exactRotation, Vector3.up), exactScale); Material matSingle = MaterialFor(thing); if (!ForcePropertyBlock && color.IndistinguishableFrom(matSingle.color)) { Graphics.DrawMesh(MeshPool.plane10, matrix, matSingle, layer, null, 0); } else { Graphic_Mote_Random.propertyBlock.SetColor(ShaderPropertyIDs.Color, color); Graphics.DrawMesh(MeshPool.plane10, matrix, matSingle, layer, null, 0, Graphic_Mote_Random.propertyBlock); } } }
public virtual void AbilityTick() { VerbTracker.VerbsTick(); if (def.warmupMote != null && verb.WarmingUp) { if (warmupMote == null || warmupMote.Destroyed) { warmupMote = MoteMaker.MakeStaticMote(pawn.DrawPos + def.moteDrawOffset, pawn.Map, def.warmupMote); } else { warmupMote.Maintain(); } } if (verb.WarmingUp && !CanApplyOn(verb.CurrentTarget)) { verb.WarmupStance?.Interrupt(); verb.Reset(); } if (cooldownTicks > 0) { cooldownTicks--; if (cooldownTicks == 0 && def.sendLetterOnCooldownComplete) { Find.LetterStack.ReceiveLetter("AbilityReadyLabel".Translate(def.LabelCap), "AbilityReadyText".Translate(pawn, def.label), LetterDefOf.NeutralEvent, new LookTargets(pawn)); } } }
static void Mote_SpawnSetup_Postfix(Mote __instance) { if (__instance.Graphic is Graphic_AnimatedMote GAM && CustomTransformation_MoteDef.MyNamed(__instance.def.defName) is CustomTransformation_MoteDef CTMD) { GAM.MyDebug = CTMD.debug; if (CTMD.HasMisc) { GAM.Flipped = CTMD.transformation.misc.flipped; } if (CTMD.HasAnimatedMote) { GAM.FrameOffset = CTMD.transformation.animatedMote.frameOffset; //GAM.FrameOffset += CTMD.transformation.animatedMote.randomFrameOffset.RandomInRange; GAM.TicksPerFrame = CTMD.transformation.animatedMote.ticksPerFrame; GAM.Engine = CTMD.transformation.animatedMote.engine; } if (CTMD.HasRandomRotationRate) { __instance.rotationRate = CTMD.transformation.rotation.randRotRate.range.RandomInRange; } if (CTMD.HasPulsingScale) { GAM.PulsingScaleRange = CTMD.transformation.scale.pulsingScale.range; GAM.PulsingScaleSpeed = CTMD.transformation.scale.pulsingScale.speed; } } }
public int GetAnotherIndex(Mote mote) { int stairCaseInput = (int)Math.Floor((double)(TickEngine(mote) / TicksPerFrame)); int curFrame = stairCaseInput % subGraphics.Length; return(curFrame); }
void SpawnParticle(Vector2 pos, Vector2 targetPos, Color c) { Vector3 p = pos; p.z = transform.position.z + zOffset; Gradient g = new Gradient(); g.FromColor(c); GameObject go = new GameObject(); go.name = "ResourceMote"; go.transform.position = p; TrailRenderer tr = go.AddComponent <TrailRenderer>(); tr.material = material; tr.time = trailTime; tr.colorGradient = g; tr.widthMultiplier = trailWidth; Mote mote = new Mote(); mote.birthTime = Time.unscaledTime; mote.targetPos = targetPos; mote.velocity = Random.insideUnitCircle.normalized * speed; mote.trail = tr; motes.Add(mote); }
protected void MeditationTick() { pawn.skills.Learn(SkillDefOf.Intellectual, 0.0180000011f); pawn.GainComfortFromCellIfPossible(); if (pawn.needs.joy != null) { JoyUtility.JoyTickCheckEnd(pawn, JoyTickFullJoyAction.None); } if (pawn.IsHashIntervalTick(100)) { MoteMaker.ThrowMetaIcon(pawn.Position, pawn.Map, ThingDefOf.Mote_Meditating); } if (!ModsConfig.RoyaltyActive) { return; } pawn.psychicEntropy.Notify_Meditated(); if (pawn.HasPsylink && pawn.psychicEntropy.PsychicSensitivity > float.Epsilon) { if (psyfocusMote == null || psyfocusMote.Destroyed) { psyfocusMote = MoteMaker.MakeAttachedOverlay(pawn, ThingDefOf.Mote_PsyfocusPulse, Vector3.zero); } psyfocusMote.Maintain(); if (sustainer == null || sustainer.Ended) { sustainer = SoundDefOf.MeditationGainPsyfocus.TrySpawnSustainer(SoundInfo.InMap(pawn, MaintenanceType.PerTick)); } sustainer.Maintain(); pawn.psychicEntropy.GainPsyfocus(Focus.Thing); } }
public override void Apply(LocalTargetInfo target, LocalTargetInfo dest) { base.Apply(target, dest); Map map = parent.pawn.Map; foreach (IntVec3 item in AffectedCells(target, map)) { List<Thing> thingList = item.GetThingList(map); for (int num = thingList.Count - 1; num >= 0; num--) { if (thingList[num] is Fire) { thingList[num].Destroy(); } } if (!item.Filled(map)) { FilthMaker.TryMakeFilth(item, map, ThingDefOf.Filth_Water); } Mote mote = MoteMaker.MakeStaticMote(item.ToVector3Shifted(), map, ThingDefOf.Mote_WaterskipSplashParticles); mote.rotationRate = Rand.Range(-30f, 30f); mote.exactRotation = 90 * Rand.RangeInclusive(0, 3); if (item != target.Cell) { MoteMaker.MakeStaticMote(item, parent.pawn.Map, ThingDefOf.Mote_PsycastSkipEffect); } } }
private void CheckBulletFire(Mote mote) { if (mote == null) { return; } // Launch if (mote.def == ThingDefOf.Mote_ShotFlash) { float heat = mote.exactScale.x * 4f; if (this.flammableLinkcomp.TrySparksFly(heat) == SparksFlyResult.Undefine) { MoteUtility.DrawHeatedMote(this.flammableLinkcomp.HeatRatio, base.DrawPos, base.Position, base.Map); } #if DEBUG Log.Message("Mote_ShotFlash base:" + base.DrawPos + " heat:" + heat + " cap:" + this.flammableLinkcomp.AmountOfHeat); #endif } // Impact if (mote.def == ThingDefOf.Mote_ShotHit_Dirt) { if (this.flammableLinkcomp.TrySparksFly(60f) == SparksFlyResult.Undefine) { MoteUtility.DrawHeatedMote(this.flammableLinkcomp.HeatRatio, base.DrawPos, base.Position, base.Map); } #if DEBUG Log.Message("Mote_ShotHit_Dirt base:" + base.DrawPos + " cap:" + this.flammableLinkcomp.AmountOfHeat); #endif } }
private void CheckBulletFire(Mote mote) { if (mote == null) { return; } // Launch if (mote.def.defName.Contains("ShotFlash")) { var heat = mote.exactScale.x * 4f; if (flammableLinkcomp.TrySparksFly(heat) == SparksFlyResult.Undefine) { FleckUtility.DrawHeatedMote(flammableLinkcomp.HeatRatio, base.DrawPos, Position, Map); } #if DEBUG Log.Message("Mote_ShotFlash base:" + base.DrawPos + " heat:" + heat + " cap:" + this.flammableLinkcomp.AmountOfHeat); #endif } // Impact if (!mote.def.defName.Contains("ShotHit_Dirt")) { return; } if (flammableLinkcomp.TrySparksFly(60f) == SparksFlyResult.Undefine) { FleckUtility.DrawHeatedMote(flammableLinkcomp.HeatRatio, base.DrawPos, Position, Map); } #if DEBUG Log.Message("Mote_ShotHit_Dirt base:" + base.DrawPos + " cap:" + this.flammableLinkcomp.AmountOfHeat); #endif }
public override void QueueCastingJob(LocalTargetInfo target, LocalTargetInfo destination) { base.QueueCastingJob(target, destination); if (moteCast == null || moteCast.Destroyed) { moteCast = MoteMaker.MakeAttachedOverlay(pawn, ThingDefOf.Mote_CastPsycast, MoteCastOffset, MoteCastScale, base.verb.verbProps.warmupTime - MoteCastFadeTime); } }
protected void Emit() { mote = MoteMaker.MakeStaticMote(parent.DrawPos + Props.offset, parent.Map, Props.mote); if (!Props.soundOnEmission.NullOrUndefined()) { Props.soundOnEmission.PlayOneShot(SoundInfo.InMap(parent)); } }
public static bool MoteSpawned(RealtimeMoteList __instance, Mote newMote) { lock (__instance) { __instance.allMotes.Add(newMote); } return(false); }
public static void Postfix(Mote __instance, ref Vector3 __result) { if (DrawPos_Patch.ChangeDrawPos) { __result.z += DrawPos_Patch.zLevelOffset; __result.y += DrawPos_Patch.yLevelOffset; } }
public static bool prefix(ref RealtimeMoteList __instance, Mote oldMote) { lock (locker) { __instance.allMotes.Remove(oldMote); } return(false); }
public static bool prefix(ref RealtimeMoteList __instance, Mote newMote) { lock (locker) { __instance.allMotes.Add(newMote); } return(false); }
public static Mote MakeStunOverlay(Thing stunnedThing) { Mote obj = (Mote)ThingMaker.MakeThing(ThingDefOf.Mote_Stun); obj.Attach(stunnedThing); GenSpawn.Spawn(obj, stunnedThing.Position, stunnedThing.Map); return(obj); }
public static Mote MakeStunOverlay(Thing stunnedThing) { Mote mote = (Mote)ThingMaker.MakeThing(ThingDefOf.Mote_Stun, null); mote.Attach(stunnedThing); GenSpawn.Spawn(mote, stunnedThing.Position, stunnedThing.Map); return(mote); }
public SavedJob(Job job) { def = job.def; targetA = job.targetA; targetB = job.targetB; targetC = job.targetC; targetQueueA = job.targetQueueA; targetQueueB = job.targetQueueB; count = job.count; countQueue = job.countQueue; startTick = job.startTick; expiryInterval = job.expiryInterval; checkOverrideOnExpire = job.checkOverrideOnExpire; playerForced = job.playerForced; placedThings = job.placedThings; maxNumMeleeAttacks = job.maxNumMeleeAttacks; maxNumStaticAttacks = job.maxNumStaticAttacks; locomotionUrgency = job.locomotionUrgency; haulMode = job.haulMode; bill = job.bill; commTarget = job.commTarget; plantDefToSow = job.plantDefToSow; verbToUse = job.verbToUse; haulOpportunisticDuplicates = job.haulOpportunisticDuplicates; exitMapOnArrival = job.exitMapOnArrival; failIfCantJoinOrCreateCaravan = job.failIfCantJoinOrCreateCaravan; killIncappedTarget = job.killIncappedTarget; ignoreForbidden = job.ignoreForbidden; ignoreDesignations = job.ignoreDesignations; canBash = job.canBash; canUseRangedWeapon = job.canUseRangedWeapon; haulDroppedApparel = job.haulDroppedApparel; restUntilHealed = job.restUntilHealed; ignoreJoyTimeAssignment = job.ignoreJoyTimeAssignment; doUntilGatheringEnded = job.doUntilGatheringEnded; overeat = job.overeat; attackDoorIfTargetLost = job.attackDoorIfTargetLost; takeExtraIngestibles = job.takeExtraIngestibles; expireRequiresEnemiesNearby = job.expireRequiresEnemiesNearby; lord = job.lord; collideWithPawns = job.collideWithPawns; forceSleep = job.forceSleep; interaction = job.interaction; endIfCantShootTargetFromCurPos = job.endIfCantShootTargetFromCurPos; endIfCantShootInMelee = job.endIfCantShootInMelee; checkEncumbrance = job.checkEncumbrance; followRadius = job.followRadius; endAfterTendedOnce = job.endAfterTendedOnce; quest = job.quest; mote = job.mote; reactingToMeleeThreat = job.reactingToMeleeThreat; wasOnMeditationTimeAssignment = job.wasOnMeditationTimeAssignment; psyfocusTargetLast = job.psyfocusTargetLast; //jobGiverThinkTree = job.jobGiverThinkTree; //jobGiver = job.jobGiver; workGiverDef = job.workGiverDef; ability = job.ability; }
protected override IEnumerable <Toil> MakeNewToils() { if (!ModLister.RoyaltyInstalled) { Log.ErrorOnce("Bestowing cermonies are a Royalty-specific game system. If you want to use this code please check ModLister.RoyaltyInstalled before calling it. See rules on the Ludeon forum for more info.", 5464564); yield break; } AddFailCondition(() => Bestower.GetLord() == null || Bestower.GetLord().CurLordToil == null || !(Bestower.GetLord().CurLordToil is LordToil_BestowingCeremony_Wait)); yield return(Toils_Goto.GotoCell(TargetIndex.B, PathEndMode.OnCell)); Toil waitToil = Toils_General.Wait(471); waitToil.AddPreInitAction(delegate { Messages.Message("MessageBestowingCeremonyStarted".Translate(pawn.Named("PAWN")), Bestower, MessageTypeDefOf.PositiveEvent); }); waitToil.AddPreInitAction(delegate { if (!AnalyzeThroneRoom(Bestower, pawn)) { Messages.Message("BestowingCeremonyThroneroomRequirementsNotSatisfied".Translate(pawn.Named("PAWN"), pawn.royalty.GetTitleAwardedWhenUpdating(Bestower.Faction, pawn.royalty.GetFavor(Bestower.Faction)).label.Named("TITLE")), pawn, MessageTypeDefOf.NegativeEvent); ((LordJob_BestowingCeremony)Bestower.GetLord().LordJob).MakeCeremonyFail(); } }); waitToil.AddPreInitAction(delegate { SoundDefOf.Bestowing_Start.PlayOneShot(pawn); }); waitToil.tickAction = delegate { pawn.rotationTracker.FaceTarget(Bestower); if (mote == null || mote.Destroyed) { Vector3 loc = (pawn.TrueCenter() + Bestower.TrueCenter()) / 2f; mote = MoteMaker.MakeStaticMote(loc, pawn.Map, ThingDefOf.Mote_Bestow); } mote.Maintain(); if ((sound == null || sound.Ended) && waitToil.actor.jobs.curDriver.ticksLeftThisToil <= 307) { sound = SoundDefOf.Bestowing_Warmup.TrySpawnSustainer(SoundInfo.InMap(new TargetInfo(pawn.Position, pawn.Map), MaintenanceType.PerTick)); } if (sound != null) { sound.Maintain(); } }; waitToil.handlingFacing = false; waitToil.socialMode = RandomSocialMode.Off; waitToil.WithProgressBarToilDelay(TargetIndex.A); yield return(waitToil); yield return(Toils_General.Do(delegate { CeremonyJob.FinishCeremony(pawn); MoteMaker.MakeStaticMote((pawn.TrueCenter() + Bestower.TrueCenter()) / 2f, pawn.Map, ThingDefOf.Mote_PsycastAreaEffect, 2f); SoundDefOf.Bestowing_Finished.PlayOneShot(pawn); })); }
// Token: 0x060022A7 RID: 8871 RVA: 0x00103CA4 File Offset: 0x001020A4 public static void MakeMechFallMote(IntVec3 cell, Map map) { Mote mote = (Mote)ThingMaker.MakeThing(RimWorld.ThingDefOf.Mote_Bombardment, null); mote.exactPosition = cell.ToVector3Shifted(); mote.Scale = 5f; mote.rotationRate = 0f; GenSpawn.Spawn(mote, cell, map); }
public static void PlaceTempRoof(IntVec3 cell, Map map) { if (cell.ShouldSpawnMotesAt(map)) { Mote mote = (Mote)ThingMaker.MakeThing(ThingDefOf.Mote_TempRoof, null); mote.exactPosition = cell.ToVector3Shifted(); GenSpawn.Spawn(mote, cell, map); } }
public static void MakePowerBeamMote(IntVec3 cell, Map map) { Mote mote = (Mote)ThingMaker.MakeThing(ThingDefOf.Mote_PowerBeam, null); mote.exactPosition = cell.ToVector3Shifted(); mote.Scale = 90f; mote.rotationRate = 1.2f; GenSpawn.Spawn(mote, cell, map); }
public static void MakeBombardmentMote(IntVec3 cell, Map map) { Mote mote = (Mote)ThingMaker.MakeThing(ThingDefOf.Mote_Bombardment, null); mote.exactPosition = cell.ToVector3Shifted(); mote.Scale = (float)((float)Mathf.Max(23, 25) * 6.0); mote.rotationRate = 1.2f; GenSpawn.Spawn(mote, cell, map); }
public static void MakeCustomPowerBeamMote(IntVec3 cell, Map map) { Mote mote = (Mote)ThingMaker.MakeThing(AADefOf.Mote_MeguminBeam_AA); mote.exactPosition = cell.ToVector3Shifted(); mote.Scale = 90f; mote.rotationRate = 1.2f; GenSpawn.Spawn((Thing)mote, cell, map, WipeMode.Vanish); }
public static void MakePowerBeamMote(IntVec3 cell, Map map) { Mote obj = (Mote)ThingMaker.MakeThing(ThingDefOf.Mote_PowerBeam); obj.exactPosition = cell.ToVector3Shifted(); obj.Scale = 90f; obj.rotationRate = 1.2f; GenSpawn.Spawn(obj, cell, map); }
public static void MakeBombardmentMote_NewTmp(IntVec3 cell, Map map, float scale) { Mote obj = (Mote)ThingMaker.MakeThing(ThingDefOf.Mote_Bombardment); obj.exactPosition = cell.ToVector3Shifted(); obj.Scale = 150f * scale; obj.rotationRate = 1.2f; GenSpawn.Spawn(obj, cell, map); }
private void DoMuzzleFlash(Vector3 pos) { Mote mote = (Mote)ThingMaker.MakeThing(AADefOf.Mote_LargeMuzzleFlash_AA, null); mote.Scale = 2.6f; mote.exactRotation = base.CurrentRotation; mote.exactPosition = pos; GenSpawn.Spawn(mote, base.parentTurret.Position, base.parentTurret.Map, WipeMode.Vanish); }
public static void MakeBombardmentMote(IntVec3 cell, Map map) { Mote obj = (Mote)ThingMaker.MakeThing(ThingDefOf.Mote_Bombardment); obj.exactPosition = cell.ToVector3Shifted(); obj.Scale = (float)Mathf.Max(23, 25) * 6f; obj.rotationRate = 1.2f; GenSpawn.Spawn(obj, cell, map); }
public static void MakeStaticMote(Vector3 loc, Map map, ThingDef moteDef, float scale = 1f) { if (loc.ShouldSpawnMotesAt(map) && !map.moteCounter.Saturated) { Mote mote = (Mote)ThingMaker.MakeThing(moteDef, null); mote.exactPosition = loc; mote.Scale = scale; GenSpawn.Spawn(mote, loc.ToIntVec3(), map); } }
protected override IEnumerable<Toil> MakeNewToils() { QualityCategory fishingEquipmentQuality = QualityCategory.Normal; float catchSomethingThreshold = 0f; Building_FishingPier fishingPier = this.TargetThingA as Building_FishingPier; Passion passion = Passion.None; int fishingDuration = 1000; const float skillGainPerTick = 0.15f; float skillGainFactor = 0f; this.AddEndCondition(() => { var targ = this.pawn.jobs.curJob.GetTarget(fishingPierIndex).Thing; if (targ is Building && !targ.Spawned) return JobCondition.Incompletable; return JobCondition.Ongoing; }); this.FailOnBurningImmobile(fishingPierIndex); // Bill giver or product burning in carry phase. yield return Toils_Reserve.Reserve(fishingPierIndex); float statValue = this.pawn.GetStatValue(Util_FishIndustry.FishingSpeedDef, true); fishingDuration = (int)Math.Round((double)(800f / statValue)); yield return Toils_Goto.GotoThing(fishingPierIndex, fishingPier.riverCell).FailOnDespawnedOrNull(fishingPierIndex); Toil verifyFisherHasFishingEquipmentToil = new Toil() { initAction = () => { if ((this.pawn.equipment.Primary != null) && (this.pawn.equipment.Primary.def == Util_FishIndustry.HarpoonDef)) { this.fishingEquipment = FishingEquipment.Harpoon; this.pawn.equipment.Primary.TryGetQuality(out fishingEquipmentQuality); } foreach (Apparel apparel in this.pawn.apparel.WornApparel) { if (apparel.def == Util_FishIndustry.FishingRodDef) { this.fishingEquipment = FishingEquipment.FishingRod; apparel.TryGetQuality(out fishingEquipmentQuality); break; } } if (this.fishingEquipment == FishingEquipment.NoEquipment) { this.pawn.jobs.EndCurrentJob(JobCondition.Incompletable); } } }; yield return verifyFisherHasFishingEquipmentToil; Toil fishToil = new Toil() { initAction = () => { ThingDef moteDef = null; if (fishingEquipment == FishingEquipment.FishingRod) { if (fishingPier.Rotation == Rot4.North) { moteDef = Util_FishIndustry.MoteFishingRodNorthDef; } else if (fishingPier.Rotation == Rot4.East) { moteDef = Util_FishIndustry.MoteFishingRodEastDef; } else if (fishingPier.Rotation == Rot4.South) { moteDef = Util_FishIndustry.MoteFishingRodSouthDef; } else { moteDef = Util_FishIndustry.MoteFishingRodWestDef; } } if (moteDef != null) { this.fishingRodMote = (Mote)ThingMaker.MakeThing(moteDef, null); this.fishingRodMote.exactPosition = fishingPier.fishingSpotCell.ToVector3Shifted(); this.fishingRodMote.Scale = 1f; GenSpawn.Spawn(this.fishingRodMote, fishingPier.fishingSpotCell); } WorkTypeDef fishingWorkDef = DefDatabase<WorkTypeDef>.GetNamed("Fishing"); passion = this.pawn.skills.MaxPassionOfRelevantSkillsFor(fishingWorkDef); if (passion == Passion.None) { skillGainFactor = 0.3f; } else if (passion == Passion.Minor) { skillGainFactor = 1f; } else { skillGainFactor = 1.5f; } }, tickAction = () => { if (fishingEquipment == FishingEquipment.Harpoon) { if (Find.TickManager.TicksGame % GenTicks.TickRareInterval == 0) { Bullet thrownHarpoon = GenSpawn.Spawn(Util_FishIndustry.HarpoonDef.Verbs.First().projectileDef, this.pawn.Position) as Bullet; TargetInfo targetCell = new TargetInfo(fishingPier.fishingSpotCell + new IntVec3(Rand.RangeInclusive(-1, 1), 0, Rand.RangeInclusive(0, 2)).RotatedBy(fishingPier.Rotation)); thrownHarpoon.Launch(this.pawn, targetCell); } } this.pawn.Drawer.rotator.FaceCell(fishingPier.fishingSpotCell); if (passion == Passion.Minor) { this.pawn.needs.joy.GainJoy(NeedTunings.JoyPerXpForPassionMinor, JoyKindDefOf.Work); } else if (passion == Passion.Major) { this.pawn.needs.joy.GainJoy(NeedTunings.JoyPerXpForPassionMajor, JoyKindDefOf.Work); } SkillDef fishingSkillDef = DefDatabase<SkillDef>.GetNamed("Fishing"); this.pawn.skills.Learn(fishingSkillDef, skillGainPerTick * skillGainFactor); if (this.ticksLeftThisToil == 1) { if (this.fishingRodMote != null) { Log.Message("destroy mote"); this.fishingRodMote.Destroy(); } } }, defaultDuration = fishingDuration, defaultCompleteMode = ToilCompleteMode.Delay }; yield return fishToil.WithProgressBarToilDelay(fishingPierIndex); yield return verifyFisherHasFishingEquipmentToil; // Could be dropped during fishToil. Toil computeChanceToCatchToil = new Toil() { initAction = () => { float fishingSkillLevel = 0f; WorkTypeDef fishingWorkDef = DefDatabase<WorkTypeDef>.GetNamed("Fishing"); fishingSkillLevel = this.pawn.skills.AverageOfRelevantSkillsFor(fishingWorkDef); float fishingEquipmentQualityFactor = (float)fishingEquipmentQuality / (float)QualityCategory.Legendary; float fishingSkillFactor = fishingSkillLevel / 20f; float snowFactor = 1 - Find.SnowGrid.GetDepth(fishingPier.fishingSpotCell); float fishingEquipmentOffset = 0f; switch (this.fishingEquipment) { case FishingEquipment.Harpoon: fishingEquipmentOffset = 0.2f; break; case FishingEquipment.FishingRod: fishingEquipmentOffset = 0.5f; break; } catchSomethingThreshold = ((fishingEquipmentOffset * fishingEquipmentQualityFactor) + 0.4f * fishingSkillFactor) * (0.25f + 0.75f * snowFactor); // Reframe min and max chance (min 5%, max 75 % chance of success). catchSomethingThreshold = catchSomethingThreshold * 0.75f; catchSomethingThreshold = Math.Max(catchSomethingThreshold, 0.05f); }, defaultCompleteMode = ToilCompleteMode.Instant }; yield return computeChanceToCatchToil; Toil catchFishToil = new Toil() { initAction = () => { Job curJob = this.pawn.jobs.curJob; Thing fishingCatch = null; bool catchIsSuccessful = Rand.Value <= catchSomethingThreshold; if (catchIsSuccessful == false) { MoteMaker.ThrowMetaIcon(this.pawn.Position, ThingDefOf.Mote_IncapIcon); this.pawn.jobs.EndCurrentJob(JobCondition.Incompletable); return; } float catchSelectorValue = Rand.Value; if (catchSelectorValue > 0.04f) { // Catch a fish. bool fishSpotIsMarshy = (Find.TerrainGrid.TerrainAt(fishingPier.fishingSpotCell) == TerrainDef.Named("Marsh")); bool isDaytime = (SkyManager.CurSkyGlow >= 0.4f); ThingDef caugthFishDef = Util_FishIndustry.TailteethDef; if (fishSpotIsMarshy && isDaytime) { caugthFishDef = (from fishSpecies in Util_FishIndustry.GetFishSpeciesList() where fishSpecies.livesInMarsh where fishSpecies.catchableDuringDay select fishSpecies).RandomElementByWeight((ThingDef_FishSpecies def) => def.commonality); } else if (fishSpotIsMarshy && !isDaytime) { caugthFishDef = (from fishSpecies in Util_FishIndustry.GetFishSpeciesList() where fishSpecies.livesInMarsh where fishSpecies.catchableDuringNight select fishSpecies).RandomElementByWeight((ThingDef_FishSpecies def) => def.commonality); } else if (!fishSpotIsMarshy && isDaytime) { caugthFishDef = (from fishSpecies in Util_FishIndustry.GetFishSpeciesList() where fishSpecies.livesInSea where fishSpecies.catchableDuringDay select fishSpecies).RandomElementByWeight((ThingDef_FishSpecies def) => def.commonality); } else { caugthFishDef = (from fishSpecies in Util_FishIndustry.GetFishSpeciesList() where fishSpecies.livesInSea where fishSpecies.catchableDuringNight select fishSpecies).RandomElementByWeight((ThingDef_FishSpecies def) => def.commonality); } /*TerrainDef fishSpotType = Find.TerrainGrid.TerrainAt(fishingPier.fishingSpotCell); List<ThingDef> fishSpeciesList = null; ThingDef_FishSpecies.AquaticEnvironment aquaticEnvironment; ThingDef_FishSpecies.LivingTime livingTime; float fishSpeciesTotalCommonality = 0f; float fishSpeciesCommonalitySum = 0f; // Aquatic environment. if (fishSpotType == TerrainDef.Named("Marsh")) { aquaticEnvironment = ThingDef_FishSpecies.AquaticEnvironment.Marsh; } else { aquaticEnvironment = ThingDef_FishSpecies.AquaticEnvironment.Sea; } // Day time. if (SkyManager.CurSkyGlow >= 0.4f) { livingTime = ThingDef_FishSpecies.LivingTime.Day; } else { livingTime = ThingDef_FishSpecies.LivingTime.Night; } fishSpeciesList = Util_FishIndustry.GetFishSpeciesList(aquaticEnvironment, livingTime); fishSpeciesTotalCommonality = Util_FishIndustry.GetFishSpeciesTotalCommonality(aquaticEnvironment, livingTime); float randomSelector = Rand.Range(0f, fishSpeciesTotalCommonality); ThingDef selectedFishSpecies = null; for (int fishSpeciesIndex = 0; fishSpeciesIndex < fishSpeciesList.Count; fishSpeciesIndex++) { ThingDef_FishSpecies currentFishSpecies = fishSpeciesList[fishSpeciesIndex] as ThingDef_FishSpecies; fishSpeciesCommonalitySum += currentFishSpecies.commonality; if (randomSelector <= fishSpeciesCommonalitySum) { selectedFishSpecies = currentFishSpecies; break; } }*/ fishingCatch = GenSpawn.Spawn(caugthFishDef, this.pawn.Position); fishingCatch.stackCount = (caugthFishDef as ThingDef_FishSpecies).catchQuantity; fishingPier.fishStock--; } else if (catchSelectorValue > 0.02) { fishingCatch = GenSpawn.Spawn(Util_FishIndustry.OysterDef, this.pawn.Position); fishingCatch.stackCount = Rand.RangeInclusive(5, 27); } else { float bonusCatchValue = Rand.Value; if (bonusCatchValue < 0.01f) { // Really small chance to find a sunken treasure!!! fishingCatch = GenSpawn.Spawn(ThingDefOf.Gold, this.pawn.Position); fishingCatch.stackCount = Rand.RangeInclusive(58, 289); Thing treasureSilver = GenSpawn.Spawn(ThingDefOf.Silver, fishingPier.middleCell); treasureSilver.stackCount = Rand.RangeInclusive(237, 2154); string eventText = this.pawn.Name.ToStringShort.CapitalizeFirst() + " has found a sunken treasure while fishing! What a good catch!\n"; Find.LetterStack.ReceiveLetter("Sunken treasure!", eventText, LetterType.Good, this.pawn.Position); } else if (bonusCatchValue < 0.02f) { // Really small chance to find a complete power armor set + sniper or charge rifle. Thing powerArmor = GenSpawn.Spawn(ThingDef.Named("Apparel_PowerArmor"), this.pawn.Position); fishingCatch = powerArmor; // Used to carry the power armor. Thing powerArmorHelmet = GenSpawn.Spawn(ThingDef.Named("Apparel_PowerArmorHelmet"), this.pawn.Position); Thing rifle = null; if (Rand.Value < 0.5f) { rifle = GenSpawn.Spawn(ThingDef.Named("Gun_ChargeRifle"), this.pawn.Position); } else { rifle = GenSpawn.Spawn(ThingDef.Named("Gun_SniperRifle"), this.pawn.Position); } CompQuality qualityComp = powerArmor.TryGetComp<CompQuality>(); if (qualityComp != null) { qualityComp.SetQuality(QualityCategory.Masterwork, ArtGenerationContext.Outsider); } qualityComp = powerArmorHelmet.TryGetComp<CompQuality>(); if (qualityComp != null) { qualityComp.SetQuality(QualityCategory.Masterwork, ArtGenerationContext.Outsider); } qualityComp = rifle.TryGetComp<CompQuality>(); if (qualityComp != null) { qualityComp.SetQuality(QualityCategory.Masterwork, ArtGenerationContext.Outsider); } Faction faction = Find.FactionManager.FirstFactionOfDef(FactionDefOf.SpacerHostile); Pawn deadMarine = PawnGenerator.GeneratePawn(PawnKindDefOf.SpaceSoldier, faction); GenSpawn.Spawn(deadMarine, fishingPier.bankCell); HealthUtility.GiveInjuriesToKill(deadMarine); List<Thing> thingsList = deadMarine.Position.GetThingList(); foreach (Thing thing in thingsList) { if (thing.def.defName.Contains("Corpse")) { CompRottable rotComp = thing.TryGetComp<CompRottable>(); if (rotComp != null) { rotComp.RotProgress = 20f * GenDate.TicksPerDay; // 20 days so the corpse is dessicated. } } } string eventText = this.pawn.Name.ToStringShort.CapitalizeFirst() + " has cought a dead body while fishing!\n\n'This is really disgusting but look at his gear! This guy was probably a Mining & Co. security member. I wonder what happend to him...'\n"; Find.LetterStack.ReceiveLetter("Dead marine", eventText, LetterType.Good, this.pawn.Position); } else { // Find a small amount of gold. fishingCatch = GenSpawn.Spawn(ThingDefOf.Gold, this.pawn.Position); fishingCatch.stackCount = Rand.RangeInclusive(1, 7); } // TODO: add chance to get hurt by a tailteeth (missing finger or even hand!). } IntVec3 storageCell; if (StoreUtility.TryFindBestBetterStoreCellFor(fishingCatch, this.pawn, StoragePriority.Unstored, this.pawn.Faction, out storageCell, true)) { this.pawn.carrier.TryStartCarry(fishingCatch); curJob.targetB = storageCell; curJob.targetC = fishingCatch; curJob.maxNumToCarry = 99999; } else { this.pawn.jobs.EndCurrentJob(JobCondition.Succeeded); } } }; yield return catchFishToil; // Reserve the product and storage cell. yield return Toils_Reserve.Reserve(TargetIndex.B); yield return Toils_Reserve.Reserve(TargetIndex.C); Toil carryToCell = Toils_Haul.CarryHauledThingToCell(TargetIndex.B); yield return carryToCell; yield return Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, carryToCell, true); yield return Toils_Reserve.Release(fishingPierIndex); }