Skip to content

Commit

Permalink
New Command 2056 - Spawn Map Event
Browse files Browse the repository at this point in the history
Command that clones Events from any map inside the current map.

Co-Authored-By: Primekick <[email protected]>
  • Loading branch information
jetrotal and Primekick committed May 7, 2024
1 parent b313163 commit a9bf6f8
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 19 deletions.
4 changes: 4 additions & 0 deletions src/game_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ class Game_Event : public Game_EventBase {
*/
Game_Event(int map_id, const lcf::rpg::Event* event);

void SetUnderlyingEvent(const lcf::rpg::Event* ev) {
event = ev;
}

/** Load from saved game */
void SetSaveData(lcf::rpg::SaveMapEvent save);

Expand Down
12 changes: 12 additions & 0 deletions src/game_interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -826,6 +826,8 @@ bool Game_Interpreter::ExecuteCommand(lcf::rpg::EventCommand const& com) {
return CommandManiacControlStrings(com);
case Cmd::Maniac_CallCommand:
return CommandManiacCallCommand(com);
case static_cast<Cmd>(2056): //EasyRPG_SpawnMapEvent
return CommandSpawnMapEvent(com);
default:
return true;
}
Expand Down Expand Up @@ -5108,6 +5110,16 @@ bool Game_Interpreter::CommandManiacCallCommand(lcf::rpg::EventCommand const& co
return true;
}

bool Game_Interpreter::CommandSpawnMapEvent(lcf::rpg::EventCommand const& com) {
int src_map = ValueOrVariable(com.parameters[0], com.parameters[1]);
int src_event = ValueOrVariable(com.parameters[2], com.parameters[3]);
int target_x = ValueOrVariable(com.parameters[4], com.parameters[5]);
int target_y = ValueOrVariable(com.parameters[6], com.parameters[7]);

Game_Map::CloneMapEvent(src_map, src_event, target_x, target_y);
return true;
}

Game_Interpreter& Game_Interpreter::GetForegroundInterpreter() {
return Game_Battle::IsBattleRunning()
? Game_Battle::GetInterpreter()
Expand Down
2 changes: 2 additions & 0 deletions src/game_interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,8 @@ class Game_Interpreter
bool CommandManiacControlStrings(lcf::rpg::EventCommand const& com);
bool CommandManiacCallCommand(lcf::rpg::EventCommand const& com);

bool CommandSpawnMapEvent(lcf::rpg::EventCommand const& com);

int DecodeInt(lcf::DBArray<int32_t>::const_iterator& it);
const std::string DecodeString(lcf::DBArray<int32_t>::const_iterator& it);
lcf::rpg::MoveCommand DecodeMove(lcf::DBArray<int32_t>::const_iterator& it);
Expand Down
102 changes: 83 additions & 19 deletions src/game_map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -342,40 +342,104 @@ std::unique_ptr<lcf::rpg::Map> Game_Map::loadMapFile(int map_id) {

void Game_Map::SetupCommon() {
if (!Tr::GetCurrentTranslationId().empty()) {
// Build our map translation id.
std::stringstream ss;
ss << "map" << std::setfill('0') << std::setw(4) << GetMapId() << ".po";

// Translate all messages for this map
Player::translation.RewriteMapMessages(ss.str(), *map);
TranslateMapMessages(GetMapId(), *map);
}
SetNeedRefresh(true);

PrintPathToMap();

// Restart all common events after translation change
// Otherwise new strings are not applied
if (translation_changed) {
InitCommonEvents();
}

// Create the map events
CreateMapEvents();
}

bool Game_Map::CloneMapEvent(int src_map_id, int src_event_id, int target_x, int target_y) {
auto source_map = Game_Map::loadMapFile(src_map_id);
if (source_map == nullptr) {
Output::Warning("CloneMapEvent: Invalid source map ID {}", src_map_id);
return true;
}

if (!Tr::GetCurrentTranslationId().empty()) {
TranslateMapMessages(src_map_id, *source_map);
}

const lcf::rpg::Event* source_event = FindEventById(source_map->events, src_event_id);
if (source_event == nullptr) {
Output::Warning("CloneMapEvent: Event ID {} not found on source map {}", src_event_id, src_map_id);
return true;
}

lcf::rpg::Event new_event = *source_event;
new_event.ID = GetNextAvailableEventId();
new_event.x = target_x;
new_event.y = target_y;

map->events.push_back(new_event);

events.emplace_back(GetMapId(), &map->events.back());
FixUnderlyingEventReferences();

AddEventToCache(new_event);

Scene_Map* scene = (Scene_Map*)Scene::Find(Scene::Map).get();
scene->spriteset->Refresh();

return true;
}

void Game_Map::TranslateMapMessages(int mapId, lcf::rpg::Map& map) {
std::stringstream ss;
ss << "map" << std::setfill('0') << std::setw(4) << mapId << ".po";
Player::translation.RewriteMapMessages(ss.str(), map);
}

void Game_Map::CreateMapEvents() {
events.reserve(map->events.size());
for (auto& ev : map->events) {
events.emplace_back(GetMapId(), &ev);
AddEventToCache(ev);
}
}

for (const auto& pg : ev.pages) {
if (pg.condition.flags.switch_a) {
AddEventToSwitchCache(ev, pg.condition.switch_a_id);
}
if (pg.condition.flags.switch_b) {
AddEventToSwitchCache(ev, pg.condition.switch_b_id);
}
if (pg.condition.flags.variable) {
AddEventToVariableCache(ev, pg.condition.variable_id);
}
inline void Game_Map::FixUnderlyingEventReferences() {
size_t idx = 0;
for (auto& ev : events) {
ev.SetUnderlyingEvent(&map->events.at(idx++));
}
}

void Game_Map::AddEventToCache(lcf::rpg::Event& ev) {
for ( auto& pg : ev.pages) {
if (pg.condition.flags.switch_a) {
AddEventToSwitchCache(ev, pg.condition.switch_a_id);
}
if (pg.condition.flags.switch_b) {
AddEventToSwitchCache(ev, pg.condition.switch_b_id);
}
if (pg.condition.flags.variable) {
AddEventToVariableCache(ev, pg.condition.variable_id);
}
}
}

const lcf::rpg::Event* Game_Map::FindEventById(const std::vector<lcf::rpg::Event>& events, int eventId) {
for (const auto& ev : events) {
if (ev.ID == eventId) {
return &ev;
}
}
return nullptr;
}

int Game_Map::GetNextAvailableEventId() {
int maxEventId = 0;
for (const auto& ev : map->events) {
maxEventId = std::max(maxEventId, ev.ID);
}
return maxEventId + 1;
}

void Game_Map::AddEventToSwitchCache(lcf::rpg::Event& ev, int switch_id) {
Expand Down
8 changes: 8 additions & 0 deletions src/game_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,14 @@ namespace Game_Map {
/** Disposes Game_Map. */
void Dispose();

bool CloneMapEvent(int src_map_id, int src_event_id, int target_x, int target_y);
void TranslateMapMessages(int mapId, lcf::rpg::Map& map);
void CreateMapEvents();
inline void FixUnderlyingEventReferences();
void AddEventToCache(lcf::rpg::Event& ev);
const lcf::rpg::Event* FindEventById(const std::vector<lcf::rpg::Event>& events, int eventId);
int GetNextAvailableEventId();

/**
* Loads the map from disk
*
Expand Down

0 comments on commit a9bf6f8

Please sign in to comment.