Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions HeavenClient/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@ if(HEAVENCLIENT_BUILD_TESTS)
add_executable(shop_list_tests tests/shop_list.cpp Net/InPacket.cpp)
target_include_directories(shop_list_tests PRIVATE ${PROJECT_SOURCE_DIR}/libs/NoLifeNx)
add_test(NAME shop_list COMMAND shop_list_tests)
add_executable(movement_path_tests tests/movement_path.cpp Net/InPacket.cpp Net/Handlers/Helpers/MovementParser.cpp)
target_include_directories(movement_path_tests PRIVATE ${PROJECT_SOURCE_DIR}/libs/NoLifeNx)
add_test(NAME movement_path COMMAND movement_path_tests)
add_executable(status_messages_tests tests/status_messages.cpp Net/InPacket.cpp)
target_include_directories(status_messages_tests PRIVATE ${PROJECT_SOURCE_DIR}/libs/NoLifeNx)
add_test(NAME status_messages COMMAND status_messages_tests)
Expand Down
46 changes: 11 additions & 35 deletions HeavenClient/Character/OtherChar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,46 +22,29 @@
namespace ms
{
OtherChar::OtherChar(int32_t id, const CharLook &lk, uint8_t lvl, int16_t jb, const std::string &nm, int8_t st,
Point<int16_t> pos) : Char(id, lk, nm)
Point<int16_t> pos) : Char(id, lk, nm),
path({ static_cast<double>(pos.x()), static_cast<double>(pos.y()), 0.0, 0.0, 0,
static_cast<uint8_t>(st) })
{
level = lvl;
job = jb;
set_position(pos);

lastmove.xpos = pos.x();
lastmove.ypos = pos.y();
lastmove.newstate = st;
timer = 0;

attackspeed = 6;
attacking = false;
}

int8_t OtherChar::update(const Physics &physics)
{
if (timer > 1)
{
timer--;
} else if (timer == 1)
{
if (!movements.empty())
{
lastmove = movements.front();
movements.pop();
} else
{
timer = 0;
}
}
path.step(Constants::TIMESTEP);

const move_path::Player::State &now = path.get_state();

if (!attacking)
{
uint8_t laststate = lastmove.newstate;
set_state(laststate);
}
set_state(now.stance);

phobj.hspeed = lastmove.xpos - phobj.crnt_x();
phobj.vspeed = lastmove.ypos - phobj.crnt_y();
phobj.hspeed = now.x - phobj.crnt_x();
phobj.vspeed = now.y - phobj.crnt_y();
phobj.move();

physics.get_fht().update_fh(phobj);
Expand All @@ -76,13 +59,7 @@ namespace ms

void OtherChar::send_movement(const std::vector<Movement> &newmoves)
{
movements.push(newmoves.back());

if (timer == 0)
{
constexpr uint16_t DELAY = 50;
timer = DELAY;
}
path.receive(newmoves);
}

void OtherChar::update_skill(int32_t skillid, uint8_t skilllevel)
Expand All @@ -99,8 +76,7 @@ namespace ms
{
look = newlook;

uint8_t laststate = lastmove.newstate;
set_state(laststate);
set_state(path.get_state().stance);
}

int8_t OtherChar::get_integer_attackspeed() const
Expand Down
9 changes: 3 additions & 6 deletions HeavenClient/Character/OtherChar.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,8 @@

#include "Look/CharLook.h"

#include "../Gameplay/Movement.h"
#include "../Gameplay/MovePath.h"

#include <queue>
#include <vector>

namespace ms
Expand All @@ -42,7 +41,7 @@ namespace ms
// Update the character.
int8_t update(const Physics &physics) override;

// Add the movements which this character will go through next.
// Queue a path for the character to play.
void send_movement(const std::vector<Movement> &movements);

// Update a skill level.
Expand All @@ -66,9 +65,7 @@ namespace ms
private:
uint16_t level;
int16_t job;
std::queue<Movement> movements;
Movement lastmove;
uint16_t timer;
move_path::Player path;

std::unordered_map<int32_t, uint8_t> skilllevels;
uint8_t attackspeed;
Expand Down
37 changes: 31 additions & 6 deletions HeavenClient/Character/Player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ namespace ms
ladder = nullptr;
set_chair(0);
nullstate.update_state(*this);
path.reset(current_move(0));
}

void Player::send_action(KeyAction::Id action, bool down)
Expand Down Expand Up @@ -259,19 +260,43 @@ namespace ms

update_recovery();

