Ir para conteúdo

[Creaturescript/C++] onMove


Oneshot

Posts Recomendados

Nome: onMove

Tipo: Creaturescript/C++

Autor: Doggynub

 


 

Este é um código C++ extra para os servidores, um creaturescript, que facilita muito a programação de variados scripts. É possível criar um script que bloqueia que itens sejam jogados em teleports, por exemplo.

 


 

Em creatureevent.h, procure por:

 

CREATURE_EVENT_PREPAREDEATH,

 

Logo abaixo, adicione:

 

CREATURE_EVENT_ONMOVE

 

Procure por:

 

uint32_t executePrepareDeath(Creature* creature, DeathList deathList);

 

E logo abaixo, adicione:

 

uint32_t executeOnMove(Player* player, Item* item, const Position& fromPosition, const Position& toPosition, Item* fromItem, Item* toItem, Item* fromGround, Item* toGround, std::map<std::string,int> status);

 


 

Em creatureevent.cpp, procure por:

 

else if(tmpStr == "preparedeath")
 m_type = CREATURE_EVENT_PREPAREDEATH;

 

Logo abaixo, adicione:

 

else if(tmpStr == "move")
 m_type = CREATURE_EVENT_ONMOVE;

 

Procure por:

 

case CREATURE_EVENT_PREPAREDEATH:
  return "onPrepareDeath";

 

Abaixo, adicione:

 

 case CREATURE_EVENT_ONMOVE:
  return "onMoveItem";

 

Procure por:

 

case CREATURE_EVENT_PREPAREDEATH:
  return "cid, deathList";

 

Abaixo, adicione:

 

 case CREATURE_EVENT_ONMOVE:
  return "cid, item, formPosition, toPosition, fromItem, toItem, fromGround, toGround, status";

 

No fim do arquivo, adicione:

 

0.4

 

 

// custom move
uint32_t CreatureEvent::executeOnMove(Player* player, Item* item, const Position& fromPosition, const Position& toPosition,
Item* fromItem, Item* toItem, Item* fromGround, Item* toGround, std::map<std::string,int> status)
{
//onMoveItem(cid, item, formPosition, toPosition, fromItem, toItem, fromGround, toGround, status)
if(m_interface->reserveEnv())
{
 ScriptEnviroment* env = m_interface->getEnv();
 if(m_scripted == EVENT_SCRIPT_BUFFER)
 {
  env->setRealPos(player->getPosition());
  std::stringstream scriptstream;
  scriptstream << "local cid = " << env->addThing(player) << std::endl;

  env->streamThing(scriptstream, "item" ,item, env->addThing(item));
  env->streamPosition(scriptstream, "fromPosition", fromPosition);
  env->streamPosition(scriptstream, "toPosition", toPosition);


  env->streamThing(scriptstream, "fromItem",fromItem, env->addThing(fromItem));
  env->streamThing(scriptstream, "toItem",toItem, env->addThing(toItem));
  env->streamThing(scriptstream, "fromGround",fromGround, env->addThing(fromGround));
  env->streamThing(scriptstream, "toGround",toGround, env->addThing(toGround));



  scriptstream << "local status = {}" << std::endl;
  for(std::map<std::string,int>::iterator it = status.begin(); it != status.end(); ++it)
  {
scriptstream << "status."<< it->first << " = " << it->second;

  }


  if(m_scriptData)
scriptstream << *m_scriptData;

  bool result = true;
  if(m_interface->loadBuffer(scriptstream.str()))
  {
lua_State* L = m_interface->getState();
result = m_interface->getGlobalBool(L, "_result", true);
  }

  m_interface->releaseEnv();
  return result;
 }
 else
 {
  #ifdef __DEBUG_LUASCRIPTS__
  char desc[30];
  sprintf(desc, "%s", player->getName().c_str());
  env->setEvent(desc);
  #endif

  env->setScriptId(m_scriptId, m_interface);
  env->setRealPos(player->getPosition());

  lua_State* L = m_interface->getState();
  m_interface->pushFunction(m_scriptId);

  lua_pushnumber(L, env->addThing(player));

  LuaInterface::pushThing(L, item, env->addThing(item));
  LuaInterface::pushPosition(L, fromPosition);
  LuaInterface::pushPosition(L, toPosition);

  LuaInterface::pushThing(L, fromItem, env->addThing(fromItem));
  LuaInterface::pushThing(L, toItem, env->addThing(toItem));
  LuaInterface::pushThing(L, fromGround, env->addThing(fromGround));
  LuaInterface::pushThing(L, toGround, env->addThing(toGround));


  lua_newtable(L);
  std::map<std::string,int>::iterator it = status.begin();
  for(std::map<std::string,int>::iterator it = status.begin(); it != status.end(); ++it)
  {
LuaInterface::setField(L, it->first.c_str(), it->second);
  }






  bool result = m_interface->callFunction(9);
  m_interface->releaseEnv();
  return result;
 }
}
else
{
 std::clog << "[Error - CreatureEvent::executeMove] Call stack overflow." << std::endl;
 return 0;
}
}
//

 

 

