| 454 | } |
| 455 | |
| 456 | void ContainerObject::tickCrafting(float dt) { |
| 457 | if (!m_crafting.get()) |
| 458 | return; |
| 459 | |
| 460 | auto inputItems = m_items->items(); |
| 461 | inputItems.removeLast(); |
| 462 | auto recipe = recipeForMaterials(inputItems); |
| 463 | bool craftingFail = false; |
| 464 | if (recipe.isNull() || m_goalRecipe != recipe) |
| 465 | craftingFail = true; |
| 466 | ItemPtr targetItem = m_items->at(m_items->size() - 1); |
| 467 | if (targetItem) { |
| 468 | if (!targetItem->matches(m_goalRecipe.output, true)) |
| 469 | craftingFail = true; |
| 470 | else if (targetItem->count() + m_goalRecipe.output.count() > targetItem->maxStack()) |
| 471 | craftingFail = true; |
| 472 | } |
| 473 | if (craftingFail) { |
| 474 | m_crafting.set(false); |
| 475 | m_craftingProgress.set(0); |
| 476 | m_goalRecipe = ItemRecipe(); |
| 477 | return; |
| 478 | } |
| 479 | if (m_goalRecipe.duration > 0) |
| 480 | m_craftingProgress.set(m_craftingProgress.get() + dt / m_goalRecipe.duration); |
| 481 | else |
| 482 | m_craftingProgress.set(1.0f); |
| 483 | if (m_craftingProgress.get() >= 1.0f) { |
| 484 | m_craftingProgress.set(0); |
| 485 | for (auto const& input : m_goalRecipe.inputs) { |
| 486 | bool consumed = m_items->consumeItems(input); |
| 487 | _unused(consumed); |
| 488 | starAssert(consumed); |
| 489 | } |
| 490 | ItemPtr overflow = |
| 491 | m_items->putItems(m_items->size() - 1, Root::singleton().itemDatabase()->item(m_goalRecipe.output)); |
| 492 | if (overflow) |
| 493 | world()->addEntity(ItemDrop::createRandomizedDrop(overflow, position())); |
| 494 | itemsUpdated(); |
| 495 | } |
| 496 | } |
| 497 | |
| 498 | ItemPtr ContainerObject::doAddItems(ItemPtr const& items) { |
| 499 | itemsUpdated(); |
nothing calls this directly
no test coverage detected