public override void Tick() { base.Tick(); AdjustPowerNeed(); if (!powerComp.PowerOn && soundSustainer != null && !soundSustainer.Ended) { soundSustainer.End(); } if (flickableComp == null || (flickableComp != null && flickableComp.SwitchIsOn)) { //State machine switch (printerStatus) { case CrafterStatus.Filling: { //Emit smoke if (powerComp.PowerOn && Current.Game.tickManager.TicksGame % 300 == 0) { MoteMaker.ThrowSmoke(Position.ToVector3(), Map, 1f); } //If we aren't being filled, then start. var pendingRequests = orderProcessor.PendingRequests(); bool startPrinting = pendingRequests == null; if (pendingRequests != null && pendingRequests.Count() == 0) { startPrinting = true; } if (startPrinting) { //Initiate printing phase. StartPrinting(); } } break; case CrafterStatus.Crafting: { if (powerComp.PowerOn) { //Emit smoke if (Current.Game.tickManager.TicksGame % 100 == 0) { MoteMaker.ThrowSmoke(Position.ToVector3(), Map, 1.33f); } //Visual effects if (Current.Game.tickManager.TicksGame % 250 == 0) { for (int i = 0; i < 3; i++) { MoteMaker.ThrowMicroSparks(Position.ToVector3() + new Vector3(Rand.Range(-1, 1), 0f, Rand.Range(-1, 1)), Map); } } //Sound effect if (soundSustainer == null || soundSustainer.Ended) { SoundDef soundDef = printerProperties.craftingSound; if (soundDef != null && soundDef.sustain) { SoundInfo info = SoundInfo.InMap(this, MaintenanceType.PerTick); soundSustainer = soundDef.TrySpawnSustainer(info); } } if (soundSustainer != null && !soundSustainer.Ended) { soundSustainer.Maintain(); } //Periodically use resources. nextResourceTick--; if (nextResourceTick <= 0) { nextResourceTick = printerProperties.resourceTick; //Deduct resources from each category. foreach (ThingOrderRequest thingOrderRequest in orderProcessor.requestedItems) { if (thingOrderRequest.nutrition) { //Food if (CountNutrition() > 0f) { //Grab first stack of Nutrition. Thing item = ingredients.First(thing => thing.def.IsIngestible); if (item != null) { int resourceTickAmount = (int)Math.Ceiling((thingOrderRequest.amount / ((double)(printerProperties.ticksToCraft + extraTimeCost) / printerProperties.resourceTick))); int amount = Math.Min(resourceTickAmount, item.stackCount); Thing outThing = null; Corpse outCorpse = item as Corpse; if (outCorpse != null) { if (outCorpse.IsDessicated()) { //If rotten, just drop it. ingredients.TryDrop(outCorpse, InteractionCell, Map, ThingPlaceMode.Near, 1, out outThing); } else { //Not rotten, dump all equipment. ingredients.TryDrop(outCorpse, InteractionCell, Map, ThingPlaceMode.Near, 1, out outThing); outCorpse.InnerPawn?.equipment?.DropAllEquipment(InteractionCell, false); outCorpse.InnerPawn?.apparel?.DropAll(InteractionCell, false); item.Destroy(); } } else { Thing takenItem = ingredients.Take(item, amount); takenItem.Destroy(); } } } } else { //Item if (ingredients.Any(thing => thing.def == thingOrderRequest.thingDef)) { //Grab first stack of Plasteel. Thing item = ingredients.First(thing => thing.def == thingOrderRequest.thingDef); if (item != null) { int resourceTickAmount = (int)Math.Ceiling((thingOrderRequest.amount / ((float)(printerProperties.ticksToCraft + extraTimeCost) / printerProperties.resourceTick))); int amount = Math.Min(resourceTickAmount, item.stackCount); Thing takenItem = ingredients.Take(item, amount); takenItem.Destroy(); } } } } } //Are we done yet? if (printingTicksLeft > 0) { printingTicksLeft--; } else { printerStatus = CrafterStatus.Finished; } } } break; case CrafterStatus.Finished: { if (pawnToPrint != null) { //Clear remaining materials. ingredients.ClearAndDestroyContents(); //Add effects FilthMaker.TryMakeFilth(InteractionCell, Map, RimWorld.ThingDefOf.Filth_Slime, 5); //Spawn GenSpawn.Spawn(pawnToPrint, InteractionCell, Map); pawnToPrint.health.AddHediff(RimWorld.HediffDefOf.CryptosleepSickness); pawnToPrint.needs.mood.thoughts.memories.TryGainMemory(NeedsDefOf.ChJAndroidSpawned); //Make and send letter. ChoiceLetter letter = LetterMaker.MakeLetter("AndroidPrintedLetterLabel".Translate(pawnToPrint.Name.ToStringShort), "AndroidPrintedLetterDescription".Translate(pawnToPrint.Name.ToStringFull), LetterDefOf.PositiveEvent, pawnToPrint); Find.LetterStack.ReceiveLetter(letter); //Reset pawnToPrint = null; printerStatus = CrafterStatus.Idle; extraTimeCost = 0; orderProcessor.requestedItems.Clear(); } } break; default: { if (soundSustainer != null && !soundSustainer.Ended) { soundSustainer.End(); } } break; } } }
public override void Tick() { base.Tick(); AdjustPowerNeed(); if (flickableComp == null || (flickableComp != null && flickableComp.SwitchIsOn)) { //State machine switch (crafterStatus) { case CrafterStatus.Filling: { ExtraCrafterTickAction(); //If we aren't being filled, then start. var pendingRequests = orderProcessor.PendingRequests(); bool startPrinting = pendingRequests == null; if (pendingRequests != null && pendingRequests.Count() == 0) { startPrinting = true; } if (startPrinting) { //Initiate printing phase. StartPrinting(); } } break; case CrafterStatus.Crafting: { ExtraCrafterTickAction(); if (powerComp.PowerOn) { //Periodically use resources. nextResourceTick--; if (nextResourceTick <= 0) { nextResourceTick = printerProperties.resourceTick; //Deduct resources from each category. foreach (ThingOrderRequest thingOrderRequest in orderProcessor.requestedItems) { if (thingOrderRequest.nutrition) { //Food if (CountNutrition() > 0f) { //Grab first stack of Nutrition. Thing item = ingredients.First(thing => thing.def.IsIngestible); if (item != null) { int resourceTickAmount = (int)Math.Ceiling((thingOrderRequest.amount / ((double)CraftingTicks / printerProperties.resourceTick))); int amount = Math.Min(resourceTickAmount, item.stackCount); Thing outThing = null; Corpse outCorpse = item as Corpse; if (outCorpse != null) { if (outCorpse.IsDessicated()) { //If rotten, just drop it. ingredients.TryDrop(outCorpse, InteractionCell, Map, ThingPlaceMode.Near, 1, out outThing); } else { //Not rotten, dump all equipment. ingredients.TryDrop(outCorpse, InteractionCell, Map, ThingPlaceMode.Near, 1, out outThing); outCorpse.InnerPawn?.equipment?.DropAllEquipment(InteractionCell, false); outCorpse.InnerPawn?.apparel?.DropAll(InteractionCell, false); item.Destroy(); } } else { Thing takenItem = ingredients.Take(item, amount); takenItem.Destroy(); } } } } else { //Item if (ingredients.Any(thing => thing.def == thingOrderRequest.thingDef)) { //Grab first stack of Plasteel. Thing item = ingredients.First(thing => thing.def == thingOrderRequest.thingDef); if (item != null) { int resourceTickAmount = (int)Math.Ceiling((thingOrderRequest.amount / ((float)CraftingTicks / printerProperties.resourceTick))); int amount = Math.Min(resourceTickAmount, item.stackCount); Thing takenItem = ingredients.Take(item, amount); takenItem.Destroy(); } } } } } //Are we done yet? if (craftingTicksLeft > 0) { craftingTicksLeft--; } else { crafterStatus = CrafterStatus.Finished; } } } break; case CrafterStatus.Finished: { if (pawnBeingCrafted != null) { ExtraCrafterTickAction(); //Clear remaining materials. ingredients.ClearAndDestroyContents(); //Spawn GenSpawn.Spawn(pawnBeingCrafted, InteractionCell, Map); if (printerProperties.hediffOnPawnCrafted != null) { pawnBeingCrafted.health.AddHediff(printerProperties.hediffOnPawnCrafted); } if (printerProperties.thoughtOnPawnCrafted != null) { pawnBeingCrafted.needs.mood.thoughts.memories.TryGainMemory(printerProperties.thoughtOnPawnCrafted); } //Make and send letter. ChoiceLetter letter = LetterMaker.MakeLetter(printerProperties.pawnCraftedLetterLabel.Translate(pawnBeingCrafted.Name.ToStringShort), printerProperties.pawnCraftedLetterText.Translate(pawnBeingCrafted.Name.ToStringFull), LetterDefOf.PositiveEvent, pawnBeingCrafted); Find.LetterStack.ReceiveLetter(letter); //Reset pawnBeingCrafted = null; crafterStatus = CrafterStatus.Idle; FinishAction(); } } break; default: break; } } }