0.3.6

 

 

uint32_t CreatureEvent::executeOnMove(Player* player, Item* item, const Position& fromPosition, const Position& toPosition,
Item* fromItem, Item* toItem, Item* fromGround, Item* toGround, std::map<std::string,int> status)
{
//onMoveItem(cid, item, formPosition, toPosition, fromItem, toItem, fromGround, toGround, move)
if(m_interface->reserveEnv())
{
 ScriptEnviroment* env = m_interface->getEnv();
 if(m_scripted == EVENT_SCRIPT_BUFFER)
 {
  env->setRealPos(player->getPosition());
  std::stringstream scriptstream;
  scriptstream << "local cid = " << env->addThing(player) << std::endl;

  env->streamThing(scriptstream, "item" ,item, env->addThing(item));
  env->streamPosition(scriptstream, "fromPosition", fromPosition);
  env->streamPosition(scriptstream, "toPosition", toPosition);


  env->streamThing(scriptstream, "fromItem",fromItem, env->addThing(fromItem));
  env->streamThing(scriptstream, "toItem",toItem, env->addThing(toItem));
  env->streamThing(scriptstream, "fromGround",fromGround, env->addThing(fromGround));
  env->streamThing(scriptstream, "toGround",toGround, env->addThing(toGround));


  scriptstream << "local status = {}" << std::endl;
  for(std::map<std::string,int>::iterator it = status.begin(); it != status.end(); ++it)
  {
scriptstream << "status."<< it->first << " = " << it->second;

  }

  scriptstream << m_scriptData;

  bool result = true;
  if(m_interface->loadBuffer(scriptstream.str()))
  {
lua_State* L = m_interface->getState();
result = m_interface->getGlobalBool(L, "_result", true);
  }

  m_interface->releaseEnv();
  return result;
 }
 else
 {
  #ifdef __DEBUG_LUASCRIPTS__
  char desc[30];
  sprintf(desc, "%s", player->getName().c_str());
  env->setEvent(desc);
  #endif

  env->setScriptId(m_scriptId, m_interface);
  env->setRealPos(player->getPosition());

  lua_State* L = m_interface->getState();
  m_interface->pushFunction(m_scriptId);

  lua_pushnumber(L, env->addThing(player));

  LuaScriptInterface::pushThing(L, item, env->addThing(item));
  LuaScriptInterface::pushPosition(L, fromPosition);
  LuaScriptInterface::pushPosition(L, toPosition);

  LuaScriptInterface::pushThing(L, fromItem, env->addThing(fromItem));
  LuaScriptInterface::pushThing(L, toItem, env->addThing(toItem));
  LuaScriptInterface::pushThing(L, fromGround, env->addThing(fromGround));
  LuaScriptInterface::pushThing(L, toGround, env->addThing(toGround));

  lua_newtable(L);
  std::map<std::string,int>::iterator it = status.begin();
  for(std::map<std::string,int>::iterator it = status.begin(); it != status.end(); ++it)
  {
LuaScriptInterface::setField(L, it->first.c_str(), it->second);
  }

  bool result = m_interface->callFunction(9);
  m_interface->releaseEnv();
  return result;
 }
}
else
{
 std::clog << "[Error - CreatureEvent::executeMove] Call stack overflow." << std::endl;
 return 0;
}
}

 

 


 

