Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Player set/get cannotMove #2553

Merged
merged 12 commits into from Dec 1, 2020
2 changes: 2 additions & 0 deletions data/lib/compat/compat.lua
Expand Up @@ -347,6 +347,7 @@ function getCreatureBaseSpeed(cid) local c = Creature(cid) return c and c:getBas
function getCreatureLookDirection(cid) local c = Creature(cid) return c and c:getDirection() or false end
function getCreatureHideHealth(cid) local c = Creature(cid) return c and c:isHealthHidden() or false end
function getCreatureSkullType(cid) local c = Creature(cid) return c and c:getSkull() or false end
function getCreatureNoMove(cid) local c = Creature(cid) return c and c:isMovementBlocked() or false end

function getCreatureTarget(cid)
local c = Creature(cid)
Expand Down Expand Up @@ -390,6 +391,7 @@ function doCreatureSetSkullType(cid, skull) local c = Creature(cid) return c and
function setCreatureMaxHealth(cid, health) local c = Creature(cid) return c and c:setMaxHealth(health) or false end
function setCreatureMaxMana(cid, mana) local c = Creature(cid) return c and c:setMaxMana(mana) or false end
function doCreatureSetHideHealth(cid, hide) local c = Creature(cid) return c and c:setHiddenHealth(hide) or false end
function doCreatureSetNoMove(cid, block) local c = Creature(cid) return c and c:setMovementBlocked(block) or false end
function doCreatureSay(cid, text, type, ...) local c = Creature(cid) return c and c:say(text, type, ...) or false end
function doCreatureChangeOutfit(cid, outfit) local c = Creature(cid) return c and c:setOutfit(outfit) or false end
function doSetCreatureDropLoot(cid, doDrop) local c = Creature(cid) return c and c:setDropLoot(doDrop) or false end
Expand Down
6 changes: 6 additions & 0 deletions src/creature.cpp
Expand Up @@ -249,6 +249,12 @@ bool Creature::getNextStep(Direction& dir, uint32_t&)

void Creature::startAutoWalk(const std::forward_list<Direction>& listDir)
{
Player* player = getPlayer();
if (player && player->isMovementBlocked()) {
player->sendCancelWalk();
return;
}

listWalkDir = listDir;

size_t size = 0;
Expand Down
8 changes: 8 additions & 0 deletions src/creature.h
Expand Up @@ -409,6 +409,13 @@ class Creature : virtual public Thing
void setUseDefense(bool useDefense) {
canUseDefense = useDefense;
}
void setMovementBlocked(bool state) {
movementBlocked = state;
cancelNextWalk = true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we set canMove to true, do we still cancelNextWalk?

Copy link
Contributor

@soul4soul soul4soul Apr 3, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I too was wondering about cancelNextWalk always being set to true in this function. What is the reason for the code not being this or similar

Suggested change
cancelNextWalk = true;
cancelNextWalk = !move;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still curious about this.

Copy link
Member

@Znote Znote Nov 5, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My guess is to fix desync issues mid-action, this is called to toggle the states, but no matter which direction it toggles to, you dont want to give the user half a sqm headstart as it may create odd client behavior. So even if you just got permission to walk, the character pos gets a cancel byte one last time to set the timings straight. (I might be wrong though).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Znote but if player is already movement blocked then he cannot walk, so what desynchro?

}
bool isMovementBlocked() const {
return movementBlocked;
}

//creature script events
bool registerCreatureEvent(const std::string& name);
Expand Down Expand Up @@ -526,6 +533,7 @@ class Creature : virtual public Thing
bool forceUpdateFollowPath = false;
bool hiddenHealth = false;
bool canUseDefense = true;
bool movementBlocked = false;

//creature script events
bool hasEventRegistered(CreatureEventType_t event) const {
Expand Down
10 changes: 10 additions & 0 deletions src/game.cpp
Expand Up @@ -695,6 +695,11 @@ void Game::playerMoveCreature(Player* player, Creature* movingCreature, const Po
return;
}

if (movingCreature->isMovementBlocked()) {
player->sendCancelMessage(RETURNVALUE_NOTMOVEABLE);
return;
}

player->setNextActionTask(nullptr);

if (!Position::areInRange<1, 1, 0>(movingCreatureOrigPos, player->getPosition())) {
Expand Down Expand Up @@ -1804,6 +1809,11 @@ void Game::playerMove(uint32_t playerId, Direction direction)
return;
}

if (player->isMovementBlocked()) {
player->sendCancelWalk();
return;
}

player->resetIdleTime();
player->setNextWalkActionTask(nullptr);

Expand Down
27 changes: 27 additions & 0 deletions src/luascript.cpp
Expand Up @@ -2215,6 +2215,7 @@ void LuaScriptInterface::registerFunctions()
registerMethod("Creature", "isCreature", LuaScriptInterface::luaCreatureIsCreature);
registerMethod("Creature", "isInGhostMode", LuaScriptInterface::luaCreatureIsInGhostMode);
registerMethod("Creature", "isHealthHidden", LuaScriptInterface::luaCreatureIsHealthHidden);
registerMethod("Creature", "isMovementBlocked", LuaScriptInterface::luaCreatureIsMovementBlocked);
registerMethod("Creature", "isImmune", LuaScriptInterface::luaCreatureIsImmune);

registerMethod("Creature", "canSee", LuaScriptInterface::luaCreatureCanSee);
Expand Down Expand Up @@ -2255,6 +2256,7 @@ void LuaScriptInterface::registerFunctions()
registerMethod("Creature", "getMaxHealth", LuaScriptInterface::luaCreatureGetMaxHealth);
registerMethod("Creature", "setMaxHealth", LuaScriptInterface::luaCreatureSetMaxHealth);
registerMethod("Creature", "setHiddenHealth", LuaScriptInterface::luaCreatureSetHiddenHealth);
registerMethod("Creature", "setMovementBlocked", LuaScriptInterface::luaCreatureSetMovementBlocked);

registerMethod("Creature", "getSkull", LuaScriptInterface::luaCreatureGetSkull);
registerMethod("Creature", "setSkull", LuaScriptInterface::luaCreatureSetSkull);
Expand Down Expand Up @@ -7010,6 +7012,18 @@ int LuaScriptInterface::luaCreatureIsHealthHidden(lua_State* L)
return 1;
}

int LuaScriptInterface::luaCreatureIsMovementBlocked(lua_State* L)
{
// creature:isMovementBlocked()
const Creature* creature = getUserdata<const Creature>(L, 1);
if (creature) {
pushBoolean(L, creature->isMovementBlocked());
} else {
lua_pushnil(L);
}
return 1;
}

int LuaScriptInterface::luaCreatureCanSee(lua_State* L)
{
// creature:canSee(position)
Expand Down Expand Up @@ -7430,6 +7444,19 @@ int LuaScriptInterface::luaCreatureSetHiddenHealth(lua_State* L)
return 1;
}

int LuaScriptInterface::luaCreatureSetMovementBlocked(lua_State* L)
{
// creature:setMovementBlocked(state)
Creature* creature = getUserdata<Creature>(L, 1);
if (creature) {
creature->setMovementBlocked(getBoolean(L, 2));
pushBoolean(L, true);
} else {
lua_pushnil(L);
}
return 1;
}

int LuaScriptInterface::luaCreatureGetSkull(lua_State* L)
{
// creature:getSkull()
Expand Down
2 changes: 2 additions & 0 deletions src/luascript.h
Expand Up @@ -757,6 +757,7 @@ class LuaScriptInterface
static int luaCreatureIsCreature(lua_State* L);
static int luaCreatureIsInGhostMode(lua_State* L);
static int luaCreatureIsHealthHidden(lua_State* L);
static int luaCreatureIsMovementBlocked(lua_State* L);
static int luaCreatureIsImmune(lua_State* L);

static int luaCreatureCanSee(lua_State* L);
Expand Down Expand Up @@ -797,6 +798,7 @@ class LuaScriptInterface
static int luaCreatureGetMaxHealth(lua_State* L);
static int luaCreatureSetMaxHealth(lua_State* L);
static int luaCreatureSetHiddenHealth(lua_State* L);
static int luaCreatureSetMovementBlocked(lua_State* L);

static int luaCreatureGetSkull(lua_State* L);
static int luaCreatureSetSkull(lua_State* L);
Expand Down