Skip to content

Commit

Permalink
Merge pull request #3306 from EasyRPG-NewFeatures/Primekick-RewriteMa…
Browse files Browse the repository at this point in the history
…pPartial

Partially implement Maniacs Command 3015: RewriteMap
  • Loading branch information
Ghabry authored Dec 1, 2024
2 parents c256675 + a5c3aed commit edec538
Show file tree
Hide file tree
Showing 9 changed files with 307 additions and 30 deletions.
33 changes: 31 additions & 2 deletions src/game_interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4553,12 +4553,41 @@ bool Game_Interpreter::CommandManiacKeyInputProcEx(lcf::rpg::EventCommand const&
return true;
}

bool Game_Interpreter::CommandManiacRewriteMap(lcf::rpg::EventCommand const&) {
bool Game_Interpreter::CommandManiacRewriteMap(lcf::rpg::EventCommand const& com) {
if (!Player::IsPatchManiac()) {
return true;
}

Output::Warning("Maniac Patch: Command RewriteMap not supported");
int mode = com.parameters[0];
bool is_replace_range = com.parameters[1] != 0;
bool is_upper_layer = com.parameters[2] != 0;

int tile_index = ValueOrVariableBitfield(mode, 0, com.parameters[3]);
int x_start = ValueOrVariableBitfield(mode, 1, com.parameters[4]);
int y_start = ValueOrVariableBitfield(mode, 2, com.parameters[5]);
int width = ValueOrVariableBitfield(mode, 3, com.parameters[6]);
int height = ValueOrVariableBitfield(mode, 4, com.parameters[7]);

bool disable_autotile = com.parameters[8] != 0;

Scene_Map* scene = (Scene_Map*)Scene::Find(Scene::Map).get();
if (!scene)
return true;

if (is_upper_layer) {
for (auto y = y_start; y < y_start + height; ++y) {
for (auto x = x_start; x < x_start + width; ++x) {
scene->spriteset->ReplaceUpAt(x, y, tile_index);
}
}
} else {
for (auto y = y_start; y < y_start + height; ++y) {
for (auto x = x_start; x < x_start + width; ++x) {
scene->spriteset->ReplaceDownAt(x, y, tile_index, disable_autotile);
}
}
}

return true;
}

Expand Down
6 changes: 6 additions & 0 deletions src/game_map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1879,6 +1879,12 @@ int Game_Map::SubstituteUp(int old_id, int new_id) {
return DoSubstitute(map_info.upper_tiles, old_id, new_id);
}

void Game_Map::ReplaceTileAt(int x, int y, int new_id, int layer) {
auto pos = x + y * map->width;
auto& layer_vec = layer >= 1 ? map->upper_layer : map->lower_layer;
layer_vec[pos] = static_cast<int16_t>(new_id);
}

std::string Game_Map::ConstructMapName(int map_id, bool is_easyrpg) {
std::stringstream ss;
ss << "Map" << std::setfill('0') << std::setw(4) << map_id;
Expand Down
1 change: 1 addition & 0 deletions src/game_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,7 @@ namespace Game_Map {
Game_Vehicle* GetVehicle(Game_Vehicle::Type which);
int SubstituteDown(int old_id, int new_id);
int SubstituteUp(int old_id, int new_id);
void ReplaceTileAt(int x, int y, int new_id, int layer);

/**
* Checks if its possible to step onto the tile at (x,y)
Expand Down
33 changes: 33 additions & 0 deletions src/map_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,17 @@ static constexpr int NUM_LOWER_TILES = BLOCK_F_INDEX;
static constexpr int NUM_UPPER_TILES = BLOCK_F_TILES;
static constexpr int NUM_TILES = NUM_LOWER_TILES + NUM_UPPER_TILES;

// Bit positions for neighbors
static constexpr uint8_t NEIGHBOR_NW = 0x80; // 0b10000000
static constexpr uint8_t NEIGHBOR_N = 0x40; // 0b01000000
static constexpr uint8_t NEIGHBOR_NE = 0x20; // 0b00100000
static constexpr uint8_t NEIGHBOR_W = 0x10; // 0b00010000
static constexpr uint8_t NEIGHBOR_E = 0x08; // 0b00001000
static constexpr uint8_t NEIGHBOR_SW = 0x04; // 0b00000100
static constexpr uint8_t NEIGHBOR_S = 0x02; // 0b00000010
static constexpr uint8_t NEIGHBOR_SE = 0x01; // 0b00000001


/** Passability flags. */
namespace Passable {
enum Passable {
Expand Down Expand Up @@ -94,4 +105,26 @@ inline int ChipIdToIndex(int chip_id) {
return 0;
}

inline int IndexToChipId(int index) {
if (index >= BLOCK_A_INDEX && index < BLOCK_B_INDEX) {
return BLOCK_A + (index - BLOCK_A_INDEX) * BLOCK_A_STRIDE;
}
else if (index >= BLOCK_B_INDEX && index < BLOCK_C_INDEX) {
return BLOCK_B + (index - BLOCK_B_INDEX) * BLOCK_B_STRIDE;
}
else if (index >= BLOCK_C_INDEX && index < BLOCK_D_INDEX) {
return BLOCK_C + (index - BLOCK_C_INDEX) * BLOCK_C_STRIDE;
}
else if (index >= BLOCK_D_INDEX && index < BLOCK_E_INDEX) {
return BLOCK_D + (index - BLOCK_D_INDEX) * BLOCK_D_STRIDE;
}
else if (index >= BLOCK_E_INDEX && index < BLOCK_F_INDEX) {
return BLOCK_E + (index - BLOCK_E_INDEX) * BLOCK_E_STRIDE;
}
else if (index >= BLOCK_F_INDEX) {
return BLOCK_F + (index - BLOCK_F_INDEX) * BLOCK_F_STRIDE;
}
return 0;
}

#endif
11 changes: 11 additions & 0 deletions src/spriteset_map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "bitmap.h"
#include "player.h"
#include "drawable_list.h"
#include "map_data.h"

Spriteset_Map::Spriteset_Map() {
panorama = std::make_unique<Plane>();
Expand Down Expand Up @@ -173,6 +174,16 @@ void Spriteset_Map::SubstituteUp(int old_id, int new_id) {
}
}

void Spriteset_Map::ReplaceDownAt(int x, int y, int tile_index, bool disable_autotile) {
auto tile_id = IndexToChipId(tile_index);
tilemap->SetMapTileDataDownAt(x, y, tile_id, disable_autotile);
}

void Spriteset_Map::ReplaceUpAt(int x, int y, int tile_index) {
auto tile_id = IndexToChipId(tile_index);
tilemap->SetMapTileDataUpAt(x, y, tile_id);
}

bool Spriteset_Map::RequireClear(DrawableList& drawable_list) {
if (drawable_list.empty()) {
return true;
Expand Down
10 changes: 10 additions & 0 deletions src/spriteset_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,16 @@ class Spriteset_Map {
*/
void SubstituteUp(int old_id, int new_id);

/**
* Replaces a single tile in lower layer at the given coordinates.
*/
void ReplaceDownAt(int x, int y, int tile_index, bool disable_autotile);

/**
* Replaces a single tile in upper layer at the given coordinates.
*/
void ReplaceUpAt(int x, int y, int tile_index);

/**
* @return true if we should clear the screen before drawing the map
*/
Expand Down
10 changes: 10 additions & 0 deletions src/tilemap.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,11 @@ class Tilemap {

const std::vector<short>& GetMapDataDown() const;
void SetMapDataDown(std::vector<short> down);
void SetMapTileDataDownAt(int x, int y, int tile_id, bool disable_autotile);

const std::vector<short>& GetMapDataUp() const;
void SetMapDataUp(std::vector<short> up);
void SetMapTileDataUpAt(int x, int y, int tile_id);

const std::vector<unsigned char>& GetPassableUp() const;
void SetPassableUp(std::vector<unsigned char> up);
Expand Down Expand Up @@ -81,6 +83,10 @@ inline void Tilemap::SetMapDataDown(std::vector<short> down) {
layer_down.SetMapData(std::move(down));
}

inline void Tilemap::SetMapTileDataDownAt(int x, int y, int tile_id, bool disable_autotile) {
layer_down.SetMapTileDataAt(x, y, tile_id, disable_autotile);
}

inline const std::vector<short>& Tilemap::GetMapDataUp() const {
return layer_up.GetMapData();
}
Expand All @@ -89,6 +95,10 @@ inline void Tilemap::SetMapDataUp(std::vector<short> up) {
layer_up.SetMapData(std::move(up));
}

inline void Tilemap::SetMapTileDataUpAt(int x, int y, int tile_id) {
layer_down.SetMapTileDataAt(x, y, tile_id, true);
}

inline const std::vector<unsigned char>& Tilemap::GetPassableDown() const {
return layer_down.GetPassable();
}
Expand Down
Loading

0 comments on commit edec538

Please sign in to comment.