No arquivo game.cpp, procure:

 

bool Game::playerMoveItem(uint32_t playerId, const Position& fromPos, uint16_t spriteId, int16_t fromStackpos, const Position& toPos, uint8_t count)

 

Troque TODA ELA pelo conteúdo abaixo:

 

0.3.6

 

 

bool Game::playerMoveItem(uint32_t playerId, const Position& fromPos,
uint16_t spriteId, int16_t fromStackpos, const Position& toPos, uint8_t count)
{
Player* player = getPlayerByID(playerId);
//custom move
bool equip = false, deequip =false,fromDepot = false, toDepot = false;
//
if(!player || player->isRemoved() || player->hasFlag(PlayerFlag_CannotMoveItems))
 return false;

if(!player->canDoAction())
{
 uint32_t delay = player->getNextActionTime();
 SchedulerTask* task = createSchedulerTask(delay, boost::bind(&Game::playerMoveItem, this,
  playerId, fromPos, spriteId, fromStackpos, toPos, count));

 player->setNextActionTask(task);
 return false;
}

player->setNextActionTask(NULL);
Cylinder* fromCylinder = internalGetCylinder(player, fromPos);

//custom move
Item* fromItem = NULL;
Item* fromGround = NULL;
Player* fromPlayer= 0;

//

uint8_t fromIndex = 0;
if(fromPos.x == 0xFFFF)
{
 if(fromPos.y & 0x40)
 {
  fromIndex = static_cast<uint8_t>(fromPos.z);

  fromItem = fromCylinder->getItem();
  if (fromItem)
  {
fromPlayer = fromItem->getHoldingPlayer();
Item* parentFromItem = fromItem->getTopParent()->getItem();
if (fromItem->isDepot() || (parentFromItem && parentFromItem->isDepot()) )
 fromDepot = true;
  }
 }
 else
 {
  fromIndex = static_cast<uint8_t>(fromPos.y);
  //custom move
  deequip = true;
  //
 }
}
else
{
 fromIndex = fromStackpos;
 const TileItemVector* items = fromCylinder->getTile()->getItemList();

 Thing* thing = internalGetThing(player, fromPos, fromIndex, spriteId, STACKPOS_MOVE);

if(thing && thing->getItem())
 {
  Item* movingItem = thing->getItem();

  fromItem = NULL;

  fromGround = fromCylinder->getTile()->ground;
  for(ItemVector::const_reverse_iterator it = items->rbegin(); it != items->rend(); ++it)
  {
if((*it) != movingItem)
 fromItem = (*it);
  }

  if(!fromItem || fromItem == movingItem )
fromItem = fromGround ;
 }
}



Thing* thing = internalGetThing(player, fromPos, fromIndex, spriteId, STACKPOS_MOVE);
if(!thing || !thing->getItem())
{
 player->sendCancelMessage(RET_NOTPOSSIBLE);
 return false;
}

Item* item = thing->getItem();
Cylinder* toCylinder = internalGetCylinder(player, toPos);

//custom move
Item* toItem = NULL;
Item* toGround=NULL;
Player* toPlayer = NULL;


uint8_t toIndex = 0;
if(toPos.x == 0xFFFF)
{
 if(toPos.y & 0x40)
 {
  toIndex = static_cast<uint8_t>(toPos.z);
  if(toCylinder)
  {
toItem = toCylinder->getItem();

if(toItem)
{
 toPlayer = toItem->getHoldingPlayer();
 Item* parentToItem = toItem->getTopParent()->getItem();

 if (toItem->isDepot() || (parentToItem && parentToItem->isDepot()) )
  toDepot = true;
}
  }
 }
 else
 {
  toIndex = static_cast<uint8_t>(toPos.y);
  equip = true;
  //custom move
  Item* inveItem = player->getInventoryItem((slots_t)(unsigned)toIndex);
  if (inveItem  && inveItem->isContainer())
toItem = inveItem;


  //
 }
}
else
{
 if(toCylinder)
 {
  toItem = toCylinder->getTile()->getTopDownItem();
  toGround = toCylinder->getTile()->ground;
  if(!toItem)
toItem  = toGround;
 }
}

//custom move
Item* toSlotItem= (player->getInventoryItem((slots_t)((unsigned)toIndex)));
bool checkToSlot = false;

if (toSlotItem)
 checkToSlot= toSlotItem->isContainer();;
//

if(!fromCylinder || !toCylinder || !item || item->getClientID() != spriteId)
{
 player->sendCancelMessage(RET_NOTPOSSIBLE);
 return false;
}

if(!player->hasCustomFlag(PlayerCustomFlag_CanPushAllItems) && (!item->isPushable() || (item->isLoadedFromMap() &&
 (item->getUniqueId() != 0 || (item->getActionId() != 0 && item->getContainer())))))
{
 player->sendCancelMessage(RET_NOTMOVEABLE);
 return false;
}

const Position& mapFromPos = fromCylinder->getTile()->getPosition();
const Position& mapToPos = toCylinder->getTile()->getPosition();

const Position& playerPos = player->getPosition();
if(playerPos.z > mapFromPos.z && !player->hasCustomFlag(PlayerCustomFlag_CanThrowAnywhere))
{
 player->sendCancelMessage(RET_FIRSTGOUPSTAIRS);
 return false;
}

if(playerPos.z < mapFromPos.z && !player->hasCustomFlag(PlayerCustomFlag_CanThrowAnywhere))
{
 player->sendCancelMessage(RET_FIRSTGODOWNSTAIRS);
 return false;
}

if(!Position::areInRange<1,1,0>(playerPos, mapFromPos) && !player->hasCustomFlag(PlayerCustomFlag_CanMoveFromFar))
{
 //need to walk to the item first before using it
 std::list<Direction> listDir;
 if(getPathToEx(player, item->getPosition(), 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::playerMoveItem, this,
playerId, fromPos, spriteId, fromStackpos, toPos, count));

  player->setNextWalkActionTask(task);
  return true;
 }

 player->sendCancelMessage(RET_THEREISNOWAY);
 return false;
}

