| 563 | } |
| 564 | |
| 565 | void Projectile::processAction(Json const& action) { |
| 566 | Json parameters; |
| 567 | String command; |
| 568 | |
| 569 | if (action.type() == Json::Type::Object) { |
| 570 | parameters = action; |
| 571 | command = parameters.getString("action").toLower(); |
| 572 | } else { |
| 573 | command = action.toString().toLower(); |
| 574 | } |
| 575 | |
| 576 | auto doWithDelay = [this](int stepsDelay, WorldAction function) { |
| 577 | if (stepsDelay == 0) |
| 578 | function(world()); |
| 579 | else |
| 580 | world()->timer((float)stepsDelay / 60.f, function); |
| 581 | }; |
| 582 | |
| 583 | if (command == "tile") { |
| 584 | if (isSlave()) |
| 585 | return; |
| 586 | |
| 587 | auto materialDatabase = Root::singleton().materialDatabase(); |
| 588 | List<MaterialId> tileDrops; |
| 589 | unsigned totalDrops = 0; |
| 590 | for (auto sets : parameters.getArray("materials")) { |
| 591 | unsigned numDrops = sets.getUInt("quantity", 1); |
| 592 | auto mat = materialDatabase->materialId(sets.getString("kind")); |
| 593 | for (unsigned i = 0; i < numDrops; i++) |
| 594 | tileDrops.push_back(mat); |
| 595 | totalDrops += numDrops; |
| 596 | } |
| 597 | |
| 598 | List<Vec2I> openSpaces = world()->findEmptyTiles(m_lastNonCollidingTile, parameters.getInt("radius", 2), totalDrops); |
| 599 | if (openSpaces.size() < totalDrops) |
| 600 | Logger::debug("Couldn't find a place for all the tile drops. {} drops requested, {} spaces found.", totalDrops, openSpaces.size()); |
| 601 | |
| 602 | bool allowEntityOverlap = parameters.getBool("allowEntityOverlap", true); |
| 603 | |
| 604 | Random::shuffle(tileDrops); |
| 605 | for (auto& tile : zip(openSpaces, tileDrops)) { |
| 606 | if (!world()->modifyTile(std::get<0>(tile), PlaceMaterial{TileLayer::Foreground, std::get<1>(tile), MaterialHue()}, allowEntityOverlap)) { |
| 607 | auto itemDrop = ItemDrop::createRandomizedDrop(materialDatabase->materialItemDrop(std::get<1>(tile)), (Vec2F)std::get<0>(tile)); |
| 608 | world()->addEntity(itemDrop); |
| 609 | } |
| 610 | } |
| 611 | |
| 612 | } else if (command == "applysurfacemod") { |
| 613 | if (isSlave()) |
| 614 | return; |
| 615 | |
| 616 | auto materialDatabase = Root::singleton().materialDatabase(); |
| 617 | Maybe<ModId> previousMod = |
| 618 | parameters.optString("previousMod").apply(bind(&MaterialDatabase::modId, materialDatabase, _1)); |
| 619 | ModId newMod = materialDatabase->modId(parameters.getString("newMod")); |
| 620 | int radius = parameters.getInt("radius", 0); |
| 621 | float chance = parameters.getFloat("chance", 1.0f); |
| 622 |
nothing calls this directly
no test coverage detected