Skip to content

Commit

Permalink
Pathfinder, Activate Event
Browse files Browse the repository at this point in the history
PathFinder(UseVarID, ID, UseVarX, x, UseVarY, y), command ID 20001

UseVarID = 1= >Use variables[ID] instead of ID
ID = EventID, 0 for player
UseVarX = 1 => Use variables[x] instead of x
x = destination X
UseVarY = 1 => Use variables[y] instead of y
y = destination Y

ActivateEvent(UseVarX, x, UseVarY, y), command ID 20002

UseVarX = 1 => Use variables[x] instead of x
x = destination X
UseVarY = 1 => Use variables[y] instead of y
y = destination Y
  • Loading branch information
MackValentine committed Jun 17, 2023
1 parent 6832809 commit 8f3dc56
Show file tree
Hide file tree
Showing 4 changed files with 255 additions and 0 deletions.
214 changes: 214 additions & 0 deletions src/game_interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,8 @@ bool Game_Interpreter::ExecuteCommand() {
auto& frame = GetFrame();
const auto& com = frame.commands[frame.current_command];

// Output::Debug("Event code : {}", com.code);

switch (static_cast<Cmd>(com.code)) {
case Cmd::ShowMessage:
return CommandShowMessage(com);
Expand Down Expand Up @@ -818,6 +820,10 @@ bool Game_Interpreter::ExecuteCommand() {
return CommandManiacSetGameOption(com);
case Cmd::Maniac_CallCommand:
return CommandManiacCallCommand(com);
case Cmd::Mack_Pathfinder:

This comment has been minimized.

Copy link
@MackValentine

MackValentine Jun 17, 2023

Author Collaborator

Still need to generate to Command in liblcf\src\generated\lcf\rpg\eventcommand.h

This comment has been minimized.

Copy link
@jetrotal

jetrotal Jun 18, 2023

Thanks!

We now have a fork of liblcf:
https://github.com/EasyRPG-NewFeatures/liblcf
so, we can branch from it.

btw, looks like the commands should be 2001 and 2002, instead 20001 and 20002.

At least, that's what it was suggested by @Ghabry annotations here: EasyRPG#3034

return CommandSearchPath(com);
case Cmd::Mack_ActivateEvent:
return CommandActivateEventAt(com);
default:
return true;
}
Expand Down Expand Up @@ -4680,3 +4686,211 @@ bool Game_Interpreter::ManiacCheckContinueLoop(int val, int val2, int type, int
return false;
}
}


bool Game_Interpreter::CommandSearchPath(lcf::rpg::EventCommand const& com) {

int eventID, destX, destY;
bool passableDestination = true;

if (com.string == "false")
passableDestination = false;

eventID = com.parameters[1];

destX = com.parameters[3];
destY = com.parameters[5];

if (com.parameters[0] == 1)
eventID = Main_Data::game_variables->Get(eventID);
if (com.parameters[2] == 1)
destX = Main_Data::game_variables->Get(destX);
if (com.parameters[4] == 1)
destY = Main_Data::game_variables->Get(destY);


Game_Character* event;
if (eventID == 0)
event = Main_Data::game_player.get();
else
event = GetCharacter(eventID);

NoeudA start = NoeudA(event->GetX(), event->GetY(), 0, -1);
if (start.x == destX && start.y == destY)
return true;

//Output::Debug("Pathfinding : {} {} {} {} {}", eventID, destX, destY, start.x, start.y);

std::vector<NoeudA> list;
std::vector<NoeudA> closedList;
std::vector<NoeudA> listMove;

list.push_back(start);
int id = 0;
int idd = 0;

while (!list.empty()) {
if (id >= list.size()) {
//Output::Debug("Give up");
//return true;
}

NoeudA n = pop_front(list);//list[id];
closedList.push_back(n);

if (n.x == destX && n.y == destY) {

//Output::Debug("Chemin :");
NoeudA* node = &n;
while (node != nullptr) {
//Output::Debug("N {} {} {}", node->x, node->y, node->parentID);

NoeudA nodeF = NoeudA(node->x, node->y, 0, node->direction);
nodeF.parentX = n.x;
nodeF.parentY = n.y;

listMove.push_back(nodeF);
int nid = node->parentID;
node = nullptr;
for (NoeudA na : closedList) {
if (na.id == nid) {
node = &na;
break;
}
}
}

std::reverse(listMove.rbegin(), listMove.rend());

lcf::rpg::MoveRoute route;
// route.skippable = true;
route.repeat = false;

if (!event->MakeWay(n.parentX, n.parentY, n.x, n.y)) {
listMove.pop_back();
}

if (listMove.size() <= 1 && n.direction <= 3) {
listMove.clear();
n.direction += 12;
listMove.push_back(n);
}

for (NoeudA node2 : listMove) {
if (node2.direction >= 0) {
lcf::rpg::MoveCommand cmd;
cmd.command_id = node2.direction;
route.move_commands.push_back(cmd);

//Output::Debug("NF {} {} {}", node2.x, node2.y, cmd.command_id);
}
}

lcf::rpg::MoveCommand cmd;
cmd.command_id = 23;
route.move_commands.push_back(cmd);

event->ForceMoveRoute(route, 8);

return true;

}
else {

std::vector<NoeudA> neighbour;
NoeudA nn = NoeudA(n.x + 1, n.y, n.cout + 1, 1); // Right
neighbour.push_back(nn);
nn = NoeudA(n.x, n.y - 1, n.cout + 1, 0); // Up
neighbour.push_back(nn);
nn = NoeudA(n.x - 1, n.y, n.cout + 1, 3); // left
neighbour.push_back(nn);
nn = NoeudA(n.x, n.y + 1, n.cout + 1, 2); // Down
neighbour.push_back(nn);

nn = NoeudA(n.x - 1, n.y + 1, n.cout + 1, 6); // Down Left
neighbour.push_back(nn);
nn = NoeudA(n.x + 1, n.y - 1, n.cout + 1, 4); // Up Right
neighbour.push_back(nn);
nn = NoeudA(n.x - 1, n.y - 1, n.cout + 1, 7); // Up Left
neighbour.push_back(nn);
nn = NoeudA(n.x + 1, n.y + 1, n.cout + 1, 5); // Down Right
neighbour.push_back(nn);


for (NoeudA a : neighbour) {
idd++;
a.parentX = n.x;
a.parentY = n.y;
a.id = idd;
a.parentID = n.id;
int i = vectorContains(list, a);
//if (!((vectorContains(closedList, a) != -1) || (i != -1 && i < list.size() && list[i].cout < a.cout))) {
//if (!((i != -1 && i < list.size() && list[i].cout < a.cout))) {
if (i < 0) {
if (event->MakeWay(n.x, n.y, a.x, a.y) || (passableDestination && a.x == destX && a.y == destY)) {
//Output::Debug(" {} {} {} {}", a.x, a.y, a.id, a.direction);
if (a.direction == 4) {
if (event->MakeWay(n.x, n.y, n.x + 1, n.y) || event->MakeWay(n.x, n.y, n.x, n.y - 1))
list.push_back(a);
}
else if (a.direction == 5) {
if (event->MakeWay(n.x, n.y, n.x + 1, n.y) || event->MakeWay(n.x, n.y, n.x, n.y + 1))
list.push_back(a);
}
else if (a.direction == 6) {
if (event->MakeWay(n.x, n.y, n.x - 1, n.y) || event->MakeWay(n.x, n.y, n.x, n.y + 1))
list.push_back(a);
}
else if (a.direction == 7) {
if (event->MakeWay(n.x, n.y, n.x - 1, n.y) || event->MakeWay(n.x, n.y, n.x, n.y - 1))
list.push_back(a);
}
else
list.push_back(a);
}
}
//closedList.push_back(a);
}

}
id++;
}

return true;
}

int Game_Interpreter::vectorContains(std::vector<NoeudA> v, NoeudA n) {
int id = -1;
for (NoeudA na : v) {
if (na.x == n.x && na.y == n.y) {
id = na.id;
break;
}
}
return id;
}

Game_Interpreter::NoeudA Game_Interpreter::pop_front(std::vector<NoeudA>& vec)
{
assert(!vec.empty());
NoeudA a = vec[0];
vec.erase(vec.begin());
return a;
}

bool Game_Interpreter::CommandActivateEventAt(lcf::rpg::EventCommand const& com) {

int x = com.parameters[1];
int y = com.parameters[3];

if (com.parameters[0] == 1)
x = Main_Data::game_variables->Get(x);
if (com.parameters[2] == 1)
y = Main_Data::game_variables->Get(y);

// Output::Debug("ActiveEvent : {} {}", x, y);

bool b = Main_Data::game_player->ActivateEventAt(x, y);

return true;
}
36 changes: 36 additions & 0 deletions src/game_interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,42 @@ class Game_Interpreter
bool CommandManiacSetGameOption(lcf::rpg::EventCommand const& com);
bool CommandManiacCallCommand(lcf::rpg::EventCommand const& com);

// Custom Commands
bool CommandSearchPath(lcf::rpg::EventCommand const& com);
bool CommandActivateEventAt(lcf::rpg::EventCommand const& com);


struct NoeudA {
NoeudA(int a, int b, int c, int d) {
x = a;
y = b;
cout = c;
direction = d;
}
int x;
int y;
int cout;
int id = 0;

int parentID = -1;
int parentX = -1;
int parentY = -1;
int direction;

friend bool operator==(const NoeudA& n1, const NoeudA& n2)
{
return n1.x == n2.x && n1.y == n2.y;
}

bool operator()(NoeudA const& a, NoeudA const& b)
{
return a.id > b.id;
}

};
int vectorContains(std::vector<NoeudA> v, NoeudA x);
NoeudA pop_front(std::vector<NoeudA>& vec);

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
3 changes: 3 additions & 0 deletions src/game_player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -835,3 +835,6 @@ void Game_Player::UpdatePan() {
data()->pan_current_y -= dy;
}

bool Game_Player::ActivateEventAt(int x, int y) {
return CheckEventTriggerThere({ lcf::rpg::EventPage::Trigger_action }, x, y, true);
}
2 changes: 2 additions & 0 deletions src/game_player.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ class Game_Player : public Game_PlayerBase {
bool IsDatabaseCompatibleWithSave(int database_save_count) const;

void UpdateSaveCounts(int db_save_count, int map_save_count);

bool ActivateEventAt(int x, int y);
private:
using TriggerSet = lcf::FlagSet<lcf::rpg::EventPage::Trigger>;

Expand Down

0 comments on commit 8f3dc56

Please sign in to comment.