protected void FurnaceWindowChanged(object sender, WindowChangeEventArgs e, IWorld world) { if (Handling) { return; } var window = sender as FurnaceWindow; var index = e.SlotIndex; if (index >= FurnaceWindow.MainIndex) { return; } Handling = true; e.Handled = true; window[index] = e.Value; var state = GetState(world, window.Coordinates); state.Items[0] = window[0]; state.Items[1] = window[1]; state.Items[2] = window[2]; SetState(world, window.Coordinates, state); Handling = true; if (!TrackedFurnaces.ContainsKey(window.Coordinates)) { TryInitializeFurnace(state, window.EventScheduler, world, window.Coordinates, window.ItemRepository); } Handling = false; }
private void TryInitializeFurnace(FurnaceState state, EventScheduler scheduler, IWorld world, Coordinates3D coords, IItemRepository itemRepository) { if (TrackedFurnaces.ContainsKey(coords)) { return; } var inputStack = state.Items[FurnaceWindow.IngredientIndex]; var fuelStack = state.Items[FurnaceWindow.FuelIndex]; var outputStack = state.Items[FurnaceWindow.OutputIndex]; var input = itemRepository.GetItemProvider(inputStack.Id) as ISmeltableItem; var fuel = itemRepository.GetItemProvider(fuelStack.Id) as IBurnableItem; if (state.BurnTimeRemaining > 0) { if (state.CookTime == -1 && input != null && (outputStack.Empty || outputStack.CanMerge(input.SmeltingOutput))) { state.CookTime = 0; SetState(world, coords, state); } var subject = new FurnaceEventSubject(); TrackedFurnaces[coords] = subject; scheduler.ScheduleEvent("smelting", subject, TimeSpan.FromSeconds(1), server => UpdateFurnace(server.Scheduler, world, coords, itemRepository)); return; } if (fuel != null && input != null) // We can maybe start { if (outputStack.Empty || outputStack.CanMerge(input.SmeltingOutput)) { // We can definitely start state.BurnTimeRemaining = state.BurnTimeTotal = (short)(fuel.BurnTime.TotalSeconds * 20); state.CookTime = 0; state.Items[FurnaceWindow.FuelIndex].Count--; SetState(world, coords, state); world.SetBlockId(coords, LitFurnaceBlock.BlockId); var subject = new FurnaceEventSubject(); TrackedFurnaces[coords] = subject; scheduler.ScheduleEvent("smelting", subject, TimeSpan.FromSeconds(1), server => UpdateFurnace(server.Scheduler, world, coords, itemRepository)); } } }
private void UpdateFurnace(EventScheduler scheduler, IWorld world, Coordinates3D coords, IItemRepository itemRepository) { if (TrackedFurnaces.ContainsKey(coords)) { TrackedFurnaces.Remove(coords); } if (world.GetBlockId(coords) != BlockId && world.GetBlockId(coords) != LitFurnaceBlock.BlockId) { return; } var state = GetState(world, coords); var inputStack = state.Items[FurnaceWindow.IngredientIndex]; var outputStack = state.Items[FurnaceWindow.OutputIndex]; var input = itemRepository.GetItemProvider(inputStack.Id) as ISmeltableItem; // Update burn time var burnTime = state.BurnTimeRemaining; if (state.BurnTimeRemaining > 0) { state.BurnTimeRemaining -= 20; // ticks if (state.BurnTimeRemaining <= 0) { state.BurnTimeRemaining = 0; state.BurnTimeTotal = 0; world.SetBlockId(coords, BlockId); } } // Update cook time if (state.CookTime < 200 && state.CookTime >= 0) { state.CookTime += 20; // ticks if (state.CookTime >= 200) { state.CookTime = 200; } } // Are we done cooking? if (state.CookTime == 200 && burnTime > 0) { state.CookTime = -1; if (input != null && (outputStack.Empty || outputStack.CanMerge(input.SmeltingOutput))) { if (outputStack.Empty) { outputStack = input.SmeltingOutput; } else if (outputStack.CanMerge(input.SmeltingOutput)) { outputStack.Count += input.SmeltingOutput.Count; } state.Items[FurnaceWindow.OutputIndex] = outputStack; state.Items[FurnaceWindow.IngredientIndex].Count--; } } SetState(world, coords, state); TryInitializeFurnace(state, scheduler, world, coords, itemRepository); }