//hangable item specific code
if(item->isHangable() && toCylinder->getTile()->hasProperty(SUPPORTHANGABLE))
{
 //destination supports hangable objects so need to move there first
 if(toCylinder->getTile()->hasProperty(ISVERTICAL))
 {
  if(player->getPosition().x + 1 == mapToPos.x)
  {
player->sendCancelMessage(RET_NOTPOSSIBLE);
return false;
  }
 }
 else if(toCylinder->getTile()->hasProperty(ISHORIZONTAL))
 {
  if(player->getPosition().y + 1 == mapToPos.y)
  {
player->sendCancelMessage(RET_NOTPOSSIBLE);
return false;
  }
 }

 if(!Position::areInRange<1,1,0>(playerPos, mapToPos) && !player->hasCustomFlag(PlayerCustomFlag_CanMoveFromFar))
 {
  Position walkPos = mapToPos;
  if(toCylinder->getTile()->hasProperty(ISVERTICAL))
walkPos.x -= -1;

  if(toCylinder->getTile()->hasProperty(ISHORIZONTAL))
walkPos.y -= -1;

  Position itemPos = fromPos;
  int16_t itemStackpos = fromStackpos;
  if(fromPos.x != 0xFFFF && Position::areInRange<1,1,0>(mapFromPos, player->getPosition())
&& !Position::areInRange<1,1,0>(mapFromPos, walkPos))
  {
//need to pickup the item first
Item* moveItem = NULL;
ReturnValue ret = internalMoveItem(player, fromCylinder, player, INDEX_WHEREEVER, item, count, &moveItem);
if(ret != RET_NOERROR)
{
 player->sendCancelMessage(ret);
 return false;
}

//changing the position since its now in the inventory of the player
internalGetPosition(moveItem, itemPos, itemStackpos);
  }

  std::list<Direction> listDir;
  if(map->getPathTo(player, walkPos, listDir))
  {
Dispatcher::getInstance().addTask(createTask(boost::bind(&Game::playerAutoWalk,
 this, player->getID(), listDir)));
SchedulerTask* task = createSchedulerTask(player->getStepDuration(), boost::bind(&Game::playerMoveItem, this,
 playerId, itemPos, spriteId, itemStackpos, toPos, count));

player->setNextWalkActionTask(task);
return true;
  }

  player->sendCancelMessage(RET_THEREISNOWAY);
  return false;
 }
}