uint8_t stancebyte = facing_right ? state : state + 1;
Movement newmove(phobj, stancebyte);
bool needupdate = lastmove.hasmoved(newmove);
path.step(current_move(0), Constants::TIMESTEP);

if (needupdate)
if (path.ready())
{
MovePlayerPacket(newmove).dispatch();
lastmove = newmove;
move_path::Path sent = path.flush();

if (!sent.idle)
MovePlayerPacket(sent).dispatch();
}

return get_layer();
}

uint8_t Player::get_stancebyte() const
{
return facing_right ? state : state + 1;
}

void Player::record_move(uint8_t command)
{
path.add(current_move(command));
}

Movement Player::current_move(uint8_t command) const
{
Movement move(phobj, get_stancebyte(), command, 0);

if (is_dead())
move.fh = 0;
else if (ladder)
move.fh = -ladder->get_id();
else if (!phobj.onground)
move.fh = 0;

return move;
}

void Player::update_death()
{
bool dead = stats.get_stat(MapleStat::Id::HP) <= 0;
Expand Down
12 changes: 11 additions & 1 deletion HeavenClient/Character/Player.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

#include "Inventory/Inventory.h"

#include "../Gameplay/MovePath.h"
#include "../Gameplay/Playable.h"

#include "../Gameplay/Combat/Skill.h"
Expand Down Expand Up @@ -64,6 +65,10 @@ namespace ms
// Respawn the player at the given position
void respawn(Point<int16_t> position, bool underwater);

// Mark where the player is now in the path to the server, as
// element `command` of no duration (v83 FUN_0052ef17).
void record_move(uint8_t command);

// Sends a Keyaction to the player's state, to apply forces, change the state and other behaviour.
void send_action(KeyAction::Id action, bool pressed);

Expand Down Expand Up @@ -304,7 +309,12 @@ namespace ms

std::map<KeyAction::Id, bool> keysdown;

Movement lastmove;
move_path::Recorder path;

uint8_t get_stancebyte() const;

// Where the player is and how it moves, as path element `command`.
Movement current_move(uint8_t command) const;

Randomizer randomizer;

Expand Down
8 changes: 8 additions & 0 deletions HeavenClient/Gameplay/MapleMap/MapInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,13 +156,21 @@ namespace ms

Ladder::Ladder(nl::node src)
{
std::string name = src.name();
id = 0;
std::from_chars(name.data(), name.data() + name.size(), id);
x = src["x"];
y1 = src["y1"];
y2 = src["y2"];
ladder = src["l"].get_bool();
uf = src["uf"].get_bool();
}

int16_t Ladder::get_id() const
{
return id;
}

bool Ladder::is_ladder() const
{
return ladder;
Expand Down
4 changes: 4 additions & 0 deletions HeavenClient/Gameplay/MapleMap/MapInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ namespace ms

bool is_ladder() const;

// Its number in the map.
int16_t get_id() const;

// Whether climbing past the top steps onto a platform (uf).
bool leads_up() const;

Expand All @@ -57,6 +60,7 @@ namespace ms
int16_t get_bottom() const;

private:
int16_t id;
int16_t x;
int16_t y1;
int16_t y2;
Expand Down
19 changes: 19 additions & 0 deletions HeavenClient/Gameplay/MapleMap/MapNpcs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ namespace ms
npcs.add(spawn.instantiate(physics));
}

for (; !controls.empty(); controls.pop())
{
auto [oid, control] = controls.front();

if (auto npc = npcs.get(oid))
static_cast<Npc *>(npc.get())->set_control(control);
}

npcs.update(physics);
}

Expand All @@ -59,6 +67,17 @@ namespace ms
npc->deactivate();
}

void MapNpcs::control(int32_t oid, bool control)
{
controls.emplace(oid, control);
}

void MapNpcs::act(int32_t oid, int8_t action, int8_t line)
{
if (auto npc = npcs.get(oid))
static_cast<Npc *>(npc.get())->act(action, line);
}

void MapNpcs::clear()
{
npcs.clear();
Expand Down
7 changes: 7 additions & 0 deletions HeavenClient/Gameplay/MapleMap/MapNpcs.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ namespace ms
// Remove the npc with the specified oid;
void remove(int32_t oid);

// Take control of an NPC, or give it up, once it has spawned.
void control(int32_t oid, bool control);

// Play the action the NPC's controller chose.
void act(int32_t oid, int8_t action, int8_t line);

// Remove all NPCs.
void clear();

Expand All @@ -62,5 +68,6 @@ namespace ms
MapObjects npcs;

std::queue<NpcSpawn> spawns;
std::queue<std::pair<int32_t, bool>> controls;
};
}
Loading
Loading