Skip to content

Commit

Permalink
feat: monsters weight
Browse files Browse the repository at this point in the history
  • Loading branch information
phacUFPE committed Sep 27, 2024
1 parent 64a0877 commit 079410f
Show file tree
Hide file tree
Showing 26 changed files with 367 additions and 160 deletions.
14 changes: 7 additions & 7 deletions source/common_windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,14 +211,14 @@ struct MapConversionContext {
NpcMap npcType;

void operator()(Map &map, Tile* tile, long long done) {
if (tile->monster) {
MonsterMap::iterator f = monsterType.find(tile->monster->getName());
if (f == monsterType.end()) {
MonsterInfo info = {
tile->monster->getName(),
tile->monster->getLookType()
for (const auto monster : tile->monsters) {
const auto it = monsterType.find(monster->getName());
if (it == monsterType.end()) {
MonsterInfo monsterInfo = {
monster->getName(),
monster->getLookType()
};
monsterType[tile->monster->getName()] = info;
monsterType[monster->getName()] = monsterInfo;
}
}
if (tile->npc) {
Expand Down
43 changes: 32 additions & 11 deletions source/copybuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ void CopyBuffer::copy(Editor &editor, int floor) {

int tile_count = 0;
int item_count = 0;
int monsterCount = 0;
copyPos = Position(0xFFFF, 0xFFFF, floor);

for (Tile* tile : editor.getSelection()) {
Expand All @@ -83,9 +84,13 @@ void CopyBuffer::copy(Editor &editor, int floor) {
}

// Monster
if (tile->monster && tile->monster->isSelected()) {
copied_tile->monster = tile->monster->deepCopy();
const auto monstersSelection = tile->getSelectedMonsters();
for (auto monsterIt = monstersSelection.begin(); monsterIt != monstersSelection.end(); ++monsterIt) {
++monsterCount;
// Copy items to copybuffer
copied_tile->addMonster((*monsterIt)->deepCopy());
}

if (tile->spawnMonster && tile->spawnMonster->isSelected()) {
copied_tile->spawnMonster = tile->spawnMonster->deepCopy();
}
Expand All @@ -108,9 +113,16 @@ void CopyBuffer::copy(Editor &editor, int floor) {
}
}

std::ostringstream ss;
ss << "Copied " << tile_count << " tile" << (tile_count > 1 ? "s" : "") << " (" << item_count << " item" << (item_count > 1 ? "s" : "") << ")";
g_gui.SetStatusText(wxstr(ss.str()));
fmt::dynamic_format_arg_store<fmt::format_context> store;

store.push_back(tile_count);
tile_count > 1 ? store.push_back("s") : store.push_back("");
store.push_back(item_count);
item_count > 1 ? store.push_back("s") : store.push_back("");
store.push_back(monsterCount);
monsterCount > 1 ? store.push_back("s") : store.push_back("");

g_gui.SetStatusText(fmt::vformat("Copied {} tile{}, {} item{} and {} monster{}", store));
}

void CopyBuffer::cut(Editor &editor, int floor) {
Expand All @@ -125,6 +137,7 @@ void CopyBuffer::cut(Editor &editor, int floor) {
Map &map = editor.getMap();
int tile_count = 0;
int item_count = 0;
int monsterCount = 0;
copyPos = Position(0xFFFF, 0xFFFF, floor);

BatchAction* batch = editor.createBatch(ACTION_CUT_TILES);
Expand Down Expand Up @@ -153,9 +166,10 @@ void CopyBuffer::cut(Editor &editor, int floor) {
}

// Monster
if (newtile->monster && newtile->monster->isSelected()) {
copied_tile->monster = newtile->monster;
newtile->monster = nullptr;
const auto monsterSelection = newtile->popSelectedMonsters();
for (auto monsterIt = monsterSelection.begin(); monsterIt != monsterSelection.end(); ++monsterIt) {
++monsterCount;
copied_tile->monsters.emplace_back(*monsterIt);
}

if (newtile->spawnMonster && newtile->spawnMonster->isSelected()) {
Expand Down Expand Up @@ -226,9 +240,16 @@ void CopyBuffer::cut(Editor &editor, int floor) {
editor.addBatch(batch);
editor.updateActions();

std::stringstream ss;
ss << "Cut out " << tile_count << " tile" << (tile_count > 1 ? "s" : "") << " (" << item_count << " item" << (item_count > 1 ? "s" : "") << ")";
g_gui.SetStatusText(wxstr(ss.str()));
fmt::dynamic_format_arg_store<fmt::format_context> store;

store.push_back(tile_count);
tile_count > 1 ? store.push_back("s") : store.push_back("");
store.push_back(item_count);
item_count > 1 ? store.push_back("s") : store.push_back("");
store.push_back(monsterCount);
monsterCount > 1 ? store.push_back("s") : store.push_back("");

g_gui.SetStatusText(fmt::vformat("Cut out {} tile{}, {} item{} and {} monster{}", store));
}

void CopyBuffer::paste(Editor &editor, const Position &toPosition) {
Expand Down
27 changes: 20 additions & 7 deletions source/editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1100,10 +1100,20 @@ void Editor::moveSelection(const Position &offset) {
new_tile->spawnMonster = nullptr;
}
// Move monster
if (new_tile->monster && new_tile->monster->isSelected()) {
storage_tile->monster = new_tile->monster;
new_tile->monster = nullptr;
const auto monstersSelection = new_tile->popSelectedMonsters();
for (const auto monster : monstersSelection) {
storage_tile->addMonster(monster);
}
/*
if (!new_tile->monsters.empty()) {
const auto view = std::ranges::remove_if(new_tile->monsters.begin(), new_tile->monsters.end(), [](const auto monster) {
return monster->isSelected();
});
storage_tile->monsters = std::vector<Monster*>(view.begin(), view.end());
new_tile->monsters.erase(view.begin(), view.end());
}
*/
// Move npc
if (new_tile->npc && new_tile->npc->isSelected()) {
storage_tile->npc = new_tile->npc;
Expand Down Expand Up @@ -1325,6 +1335,7 @@ void Editor::destroySelection() {
} else {
int tile_count = 0;
int item_count = 0;
int monsterCount = 0;
PositionList tilestoborder;

BatchAction* batch = actionQueue->createBatch(ACTION_DELETE_TILES);
Expand All @@ -1342,10 +1353,12 @@ void Editor::destroySelection() {
// Delete the items from the tile
delete *iit;
}
// Monster
if (newtile->monster && newtile->monster->isSelected()) {
delete newtile->monster;
newtile->monster = nullptr;

const auto monstersSelection = newtile->popSelectedMonsters();
for (auto monsterIt = monstersSelection.begin(); monsterIt != monstersSelection.end(); ++monsterIt) {
++monsterCount;
// Delete the monsters from the tile
delete *monsterIt;
}

if (newtile->spawnMonster && newtile->spawnMonster->isSelected()) {
Expand Down
1 change: 1 addition & 0 deletions source/gui_ids.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ enum EditorActionID {
PALETTE_MONSTER_SPAWN_TIME,
PALETTE_MONSTER_SPAWN_SIZE,
PALETTE_MONSTER_SPAWN_DENSITY,
PALETTE_MONSTER_DEFAULT_WEIGHT,

PALETTE_NPC_TILESET_CHOICE,
PALETTE_NPC_LISTBOX,
Expand Down
62 changes: 36 additions & 26 deletions source/iomap_otbm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1058,6 +1058,11 @@ bool IOMapOTBM::loadSpawnsMonster(Map &map, pugi::xml_document &doc) {
spawntime = g_settings.getInteger(Config::DEFAULT_SPAWN_MONSTER_TIME);
}

uint8_t weight = monsterNode.attribute("weight").as_uint();
if (weight == 0) {
weight = g_settings.getInteger(Config::MONSTER_DEFAULT_WEIGHT);
}

Direction direction = NORTH;
int dir = monsterNode.attribute("direction").as_int(-1);
if (dir >= DIRECTION_FIRST && dir <= DIRECTION_LAST) {
Expand Down Expand Up @@ -1090,16 +1095,14 @@ bool IOMapOTBM::loadSpawnsMonster(Map &map, pugi::xml_document &doc) {
}

if (!monsterTile) {
wxString err;
err << "Discarding monster \"" << name << "\" at " << monsterPosition.x << ":" << monsterPosition.y << ":" << monsterPosition.z << " due to invalid position.";
warnings.Add(err);
const auto error = fmt::format("Discarding monster \"{}\" at {}:{}:{} due to invalid position", name, monsterPosition.x, monsterPosition.y, monsterPosition.z);
warnings.Add(error);
break;
}

if (monsterTile->monster) {
wxString err;
err << "Duplicate monster \"" << name << "\" at " << monsterPosition.x << ":" << monsterPosition.y << ":" << monsterPosition.z << " was discarded.";
warnings.Add(err);
if (monsterTile->isMonsterRepeated(name)) {
const auto error = fmt::format("Duplicate monster \"{}\" at {}:{}:{} was discarded.", name, monsterPosition.x, monsterPosition.y, monsterPosition.z);
warnings.Add(error);
break;
}

Expand All @@ -1111,7 +1114,8 @@ bool IOMapOTBM::loadSpawnsMonster(Map &map, pugi::xml_document &doc) {
Monster* monster = newd Monster(type);
monster->setDirection(direction);
monster->setSpawnMonsterTime(spawntime);
monsterTile->monster = monster;
monster->setWeight(weight);
monsterTile->monsters.emplace_back(monster);

if (monsterTile->getLocation()->getSpawnMonsterCount() == 0) {
// No monster spawn, create a newd one
Expand Down Expand Up @@ -1766,26 +1770,32 @@ bool IOMapOTBM::saveSpawns(Map &map, pugi::xml_document &doc) {
for (int32_t x = -radius; x <= radius; ++x) {
Tile* monster_tile = map.getTile(spawnPosition + Position(x, y, 0));
if (monster_tile) {
Monster* monster = monster_tile->monster;
if (monster && !monster->isSaved()) {
pugi::xml_node monsterNode = spawnNode.append_child("monster");
monsterNode.append_attribute("name") = monster->getName().c_str();
monsterNode.append_attribute("x") = x;
monsterNode.append_attribute("y") = y;
monsterNode.append_attribute("z") = spawnPosition.z;
auto monsterSpawnTime = monster->getSpawnMonsterTime();
if (monsterSpawnTime > std::numeric_limits<uint32_t>::max() || monsterSpawnTime < std::numeric_limits<uint32_t>::min()) {
monsterSpawnTime = 60;
}
for (const auto monster : monster_tile->monsters) {
if (monster && !monster->isSaved()) {
pugi::xml_node monsterNode = spawnNode.append_child("monster");
monsterNode.append_attribute("name") = monster->getName().c_str();
monsterNode.append_attribute("x") = x;
monsterNode.append_attribute("y") = y;
monsterNode.append_attribute("z") = spawnPosition.z;
auto monsterSpawnTime = monster->getSpawnMonsterTime();
if (monsterSpawnTime > std::numeric_limits<uint32_t>::max() || monsterSpawnTime < std::numeric_limits<uint32_t>::min()) {
monsterSpawnTime = 60;
}

monsterNode.append_attribute("spawntime") = monsterSpawnTime;
if (monster->getDirection() != NORTH) {
monsterNode.append_attribute("direction") = monster->getDirection();
}
monsterNode.append_attribute("spawntime") = monsterSpawnTime;
if (monster->getDirection() != NORTH) {
monsterNode.append_attribute("direction") = monster->getDirection();
}

// Mark as saved
monster->save();
monsterList.push_back(monster);
if (monster_tile->monsters.size() > 1) {
const auto weight = monster->getWeight();
monsterNode.append_attribute("weight") = weight > 0 ? weight : g_settings.getInteger(Config::MONSTER_DEFAULT_WEIGHT);
}

// Mark as saved
monster->save();
monsterList.push_back(monster);
}
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions source/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ _Ret_bytecap_(_Size) inline void* __CRTDECL operator new[](size_t _Size, const c

#include <asio.hpp>
#include <fmt/core.h>
#include <fmt/format.h>
#include <fmt/args.h>
#include <nlohmann/json.hpp>

#include "definitions.h"
Expand Down
25 changes: 16 additions & 9 deletions source/main_menubar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1540,7 +1540,7 @@ void MainMenuBar::OnMapRemoveEmptyMonsterSpawns(wxCommandEvent &WXUNUSED(event))
g_gui.CreateLoadBar("Searching map for empty monsters spawns to remove...");

Map &map = g_gui.GetCurrentMap();
MonsterVector monster;
MonsterVector monsters;
TileVector toDeleteSpawns;
for (const auto &spawnPosition : map.spawnsMonster) {
Tile* tile = map.getTile(spawnPosition);
Expand All @@ -1554,10 +1554,19 @@ void MainMenuBar::OnMapRemoveEmptyMonsterSpawns(wxCommandEvent &WXUNUSED(event))
for (int32_t y = -radius; y <= radius; ++y) {
for (int32_t x = -radius; x <= radius; ++x) {
Tile* creature_tile = map.getTile(spawnPosition + Position(x, y, 0));
if (creature_tile && creature_tile->monster && !creature_tile->monster->isSaved()) {
creature_tile->monster->save();
monster.push_back(creature_tile->monster);
empty = false;
if (creature_tile) {
for (const auto monster : creature_tile->monsters) {
if (empty) {
empty = false;
}

if (monster->isSaved()) {
continue;
}

monster->save();
monsters.push_back(monster);
}
}
}
}
Expand All @@ -1567,7 +1576,7 @@ void MainMenuBar::OnMapRemoveEmptyMonsterSpawns(wxCommandEvent &WXUNUSED(event))
}
}

for (Monster* monster : monster) {
for (const auto monster : monsters) {
monster->reset();
}

Expand Down Expand Up @@ -1847,9 +1856,7 @@ void MainMenuBar::OnMapStatistics(wxCommandEvent &WXUNUSED(event)) {
spawn_npc_count += 1;
}

if (tile->monster) {
monster_count += 1;
}
monster_count += tile->monsters.size();

if (tile->npc) {
npc_count += 1;
Expand Down
13 changes: 7 additions & 6 deletions source/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -893,12 +893,13 @@ int64_t RemoveMonstersOnMap(Map &map, bool selectedOnly) {
++it;
continue;
}
if (tile->monster) {
delete tile->monster;
tile->monster = nullptr;
for (auto monster : tile->monsters) {
delete monster;
++removed;
}

tile->monsters.clear();

++it;
}
return removed;
Expand All @@ -919,10 +920,10 @@ std::pair<int64_t, std::unordered_map<std::string, int64_t>> CountMonstersOnMap(
++it;
continue;
}
if (tile->monster) {

for (const auto monster : tile->monsters) {
++total;
std::string monsterName = tile->monster->getName();
++monsterCount[monsterName];
++monsterCount[monster->getName()];
}

++it;
Expand Down
Loading

0 comments on commit 079410f

Please sign in to comment.