if(!player->hasCustomFlag(PlayerCustomFlag_CanThrowAnywhere))
{
 if((std::abs(playerPos.x - mapToPos.x) > item->getThrowRange()) ||
  (std::abs(playerPos.y - mapToPos.y) > item->getThrowRange()) ||
  (std::abs(mapFromPos.z - mapToPos.z) * 4 > item->getThrowRange()))
 {
  player->sendCancelMessage(RET_DESTINATIONOUTOFREACH);
  return false;
 }
}

if(!canThrowObjectTo(mapFromPos, mapToPos) && !player->hasCustomFlag(PlayerCustomFlag_CanThrowAnywhere))
{
 player->sendCancelMessage(RET_CANNOTTHROW);
 return false;
}

//custom move
bool Out = (fromPlayer) ? true : false;
bool In = (toPlayer) ? true : false;
std::map<std::string,int> status;

status["inInv"] = (equip && !deequip && !checkToSlot) ? 1:( (!equip && deequip) || (deequip && equip && checkToSlot) ) ? 0 : (equip && deequip && !checkToSlot) ? 2 :3;
status["inDepot"] = (fromDepot && !toDepot) ? 0 : (!fromDepot && toDepot) ? 1: (fromDepot && toDepot) ? 2:3;
status["inInvBag"] = (Out && !In && !checkToSlot )? 0:((In && !Out) || (!Out && equip && checkToSlot)) ? 1:((In && Out) || (Out && equip && checkToSlot))?2:3;
status["slot"] = (int) toIndex;


bool deny = false;
CreatureEventList moveEvents = player->getCreatureEvents(CREATURE_EVENT_ONMOVE);
for(CreatureEventList::iterator it = moveEvents.begin(); it != moveEvents.end(); ++it)
{
 if(!(*it)->executeOnMove(player, item, mapFromPos, mapToPos, fromItem,toItem,fromGround,toGround,status))
  deny = true;
}

if(deny)
 return false;

ReturnValue ret = internalMoveItem(player, fromCylinder, toCylinder, toIndex, item, count, NULL);
if(ret == RET_NOERROR)
 return true;

player->sendCancelMessage(ret);
return false;
}

 

 

 

0.4

 

 

