What is it?
It's a movement script that creates a own training room for player, in random void position you will select from your map cordinates. When player don't want to train anymore, he go to teleport in training room and he will be teleported, also training room will dissapear, because we saving infinity space ofcourse .
Why use it?
Well, I self never liked to create training rooms, I even dislike to open map editor it is pain to my heart and head. But that's not a reason you should to use script. The main reason is, you not must to spend your time in creating huge and large training rooms for players, everything what you will have to do in map editor is create teleport where you want and set action id: 8770 on it.
Can it lag or crash server?
I don't think so, it's very basic script it maybe can looks huge but it isin't. You even can set cords 20kx20k.
for 0.3.6 it will requires some source changes, because you not allowed to createItem in Void it wont take too much time, here it is:
luascript.cpp
find this function line:
and replace it all to this:
iomap.h
find this line:
and you need it to move in public section result will look like this:
tile.h
find this line:
and you need it to move in public section result will look like this:
So thats all for 0.3.6 source edits, and 0.4 don't need it.
LUA PART FOR BOTH 0.3.6 and 0.4:
movements.xml
custom/training_tile_in.lua
custom/training_tile_out.lua
Important to know: This script/code was not supposed to be for public, I don't care about tabbing or shortings it is supposed to be for my project but because lack of time I had to leave it. And I felt friendly ofcourse to release it =^_^=
However if something not working, let me know ofcourse I will fix it.
It's a movement script that creates a own training room for player, in random void position you will select from your map cordinates. When player don't want to train anymore, he go to teleport in training room and he will be teleported, also training room will dissapear, because we saving infinity space ofcourse .
Why use it?
Well, I self never liked to create training rooms, I even dislike to open map editor it is pain to my heart and head. But that's not a reason you should to use script. The main reason is, you not must to spend your time in creating huge and large training rooms for players, everything what you will have to do in map editor is create teleport where you want and set action id: 8770 on it.
Can it lag or crash server?
I don't think so, it's very basic script it maybe can looks huge but it isin't. You even can set cords 20kx20k.
for 0.3.6 it will requires some source changes, because you not allowed to createItem in Void it wont take too much time, here it is:
luascript.cpp
find this function line:
Code:
int32_t LuaScriptInterface::luaDoCreateItem(lua_State* L)
and replace it all to this:
Code:
int32_t LuaScriptInterface::luaDoCreateItem(lua_State* L)
{
//doCreateItem(itemid[, type/count], pos)
//Returns uid of the created item, only works on tiles.
PositionEx pos;
popPosition(L, pos);
uint32_t count = 1;
if(lua_gettop(L) > 1)
count = popNumber(L);
uint32_t itemId = popNumber(L);
ScriptEnviroment* env = getEnv();
Tile* tile = g_game.getTile(pos);
const ItemType& it = Item::items[itemId];
if((!tile))
{
if(it.group == ITEM_GROUP_GROUND)
{
Item* item = Item::CreateItem(itemId);
tile = IOMap::createTile(item, NULL, pos.x, pos.y, pos.z);
g_game.setTile(tile);
tile->onUpdateTile();
lua_pushnumber(L, env->addThing(item));
return 1;
}
else
{
errorEx(getError(LUA_ERROR_TILE_NOT_FOUND));
lua_pushboolean(L, false);
return 1;
}
}
int32_t itemCount = 1, subType = 1;
if(it.hasSubType())
{
if(it.stackable)
itemCount = (int32_t)std::ceil((float)count / 100);
subType = count;
}
else
itemCount = std::max((uint32_t)1, count);
while(itemCount > 0)
{
int32_t stackCount = std::min(100, subType);
Item* newItem = Item::CreateItem(itemId, stackCount);
if(!newItem)
{
errorEx(getError(LUA_ERROR_ITEM_NOT_FOUND));
lua_pushboolean(L, false);
return 1;
}
if(it.stackable)
subType -= stackCount;
ReturnValue ret = g_game.internalAddItem(NULL, tile, newItem, INDEX_WHEREEVER, FLAG_NOLIMIT);
if(ret != RET_NOERROR)
{
delete newItem;
lua_pushboolean(L, false);
return 1;
}
--itemCount;
if(itemCount)
continue;
if(newItem->getParent())
lua_pushnumber(L, env->addThing(newItem));
else //stackable item stacked with existing object, newItem will be released
lua_pushnil(L);
return 1;
}
lua_pushnil(L);
return 1;
}
iomap.h
find this line:
Code:
static Tile* createTile(Item*& ground, Item* item, uint16_t px, uint16_t py, uint16_t pz);
and you need it to move in public section result will look like this:
Code:
class IOMap
{
public:
IOMap() {}
virtual ~IOMap() {}
static Tile* createTile(Item*& ground, Item* item, uint16_t px, uint16_t py, uint16_t pz);
bool loadMap(Map* map, const std::string& identifier);
/* Load the spawns
* \param map pointer to the Map class
* \returns Returns true if the spawns were loaded successfully
*/
bool loadSpawns(Map* map);
/* Load the houses (not house tile-data)
* \param map pointer to the Map class
* \returns Returns true if the houses were loaded successfully
*/
bool loadHouses(Map* map);
const std::string& getLastErrorString() const {return errorString;}
void setLastErrorString(const std::string& _errorString) {errorString = _errorString;}
protected:
std::string errorString;
};
tile.h
find this line:
Code:
void onUpdateTile();
and you need it to move in public section result will look like this:
Code:
class Tile : public Cylinder
{
public:
static Tile& nullTile;
Tile(uint16_t x, uint16_t y, uint16_t z);
virtual ~Tile();
TileItemVector* getItemList();
const TileItemVector* getItemList() const;
TileItemVector* makeItemList();
CreatureVector* getCreatures();
const CreatureVector* getCreatures() const;
CreatureVector* makeCreatures();
HouseTile* getHouseTile();
const HouseTile* getHouseTile() const;
bool isHouseTile() const {return hasFlag(TILESTATE_HOUSE);}
MagicField* getFieldItem() const;
Teleport* getTeleportItem() const;
TrashHolder* getTrashHolder() const;
Mailbox* getMailbox() const;
BedItem* getBedItem() const;
Creature* getTopCreature();
Item* getTopTopItem();
Item* getTopDownItem();
bool isMoveableBlocking() const;
Thing* getTopVisibleThing(const Creature* creature);
Creature* getTopVisibleCreature(const Creature* creature);
const Creature* getTopVisibleCreature(const Creature* creature) const;
Item* getItemByTopOrder(uint32_t topOrder);
uint32_t getThingCount() const {return thingCount;}
uint32_t getCreatureCount() const;
uint32_t getItemCount() const;
uint32_t getTopItemCount() const;
uint32_t getDownItemCount() const;
bool hasProperty(enum ITEMPROPERTY prop) const;
bool hasProperty(Item* exclude, enum ITEMPROPERTY prop) const;
bool hasFlag(tileflags_t flag) const {return ((m_flags & (uint32_t)flag) == (uint32_t)flag);}
void setFlag(tileflags_t flag) {m_flags |= (uint32_t)flag;}
void resetFlag(tileflags_t flag) {m_flags &= ~(uint32_t)flag;}
bool positionChange() const {return hasFlag(TILESTATE_TELEPORT);}
bool floorChange(FloorChange_t change = CHANGE_NONE) const
{
switch(change)
{
case CHANGE_DOWN:
return hasFlag(TILESTATE_FLOORCHANGE_DOWN);
case CHANGE_NORTH:
return hasFlag(TILESTATE_FLOORCHANGE_NORTH);
case CHANGE_SOUTH:
return hasFlag(TILESTATE_FLOORCHANGE_SOUTH);
case CHANGE_EAST:
return hasFlag(TILESTATE_FLOORCHANGE_EAST);
case CHANGE_WEST:
return hasFlag(TILESTATE_FLOORCHANGE_WEST);
case CHANGE_NORTH_EX:
return hasFlag(TILESTATE_FLOORCHANGE_NORTH_EX);
case CHANGE_SOUTH_EX:
return hasFlag(TILESTATE_FLOORCHANGE_SOUTH_EX);
case CHANGE_EAST_EX:
return hasFlag(TILESTATE_FLOORCHANGE_EAST_EX);
case CHANGE_WEST_EX:
return hasFlag(TILESTATE_FLOORCHANGE_WEST_EX);
case CHANGE_NONE:
return hasFlag(TILESTATE_FLOORCHANGE);
default:
break;
}
return false;
}
ZoneType_t getZone() const
{
if(hasFlag(TILESTATE_PROTECTIONZONE))
return ZONE_PROTECTION;
if(hasFlag(TILESTATE_NOPVPZONE))
return ZONE_NOPVP;
if(hasFlag(TILESTATE_PVPZONE))
return ZONE_PVP;
return ZONE_NORMAL;
}
bool isSwimmingPool(bool checkPz = true) const;
bool hasHeight(uint32_t n) const;
void moveCreature(Creature* actor, Creature* creature, Cylinder* toCylinder, bool forceTeleport = false);
int32_t getClientIndexOfThing(const Player* player, const Thing* thing) const;
//cylinder implementations
virtual Cylinder* getParent() {return NULL;}
virtual const Cylinder* getParent() const {return NULL;}
virtual bool isRemoved() const {return false;}
virtual Position getPosition() const {return pos;}
virtual Tile* getTile() {return this;}
virtual const Tile* getTile() const {return this;}
virtual Item* getItem() {return NULL;}
virtual const Item* getItem() const {return NULL;}
virtual Creature* getCreature() {return NULL;}
virtual const Creature* getCreature() const {return NULL;}
virtual ReturnValue __queryAdd(int32_t index, const Thing* thing, uint32_t count,
uint32_t flags) const;
virtual ReturnValue __queryMaxCount(int32_t index, const Thing* thing, uint32_t count,
uint32_t& maxQueryCount, uint32_t flags) const;
virtual ReturnValue __queryRemove(const Thing* thing, uint32_t count, uint32_t flags) const;
virtual Cylinder* __queryDestination(int32_t& index, const Thing* thing, Item** destItem,
uint32_t& flags);
virtual void __addThing(Creature* actor, Thing* thing) {__addThing(actor, 0, thing);}
virtual void __addThing(Creature* actor, int32_t index, Thing* thing);
virtual void __updateThing(Thing* thing, uint16_t itemId, uint32_t count);
virtual void __replaceThing(uint32_t index, Thing* thing);
virtual void __removeThing(Thing* thing, uint32_t count);
virtual int32_t __getIndexOfThing(const Thing* thing) const;
virtual int32_t __getFirstIndex() const {return 0;}
virtual int32_t __getLastIndex() const {return thingCount;}
virtual uint32_t __getItemTypeCount(uint16_t itemId, int32_t subType = -1, bool itemCount = true) const;
virtual Thing* __getThing(uint32_t index) const;
virtual void postAddNotification(Creature* actor, Thing* thing, const Cylinder* oldParent,
int32_t index, cylinderlink_t link = LINK_OWNER);
virtual void postRemoveNotification(Creature* actor, Thing* thing, const Cylinder* newParent,
int32_t index, bool isCompleteRemoval, cylinderlink_t link = LINK_OWNER);
virtual void __internalAddThing(Thing* thing) {__internalAddThing(0, thing);}
virtual void __internalAddThing(uint32_t index, Thing* thing);
void onUpdateTile();
private:
void onAddTileItem(Item* item);
void onUpdateTileItem(Item* oldItem, const ItemType& oldType, Item* newItem, const ItemType& newType);
void onRemoveTileItem(const SpectatorVec& list, std::vector<uint32_t>& oldStackPosVector, Item* item);
void updateTileFlags(Item* item, bool removed);
protected:
bool isDynamic() const {return (m_flags & TILESTATE_DYNAMIC_TILE);}
public:
QTreeLeafNode* qt_node;
Item* ground;
protected:
Position pos;
uint32_t m_flags, thingCount;
};
So thats all for 0.3.6 source edits, and 0.4 don't need it.
LUA PART FOR BOTH 0.3.6 and 0.4:
movements.xml
Code:
<movevent type="StepIn" actionid="8770" event="script" value="custom/training_tile_in.lua" />
<movevent type="StepIn" actionid="8771" event="script" value="custom/training_tile_out.lua" />
custom/training_tile_in.lua
Lua:
local config = {
fromPosition = {x = 1008, y = 795, z = 12}, -- void area (black screen in map editor) south-west corner
toPosition = {x = 1210, y = 853, z = 15}, -- void area (black screen in map editor) north-east corner
-- A hint toPosition config cordinates numbers must be higher than fromPosition cordinates numbers
teleport = 1387,
fire = 1484,
northWall = 1114,
northWallSmall = 1113,
westNorthWall = 1115,
westWall = 1116,
ground = 406
}
function onStepIn(cid, item, pos)
local pos = {x = math.random(config.fromPosition.x, config.toPosition.x), y = math.random(config.fromPosition.y, config.toPosition.y), z = math.random(config.fromPosition.z, config.toPosition.z)}
resultPos = pos
if getTileItemById({x=resultPos.x, y=resultPos.y, z=resultPos.z}, config.ground).uid < 1 then
if getTileItemById({x=resultPos.x+1, y=resultPos.y, z=resultPos.z}, config.ground).uid < 1 then
if getTileItemById({x=resultPos.x+2, y=resultPos.y, z=resultPos.z}, config.ground).uid < 1 then
if getTileItemById({x=resultPos.x+3, y=resultPos.y, z=resultPos.z}, config.ground).uid < 1 then
if getTileItemById({x=resultPos.x+4, y=resultPos.y, z=resultPos.z}, config.ground).uid < 1 then
if getTileItemById({x=resultPos.x, y=resultPos.y+1, z=resultPos.z}, config.ground).uid < 1 then
if getTileItemById({x=resultPos.x, y=resultPos.y+2, z=resultPos.z}, config.ground).uid < 1 then
if getTileItemById({x=resultPos.x, y=resultPos.y+3, z=resultPos.z}, config.ground).uid < 1 then
if getTileItemById({x=resultPos.x, y=resultPos.y+4, z=resultPos.z}, config.ground).uid < 1 then
if getTileItemById({x=resultPos.x+4, y=resultPos.y+1, z=resultPos.z}, config.ground).uid < 1 then
if getTileItemById({x=resultPos.x+4, y=resultPos.y+2, z=resultPos.z}, config.ground).uid < 1 then
if getTileItemById({x=resultPos.x+4, y=resultPos.y+3, z=resultPos.z}, config.ground).uid < 1 then
if getTileItemById({x=resultPos.x+4, y=resultPos.y+4, z=resultPos.z}, config.ground).uid < 1 then
if getTileItemById({x=resultPos.x+1, y=resultPos.y+4, z=resultPos.z}, config.ground).uid < 1 then
if getTileItemById({x=resultPos.x+2, y=resultPos.y+4, z=resultPos.z}, config.ground).uid < 1 then
if getTileItemById({x=resultPos.x+3, y=resultPos.y+4, z=resultPos.z}, config.ground).uid < 1 then
if getTileItemById({x=resultPos.x+1, y=resultPos.y+3, z=resultPos.z}, config.ground).uid < 1 then
if getTileItemById({x=resultPos.x+2, y=resultPos.y+3, z=resultPos.z}, config.ground).uid < 1 then
if getTileItemById({x=resultPos.x+3, y=resultPos.y+3, z=resultPos.z}, config.ground).uid < 1 then
if getTileItemById({x=resultPos.x+1, y=resultPos.y+2, z=resultPos.z}, config.ground).uid < 1 then
if getTileItemById({x=resultPos.x+2, y=resultPos.y+2, z=resultPos.z}, config.ground).uid < 1 then
if getTileItemById({x=resultPos.x+3, y=resultPos.y+2, z=resultPos.z}, config.ground).uid < 1 then
if getTileItemById({x=resultPos.x+1, y=resultPos.y+1, z=resultPos.z}, config.ground).uid < 1 then
if getTileItemById({x=resultPos.x+2, y=resultPos.y+1, z=resultPos.z}, config.ground).uid < 1 then
if getTileItemById({x=resultPos.x+3, y=resultPos.y+1, z=resultPos.z}, config.ground).uid < 1 then
doCreateItem(config.ground, 1, {x=resultPos.x, y=resultPos.y, z=resultPos.z})
doCreateItem(config.ground, 1, {x=resultPos.x+1, y=resultPos.y, z=resultPos.z})
doCreateItem(config.ground, 1, {x=resultPos.x+2, y=resultPos.y, z=resultPos.z})
doCreateItem(config.ground, 1, {x=resultPos.x+3, y=resultPos.y, z=resultPos.z})
doCreateItem(config.ground, 1, {x=resultPos.x+4, y=resultPos.y, z=resultPos.z})
doCreateItem(config.northWallSmall, 1, {x=resultPos.x, y=resultPos.y, z=resultPos.z})
doCreateItem(config.northWall, 1, {x=resultPos.x+1, y=resultPos.y, z=resultPos.z})
doCreateItem(config.northWall, 1, {x=resultPos.x+2, y=resultPos.y, z=resultPos.z})
doCreateItem(config.northWall, 1, {x=resultPos.x+3, y=resultPos.y, z=resultPos.z})
doCreateItem(config.northWall, 1, {x=resultPos.x+4, y=resultPos.y, z=resultPos.z})
doCreateItem(config.ground, 1, {x=resultPos.x, y=resultPos.y+1, z=resultPos.z})
doCreateItem(config.ground, 1, {x=resultPos.x, y=resultPos.y+2, z=resultPos.z})
doCreateItem(config.ground, 1, {x=resultPos.x, y=resultPos.y+3, z=resultPos.z})
doCreateItem(config.ground, 1, {x=resultPos.x, y=resultPos.y+4, z=resultPos.z})
doCreateItem(config.westWall, 1, {x=resultPos.x, y=resultPos.y+1, z=resultPos.z})
doCreateItem(config.westWall, 1, {x=resultPos.x, y=resultPos.y+2, z=resultPos.z})
doCreateItem(config.westWall, 1, {x=resultPos.x, y=resultPos.y+3, z=resultPos.z})
doCreateItem(config.westWall, 1, {x=resultPos.x, y=resultPos.y+4, z=resultPos.z})
doCreateItem(config.ground, 1, {x=resultPos.x+4, y=resultPos.y+1, z=resultPos.z})
doCreateItem(config.ground, 1, {x=resultPos.x+4, y=resultPos.y+2, z=resultPos.z})
doCreateItem(config.ground, 1, {x=resultPos.x+4, y=resultPos.y+3, z=resultPos.z})
doCreateItem(config.ground, 1, {x=resultPos.x+4, y=resultPos.y+4, z=resultPos.z})
doCreateItem(config.westWall, 1, {x=resultPos.x+4, y=resultPos.y+1, z=resultPos.z})
doCreateItem(config.westWall, 1, {x=resultPos.x+4, y=resultPos.y+2, z=resultPos.z})
doCreateItem(config.westWall, 1, {x=resultPos.x+4, y=resultPos.y+3, z=resultPos.z})
doCreateItem(config.westNorthWall, 1, {x=resultPos.x+4, y=resultPos.y+4, z=resultPos.z})
doCreateItem(config.ground, 1, {x=resultPos.x+1, y=resultPos.y+4, z=resultPos.z})
doCreateItem(config.ground, 1, {x=resultPos.x+2, y=resultPos.y+4, z=resultPos.z})
doCreateItem(config.ground, 1, {x=resultPos.x+3, y=resultPos.y+4, z=resultPos.z})
doCreateItem(config.northWall, 1, {x=resultPos.x+1, y=resultPos.y+4, z=resultPos.z})
doCreateItem(config.northWall, 1, {x=resultPos.x+2, y=resultPos.y+4, z=resultPos.z})
doCreateItem(config.northWall, 1, {x=resultPos.x+3, y=resultPos.y+4, z=resultPos.z})
doCreateItem(config.ground, 1, {x=resultPos.x+1, y=resultPos.y+3, z=resultPos.z})
doCreateItem(config.ground, 1, {x=resultPos.x+2, y=resultPos.y+3, z=resultPos.z})
doCreateItem(config.ground, 1, {x=resultPos.x+3, y=resultPos.y+3, z=resultPos.z})
doCreateItem(config.ground, 1, {x=resultPos.x+1, y=resultPos.y+2, z=resultPos.z})
doCreateItem(config.ground, 1, {x=resultPos.x+2, y=resultPos.y+2, z=resultPos.z})
doCreateItem(config.ground, 1, {x=resultPos.x+3, y=resultPos.y+2, z=resultPos.z})
doCreateItem(config.ground, 1, {x=resultPos.x+1, y=resultPos.y+1, z=resultPos.z})
doCreateItem(config.ground, 1, {x=resultPos.x+2, y=resultPos.y+1, z=resultPos.z})
doCreateItem(config.ground, 1, {x=resultPos.x+3, y=resultPos.y+1, z=resultPos.z})
doCreateMonster("Training Monk", {x=resultPos.x+1, y=resultPos.y+1, z=resultPos.z})
local tele = doCreateItem(config.teleport, 1, {x=resultPos.x+2, y=resultPos.y+1, z=resultPos.z})
doItemSetAttribute(tele, "aid", 8771)
local roomGround = doCreateItem(config.ground, 1, {x=resultPos.x+2, y=resultPos.y+2, z=resultPos.z})
doItemSetAttribute(roomGround, "aid", 8772)
local roomGround2 = doCreateItem(config.ground, 1, {x=resultPos.x+2, y=resultPos.y+3, z=resultPos.z})
doItemSetAttribute(roomGround2, "aid", 8772)
doTeleportThing(cid, {x=resultPos.x+2, y=resultPos.y+2, z=resultPos.z})
doSendMagicEffect({x=resultPos.x+2, y=resultPos.y+2, z=resultPos.z}, CONST_ME_TELEPORT)
doCreateMonster("Training Monk", {x=resultPos.x+3, y=resultPos.y+1, z=resultPos.z})
doCreateItem(config.fire, 1, {x=resultPos.x+1, y=resultPos.y+2, z=resultPos.z})
doCreateItem(config.fire, 1, {x=resultPos.x+1, y=resultPos.y+3, z=resultPos.z})
doCreateItem(config.fire, 1, {x=resultPos.x+3, y=resultPos.y+2, z=resultPos.z})
doCreateItem(config.fire, 1, {x=resultPos.x+3, y=resultPos.y+3, z=resultPos.z})
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
return true
end
custom/training_tile_out.lua
Lua:
function onStepIn(cid, item, pos)
local playerpos = getCreaturePosition(cid)
for x = playerpos.x-2, playerpos.x+2 do
for y = playerpos.y-1, playerpos.y+3 do
for z = playerpos.z, playerpos.z do
local pos = {x=x, y=y, z=z, stackpos = 253}
local thing = getThingfromPos(pos)
if thing.itemid > 0 then
doRemoveCreature(thing.uid)
end
local pos = {x=x, y=y, z=z, stackpos = 1}
local thing = getThingfromPos(pos)
if thing.itemid > 0 then
doRemoveItem(thing.uid)
end
local pos = {x=x, y=y, z=z}
local thing = getThingfromPos(pos)
if thing.itemid > 0 then
doRemoveItem(thing.uid)
end
end
end
end
return true
end
Important to know: This script/code was not supposed to be for public, I don't care about tabbing or shortings it is supposed to be for my project but because lack of time I had to leave it. And I felt friendly ofcourse to release it =^_^=
However if something not working, let me know ofcourse I will fix it.
Last edited: