secondlife
Member
- Joined
- Aug 1, 2009
- Messages
- 298
- Reaction score
- 23
Hi guys!
I don't know if you know this type of "push", this is very common in old versions (like 7.92).
A more "skilled" player can move the character up to 3/4 sqms away.
I would like to know if someone with more experience could help me implement this type of push (2, 3 or 4 sqms depending on the speed of the player) in version 8.60.
I tried different ways but it didn't work.
Does anyone have any idea where I can start?
Here is my game.cpp, playerMoveCreature:
I don't know if you know this type of "push", this is very common in old versions (like 7.92).
A more "skilled" player can move the character up to 3/4 sqms away.
I would like to know if someone with more experience could help me implement this type of push (2, 3 or 4 sqms depending on the speed of the player) in version 8.60.
I tried different ways but it didn't work.
Does anyone have any idea where I can start?
Here is my game.cpp, playerMoveCreature:
Code:
bool Game::playerMoveCreature(uint32_t playerId, uint32_t movingCreatureId,
const Position& movingCreaturePos, const Position& toPos)
{
Player* player = getPlayerByID(playerId);
if(!player || player->isRemoved() || player->hasFlag(PlayerFlag_CannotMoveCreatures))
return false;
if(!player->canDoAction())
{
uint32_t delay = player->getNextActionTime();
SchedulerTask* task = createSchedulerTask(delay, boost::bind(&Game::playerMoveCreature,
this, playerId, movingCreatureId, movingCreaturePos, toPos));
player->setNextActionTask(task);
return false;
}
Creature* movingCreature = getCreatureByID(movingCreatureId);
if(!movingCreature || movingCreature->isRemoved() || movingCreature->getNoMove())
return false;
player->setNextActionTask(NULL);
if(!Position::areInRange<1,1,0>(movingCreaturePos, player->getPosition()) && !player->hasCustomFlag(PlayerCustomFlag_CanMoveFromFar))
{
//need to walk to the creature first before moving it
std::list<Direction> listDir;
if(getPathToEx(player, movingCreaturePos, listDir, 0, 1, true, true))
{
Dispatcher::getInstance().addTask(createTask(boost::bind(&Game::playerAutoWalk,
this, player->getID(), listDir)));
SchedulerTask* task = createSchedulerTask(player->getStepDuration(),
boost::bind(&Game::playerMoveCreature, this, playerId, movingCreatureId, movingCreaturePos, toPos));
player->setNextWalkActionTask(task);
return true;
}
player->sendCancelMessage(RET_THEREISNOWAY);
return false;
}
Tile* toTile = map->getTile(toPos);
if(!toTile)
{
player->sendCancelMessage(RET_NOTPOSSIBLE);
return false;
}
if((!movingCreature->isPushable() && !player->hasFlag(PlayerFlag_CanPushAllCreatures)) || !player->canSeeCreature(movingCreature))
{
player->sendCancelMessage(RET_NOTMOVEABLE);
return false;
}
//check throw distance
const Position& pos = movingCreature->getPosition();
if(!player->hasCustomFlag(PlayerCustomFlag_CanThrowAnywhere) && ((std::abs(pos.x - toPos.x) > movingCreature->getThrowRange()) ||
(std::abs(pos.y - toPos.y) > movingCreature->getThrowRange()) || (std::abs(pos.z - toPos.z) * 4 > movingCreature->getThrowRange())))
{
player->sendCancelMessage(RET_DESTINATIONOUTOFREACH);
return false;
}
if(player != movingCreature)
{
if(toTile->hasProperty(BLOCKPATH))
{
player->sendCancelMessage(RET_NOTENOUGHROOM);
return false;
}
if((movingCreature->getZone() == ZONE_PROTECTION || movingCreature->getZone() == ZONE_OPTIONAL)
&& !toTile->hasFlag(TILESTATE_OPTIONALZONE) && !toTile->hasFlag(TILESTATE_PROTECTIONZONE)
&& !player->hasFlag(PlayerFlag_IgnoreProtectionZone))
{
player->sendCancelMessage(RET_NOTPOSSIBLE);
return false;
}
if(!player->hasFlag(PlayerFlag_CanPushAllCreatures))
{
if(toTile->getCreatures() && !toTile->getCreatures()->empty())
{
player->sendCancelMessage(RET_NOTPOSSIBLE);
return false;
}
uint32_t protectionLevel = g_config.getNumber(ConfigManager::PROTECTION_LEVEL);
if(player->getLevel() < protectionLevel && player->getVocation()->isAttackable())
{
Player* movingPlayer = movingCreature->getPlayer();
if(movingPlayer && movingPlayer->getLevel() >= protectionLevel
&& movingPlayer->getVocation()->isAttackable())
{
player->sendCancelMessage(RET_PLAYERISNOTREACHABLE);
return false;
}
}
}
}
bool deny = false;
CreatureEventList pushEvents = player->getCreatureEvents(CREATURE_EVENT_PUSH);
for(CreatureEventList::iterator it = pushEvents.begin(); it != pushEvents.end(); ++it)
{
if(!(*it)->executePush(player, movingCreature) && !deny)
deny = true;
}
if(deny)
return false;
ReturnValue ret = internalMoveCreature(player, movingCreature, movingCreature->getTile(), toTile);
if(ret != RET_NOERROR)
{
if(!player->hasCustomFlag(PlayerCustomFlag_CanMoveFromFar) || !player->hasCustomFlag(PlayerCustomFlag_CanMoveAnywhere))
{
player->sendCancelMessage(ret);
return false;
}
if(!toTile->ground)
{
player->sendCancelMessage(RET_NOTPOSSIBLE);
return true;
}
internalTeleport(movingCreature, toTile->getPosition(), false);
return true;
}
if(Player* movingPlayer = movingCreature->getPlayer())
{
uint64_t delay = OTSYS_TIME() + movingPlayer->getStepDuration();
if(delay > movingPlayer->getNextActionTime())
movingPlayer->setNextAction(delay);
}
return true;
}