bool Game::playerMoveItem(uint32_t playerId, const Position& fromPos,
uint16_t spriteId, int16_t fromStackpos, const Position& toPos, uint8_t count)
{
Player* player = getPlayerByID(playerId);
//Doggynub: custom move
bool equip = false, deequip =false,fromDepot = false, toDepot = false;
int32_t fr = 0,to = 0;
//
if(!player || player->isRemoved() || player->hasFlag(PlayerFlag_CannotMoveItems))
 return false;

if(!player->canDoAction())
{
 uint32_t delay = player->getNextActionTime();
 SchedulerTask* task = createSchedulerTask(delay, boost::bind(&Game::playerMoveItem, this,
  playerId, fromPos, spriteId, fromStackpos, toPos, count));

 player->setNextActionTask(task);
 return false;
}

player->setNextActionTask(NULL);
Cylinder* fromCylinder = internalGetCylinder(player, fromPos);


uint8_t fromIndex = 0;
if(fromPos.x == 0xFFFF)
{
 if(fromPos.y & 0x40)
 {
  fromIndex = static_cast<uint8_t>(fromPos.z);
  fr = 1;

 }
 else
 {
  fromIndex = static_cast<uint8_t>(fromPos.y);
  fr = 2;
 }
}
else
{
 fromIndex = fromStackpos;
 fr = 3;
}



Thing* thing = internalGetThing(player, fromPos, fromIndex, spriteId, STACKPOS_MOVE);
if(!thing || !thing->getItem())
{
 player->sendCancelMessage(RET_NOTPOSSIBLE);
 return false;
}

Item* item = thing->getItem();
Cylinder* toCylinder = internalGetCylinder(player, toPos);



uint8_t toIndex = 0;
if(toPos.x == 0xFFFF)
{
 if(toPos.y & 0x40)
 {
  toIndex = static_cast<uint8_t>(toPos.z);
  to = 1;
 }
 else
 {
  toIndex = static_cast<uint8_t>(toPos.y);
  to = 2;
 }
}
else
 to = 3;




if(!fromCylinder || !toCylinder || !item || item->getClientID() != spriteId)
{
 player->sendCancelMessage(RET_NOTPOSSIBLE);
 return false;
}


if(!player->hasCustomFlag(PlayerCustomFlag_CanPushAllItems) && (!item->isPushable() || (item->isLoadedFromMap() &&
 (item->getUniqueId() != 0 || (item->getActionId() != 0 && item->getContainer())))))
{
 player->sendCancelMessage(RET_NOTMOVABLE);
 return false;
}

const Position &mapToPos = toCylinder->getTile()->getPosition(), &playerPos = player->getPosition(),
 &mapFromPos = fromCylinder->getTile()->getPosition();


if(playerPos.z > mapFromPos.z && !player->hasCustomFlag(PlayerCustomFlag_CanThrowAnywhere))
{
 player->sendCancelMessage(RET_FIRSTGOUPSTAIRS);
 return false;
}

if(playerPos.z < mapFromPos.z && !player->hasCustomFlag(PlayerCustomFlag_CanThrowAnywhere))
{
 player->sendCancelMessage(RET_FIRSTGODOWNSTAIRS);
 return false;
}

if(!Position::areInRange<1,1,0>(playerPos, mapFromPos) && !player->hasCustomFlag(PlayerCustomFlag_CanMoveFromFar))
{
 //need to walk to the item first before using it
 std::list<Direction> listDir;
 if(getPathToEx(player, item->getPosition(), listDir, 0, 1, true, true))
 {
  Dispatcher::getInstance().addTask(createTask(boost::bind(&Game::playerAutoWalk,
this, player->getID(), listDir)));
  SchedulerTask* task = createSchedulerTask(std::max((int32_t)SCHEDULER_MINTICKS, player->getStepDuration()),
boost::bind(&Game::playerMoveItem, this, playerId, fromPos, spriteId, fromStackpos, toPos, count));

  player->setNextWalkActionTask(task);
  return true;
 }

 player->sendCancelMessage(RET_THEREISNOWAY);
 return false;
}

//hangable item specific code
if(item->isHangable() && toCylinder->getTile()->hasProperty(SUPPORTHANGABLE))
{
 //destination supports hangable objects so need to move there first
 if(toCylinder->getTile()->hasProperty(ISVERTICAL))
 {
  if(player->getPosition().x + 1 == mapToPos.x)
  {
player->sendCancelMessage(RET_NOTPOSSIBLE);
return false;
  }
 }
 else if(toCylinder->getTile()->hasProperty(ISHORIZONTAL))
 {
  if(player->getPosition().y + 1 == mapToPos.y)
  {
player->sendCancelMessage(RET_NOTPOSSIBLE);
return false;
  }
 }

 if(!Position::areInRange<1,1,0>(playerPos, mapToPos) && !player->hasCustomFlag(PlayerCustomFlag_CanMoveFromFar))
 {
  Position walkPos = mapToPos;
  if(toCylinder->getTile()->hasProperty(ISVERTICAL))
walkPos.x -= -1;

  if(toCylinder->getTile()->hasProperty(ISHORIZONTAL))
walkPos.y -= -1;

  Position itemPos = fromPos;
  int16_t itemStackpos = fromStackpos;
  if(fromPos.x != 0xFFFF && Position::areInRange<1,1,0>(mapFromPos, player->getPosition())
&& !Position::areInRange<1,1,0>(mapFromPos, walkPos))
  {
//need to pickup the item first
Item* moveItem = NULL;
ReturnValue ret = internalMoveItem(player, fromCylinder, player, INDEX_WHEREEVER, item, count, &moveItem);
if(ret != RET_NOERROR)
{
 player->sendCancelMessage(ret);
 return false;
}

//changing the position since its now in the inventory of the player
internalGetPosition(moveItem, itemPos, itemStackpos);
  }

  std::list<Direction> listDir;
  if(map->getPathTo(player, walkPos, listDir))
  {
Dispatcher::getInstance().addTask(createTask(boost::bind(&Game::playerAutoWalk,
 this, player->getID(), listDir)));
SchedulerTask* task = createSchedulerTask(std::max((int32_t)SCHEDULER_MINTICKS, player->getStepDuration()),
 boost::bind(&Game::playerMoveItem, this, playerId, itemPos, spriteId, itemStackpos, toPos, count));

player->setNextWalkActionTask(task);
return true;
  }

  player->sendCancelMessage(RET_THEREISNOWAY);
  return false;
 }
}

if(!player->hasCustomFlag(PlayerCustomFlag_CanThrowAnywhere))
{
 if((std::abs(playerPos.x - mapToPos.x) > item->getThrowRange()) ||
  (std::abs(playerPos.y - mapToPos.y) > item->getThrowRange()) ||
  (std::abs(mapFromPos.z - mapToPos.z) * 4 > item->getThrowRange()))
 {
  player->sendCancelMessage(RET_DESTINATIONOUTOFREACH);
  return false;
 }
}

if(!canThrowObjectTo(mapFromPos, mapToPos) && !player->hasCustomFlag(PlayerCustomFlag_CanThrowAnywhere))
{
 player->sendCancelMessage(RET_CANNOTTHROW);
 return false;
}

//Doggynub: custom move
if(!item->getParent())
{
 assert(fromCylinder == item->getParent());
}

Item* toItem = NULL;
Item* fromItem = NULL;
Item* toGround=NULL;
Item* fromGround=NULL;
Player* toPlayer = NULL;
Player* fromPlayer= NULL;

Item* toSlotItem= (player->getInventoryItem((slots_t)((unsigned)toIndex)));
bool checkToSlot = false;

if (toSlotItem)
 checkToSlot= toSlotItem->isContainer();

if (fr == 1)
{
 fromItem = fromCylinder->getItem();
 if (fromItem)
 {
  fromPlayer = fromItem->getHoldingPlayer();
  Item* parentFromItem = fromItem->getTopParent()->getItem();
  if (fromItem->isDepot() || (parentFromItem && parentFromItem->isDepot()) )
fromDepot = true;
 }
}
else if (fr == 2)
 deequip = true;
else
{
 const TileItemVector* items = fromCylinder->getTile()->getItemList();
 fromItem = NULL;
 fromGround = fromCylinder->getTile()->ground;
 for(ItemVector::const_reverse_iterator it = items->rbegin(); it != items->rend(); ++it)
 {
  if((*it) != item)
fromItem = (*it);
 }

 if(!fromItem || fromItem == item )
  fromItem = fromGround ;
}

if(to == 1)
{
 toItem = toCylinder->getItem();
 if(toItem)
 {
  toPlayer = toItem->getHoldingPlayer();
  Item* parentToItem = toItem->getTopParent()->getItem();

  if (toItem->isDepot() || (parentToItem && parentToItem->isDepot()) )
toDepot = true;
 }

}
else if(to == 2)
{
 equip = true;
 Item* inveItem = player->getInventoryItem((slots_t)(unsigned)toIndex);
 if (inveItem  && inveItem->isContainer())
  toItem = inveItem;

}
else
{
 toItem = toCylinder->getTile()->getTopDownItem();
 toGround = toCylinder->getTile()->ground;
 if(!toItem)
  toItem  = toGround;

}

bool Out = (fromPlayer) ? true : false;
bool In = (toPlayer) ? true : false;
std::map<std::string,int> status;

status["inInv"] = (equip && !deequip && !checkToSlot) ? 1:( (!equip && deequip) || (deequip && equip && checkToSlot) ) ? 0 : (equip &&		   deequip && !checkToSlot) ? 2 :3;
	status["inDepot"] = (fromDepot && !toDepot) ? 0 : (!fromDepot && toDepot) ? 1: (fromDepot && toDepot) ? 2:3;
	status["inInvBag"] = (Out && !In && !checkToSlot )? 0:((In && !Out) || (!Out && equip && checkToSlot)) ? 1:((In && Out) || (Out && equip && checkToSlot))?2:3;
	status["slot"] = (int) toIndex;

bool deny = false;
CreatureEventList moveEvents = player->getCreatureEvents(CREATURE_EVENT_ONMOVE);
for(CreatureEventList::iterator it = moveEvents.begin(); it != moveEvents.end(); ++it)
{
 if(!(*it)->executeOnMove(player, item, mapFromPos, mapToPos, fromItem,toItem,fromGround,toGround,status))
  deny = true;
}

if(deny)
 return false;
//end

ReturnValue ret = internalMoveItem(player, fromCylinder, toCylinder, toIndex, item, count, NULL);
if(ret != RET_NOERROR)
{
 player->sendCancelMessage(ret);
 return false;
}

player->setNextAction(OTSYS_TIME() + g_config.getNumber(ConfigManager::ACTIONS_DELAY_INTERVAL) - 10);
return true;
}

 

 

 


 

