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;
                }
            }
        }
Example #2
0
        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;
                }
            }
        }