O código C++ acima como dito anteriormente, abre um leque grande de possibilidades de novos scripts para seu servidor.

 

As versões mais atuais do Open Tibia, como o The Forgotten Server, já possuem algo parecido compilado, um creaturescript chamado onThrow, embora este não tenha tantos extras como o passado no tópico.

 


Editado por Oneshot
Link para o comentário
Compartilhar em outros sites

  • 4 weeks later...
  • 2 years later...

Desculpe reabrir o tópico, mas essa parte estaria correto?

case CREATURE_EVENT_ONMOVE:
     return "cid, item, formPosition, toPosition, fromItem, toItem, fromGround, toGround, status";

Não seria fromPosition ao invés de formPosition?...

Link para o comentário
Compartilhar em outros sites

  • 5 months later...

No meu deu este erro:

 

587437a4cf3bb7824daff88a39260f27.png

 

Alguem ai pra ajudar?? preciso mt!! Obg

 

 

Edit@

 

EU removi estas duas linhas 1936 e 1937, que eram isso:

 

 

   if(m_scriptData)
scriptstream << *m_scriptData;

 

Vai dar algum problema?

Editado por Zet0N0Murmurouu
Link para o comentário
Compartilhar em outros sites

  • 1 month later...

otima funçao cara, mas teria um exemplo de uso? estou tentando fazer com que o player n drop items em teleports, porem n faço a minima ideia de como poderia usar essa funçao pra isso.

Link para o comentário
Compartilhar em outros sites

×
×
  • Criar Novo...