Ir para conteúdo

Posts Recomendados

como faz isso? Tô mexendo em sources fãs pouco tempo. Quando vou compilar eu aperto F9.

 

-- EDIT --

 

Arrumei o local,

cara funcionou vlw, agr vou por otclient.

mas ainda esta o limite quando uso o efeito 256 repetir o efeito numero 1. algo pra ajuda.

Verifique no player.h, provavelmente você esqueceu de editar lá. :p

Link para o comentário
Compartilhar em outros sites

Então gostei do tutorial e tudo mais, está de parabens, uma pergunta, sou meio burrinho, como posso dar continuidade aos effects depois de 0xff? qual sequencia devo usar >.<?

 

Bom, está no tutorial, haha

Pra isso, usem algum sitem de conversão de Decimal para Hexadecimal(Usei este).

Basta pegar o resultado, e adicionar 0x0 antes.

No caso, 256 é 0x100

Link para o comentário
Compartilhar em outros sites

Encontrei o console deu isso

 

Startup done :]
ERROR: audio buffer underrun
at:
[C++]: StreamSoundSource::update
ERROR: Unable to send extended opcode 1, extended opcodes are not enabled
Link para o comentário
Compartilhar em outros sites

 

Encontrei o console deu isso

 

Startup done :]
ERROR: audio buffer underrun
at:
[C++]: StreamSoundSource::update
ERROR: Unable to send extended opcode 1, extended opcodes are not enabled

 

Tem algo "exclusivo" na sua source? Se não, peço que me mande os arquivos protocolgame.cpp, protocolgame.h, player.h, game.cpp, game.h via inbox :p

(Com as edições já feitas)

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

Featzen, e o meu erro lá em cima ? você viu?

O erro do "recompilar tudo" não tem nada a ver com o aumento de limite.

 

Vá em cada arquivo editado(protocolgame.cpp, game.cpp e player.cpp) e use "compilar arquivo atual", depois, a opção "compilar", talvez seja o suficiente.

 

@Edit:

 

Reveja os passos do game.cpp e game.h

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

Game,cpp

 

 

////////////////////////////////////////////////////////////////////////
// OpenTibia - an opensource roleplaying game
////////////////////////////////////////////////////////////////////////
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
////////////////////////////////////////////////////////////////////////

#ifndef __PLAYER__
#define __PLAYER__

#include "otsystem.h"
#include "enums.h"

#include "creature.h"
#include "cylinder.h"

#include "container.h"
#include "depot.h"

#include "outfit.h"
#include "vocation.h"
#include "group.h"

#include "protocolgame.h"
#include "ioguild.h"
#include "party.h"
#include "npc.h"

class House;
class NetworkMessage;
class Weapon;
class ProtocolGame;
class Npc;
class Party;
class SchedulerTask;
class Quest;

enum skillsid_t
{
SKILL_LEVEL = 0,
SKILL_TRIES = 1,
SKILL_PERCENT = 2
};

enum playerinfo_t
{
PLAYERINFO_LEVEL,
PLAYERINFO_LEVELPERCENT,
PLAYERINFO_HEALTH,
PLAYERINFO_MAXHEALTH,
PLAYERINFO_MANA,
PLAYERINFO_MAXMANA,
PLAYERINFO_MAGICLEVEL,
PLAYERINFO_MAGICLEVELPERCENT,
PLAYERINFO_SOUL,
};

enum freeslot_t
{
SLOT_TYPE_NONE,
SLOT_TYPE_INVENTORY,
SLOT_TYPE_CONTAINER
};

enum chaseMode_t
{
CHASEMODE_STANDSTILL,
CHASEMODE_FOLLOW,
};

enum fightMode_t
{
FIGHTMODE_ATTACK,
FIGHTMODE_BALANCED,
FIGHTMODE_DEFENSE
};

enum secureMode_t
{
SECUREMODE_ON,
SECUREMODE_OFF
};

enum tradestate_t
{
TRADE_NONE,
TRADE_INITIATED,
TRADE_ACCEPT,
TRADE_ACKNOWLEDGE,
TRADE_TRANSFER
};

enum AccountManager_t
{
MANAGER_NONE,
MANAGER_NEW,
MANAGER_ACCOUNT,
MANAGER_NAMELOCK
};

enum GamemasterCondition_t
{
GAMEMASTER_INVISIBLE = 0,
GAMEMASTER_IGNORE = 1,
GAMEMASTER_TELEPORT = 2
};

enum Exhaust_t
{
EXHAUST_COMBAT = 1,
EXHAUST_HEALING = 2
};

typedef std::set VIPListSet;
typedef std::vector > ContainerVector;
typedef std::map > DepotMap;
typedef std::map MuteCountMap;
typedef std::list LearnedInstantSpellList;
typedef std::list InvitedToGuildsList;
typedef std::list PartyList;

#define SPEED_MAX 1500
#define SPEED_MIN 10
#define STAMINA_MAX (42 * 60 * 60 * 1000)
#define STAMINA_MULTIPLIER (60 * 1000)

class Player : public Creature, public Cylinder
{
public:
#ifdef __ENABLE_SERVER_DIAGNOSTIC__
static uint32_t playerCount;
#endif
Player(const std::string& name, ProtocolGame* p);
virtual ~Player();

virtual Player* getPlayer() {return this;}
virtual const Player* getPlayer() const {return this;}

static MuteCountMap muteCountMap;

virtual const std::string& getName() const {return name;}
virtual const std::string& getNameDescription() const {return nameDescription;}
virtual std::string getDescription(int32_t lookDistance) const;

const std::string& getSpecialDescription() const {return specialDescription;}
void setSpecialDescription(const std::string& desc) {specialDescription = desc;}

void manageAccount(const std::string& text);
bool isAccountManager() const {return (accountManager != MANAGER_NONE);}
void kickPlayer(bool displayEffect, bool forceLogout);

void setGUID(uint32_t _guid) {guid = _guid;}
uint32_t getGUID() const {return guid;}

static AutoList autoList;
virtual uint32_t rangeId() {return 0x10000000;}

void addList();
void removeList();

static uint64_t getExpForLevel(uint32_t lv)
{
lv--;
return ((50ULL * lv * lv * lv) - (150ULL * lv * lv) + (400ULL * lv)) / 3ULL;
}

uint32_t getPromotionLevel() const {return promotionLevel;}
void setPromotionLevel(uint32_t pLevel);

bool changeOutfit(Outfit_t outfit, bool checkList);
void hasRequestedOutfit(bool v) {requestedOutfit = v;}

Vocation* getVocation() const {return vocation;}
int32_t getPlayerInfo(playerinfo_t playerinfo) const;

void setParty(Party* _party) {party = _party;}
Party* getParty() const {return party;}
PartyShields_t getPartyShield(const Creature* creature) const;
bool isInviting(const Player* player) const;
bool isPartner(const Player* player) const;
void sendPlayerPartyIcons(Player* player);
bool addPartyInvitation(Party* party);
bool removePartyInvitation(Party* party);
void clearPartyInvitations();

uint32_t getGuildId() const {return guildId;}
void setGuildId(uint32_t newId) {guildId = newId;}
uint32_t getRankId() const {return rankId;}
void setRankId(uint32_t newId) {rankId = newId;}

GuildLevel_t getGuildLevel() const {return guildLevel;}
bool setGuildLevel(GuildLevel_t newLevel, uint32_t rank = 0);

const std::string& getGuildName() const {return guildName;}
void setGuildName(const std::string& newName) {guildName = newName;}
const std::string& getRankName() const {return rankName;}
void setRankName(const std::string& newName) {rankName = newName;}

const std::string& getGuildNick() const {return guildNick;}
void setGuildNick(const std::string& newNick) {guildNick = newNick;}

bool isGuildInvited(uint32_t guildId) const;
void leaveGuild();

void setFlags(uint64_t flags) {if(group) group->setFlags(flags);}
bool hasFlag(PlayerFlags value) const {return group != NULL && group->hasFlag(value);}
void setCustomFlags(uint64_t flags) {if(group) group->setCustomFlags(flags);}
bool hasCustomFlag(PlayerCustomFlags value) const {return group != NULL && group->hasCustomFlag(value);}

void addBlessing(int16_t blessing) {blessings += blessing;}
bool hasBlessing(int16_t value) const {return (blessings & ((int16_t)1 << value));}
uint16_t getBlessings() const;

OperatingSystem_t getOperatingSystem() const {return operatingSystem;}
void setOperatingSystem(OperatingSystem_t clientOs) {operatingSystem = clientOs;}
uint32_t getClientVersion() const {return clientVersion;}
void setClientVersion(uint32_t version) {clientVersion = version;}

bool hasClient() const {return client;}
bool isVirtual() const {return (getID() == 0);}
void disconnect() {if(client) client->disconnect();}
uint32_t getIP() const;
bool canOpenCorpse(uint32_t ownerId);

Container* getContainer(uint32_t cid);
int32_t getContainerID(const Container* container) const;

void addContainer(uint32_t cid, Container* container);
void closeContainer(uint32_t cid);

virtual bool setStorage(const uint32_t key, const std::string& value);
virtual void eraseStorage(const uint32_t key);

void generateReservedStorage();
bool transferMoneyTo(const std::string& name, uint64_t amount);
void increaseCombatValues(int32_t& min, int32_t& max, bool useCharges, bool countWeapon);

void setGroupId(int32_t newId);
int32_t getGroupId() const {return groupId;}
void setGroup(Group* newGroup);
Group* getGroup() const {return group;}

virtual bool isGhost() const {return hasCondition(CONDITION_GAMEMASTER, GAMEMASTER_INVISIBLE) || hasFlag(PlayerFlag_CannotBeSeen);}

void switchSaving() {saving = !saving;}
bool isSaving() const {return saving;}

uint32_t getIdleTime() const {return idleTime;}
void setIdleTime(uint32_t amount) {idleTime = amount;}

bool checkLoginDelay(uint32_t playerId) const;
bool isTrading() const {return tradePartner;}

uint32_t getAccount() const {return accountId;}
std::string getAccountName() const {return account;}
uint16_t getAccess() const {return group ? group->getAccess() : 0;}
uint16_t getGhostAccess() const {return group ? group->getGhostAccess() : 0;}

bool isPremium() const;
int32_t getPremiumDays() const {return premiumDays;}

uint32_t getLevel() const {return level;}
uint64_t getExperience() const {return experience;}
uint32_t getMagicLevel() const {return getPlayerInfo(PLAYERINFO_MAGICLEVEL);}
uint64_t getSpentMana() const {return manaSpent;}

uint32_t getVocationId() const {return vocation_id;}
void setVocation(uint32_t vocId);
uint16_t getSex(bool full) const {return full ? sex : sex % 2;}
void setSex(uint16_t);

uint64_t getStamina() const {return hasFlag(PlayerFlag_HasInfiniteStamina) ? STAMINA_MAX : stamina;}
void setStamina(uint64_t value) {stamina = std::min((uint64_t)STAMINA_MAX, (uint64_t)std::max((uint64_t)0, value));}
uint32_t getStaminaMinutes() const {return (uint32_t)(getStamina() / (uint64_t)STAMINA_MULTIPLIER);}
void setStaminaMinutes(uint32_t value) {setStamina((uint64_t)(value * STAMINA_MULTIPLIER));}
void useStamina(int64_t value) {stamina = std::min((int64_t)STAMINA_MAX, (int64_t)std::max((int64_t)0, ((int64_t)stamina + value)));}
uint64_t getSpentStamina() {return (uint64_t)STAMINA_MAX - stamina;}

int64_t getLastLoad() const {return lastLoad;}
time_t getLastLogin() const {return lastLogin;}
time_t getLastLogout() const {return lastLogout;}

Position getLoginPosition() const {return loginPosition;}

uint32_t getTown() const {return town;}
void setTown(uint32_t _town) {town = _town;}

virtual bool isPushable() const;
virtual int32_t getThrowRange() const {return 1;}

bool isMuted(uint16_t channelId, SpeakClasses type, uint32_t& time);
void addMessageBuffer();
void removeMessageBuffer();

double getCapacity() const {return capacity;}
void setCapacity(double newCapacity) {capacity = newCapacity;}

double getFreeCapacity() const
{
if(hasFlag(PlayerFlag_CannotPickupItem))
return 0.00;
else if(hasFlag(PlayerFlag_HasInfiniteCapacity))
return 10000.00;

return std::max(0.00, capacity - inventoryWeight);
}

virtual int32_t getSoul() const {return getPlayerInfo(PLAYERINFO_SOUL);}
virtual int32_t getMaxHealth() const {return getPlayerInfo(PLAYERINFO_MAXHEALTH);}
virtual int32_t getMaxMana() const {return getPlayerInfo(PLAYERINFO_MAXMANA);}
int32_t getSoulMax() const {return soulMax;}

Item* getInventoryItem(slots_t slot) const;
Item* getEquippedItem(slots_t slot) const;

bool isItemAbilityEnabled(slots_t slot) const {return inventoryAbilities[slot];}
void setItemAbility(slots_t slot, bool enabled) {inventoryAbilities[slot] = enabled;}

int32_t getVarSkill(skills_t skill) const {return varSkills[skill];}
void setVarSkill(skills_t skill, int32_t modifier) {varSkills[skill] += modifier;}

int32_t getVarStats(stats_t stat) const {return varStats[stat];}
void setVarStats(stats_t stat, int32_t modifier);
int32_t getDefaultStats(stats_t stat);

void setConditionSuppressions(uint32_t conditions, bool remove);

uint32_t getLossPercent(lossTypes_t lossType) const {return lossPercent[lossType];}
void setLossPercent(lossTypes_t lossType, uint32_t newPercent) {lossPercent[lossType] = newPercent;}

Depot* getDepot(uint32_t depotId, bool autoCreateDepot);
bool addDepot(Depot* depot, uint32_t depotId);
void useDepot(uint32_t depotId, bool value);

virtual bool canSee(const Position& pos) const;
virtual bool canSeeCreature(const Creature* creature) const;
virtual bool canWalkthrough(const Creature* creature) const;

virtual bool canSeeInvisibility() const {return hasFlag(PlayerFlag_CanSenseInvisibility);}

virtual RaceType_t getRace() const {return RACE_BLOOD;}

//safe-trade functions
void setTradeState(tradestate_t state) {tradeState = state;}
tradestate_t getTradeState() {return tradeState;}
Item* getTradeItem() {return tradeItem;}

//shop functions
void setShopOwner(Npc* owner, int32_t onBuy, int32_t onSell, ShopInfoList offer)
{
shopOwner = owner;
purchaseCallback = onBuy;
saleCallback = onSell;
shopOffer = offer;
}

Npc* getShopOwner(int32_t& onBuy, int32_t& onSell)
{
onBuy = purchaseCallback;
onSell = saleCallback;
return shopOwner;
}

const Npc* getShopOwner(int32_t& onBuy, int32_t& onSell) const
{
onBuy = purchaseCallback;
onSell = saleCallback;
return shopOwner;
}

//V.I.P. functions
void notifyLogIn(Player* loginPlayer);
void notifyLogOut(Player* logoutPlayer);
bool removeVIP(uint32_t guid);
bool addVIP(uint32_t guid, std::string& name, bool isOnline, bool internal = false);

//follow functions
virtual bool setFollowCreature(Creature* creature, bool fullPathSearch = false);

//follow events
virtual void onFollowCreature(const Creature* creature);

//walk events
virtual void onWalk(Direction& dir);
virtual void onWalkAborted();
virtual void onWalkComplete();

void stopWalk();
void openShopWindow();
void closeShopWindow(Npc* npc = NULL, int32_t onBuy = -1, int32_t onSell = -1);
bool canShopItem(uint16_t itemId, uint8_t subType, ShopEvent_t event);

void setChaseMode(chaseMode_t mode);
void setFightMode(fightMode_t mode) {fightMode = mode;}
void setSecureMode(secureMode_t mode) {secureMode = mode;}
secureMode_t getSecureMode() const {return secureMode;}

//combat functions
virtual bool setAttackedCreature(Creature* creature);
bool isImmune(CombatType_t type) const;
bool isImmune(ConditionType_t type) const;
bool hasShield() const;
virtual bool isAttackable() const;

virtual void changeHealth(int32_t healthChange);
virtual void changeMana(int32_t manaChange);
void changeSoul(int32_t soulChange);

bool isPzLocked() const {return pzLocked;}
void setPzLocked(bool v) {pzLocked = v;}
virtual BlockType_t blockHit(Creature* attacker, CombatType_t combatType, int32_t& damage,
bool checkDefense = false, bool checkArmor = false);
virtual void doAttacking(uint32_t interval);
virtual bool hasExtraSwing() {return lastAttack > 0 && ((OTSYS_TIME() - lastAttack) >= getAttackSpeed());}
int32_t getShootRange() const {return shootRange;}

int32_t getSkill(skills_t skilltype, skillsid_t skillinfo) const;
bool getAddAttackSkill() const {return addAttackSkillPoint;}
BlockType_t getLastAttackBlockType() const {return lastAttackBlockType;}

Item* getWeapon(bool ignoreAmmo = false);
virtual WeaponType_t getWeaponType();
int32_t getWeaponSkill(const Item* item) const;
void getShieldAndWeapon(const Item* &shield, const Item* &weapon) const;

virtual void drainHealth(Creature* attacker, CombatType_t combatType, int32_t damage);
virtual void drainMana(Creature* attacker, CombatType_t combatType, int32_t damage);

void addExperience(uint64_t exp);
void removeExperience(uint64_t exp, bool updateStats = true);
void addManaSpent(uint64_t amount, bool useMultiplier = true);
void addSkillAdvance(skills_t skill, uint32_t count, bool useMultiplier = true);
bool addUnjustifiedKill(const Player* attacked);

virtual int32_t getArmor() const;
virtual int32_t getDefense() const;
virtual float getAttackFactor() const;
virtual float getDefenseFactor() const;

void addExhaust(uint32_t ticks, Exhaust_t type);
void addInFightTicks(bool pzLock = false);
void addDefaultRegeneration(uint32_t addTicks);

virtual double getGainedExperience(Creature* attacker) const;

//combat event functions
virtual void onAddCondition(ConditionType_t type, bool hadCondition);
virtual void onAddCombatCondition(ConditionType_t type, bool hadCondition);
virtual void onEndCondition(ConditionType_t type);
virtual void onCombatRemoveCondition(const Creature* attacker, Condition* condition);
virtual void onTickCondition(ConditionType_t type, int32_t interval, bool& _remove);
virtual void onAttackedCreature(Creature* target);
virtual void onSummonAttackedCreature(Creature* summon, Creature* target);
virtual void onAttacked();
virtual void onAttackedCreatureDrain(Creature* target, int32_t points);
virtual void onSummonAttackedCreatureDrain(Creature* summon, Creature* target, int32_t points);
virtual void onTargetCreatureGainHealth(Creature* target, int32_t points);
virtual bool onKilledCreature(Creature* target, uint32_t& flags);
virtual void onGainExperience(double& gainExp, bool fromMonster, bool multiplied);
virtual void onGainSharedExperience(double& gainExp, bool fromMonster, bool multiplied);
virtual void onAttackedCreatureBlockHit(Creature* target, BlockType_t blockType);
virtual void onBlockHit(BlockType_t blockType);
virtual void onChangeZone(ZoneType_t zone);
virtual void onAttackedCreatureChangeZone(ZoneType_t zone);
virtual void onIdleStatus();
virtual void onPlacedCreature();

virtual void getCreatureLight(LightInfo& light) const;
Skulls_t getSkull() const;
Skulls_t getSkullClient(const Creature* creature) const;

bool hasAttacked(const Player* attacked) const;
void addAttacked(const Player* attacked);
void clearAttacked() {attackedSet.clear();}

time_t getSkullEnd() const {return skullEnd;}
void setSkullEnd(time_t _time, bool login, Skulls_t _skull);

bool addOutfit(uint32_t outfitId, uint32_t addons);
bool removeOutfit(uint32_t outfitId, uint32_t addons);

bool canWearOutfit(uint32_t outfitId, uint32_t addons);
bool canLogout(bool checkInfight);

//tile
//send methods
void sendAddTileItem(const Tile* tile, const Position& pos, const Item* item)
{if(client) client->sendAddTileItem(tile, pos, tile->getClientIndexOfThing(this, item), item);}
void sendUpdateTileItem(const Tile* tile, const Position& pos, const Item* oldItem, const Item* newItem)
{if(client) client->sendUpdateTileItem(tile, pos, tile->getClientIndexOfThing(this, oldItem), newItem);}
void sendRemoveTileItem(const Tile* tile, const Position& pos, uint32_t stackpos, const Item* item)
{if(client) client->sendRemoveTileItem(tile, pos, stackpos);}
void sendUpdateTile(const Tile* tile, const Position& pos)
{if(client) client->sendUpdateTile(tile, pos);}

void sendChannelMessage(std::string author, std::string text, SpeakClasses type, uint8_t channel)
{if(client) client->sendChannelMessage(author, text, type, channel);}
void sendCreatureAppear(const Creature* creature)
{if(client) client->sendAddCreature(creature, creature->getPosition(), creature->getTile()->getClientIndexOfThing(
this, creature));}
void sendCreatureDisappear(const Creature* creature, uint32_t stackpos)
{if(client) client->sendRemoveCreature(creature, creature->getPosition(), stackpos);}
void sendCreatureMove(const Creature* creature, const Tile* newTile, const Position& newPos,
const Tile* oldTile, const Position& oldPos, uint32_t oldStackpos, bool teleport)
{if(client) client->sendMoveCreature(creature, newTile, newPos, newTile->getClientIndexOfThing(
this, creature), oldTile, oldPos, oldStackpos, teleport);}

void sendCreatureTurn(const Creature* creature)
{if(client) client->sendCreatureTurn(creature, creature->getTile()->getClientIndexOfThing(this, creature));}
void sendCreatureSay(const Creature* creature, SpeakClasses type, const std::string& text, Position* pos = NULL)
{if(client) client->sendCreatureSay(creature, type, text, pos);}
void sendCreatureSquare(const Creature* creature, SquareColor_t color)
{if(client) client->sendCreatureSquare(creature, color);}
void sendCreatureChangeOutfit(const Creature* creature, const Outfit_t& outfit)
{if(client) client->sendCreatureOutfit(creature, outfit);}
void sendCreatureChangeVisible(const Creature* creature, Visible_t visible);
void sendCreatureLight(const Creature* creature)
{if(client) client->sendCreatureLight(creature);}
void sendCreatureShield(const Creature* creature)
{if(client) client->sendCreatureShield(creature);}

//container
void sendAddContainerItem(const Container* container, const Item* item);
void sendUpdateContainerItem(const Container* container, uint8_t slot, const Item* oldItem, const Item* newItem);
void sendRemoveContainerItem(const Container* container, uint8_t slot, const Item* item);
void sendContainer(uint32_t cid, const Container* container, bool hasParent)
{if(client) client->sendContainer(cid, container, hasParent);}

//inventory
void sendAddInventoryItem(slots_t slot, const Item* item)
{if(client) client->sendAddInventoryItem(slot, item);}
void sendUpdateInventoryItem(slots_t slot, const Item* oldItem, const Item* newItem)
{if(client) client->sendUpdateInventoryItem(slot, newItem);}
void sendRemoveInventoryItem(slots_t slot, const Item* item)
{if(client) client->sendRemoveInventoryItem(slot);}

//event methods
virtual void onUpdateTileItem(const Tile* tile, const Position& pos, const Item* oldItem,
const ItemType& oldType, const Item* newItem, const ItemType& newType);
virtual void onRemoveTileItem(const Tile* tile, const Position& pos,
const ItemType& iType, const Item* item);

virtual void onCreatureAppear(const Creature* creature);
virtual void onCreatureDisappear(const Creature* creature, bool isLogout);
virtual void onCreatureMove(const Creature* creature, const Tile* newTile, const Position& newPos,
const Tile* oldTile, const Position& oldPos, bool teleport);

virtual void onAttackedCreatureDisappear(bool isLogout);
virtual void onFollowCreatureDisappear(bool isLogout);

//cylinder implementations
virtual Cylinder* getParent() {return Creature::getParent();}
virtual const Cylinder* getParent() const {return Creature::getParent();}
virtual bool isRemoved() const {return Creature::isRemoved();}
virtual Position getPosition() const {return Creature::getPosition();}
virtual Tile* getTile() {return Creature::getTile();}
virtual const Tile* getTile() const {return Creature::getTile();}
virtual Item* getItem() {return NULL;}
virtual const Item* getItem() const {return NULL;}
virtual Creature* getCreature() {return this;}
virtual const Creature* getCreature() const {return this;}

//container
void onAddContainerItem(const Container* container, const Item* item);
void onUpdateContainerItem(const Container* container, uint8_t slot,
const Item* oldItem, const ItemType& oldType, const Item* newItem, const ItemType& newType);
void onRemoveContainerItem(const Container* container, uint8_t slot, const Item* item);

void onCloseContainer(const Container* container);
void onSendContainer(const Container* container);
void autoCloseContainers(const Container* container);

//inventory
void onAddInventoryItem(slots_t slot, Item* item) {}
void onUpdateInventoryItem(slots_t slot, Item* oldItem, const ItemType& oldType,
Item* newItem, const ItemType& newType);
void onRemoveInventoryItem(slots_t slot, Item* item);

void sendAnimatedText(const Position& pos, uint8_t color, std::string text) const
{if(client) client->sendAnimatedText(pos,color,text);}
void sendCancel(const std::string& msg) const
{if(client) client->sendCancel(msg);}
void sendCancelMessage(ReturnValue message) const;
void sendCancelTarget() const
{if(client) client->sendCancelTarget();}
void sendCancelWalk() const
{if(client) client->sendCancelWalk();}
void sendChangeSpeed(const Creature* creature, uint32_t newSpeed) const
{if(client) client->sendChangeSpeed(creature, newSpeed);}
void sendCreatureHealth(const Creature* creature) const
{if(client) client->sendCreatureHealth(creature);}
void sendDistanceShoot(const Position& from, const Position& to, uint8_t type) const
{if(client) client->sendDistanceShoot(from, to, type);}
void sendHouseWindow(House* house, uint32_t listId) const;
void sendOutfitWindow() const {if(client) client->sendOutfitWindow();}
void sendQuests() const {if(client) client->sendQuests();}
void sendQuestInfo(Quest* quest) const {if(client) client->sendQuestInfo(quest);}
void sendCreatureSkull(const Creature* creature) const
{if(client) client->sendCreatureSkull(creature);}
void sendFYIBox(std::string message)
{if(client) client->sendFYIBox(message);}
void sendCreatePrivateChannel(uint16_t channelId, const std::string& channelName)
{if(client) client->sendCreatePrivateChannel(channelId, channelName);}
void sendClosePrivate(uint16_t channelId) const
{if(client) client->sendClosePrivate(channelId);}
void sendIcons() const;
void sendMagicEffect(const Position& pos, uint16_t type) const
{if(client) client->sendMagicEffect(pos, type);}
void sendStats();
void sendSkills() const
{if(client) client->sendSkills();}
void sendTextMessage(MessageClasses type, const std::string& message) const
{if(client) client->sendTextMessage(type, message);}
void sendReLoginWindow() const
{if(client) client->sendReLoginWindow();}
void sendTextWindow(Item* item, uint16_t maxLen, bool canWrite) const
{if(client) client->sendTextWindow(windowTextId, item, maxLen, canWrite);}
void sendTextWindow(uint32_t itemId, const std::string& text) const
{if(client) client->sendTextWindow(windowTextId, itemId, text);}
void sendToChannel(Creature* creature, SpeakClasses type, const std::string& text, uint16_t channelId, uint32_t time = 0) const
{if(client) client->sendToChannel(creature, type, text, channelId, time);}
void sendShop() const
{if(client) client->sendShop(shopOffer);}
void sendGoods() const
{if(client) client->sendGoods(shopOffer);}
void sendCloseShop() const
{if(client) client->sendCloseShop();}
void sendTradeItemRequest(const Player* player, const Item* item, bool ack) const
{if(client) client->sendTradeItemRequest(player, item, ack);}
void sendTradeClose() const
{if(client) client->sendCloseTrade();}
void sendWorldLight(LightInfo& lightInfo)
{if(client) client->sendWorldLight(lightInfo);}
void sendChannelsDialog()
{if(client) client->sendChannelsDialog();}
void sendOpenPrivateChannel(const std::string& receiver)
{if(client) client->sendOpenPrivateChannel(receiver);}
void sendOutfitWindow()
{if(client) client->sendOutfitWindow();}
void sendCloseContainer(uint32_t cid)
{if(client) client->sendCloseContainer(cid);}
void sendChannel(uint16_t channelId, const std::string& channelName)
{if(client) client->sendChannel(channelId, channelName);}
void sendRuleViolationsChannel(uint16_t channelId)
{if(client) client->sendRuleViolationsChannel(channelId);}
void sendRemoveReport(const std::string& name)
{if(client) client->sendRemoveReport(name);}
void sendLockRuleViolation()
{if(client) client->sendLockRuleViolation();}
void sendRuleViolationCancel(const std::string& name)
{if(client) client->sendRuleViolationCancel(name);}
void sendTutorial(uint8_t tutorialId)
{if(client) client->sendTutorial(tutorialId);}
void sendAddMarker(const Position& pos, MapMarks_t markType, const std::string& desc)
{if (client) client->sendAddMarker(pos, markType, desc);}
void sendCritical() const;

void receivePing() {lastPong = OTSYS_TIME();}
virtual void onThink(uint32_t interval);
uint32_t getAttackSpeed();

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);

void setNextAction(int64_t time) {if(time > nextAction) {nextAction = time;}}
bool canDoAction() const {return nextAction <= OTSYS_TIME();}
uint32_t getNextActionTime() const;

Item* getWriteItem(uint32_t& _windowTextId, uint16_t& _maxWriteLen);
void setWriteItem(Item* item, uint16_t _maxWriteLen = 0);

House* getEditHouse(uint32_t& _windowTextId, uint32_t& _listId);
void setEditHouse(House* house, uint32_t listId = 0);

void learnInstantSpell(const std::string& name);
void unlearnInstantSpell(const std::string& name);
bool hasLearnedInstantSpell(const std::string& name) const;

VIPListSet VIPList;
ContainerVector containerVec;
InvitedToGuildsList invitedToGuildsList;
ConditionList storedConditionList;
DepotMap depots;

uint32_t marriage;
uint64_t balance;
double rates[sKILL__LAST + 1];
Container transferContainer;

protected:
void checkTradeState(const Item* item);

bool gainExperience(double& gainExp, bool fromMonster);
bool rateExperience(double& gainExp, bool fromMonster);
void updateBaseSpeed()
{
if(!hasFlag(PlayerFlag_SetMaxSpeed))
baseSpeed = vocation->getBaseSpeed() + (2 * (level - 1));
else
baseSpeed = SPEED_MAX;
}

void updateInventoryWeight();
void updateInventoryGoods(uint32_t itemId);
void updateItemsLight(bool internal = false);

void setNextWalkActionTask(SchedulerTask* task);
void setNextWalkTask(SchedulerTask* task);
void setNextActionTask(SchedulerTask* task);

virtual bool onDeath();
virtual Item* createCorpse(DeathList deathList);

virtual void dropCorpse(DeathList deathList);
virtual void dropLoot(Container* corpse);

//cylinder implementations
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);
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 Thing* __getThing(uint32_t index) const;
virtual int32_t __getIndexOfThing(const Thing* thing) const;
virtual int32_t __getFirstIndex() const;
virtual int32_t __getLastIndex() const;
virtual uint32_t __getItemTypeCount(uint16_t itemId, int32_t subType = -1,
bool itemCount = true) const;
virtual std::map& __getAllItemTypeCount(std::map uint32_t>& countMap, bool itemCount = true) const;

virtual void __internalAddThing(Thing* thing);
virtual void __internalAddThing(uint32_t index, Thing* thing);

uint32_t getVocAttackSpeed() const {return vocation->getAttackSpeed();}
virtual int32_t getStepSpeed() const
{
if(getSpeed() > SPEED_MAX)
return SPEED_MAX;

if(getSpeed() < SPEED_MIN)
return SPEED_MIN;

return getSpeed();
}

virtual uint32_t getDamageImmunities() const {return damageImmunities;}
virtual uint32_t getConditionImmunities() const {return conditionImmunities;}
virtual uint32_t getConditionSuppressions() const {return conditionSuppressions;}

virtual uint16_t getLookCorpse() const;
virtual uint64_t getLostExperience() const;

virtual void getPathSearchParams(const Creature* creature, FindPathParams& fpp) const;
static uint32_t getPercentLevel(uint64_t count, uint64_t nextLevelCount);

bool isPromoted(uint32_t pLevel = 1) const {return promotionLevel >= pLevel;}
bool hasCapacity(const Item* item, uint32_t count) const;

private:
bool talkState[13];
bool inventoryAbilities[11];
bool pzLocked;
bool saving;
bool isConnecting;
bool requestedOutfit;
bool outfitAttributes;
bool addAttackSkillPoint;

OperatingSystem_t operatingSystem;
AccountManager_t accountManager;
PlayerSex_t managerSex;
BlockType_t lastAttackBlockType;
chaseMode_t chaseMode;
fightMode_t fightMode;
secureMode_t secureMode;
tradestate_t tradeState;
GuildLevel_t guildLevel;

int16_t blessings;
uint16_t maxWriteLen;
uint16_t sex;

int32_t premiumDays;
int32_t soul;
int32_t soulMax;
int32_t vocation_id;
int32_t groupId;
int32_t managerNumber, managerNumber2;
int32_t purchaseCallback;
int32_t saleCallback;
int32_t varSkills[sKILL_LAST + 1];
int32_t varStats[sTAT_LAST + 1];
int32_t messageBuffer;
int32_t bloodHitCount;
int32_t shieldBlockCount;
int32_t shootRange;

uint32_t clientVersion;
uint32_t messageTicks;
uint32_t idleTime;
uint32_t accountId;
uint32_t lastIP;
uint32_t level;
uint32_t levelPercent;
uint32_t magLevel;
uint32_t magLevelPercent;
uint32_t damageImmunities;
uint32_t conditionImmunities;
uint32_t conditionSuppressions;
uint32_t condition; //?
uint32_t nextStepEvent;
uint32_t actionTaskEvent;
uint32_t walkTaskEvent;
uint32_t lossPercent[LOSS_LAST + 1];
uint32_t skills[sKILL_LAST + 1][3];
uint32_t guid;
uint32_t editListId;
uint32_t windowTextId;
uint32_t guildId;
uint32_t rankId;
uint32_t promotionLevel;
uint32_t town;

time_t skullEnd;
time_t lastLogin;
time_t lastLogout;
int64_t lastLoad;
int64_t lastPong;
int64_t lastPing;
int64_t nextAction;
uint64_t stamina;
uint64_t experience;
uint64_t manaSpent;
uint64_t lastAttack;

double inventoryWeight;
double capacity;
char managerChar[100];

std::string managerString, managerString2;
std::string account, password;
std::string name, nameDescription, specialDescription;
std::string guildName, rankName, guildNick;

Position loginPosition;
LightInfo itemsLight;

Vocation* vocation;
ProtocolGame* client;
SchedulerTask* walkTask;
Party* party;
Group* group;
Item* inventory[11];
Player* tradePartner;
Item* tradeItem;
Item* writeItem;
House* editHouse;
Npc* shopOwner;

typedef std::set AttackedSet;
AttackedSet attackedSet;
ShopInfoList shopOffer;
PartyList invitePartyList;
OutfitMap outfits;
LearnedInstantSpellList learnedInstantSpellList;

friend class Game;
friend class LuaScriptInterface;
friend class Npc;
friend class Map;
friend class Actions;
friend class IOLoginData;
friend class ProtocolGame;
};
#endif

,
,>*>,>,>

 

protocolgame.cpp

 

 

////////////////////////////////////////////////////////////////////////
// OpenTibia - an opensource roleplaying game
////////////////////////////////////////////////////////////////////////
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
////////////////////////////////////////////////////////////////////////
#include "otpch.h"
#include "resources.h"

#include
#include

#include "protocolgame.h"
#include "textlogger.h"

#include "waitlist.h"
#include "player.h"

#include "connection.h"
#include "networkmessage.h"
#include "outputmessage.h"

#include "iologindata.h"
#include "ioban.h"

#include "items.h"
#include "tile.h"
#include "house.h"

#include "actions.h"
#include "creatureevent.h"
#include "quests.h"

#include "chat.h"
#include "configmanager.h"
#include "game.h"

#if defined(WINDOWS) && !defined(__CONSOLE__)
#include "gui.h"
#endif

extern Game g_game;
extern ConfigManager g_config;
extern Actions actions;
extern CreatureEvents* g_creatureEvents;
extern Chat g_chat;

template
void ProtocolGame::addGameTaskInternal(uint32_t delay, const FunctionType& func)
{
if(delay > 0)
Dispatcher::getInstance().addTask(createTask(delay, func));
else
Dispatcher::getInstance().addTask(createTask(func));
}

#ifdef __ENABLE_SERVER_DIAGNOSTIC__
uint32_t ProtocolGame::protocolGameCount = 0;
#endif

void ProtocolGame::setPlayer(Player* p)
{
player = p;
}

void ProtocolGame::releaseProtocol()
{
if(player && player->client == this)
player->client = NULL;

Protocol::releaseProtocol();
}

void ProtocolGame::deleteProtocolTask()
{
if(player)
{
g_game.freeThing(player);
player = NULL;
}

Protocol::deleteProtocolTask();
}

bool ProtocolGame::login(const std::string& name, uint32_t id, const std::string& password,
OperatingSystem_t operatingSystem, uint16_t version, bool gamemaster)
{
//dispatcher thread
PlayerVector players = g_game.getPlayersByName(name);
Player* _player = NULL;
if(!players.empty())
_player = players[random_range(0, (players.size() - 1))];

if(!_player || name == "Account Manager" || g_config.getNumber(ConfigManager::ALLOW_CLONES) > (int32_t)players.size())
{
player = new Player(name, this);
player->addRef();

player->setID();
if(!IOLoginData::getInstance()->loadPlayer(player, name, true))
{
disconnectClient(0x14, "Your character could not be loaded.");
return false;
}

Ban ban;
ban.value = player->getID();
ban.param = PLAYERBAN_BANISHMENT;

ban.type = BAN_PLAYER;
if(IOBan::getInstance()->getData(ban) && !player->hasFlag(PlayerFlag_CannotBeBanned))
{
bool deletion = ban.expires < 0;
std::string name_ = "Automatic ";
if(!ban.adminId)
name_ += (deletion ? "deletion" : "banishment");
else
IOLoginData::getInstance()->getNameByGuid(ban.adminId, name_, true);

char buffer[500 + ban.comment.length()];
sprintf(buffer, "Your character has been %s at:\n%s by: %s,\nfor the following reason:\n%s.\nThe action taken was:\n%s.\nThe comment given was:\n%s.\nYour %s%s.",
(deletion ? "deleted" : "banished"), formatDateShort(ban.added).c_str(), name_.c_str(),
getReason(ban.reason).c_str(), getAction(ban.action, false).c_str(), ban.comment.c_str(),
(deletion ? "character won't be undeleted" : "banishment will be lifted at:\n"),
(deletion ? "." : formatDateShort(ban.expires, true).c_str()));

disconnectClient(0x14, buffer);
return false;
}

if(IOBan::getInstance()->isPlayerBanished(player->getGUID(), PLAYERBAN_LOCK) && id != 1)
{
if(g_config.getBool(ConfigManager::NAMELOCK_MANAGER))
{
player->name = "Account Manager";
player->accountManager = MANAGER_NAMELOCK;

player->managerNumber = id;
player->managerString2 = name;
}
else
{
disconnectClient(0x14, "Your character has been namelocked.");
return false;
}
}
else if(player->getName() == "Account Manager" && g_config.getBool(ConfigManager::ACCOUNT_MANAGER))
{
if(id != 1)
{
player->accountManager = MANAGER_ACCOUNT;
player->managerNumber = id;
}
else
player->accountManager = MANAGER_NEW;
}

if(gamemaster && !player->hasCustomFlag(PlayerCustomFlag_GamemasterPrivileges))
{
disconnectClient(0x14, "You are not a gamemaster! Turn off the gamemaster mode in your IP changer.");
return false;
}

if(!player->hasFlag(PlayerFlag_CanAlwaysLogin))
{
if(g_game.getGameState() == GAME_STATE_CLOSING)
{
disconnectClient(0x14, "Gameworld is just going down, please come back later.");
return false;
}

if(g_game.getGameState() == GAME_STATE_CLOSED)
{
disconnectClient(0x14, "Gameworld is currently closed, please come back later.");
return false;
}
}

if(g_config.getBool(ConfigManager::ONE_PLAYER_ON_ACCOUNT) && !player->isAccountManager() &&
!IOLoginData::getInstance()->hasCustomFlag(id, PlayerCustomFlag_CanLoginMultipleCharacters))
{
bool found = false;
PlayerVector tmp = g_game.getPlayersByAccount(id);
for(PlayerVector::iterator it = tmp.begin(); it != tmp.end(); ++it)
{
if((*it)->getName() != name)
continue;

found = true;
break;
}

if(tmp.size() > 0 && !found)
{
disconnectClient(0x14, "You may only login with one character\nof your account at the same time.");
return false;
}
}

if(!WaitingList::getInstance()->login(player))
{
if(OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false))
{
TRACK_MESSAGE(output);
std::stringstream ss;
ss << "Too many players online.\n" << "You are ";

int32_t slot = WaitingList::getInstance()->getSlot(player);
if(slot)
{
ss << "at ";
if(slot > 0)
ss << slot;
else
ss << "unknown";

ss << " place on the waiting list.";
}
else
ss << "awaiting connection...";

output->AddByte(0x16);
output->AddString(ss.str());
output->AddByte(WaitingList::getTime(slot));
OutputMessagePool::getInstance()->send(output);
}

getConnection()->close();
return false;
}

if(!IOLoginData::getInstance()->loadPlayer(player, name))
{
disconnectClient(0x14, "Your character could not be loaded.");
return false;
}

player->setOperatingSystem(operatingSystem);
player->setClientVersion(version);
if(!g_game.placeCreature(player, player->getLoginPosition()) && !g_game.placeCreature(player, player->getMasterPosition(), false, true))
{
disconnectClient(0x14, "Temple position is wrong. Contact with the administration.");
return false;

}

player->lastIP = player->getIP();
player->lastLoad = OTSYS_TIME();
player->lastLogin = std::max(time(NULL), player->lastLogin + 1);

m_acceptPackets = true;
return true;
}
else if(_player->client)
{
if(m_eventConnect || !g_config.getBool(ConfigManager::REPLACE_KICK_ON_LOGIN))
{
//A task has already been scheduled just bail out (should not be overriden)
disconnectClient(0x14, "You are already logged in.");
return false;
}

g_chat.removeUserFromAllChannels(_player);
_player->disconnect();
_player->isConnecting = true;

addRef();
m_eventConnect = Scheduler::getInstance().addEvent(createSchedulerTask(
1000, boost::bind(&ProtocolGame::connect, this, _player->getID(), operatingSystem, version)));
return true;
}

addRef();
return connect(_player->getID(), operatingSystem, version);
}

bool ProtocolGame::logout(bool displayEffect, bool forceLogout)
{
//dispatcher thread
if(!player)
return false;

if(!player->isRemoved())
{
if(!forceLogout)
{
if(!IOLoginData::getInstance()->hasCustomFlag(player->getAccount(), PlayerCustomFlag_CanLogoutAnytime))
{
if(player->getTile()->hasFlag(TILESTATE_NOLOGOUT))
{
player->sendCancelMessage(RET_YOUCANNOTLOGOUTHERE);
return false;
}

if(player->hasCondition(CONDITION_INFIGHT))
{
player->sendCancelMessage(RET_YOUMAYNOTLOGOUTDURINGAFIGHT);
return false;
}

if(!g_creatureEvents->playerLogout(player, false)) //let the script handle the error message
return false;
}
else
g_creatureEvents->playerLogout(player, false);
}
else if(!g_creatureEvents->playerLogout(player, true))
return false;
}
else
displayEffect = false;

if(displayEffect && !player->isGhost())
g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);

if(Connection_ptr connection = getConnection())
connection->close();

return g_game.removeCreature(player);
}

bool ProtocolGame::connect(uint32_t playerId, OperatingSystem_t operatingSystem, uint16_t version)
{
unRef();
m_eventConnect = 0;

Player* _player = g_game.getPlayerByID(playerId);
if(!_player || _player->isRemoved() || _player->client)
{
disconnectClient(0x14, "You are already logged in.");
return false;
}

player = _player;
player->addRef();
player->isConnecting = false;

player->client = this;
player->sendCreatureAppear(player);

player->setOperatingSystem(operatingSystem);
player->setClientVersion(version);

player->lastIP = player->getIP();
player->lastLoad = OTSYS_TIME();
player->lastLogin = std::max(time(NULL), player->lastLogin + 1);

m_acceptPackets = true;
return true;
}

void ProtocolGame::disconnect()
{
if(getConnection())
getConnection()->close();
}

void ProtocolGame::disconnectClient(uint8_t error, const char* message)
{
if(OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false))
{
TRACK_MESSAGE(output);
output->AddByte(error);
output->AddString(message);
OutputMessagePool::getInstance()->send(output);
}

disconnect();
}

void ProtocolGame::onConnect()
{
if(OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false))
{
TRACK_MESSAGE(output);
enableChecksum();

output->AddByte(0x1F);
output->AddU16(random_range(0, 0xFFFF));
output->AddU16(0x00);
output->AddByte(random_range(0, 0xFF));

OutputMessagePool::getInstance()->send(output);
}
}

void ProtocolGame::onRecvFirstMessage(NetworkMessage& msg)
{
parseFirstPacket(msg);
}

bool ProtocolGame::parseFirstPacket(NetworkMessage& msg)
{
if(
#if defined(WINDOWS) && !defined(__CONSOLE__)
!GUI::getInstance()->m_connections ||
#endif
g_game.getGameState() == GAME_STATE_SHUTDOWN)
{
getConnection()->close();
return false;
}

OperatingSystem_t operatingSystem = (OperatingSystem_t)msg.GetU16();
uint16_t version = msg.GetU16();
if(!RSA_decrypt(msg))
{
getConnection()->close();
return false;
}

uint32_t key[4] = {msg.GetU32(), msg.GetU32(), msg.GetU32(), msg.GetU32()};
enableXTEAEncryption();
setXTEAKey(key);

bool gamemaster = msg.GetByte();
std::string name = msg.GetString(), character = msg.GetString(), password = msg.GetString();

msg.SkipBytes(6); //841- wtf?
if(version < CLIENT_VERSION_MIN || version > CLIENT_VERSION_MAX)
{
disconnectClient(0x14, CLIENT_VERSION_STRING);
return false;
}

if(name.empty())
{
if(!g_config.getBool(ConfigManager::ACCOUNT_MANAGER))
{
disconnectClient(0x14, "Invalid account name.");
return false;
}

name = "1";
password = "1";
}

if(g_game.getGameState() < GAME_STATE_NORMAL)
{
disconnectClient(0x14, "Gameworld is just starting up, please wait.");
return false;
}

if(g_game.getGameState() == GAME_STATE_MAINTAIN)
{
disconnectClient(0x14, "Gameworld is under maintenance, please re-connect in a while.");
return false;
}

if(ConnectionManager::getInstance()->isDisabled(getIP(), protocolId))
{
disconnectClient(0x14, "Too many connections attempts from your IP address, please try again later.");
return false;
}

if(IOBan::getInstance()->isIpBanished(getIP()))
{
disconnectClient(0x14, "Your IP is banished!");
return false;
}

uint32_t id = 1;
if(!IOLoginData::getInstance()->getAccountId(name, id))
{
ConnectionManager::getInstance()->addAttempt(getIP(), protocolId, false);
disconnectClient(0x14, "Invalid account name.");
return false;
}

std::string hash;
if(!IOLoginData::getInstance()->getPassword(id, hash, character) || !encryptTest(password, hash))
{
ConnectionManager::getInstance()->addAttempt(getIP(), protocolId, false);
disconnectClient(0x14, "Invalid password.");
return false;
}

Ban ban;
ban.value = id;

ban.type = BAN_ACCOUNT;
if(IOBan::getInstance()->getData(ban) && !IOLoginData::getInstance()->hasFlag(id, PlayerFlag_CannotBeBanned))
{
bool deletion = ban.expires < 0;
std::string name_ = "Automatic ";
if(!ban.adminId)
name_ += (deletion ? "deletion" : "banishment");
else
IOLoginData::getInstance()->getNameByGuid(ban.adminId, name_, true);

char buffer[500 + ban.comment.length()];
sprintf(buffer, "Your account has been %s at:\n%s by: %s,\nfor the following reason:\n%s.\nThe action taken was:\n%s.\nThe comment given was:\n%s.\nYour %s%s.",
(deletion ? "deleted" : "banished"), formatDateShort(ban.added).c_str(), name_.c_str(),
getReason(ban.reason).c_str(), getAction(ban.action, false).c_str(), ban.comment.c_str(),
(deletion ? "account won't be undeleted" : "banishment will be lifted at:\n"),
(deletion ? "." : formatDateShort(ban.expires, true).c_str()));

disconnectClient(0x14, buffer);
return false;
}

ConnectionManager::getInstance()->addAttempt(getIP(), protocolId, true);
Dispatcher::getInstance().addTask(createTask(boost::bind(
&ProtocolGame::login, this, character, id, password, operatingSystem, version, gamemaster)));
return true;
}

void ProtocolGame::parsePacket(NetworkMessage &msg)
{
if(!player || !m_acceptPackets || g_game.getGameState() == GAME_STATE_SHUTDOWN
|| msg.getMessageLength() <= 0)
return;

uint8_t recvbyte = msg.GetByte();
//a dead player cannot performs actions
if(player->isRemoved() && recvbyte != 0x14)
return;

if(player->isAccountManager())
{
switch(recvbyte)
{
case 0x14:
parseLogout(msg);
break;

case 0x96:
parseSay(msg);
break;

default:
sendCancelWalk();
break;
}
}
else
{
switch(recvbyte)
{
case 0x14: // logout
parseLogout(msg);
break;

case 0x1E: // keep alive / ping response
parseReceivePing(msg);
break;

case 0x64: // move with steps
parseAutoWalk(msg);
break;

case 0x65: // move north
case 0x66: // move east
case 0x67: // move south
case 0x68: // move west
parseMove(msg, (Direction)(recvbyte - 0x65));
break;

case 0x69: // stop-autowalk
addGameTask(&Game::playerStopAutoWalk, player->getID());
break;

case 0x6A:
parseMove(msg, NORTHEAST);
break;

case 0x6B:
parseMove(msg, SOUTHEAST);
break;

case 0x6C:
parseMove(msg, SOUTHWEST);
break;

case 0x6D:
parseMove(msg, NORTHWEST);
break;

case 0x6F: // turn north
case 0x70: // turn east
case 0x71: // turn south
case 0x72: // turn west
parseTurn(msg, (Direction)(recvbyte - 0x6F));
break;

case 0x78: // throw item
parseThrow(msg);
break;

case 0x79: // description in shop window
parseLookInShop(msg);
break;

case 0x7A: // player bought from shop
parsePlayerPurchase(msg);
break;

case 0x7B: // player sold to shop
parsePlayerSale(msg);
break;

case 0x7C: // player closed shop window
parseCloseShop(msg);
break;

case 0x7D: // Request trade
parseRequestTrade(msg);
break;

case 0x7E: // Look at an item in trade
parseLookInTrade(msg);
break;

case 0x7F: // Accept trade
parseAcceptTrade(msg);
break;

case 0x80: // close/cancel trade
parseCloseTrade();
break;

case 0x82: // use item
parseUseItem(msg);
break;

case 0x83: // use item
parseUseItemEx(msg);
break;

case 0x84: // battle window
parseBattleWindow(msg);
break;

case 0x85: //rotate item
parseRotateItem(msg);
break;

case 0x87: // close container
parseCloseContainer(msg);
break;

case 0x88: //"up-arrow" - container
parseUpArrowContainer(msg);
break;

case 0x89:
parseTextWindow(msg);
break;

case 0x8A:
parseHouseWindow(msg);
break;

case 0x8C: // throw item
parseLookAt(msg);
break;

case 0x96: // say something
parseSay(msg);
break;

case 0x97: // request channels
parseGetChannels(msg);
break;

case 0x98: // open channel
parseOpenChannel(msg);
break;

case 0x99: // close channel
parseCloseChannel(msg);
break;

case 0x9A: // open priv
parseOpenPriv(msg);
break;

case 0x9B: //process report
parseProcessRuleViolation(msg);
break;

case 0x9C: //gm closes report
parseCloseRuleViolation(msg);
break;

case 0x9D: //player cancels report
parseCancelRuleViolation(msg);
break;

case 0x9E: // close NPC
parseCloseNpc(msg);
break;

case 0xA0: // set attack and follow mode
parseFightModes(msg);
break;

case 0xA1: // attack
parseAttack(msg);
break;

case 0xA2: //follow
parseFollow(msg);
break;

case 0xA3: // invite party
parseInviteToParty(msg);
break;

case 0xA4: // join party
parseJoinParty(msg);
break;

case 0xA5: // revoke party
parseRevokePartyInvite(msg);
break;

case 0xA6: // pass leadership
parsePassPartyLeadership(msg);
break;

case 0xA7: // leave party
parseLeaveParty(msg);
break;

case 0xA8: // share exp
parseSharePartyExperience(msg);
break;

case 0xAA:
parseCreatePrivateChannel(msg);
break;

case 0xAB:
parseChannelInvite(msg);
break;

case 0xAC:
parseChannelExclude(msg);
break;

case 0xBE: // cancel move
parseCancelMove(msg);
break;

case 0xC9: //client request to resend the tile
parseUpdateTile(msg);
break;

case 0xCA: //client request to resend the container (happens when you store more than container maxsize)
parseUpdateContainer(msg);
break;

case 0xD2: // request outfit
if((!player->hasCustomFlag(PlayerCustomFlag_GamemasterPrivileges) || !g_config.getBool(
ConfigManager::DISABLE_OUTFITS_PRIVILEGED)) && (g_config.getBool(ConfigManager::ALLOW_CHANGEOUTFIT)
|| g_config.getBool(ConfigManager::ALLOW_CHANGECOLORS) || g_config.getBool(ConfigManager::ALLOW_CHANGEADDONS)))
parseRequestOutfit(msg);
break;

case 0xD3: // set outfit
if((!player->hasCustomFlag(PlayerCustomFlag_GamemasterPrivileges) || !g_config.getBool(ConfigManager::DISABLE_OUTFITS_PRIVILEGED))
&& (g_config.getBool(ConfigManager::ALLOW_CHANGECOLORS) || g_config.getBool(ConfigManager::ALLOW_CHANGEOUTFIT)))
parseSetOutfit(msg);
break;

case 0xDC:
parseAddVip(msg);
break;

case 0xDD:
parseRemoveVip(msg);
break;

case 0xE6:
parseBugReport(msg);
break;

case 0xE7:
parseViolationWindow(msg);
break;

case 0xE8:
parseDebugAssert(msg);
break;

case 0xF0:
parseQuests(msg);
break;

case 0xF1:
parseQuestInfo(msg);
break;

default:
{
if(g_config.getBool(ConfigManager::BAN_UNKNOWN_BYTES))
{
int64_t banTime = -1;
ViolationAction_t action = ACTION_BANISHMENT;
Account tmp = IOLoginData::getInstance()->loadAccount(player->getAccount(), true);

tmp.warnings++;
if(tmp.warnings >= g_config.getNumber(ConfigManager::WARNINGS_TO_DELETION))
action = ACTION_DELETION;
else if(tmp.warnings >= g_config.getNumber(ConfigManager::WARNINGS_TO_FINALBAN))
{
banTime = time(NULL) + g_config.getNumber(ConfigManager::FINALBAN_LENGTH);
action = ACTION_BANFINAL;
}
else
banTime = time(NULL) + g_config.getNumber(ConfigManager::BAN_LENGTH);

if(IOBan::getInstance()->addAccountBanishment(tmp.number, banTime, 13, action,
"Sending unknown packets to the server.", 0, player->getGUID()))
{
IOLoginData::getInstance()->saveAccount(tmp);
player->sendTextMessage(MSG_INFO_DESCR, "You have been banished.");

g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_WRAPS_GREEN);
Scheduler::getInstance().addEvent(createSchedulerTask(1000, boost::bind(
&Game::kickPlayer, &g_game, player->getID(), false)));
}
}

std::stringstream hex, s;
hex << "0x" << std::hex << (int16_t)recvbyte << std::dec;
s << player->getName() << " sent unknown byte: " << hex << std::endl;

LOG_MESSAGE(LOGTYPE_NOTICE, s.str(), "PLAYER")
Logger::getInstance()->eFile(getFilePath(FILE_TYPE_LOG, "bots/" + player->getName() + ".log").c_str(),
"[" + formatDate() + "] Received byte " + hex.str(), false);
break;
}
}
}
}

void ProtocolGame::GetTileDescription(const Tile* tile, NetworkMessage_ptr msg)
{
if(!tile)
return;

int32_t count = 0;
if(tile->ground)
{
msg->AddItem(tile->ground);
count++;
}

const TileItemVector* items = tile->getItemList();
const CreatureVector* creatures = tile->getCreatures();

ItemVector::const_iterator it;
if(items)
{
for(it = items->getBeginTopItem(); (it != items->getEndTopItem() && count < 10); ++it, ++count)
msg->AddItem(*it);
}

if(creatures)
{
for(CreatureVector::const_reverse_iterator cit = creatures->rbegin(); (cit != creatures->rend() && count < 10); ++cit)
{
if(!player->canSeeCreature(*cit))
continue;

bool known;
uint32_t removedKnown;
checkCreatureAsKnown((*cit)->getID(), known, removedKnown);

AddCreature(msg, (*cit), known, removedKnown);
count++;
}
}

if(items)
{
for(it = items->getBeginDownItem(); (it != items->getEndDownItem() && count < 10); ++it, ++count)
msg->AddItem(*it);
}
}

void ProtocolGame::GetMapDescription(int32_t x, int32_t y, int32_t z,
int32_t width, int32_t height, NetworkMessage_ptr msg)
{
int32_t skip = -1, startz, endz, zstep = 0;
if(z > 7)
{
startz = z - 2;
endz = std::min((int32_t)MAP_MAX_LAYERS - 1, z + 2);
zstep = 1;
}
else
{
startz = 7;
endz = 0;
zstep = -1;
}

for(int32_t nz = startz; nz != endz + zstep; nz += zstep)
GetFloorDescription(msg, x, y, nz, width, height, z - nz, skip);

if(skip >= 0)
{
msg->AddByte(skip);
msg->AddByte(0xFF);
//cc += skip;
}
}

void ProtocolGame::GetFloorDescription(NetworkMessage_ptr msg, int32_t x, int32_t y, int32_t z,
int32_t width, int32_t height, int32_t offset, int32_t& skip)
{
Tile* tile = NULL;
for(int32_t nx = 0; nx < width; nx++)
{
for(int32_t ny = 0; ny < height; ny++)
{
if((tile = g_game.getTile(Position(x + nx + offset, y + ny + offset, z))))
{
if(skip >= 0)
{
msg->AddByte(skip);
msg->AddByte(0xFF);
}

skip = 0;
GetTileDescription(tile, msg);
}
else
{
++skip;
if(skip == 0xFF)
{
msg->AddByte(0xFF);
msg->AddByte(0xFF);
skip = -1;
}
}
}
}
}

void ProtocolGame::checkCreatureAsKnown(uint32_t id, bool& known, uint32_t& removedKnown)
{
// loop through the known creature list and check if the given creature is in
for(std::list::iterator it = knownCreatureList.begin(); it != knownCreatureList.end(); ++it)
{
if((*it) != id)
continue;

// know... make the creature even more known...
knownCreatureList.erase(it);
knownCreatureList.push_back(id);

known = true;
return;
}

// ok, he is unknown...
known = false;
// ... but not in future
knownCreatureList.push_back(id);
// too many known creatures?
if(knownCreatureList.size() > 250)
{
// lets try to remove one from the end of the list
Creature* c = NULL;
for(int32_t n = 0; n < 250; n++)
{
removedKnown = knownCreatureList.front();
if(!(c = g_game.getCreatureByID(removedKnown)) || !canSee©)
break;

// this creature we can't remove, still in sight, so back to the end
knownCreatureList.pop_front();
knownCreatureList.push_back(removedKnown);
}

// hopefully we found someone to remove :S, we got only 250 tries
// if not... lets kick some players with debug errors :)
knownCreatureList.pop_front();
}
else // we can cache without problems :)
removedKnown = 0;
}

bool ProtocolGame::canSee(const Creature* c) const
{
return !c->isRemoved() && player->canSeeCreature© && canSee(c->getPosition());
}

bool ProtocolGame::canSee(const Position& pos) const
{
return canSee(pos.x, pos.y, pos.z);
}

bool ProtocolGame::canSee(uint16_t x, uint16_t y, uint16_t z) const
{
#ifdef __DEBUG__
if(z < 0 || z >= MAP_MAX_LAYERS)
std::cout << "[Warning - ProtocolGame::canSee] Z-value is out of range!" << std::endl;
#endif

const Position& myPos = player->getPosition();
if(myPos.z <= 7)
{
//we are on ground level or above (7 -> 0), view is from 7 -> 0
if(z > 7)
return false;
}
else if(myPos.z >= 8 && std::abs(myPos.z - z) > 2) //we are underground (8 -> 15), view is +/- 2 from the floor we stand on
return false;

//negative offset means that the action taken place is on a lower floor than ourself
int32_t offsetz = myPos.z - z;
return ((x >= myPos.x - 8 + offsetz) && (x <= myPos.x + 9 + offsetz) &&
(y >= myPos.y - 6 + offsetz) && (y <= myPos.y + 7 + offsetz));
}

//********************** Parse methods *******************************//
void ProtocolGame::parseLogout(NetworkMessage& msg)
{
Dispatcher::getInstance().addTask(createTask(boost::bind(&ProtocolGame::logout, this, true, false)));
}

void ProtocolGame::parseCreatePrivateChannel(NetworkMessage& msg)
{
addGameTask(&Game::playerCreatePrivateChannel, player->getID());
}

void ProtocolGame::parseChannelInvite(NetworkMessage& msg)
{
const std::string name = msg.GetString();
addGameTask(&Game::playerChannelInvite, player->getID(), name);
}

void ProtocolGame::parseChannelExclude(NetworkMessage& msg)
{
const std::string name = msg.GetString();
addGameTask(&Game::playerChannelExclude, player->getID(), name);
}

void ProtocolGame::parseGetChannels(NetworkMessage& msg)
{
addGameTask(&Game::playerRequestChannels, player->getID());
}

void ProtocolGame::parseOpenChannel(NetworkMessage& msg)
{
uint16_t channelId = msg.GetU16();
addGameTask(&Game::playerOpenChannel, player->getID(), channelId);
}

void ProtocolGame::parseCloseChannel(NetworkMessage& msg)
{
uint16_t channelId = msg.GetU16();
addGameTask(&Game::playerCloseChannel, player->getID(), channelId);
}

void ProtocolGame::parseOpenPriv(NetworkMessage& msg)
{
const std::string receiver = msg.GetString();
addGameTask(&Game::playerOpenPrivateChannel, player->getID(), receiver);
}

void ProtocolGame::parseProcessRuleViolation(NetworkMessage& msg)
{
const std::string reporter = msg.GetString();
addGameTask(&Game::playerProcessRuleViolation, player->getID(), reporter);
}

void ProtocolGame::parseCloseRuleViolation(NetworkMessage& msg)
{
const std::string reporter = msg.GetString();
addGameTask(&Game::playerCloseRuleViolation, player->getID(), reporter);
}

void ProtocolGame::parseCancelRuleViolation(NetworkMessage& msg)
{
addGameTask(&Game::playerCancelRuleViolation, player->getID());
}

void ProtocolGame::parseCloseNpc(NetworkMessage& msg)
{
addGameTask(&Game::playerCloseNpcChannel, player->getID());
}

void ProtocolGame::parseCancelMove(NetworkMessage& msg)
{
addGameTask(&Game::playerCancelAttackAndFollow, player->getID());
}

void ProtocolGame::parseReceivePing(NetworkMessage& msg)
{
addGameTask(&Game::playerReceivePing, player->getID());
}

void ProtocolGame::parseAutoWalk(NetworkMessage& msg)
{
// first we get all directions...
std::list path;
size_t dirCount = msg.GetByte();
for(size_t i = 0; i < dirCount; ++i)
{
uint8_t rawDir = msg.GetByte();
Direction dir = SOUTH;
switch(rawDir)
{
case 1:
dir = EAST;
break;
case 2:
dir = NORTHEAST;
break;
case 3:
dir = NORTH;
break;
case 4:
dir = NORTHWEST;
break;
case 5:
dir = WEST;
break;
case 6:
dir = SOUTHWEST;
break;
case 7:
dir = SOUTH;
break;
case 8:
dir = SOUTHEAST;
break;
default:
continue;
}

path.push_back(dir);
}

addGameTask(&Game::playerAutoWalk, player->getID(), path);
}

void ProtocolGame::parseMove(NetworkMessage& msg, Direction dir)
{
addGameTask(&Game::playerMove, player->getID(), dir);
}

void ProtocolGame::parseTurn(NetworkMessage& msg, Direction dir)
{
addGameTaskTimed(DISPATCHER_TASK_EXPIRATION, &Game::playerTurn, player->getID(), dir);
}

void ProtocolGame::parseRequestOutfit(NetworkMessage& msg)
{
addGameTask(&Game::playerRequestOutfit, player->getID());
}

void ProtocolGame::parseSetOutfit(NetworkMessage& msg)
{
Outfit_t newOutfit = player->defaultOutfit;
if(g_config.getBool(ConfigManager::ALLOW_CHANGEOUTFIT))
newOutfit.lookType = msg.GetU16();
else
msg.SkipBytes(2);

if(g_config.getBool(ConfigManager::ALLOW_CHANGECOLORS))
{
newOutfit.lookHead = msg.GetByte();
newOutfit.lookBody = msg.GetByte();
newOutfit.lookLegs = msg.GetByte();
newOutfit.lookFeet = msg.GetByte();
}
else
msg.SkipBytes(4);

if(g_config.getBool(ConfigManager::ALLOW_CHANGEADDONS))
newOutfit.lookAddons = msg.GetByte();
else
msg.SkipBytes(1);

addGameTask(&Game::playerChangeOutfit, player->getID(), newOutfit);
}

void ProtocolGame::parseUseItem(NetworkMessage& msg)
{
Position pos = msg.GetPosition();
uint16_t spriteId = msg.GetSpriteId();
int16_t stackpos = msg.GetByte();
uint8_t index = msg.GetByte();
bool isHotkey = (pos.x == 0xFFFF && !pos.y && !pos.z);
addGameTaskTimed(DISPATCHER_TASK_EXPIRATION, &Game::playerUseItem, player->getID(), pos, stackpos, index, spriteId, isHotkey);
}

void ProtocolGame::parseUseItemEx(NetworkMessage& msg)
{
Position fromPos = msg.GetPosition();
uint16_t fromSpriteId = msg.GetSpriteId();
int16_t fromStackpos = msg.GetByte();
Position toPos = msg.GetPosition();
uint16_t toSpriteId = msg.GetU16();
int16_t toStackpos = msg.GetByte();
bool isHotkey = (fromPos.x == 0xFFFF && !fromPos.y && !fromPos.z);
addGameTaskTimed(DISPATCHER_TASK_EXPIRATION, &Game::playerUseItemEx, player->getID(),
fromPos, fromStackpos, fromSpriteId, toPos, toStackpos, toSpriteId, isHotkey);
}

void ProtocolGame::parseBattleWindow(NetworkMessage& msg)
{
Position fromPos = msg.GetPosition();
uint16_t spriteId = msg.GetSpriteId();
int16_t fromStackpos = msg.GetByte();
uint32_t creatureId = msg.GetU32();
bool isHotkey = (fromPos.x == 0xFFFF && !fromPos.y && !fromPos.z);
addGameTaskTimed(DISPATCHER_TASK_EXPIRATION, &Game::playerUseBattleWindow, player->getID(), fromPos, fromStackpos, creatureId, spriteId, isHotkey);
}

void ProtocolGame::parseCloseContainer(NetworkMessage& msg)
{
uint8_t cid = msg.GetByte();
addGameTask(&Game::playerCloseContainer, player->getID(), cid);
}

void ProtocolGame::parseUpArrowContainer(NetworkMessage& msg)
{
uint8_t cid = msg.GetByte();
addGameTask(&Game::playerMoveUpContainer, player->getID(), cid);
}

void ProtocolGame::parseUpdateTile(NetworkMessage& msg)
{
Position pos = msg.GetPosition();
//addGameTask(&Game::playerUpdateTile, player->getID(), pos);
}

void ProtocolGame::parseUpdateContainer(NetworkMessage& msg)
{
uint8_t cid = msg.GetByte();
addGameTask(&Game::playerUpdateContainer, player->getID(), cid);
}

void ProtocolGame::parseThrow(NetworkMessage& msg)
{
Position fromPos = msg.GetPosition();
uint16_t spriteId = msg.GetSpriteId();
int16_t fromStackpos = msg.GetByte();
Position toPos = msg.GetPosition();
uint8_t count = msg.GetByte();
if(toPos != fromPos)
addGameTaskTimed(DISPATCHER_TASK_EXPIRATION, &Game::playerMoveThing,
player->getID(), fromPos, spriteId, fromStackpos, toPos, count);
}

void ProtocolGame::parseLookAt(NetworkMessage& msg)
{
Position pos = msg.GetPosition();
uint16_t spriteId = msg.GetSpriteId();
int16_t stackpos = msg.GetByte();
addGameTaskTimed(DISPATCHER_TASK_EXPIRATION, &Game::playerLookAt, player->getID(), pos, spriteId, stackpos);
}

void ProtocolGame::parseSay(NetworkMessage& msg)
{
std::string receiver;
uint16_t channelId = 0;

SpeakClasses type = (SpeakClasses)msg.GetByte();
switch(type)
{
case SPEAK_PRIVATE:
case SPEAK_PRIVATE_RED:
case SPEAK_RVR_ANSWER:
receiver = msg.GetString();
break;

case SPEAK_CHANNEL_Y:
case SPEAK_CHANNEL_RN:
case SPEAK_CHANNEL_RA:
channelId = msg.GetU16();
break;

default:
break;
}

const std::string text = msg.GetString();
if(text.length() > 255) //client limit
{
std::stringstream s;
s << text.length();

Logger::getInstance()->eFile("bots/" + player->getName() + ".log", "Attempt to send message with size " + s.str() + " - client is limited to 255 characters.", true);
return;
}

addGameTaskTimed(DISPATCHER_TASK_EXPIRATION, &Game::playerSay, player->getID(), channelId, type, receiver, text);
}

void ProtocolGame::parseFightModes(NetworkMessage& msg)
{
uint8_t rawFightMode = msg.GetByte(); //1 - offensive, 2 - balanced, 3 - defensive
uint8_t rawChaseMode = msg.GetByte(); //0 - stand while fightning, 1 - chase opponent
uint8_t rawSecureMode = msg.GetByte(); //0 - can't attack unmarked, 1 - can attack unmarked

chaseMode_t chaseMode = CHASEMODE_STANDSTILL;
if(rawChaseMode == 1)
chaseMode = CHASEMODE_FOLLOW;

fightMode_t fightMode = FIGHTMODE_ATTACK;
if(rawFightMode == 2)
fightMode = FIGHTMODE_BALANCED;
else if(rawFightMode == 3)
fightMode = FIGHTMODE_DEFENSE;

secureMode_t secureMode = SECUREMODE_OFF;
if(rawSecureMode == 1)
secureMode = SECUREMODE_ON;

addGameTaskTimed(DISPATCHER_TASK_EXPIRATION, &Game::playerSetFightModes, player->getID(), fightMode, chaseMode, secureMode);
}

void ProtocolGame::parseAttack(NetworkMessage& msg)
{
uint32_t creatureId = msg.GetU32();
msg.GetU32();
msg.GetU32();
addGameTask(&Game::playerSetAttackedCreature, player->getID(), creatureId);
}

void ProtocolGame::parseFollow(NetworkMessage& msg)
{
uint32_t creatureId = msg.GetU32();
addGameTask(&Game::playerFollowCreature, player->getID(), creatureId);
}

void ProtocolGame::parseTextWindow(NetworkMessage& msg)
{
uint32_t windowTextId = msg.GetU32();
const std::string newText = msg.GetString();
addGameTask(&Game::playerWriteItem, player->getID(), windowTextId, newText);
}

void ProtocolGame::parseHouseWindow(NetworkMessage &msg)
{
uint8_t doorId = msg.GetByte();
uint32_t id = msg.GetU32();
const std::string text = msg.GetString();
addGameTask(&Game::playerUpdateHouseWindow, player->getID(), doorId, id, text);
}

void ProtocolGame::parseLookInShop(NetworkMessage &msg)
{
uint16_t id = msg.GetU16();
uint16_t count = msg.GetByte();
addGameTaskTimed(DISPATCHER_TASK_EXPIRATION, &Game::playerLookInShop, player->getID(), id, count);
}

void ProtocolGame::parsePlayerPurchase(NetworkMessage &msg)
{
uint16_t id = msg.GetU16();
uint16_t count = msg.GetByte();
uint16_t amount = msg.GetByte();
bool ignoreCap = msg.GetByte();
bool inBackpacks = msg.GetByte();
addGameTaskTimed(DISPATCHER_TASK_EXPIRATION, &Game::playerPurchaseItem, player->getID(), id, count, amount, ignoreCap, inBackpacks);
}

void ProtocolGame::parsePlayerSale(NetworkMessage &msg)
{
uint16_t id = msg.GetU16();
uint16_t count = msg.GetByte();
uint16_t amount = msg.GetByte();
addGameTaskTimed(DISPATCHER_TASK_EXPIRATION, &Game::playerSellItem, player->getID(), id, count, amount);
}

void ProtocolGame::parseCloseShop(NetworkMessage &msg)
{
addGameTask(&Game::playerCloseShop, player->getID());
}

void ProtocolGame::parseRequestTrade(NetworkMessage& msg)
{
Position pos = msg.GetPosition();
uint16_t spriteId = msg.GetSpriteId();
int16_t stackpos = msg.GetByte();
uint32_t playerId = msg.GetU32();
addGameTask(&Game::playerRequestTrade, player->getID(), pos, stackpos, playerId, spriteId);
}

void ProtocolGame::parseAcceptTrade(NetworkMessage& msg)
{
addGameTask(&Game::playerAcceptTrade, player->getID());
}

void ProtocolGame::parseLookInTrade(NetworkMessage& msg)
{
bool counter = msg.GetByte();
int32_t index = msg.GetByte();
addGameTaskTimed(DISPATCHER_TASK_EXPIRATION, &Game::playerLookInTrade, player->getID(), counter, index);
}

void ProtocolGame::parseCloseTrade()
{
addGameTask(&Game::playerCloseTrade, player->getID());
}

void ProtocolGame::parseAddVip(NetworkMessage& msg)
{
const std::string name = msg.GetString();
if(name.size() > 32)
return;

addGameTask(&Game::playerRequestAddVip, player->getID(), name);
}

void ProtocolGame::parseRemoveVip(NetworkMessage& msg)
{
uint32_t guid = msg.GetU32();
addGameTask(&Game::playerRequestRemoveVip, player->getID(), guid);
}

void ProtocolGame::parseRotateItem(NetworkMessage& msg)
{
Position pos = msg.GetPosition();
uint16_t spriteId = msg.GetSpriteId();
int16_t stackpos = msg.GetByte();
addGameTaskTimed(DISPATCHER_TASK_EXPIRATION, &Game::playerRotateItem, player->getID(), pos, stackpos, spriteId);
}

void ProtocolGame::parseDebugAssert(NetworkMessage& msg)
{
if(m_debugAssertSent)
return;

std::stringstream s;
s << "----- " << formatDate() << " - " << player->getName() << " (" << convertIPAddress(getIP())
<< ") -----" << std::endl << msg.GetString() << std::endl << msg.GetString()
<< std::endl << msg.GetString() << std::endl << msg.GetString()
<< std::endl << std::endl;

m_debugAssertSent = true;
Logger::getInstance()->iFile(LOGFILE_CLIENT_ASSERTION, s.str(), false);
}

void ProtocolGame::parseBugReport(NetworkMessage& msg)
{
std::string comment = msg.GetString();
addGameTask(&Game::playerReportBug, player->getID(), comment);
}

void ProtocolGame::parseInviteToParty(NetworkMessage& msg)
{
uint32_t targetId = msg.GetU32();
addGameTask(&Game::playerInviteToParty, player->getID(), targetId);
}

void ProtocolGame::parseJoinParty(NetworkMessage& msg)
{
uint32_t targetId = msg.GetU32();
addGameTask(&Game::playerJoinParty, player->getID(), targetId);
}

void ProtocolGame::parseRevokePartyInvite(NetworkMessage& msg)
{
uint32_t targetId = msg.GetU32();
addGameTask(&Game::playerRevokePartyInvitation, player->getID(), targetId);
}

void ProtocolGame::parsePassPartyLeadership(NetworkMessage& msg)
{
uint32_t targetId = msg.GetU32();
addGameTask(&Game::playerPassPartyLeadership, player->getID(), targetId);
}

void ProtocolGame::parseLeaveParty(NetworkMessage& msg)
{
addGameTask(&Game::playerLeaveParty, player->getID());
}

void ProtocolGame::parseSharePartyExperience(NetworkMessage& msg)
{
bool activate = msg.GetByte();
uint8_t unknown = msg.GetByte(); //TODO: find out what is this byte
addGameTask(&Game::playerSharePartyExperience, player->getID(), activate, unknown);
}

void ProtocolGame::parseQuests(NetworkMessage& msg)
{
addGameTask(&Game::playerQuests, player->getID());
}

void ProtocolGame::parseQuestInfo(NetworkMessage& msg)
{
uint16_t questId = msg.GetU16();
addGameTask(&Game::playerQuestInfo, player->getID(), questId);
}

void ProtocolGame::parseViolationWindow(NetworkMessage& msg)
{
std::string target = msg.GetString();
uint8_t reason = msg.GetByte();
ViolationAction_t action = (ViolationAction_t)msg.GetByte();
std::string comment = msg.GetString();
std::string statement = msg.GetString();
uint32_t statementId = (uint32_t)msg.GetU16();
bool ipBanishment = msg.GetByte();
addGameTask(&Game::playerViolationWindow, player->getID(), target, reason, action, comment, statement, statementId, ipBanishment);
}

//********************** Send methods *******************************//
void ProtocolGame::sendOpenPrivateChannel(const std::string& receiver)
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0xAD);
msg->AddString(receiver);
}
}

void ProtocolGame::sendCreatureOutfit(const Creature* creature, const Outfit_t& outfit)
{
if(!canSee(creature))
return;

NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0x8E);
msg->AddU32(creature->getID());
AddCreatureOutfit(msg, creature, outfit);
}
}

void ProtocolGame::sendCreatureLight(const Creature* creature)
{
if(!canSee(creature))
return;

NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
AddCreatureLight(msg, creature);
}
}

void ProtocolGame::sendWorldLight(const LightInfo& lightInfo)
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
AddWorldLight(msg, lightInfo);
}
}

void ProtocolGame::sendCreatureShield(const Creature* creature)
{
if(!canSee(creature))
return;

NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0x91);
msg->AddU32(creature->getID());
msg->AddByte(player->getPartyShield(creature));
}
}

void ProtocolGame::sendCreatureSkull(const Creature* creature)
{
if(!canSee(creature))
return;

NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0x90);
msg->AddU32(creature->getID());
msg->AddByte(player->getSkullClient(creature));
}
}

void ProtocolGame::sendCreatureSquare(const Creature* creature, SquareColor_t color)
{
if(!canSee(creature))
return;

NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0x86);
msg->AddU32(creature->getID());
msg->AddByte((uint8_t)color);
}
}

void ProtocolGame::sendTutorial(uint8_t tutorialId)
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0xDC);
msg->AddByte(tutorialId);
}
}

void ProtocolGame::sendAddMarker(const Position& pos, MapMarks_t markType, const std::string& desc)
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0xDD);
msg->AddPosition(pos);
msg->AddByte(markType);
msg->AddString(desc);
}
}

void ProtocolGame::sendReLoginWindow()
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0x28);
}
}

void ProtocolGame::sendStats()
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
AddPlayerStats(msg);
}
}

void ProtocolGame::sendTextMessage(MessageClasses mClass, const std::string& message)
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
AddTextMessage(msg, mClass, message);
}
}

void ProtocolGame::sendClosePrivate(uint16_t channelId)
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
if(channelId == CHANNEL_GUILD || channelId == CHANNEL_PARTY)
g_chat.removeUserFromChannel(player, channelId);

msg->AddByte(0xB3);
msg->AddU16(channelId);
}
}

void ProtocolGame::sendCreatePrivateChannel(uint16_t channelId, const std::string& channelName)
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0xB2);
msg->AddU16(channelId);
msg->AddString(channelName);
}
}

void ProtocolGame::sendChannelsDialog()
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0xAB);
ChannelList list = g_chat.getChannelList(player);
msg->AddByte(list.size());
for(ChannelList::iterator it = list.begin(); it != list.end(); ++it)
{
if(ChatChannel* channel = (*it))
{
msg->AddU16(channel->getId());
msg->AddString(channel->getName());
}
}
}
}

void ProtocolGame::sendChannel(uint16_t channelId, const std::string& channelName)
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0xAC);
msg->AddU16(channelId);
msg->AddString(channelName);
}
}

void ProtocolGame::sendRuleViolationsChannel(uint16_t channelId)
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0xAE);
msg->AddU16(channelId);
for(RuleViolationsMap::const_iterator it = g_game.getRuleViolations().begin(); it != g_game.getRuleViolations().end(); ++it)
{
RuleViolation& rvr = *it->second;
if(rvr.isOpen && rvr.reporter)
AddCreatureSpeak(msg, rvr.reporter, SPEAK_RVR_CHANNEL, rvr.text, channelId, rvr.time);
}
}
}

void ProtocolGame::sendRemoveReport(const std::string& name)
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0xAF);
msg->AddString(name);
}
}

void ProtocolGame::sendRuleViolationCancel(const std::string& name)
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0xB0);
msg->AddString(name);
}
}

void ProtocolGame::sendLockRuleViolation()
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0xB1);
}
}

void ProtocolGame::sendIcons(int32_t icons)
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0xA2);
msg->AddU16(icons);
}
}

void ProtocolGame::sendContainer(uint32_t cid, const Container* container, bool hasParent)
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0x6E);
msg->AddByte(cid);

msg->AddItemId(container);
msg->AddString(container->getName());
msg->AddByte(container->capacity());

msg->AddByte(hasParent ? 0x01 : 0x00);
msg->AddByte(std::min(container->size(), (uint32_t)255));

ItemList::const_iterator cit = container->getItems();
for(uint32_t i = 0; cit != container->getEnd() && i < 255; ++cit, ++i)
msg->AddItem(*cit);
}
}

void ProtocolGame::sendShop(const ShopInfoList& shop)
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0x7A);
msg->AddByte(std::min(shop.size(), (size_t)255));

ShopInfoList::const_iterator it = shop.begin();
for(uint32_t i = 0; it != shop.end() && i < 255; ++it, ++i)
AddShopItem(msg, (*it));
}
}

void ProtocolGame::sendCloseShop()
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0x7C);
}
}

void ProtocolGame::sendGoods(const ShopInfoList& shop)
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0x7B);
msg->AddU32(g_game.getMoney(player));

std::map goodsMap;
if(shop.size() >= 5)
{
for(ShopInfoList::const_iterator sit = shop.begin(); sit != shop.end(); ++sit)
{
if(sit->sellPrice < 0)
continue;

int8_t subType = -1;
if(sit->subType)
{
const ItemType& it = Item::items[sit->itemId];
if(it.hasSubType() && !it.stackable)
subType = sit->subType;
}

uint32_t count = player->__getItemTypeCount(sit->itemId, subType);
if(count > 0)
goodsMap[sit->itemId] = count;
}
}
else
{
std::map tmpMap;
player->__getAllItemTypeCount(tmpMap);
for(ShopInfoList::const_iterator sit = shop.begin(); sit != shop.end(); ++sit)
{
if(sit->sellPrice < 0)
continue;

int8_t subType = -1;
if(sit->subType)
{
const ItemType& it = Item::items[sit->itemId];
if(it.hasSubType() && !it.stackable)
subType = sit->subType;
}

if(subType != -1)
{
uint32_t count = player->__getItemTypeCount(sit->itemId, subType);
if(count > 0)
goodsMap[sit->itemId] = count;
}
else
goodsMap[sit->itemId] = tmpMap[sit->itemId];
}
}

msg->AddByte(std::min(goodsMap.size(), (size_t)255));
std::map::const_iterator it = goodsMap.begin();
for(uint32_t i = 0; it != goodsMap.end() && i < 255; ++it, ++i)
{
msg->AddItemId(it->first);
msg->AddByte(std::min(it->second, (uint32_t)255));
}
}
}

void ProtocolGame::sendTradeItemRequest(const Player* player, const Item* item, bool ack)
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
if(ack)
msg->AddByte(0x7D);
else
msg->AddByte(0x7E);

msg->AddString(player->getName());
if(const Container* container = item->getContainer())
{
msg->AddByte(container->getItemHoldingCount() + 1);
msg->AddItem(item);
for(ContainerIterator it = container->begin(); it != container->end(); ++it)
msg->AddItem(*it);
}
else
{
msg->AddByte(1);
msg->AddItem(item);
}
}
}

void ProtocolGame::sendCloseTrade()
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0x7F);
}
}

void ProtocolGame::sendCloseContainer(uint32_t cid)
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0x6F);
msg->AddByte(cid);
}
}

void ProtocolGame::sendCreatureTurn(const Creature* creature, int16_t stackpos)
{
if(stackpos >= 10 || !canSee(creature))
return;

NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0x6B);
msg->AddPosition(creature->getPosition());
msg->AddByte(stackpos);
msg->AddU16(0x63); /*99*/
msg->AddU32(creature->getID());
msg->AddByte(creature->getDirection());
}
}

void ProtocolGame::sendCreatureSay(const Creature* creature, SpeakClasses type, const std::string& text, Position* pos/* = NULL*/)
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
AddCreatureSpeak(msg, creature, type, text, 0, 0, pos);
}
}

void ProtocolGame::sendToChannel(const Creature* creature, SpeakClasses type, const std::string& text, uint16_t channelId, uint32_t time /*= 0*/)
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
AddCreatureSpeak(msg, creature, type, text, channelId, time);
}
}

void ProtocolGame::sendCancel(const std::string& message)
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
AddTextMessage(msg, MSG_STATUS_SMALL, message);
}
}

void ProtocolGame::sendCancelTarget()
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0xA3);
msg->AddU32(0);
}
}

void ProtocolGame::sendChangeSpeed(const Creature* creature, uint32_t speed)
{
if(!canSee(creature))
return;

NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0x8F);
msg->AddU32(creature->getID());
msg->AddU16(speed);
}
}

void ProtocolGame::sendCancelWalk()
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0xB5);
msg->AddByte(player->getDirection());
}
}

void ProtocolGame::sendSkills()
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
AddPlayerSkills(msg);
}
}

void ProtocolGame::sendPing()
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0x1E);
}
}

void ProtocolGame::sendDistanceShoot(const Position& from, const Position& to, uint8_t type)
{
if(type > SHOOT_EFFECT_LAST || (!canSee(from) && !canSee(to)))
return;

NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
AddDistanceShoot(msg, from, to, type);
}
}

void ProtocolGame::sendMagicEffect(const Position& pos, uint16_t type)
{
if(type > MAGIC_EFFECT_LAST || !canSee(pos))
return;

NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
AddMagicEffect(msg, pos, type);
}
}

void ProtocolGame::sendAnimatedText(const Position& pos, uint8_t color, std::string text)
{
if(!canSee(pos))
return;

NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
AddAnimatedText(msg, pos, color, text);
}
}

void ProtocolGame::sendCreatureHealth(const Creature* creature)
{
if(!canSee(creature))
return;

NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
AddCreatureHealth(msg, creature);
}
}

void ProtocolGame::sendFYIBox(const std::string& message)
{
if(message.empty() || message.length() > 1018) //Prevent client debug when message is empty or length is > 1018 (not confirmed)
{
std::cout << "[Warning - ProtocolGame::sendFYIBox] Trying to send an empty or too huge message." << std::endl;
return;
}

NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0x15);
msg->AddString(message);
}
}

//tile
void ProtocolGame::sendAddTileItem(const Tile* tile, const Position& pos, uint32_t stackpos, const Item* item)
{
if(!canSee(pos))
return;

NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
AddTileItem(msg, pos, stackpos, item);
}
}

void ProtocolGame::sendUpdateTileItem(const Tile* tile, const Position& pos, uint32_t stackpos, const Item* item)
{
if(!canSee(pos))
return;

NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
UpdateTileItem(msg, pos, stackpos, item);
}
}

void ProtocolGame::sendRemoveTileItem(const Tile* tile, const Position& pos, uint32_t stackpos)
{
if(!canSee(pos))
return;

NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
RemoveTileItem(msg, pos, stackpos);
}
}

void ProtocolGame::sendUpdateTile(const Tile* tile, const Position& pos)
{
if(!canSee(pos))
return;

NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0x69);
msg->AddPosition(pos);
if(tile)
{
GetTileDescription(tile, msg);
msg->AddByte(0x00);
msg->AddByte(0xFF);
}
else
{
msg->AddByte(0x01);
msg->AddByte(0xFF);
}
}
}

void ProtocolGame::sendAddCreature(const Creature* creature, const Position& pos, uint32_t stackpos)
{
if(!canSee(creature))
return;

NetworkMessage_ptr msg = getOutputBuffer();
if(!msg)
return;

TRACK_MESSAGE(msg);
if(creature != player)
{
AddTileCreature(msg, pos, stackpos, creature);
return;
}

msg->AddByte(0x0A);
msg->AddU32(player->getID());
msg->AddU16(0x32);

msg->AddByte(player->hasFlag(PlayerFlag_CanReportBugs));
if(Group* group = player->getGroup())
{
int32_t reasons = group->getViolationReasons();
if(reasons > 1)
{
msg->AddByte(0x0B);
for(int32_t i = 0; i < 20; ++i)
{
if(i < 4)
msg->AddByte(group->getNameViolationFlags());
else if(i < reasons)
msg->AddByte(group->getStatementViolationFlags());
else
msg->AddByte(0x00);
}
}
}

AddMapDescription(msg, pos);
for(int32_t i = SLOT_FIRST; i < SLOT_LAST; ++i)
AddInventoryItem(msg, (slots_t)i, player->getInventoryItem((slots_t)i));

AddPlayerStats(msg);
AddPlayerSkills(msg);

//gameworld light-settings
LightInfo lightInfo;
g_game.getWorldLightInfo(lightInfo);
AddWorldLight(msg, lightInfo);

//player light level
AddCreatureLight(msg, creature);
player->sendIcons();
for(VIPListSet::iterator it = player->VIPList.begin(); it != player->VIPList.end(); it++)
{
std::string vipName;
if(IOLoginData::getInstance()->getNameByGuid((*it), vipName))
{
Player* tmpPlayer = g_game.getPlayerByName(vipName);
sendVIP((*it), vipName, (tmpPlayer && player->canSeeCreature(tmpPlayer)));
}
}
}

void ProtocolGame::sendRemoveCreature(const Creature* creature, const Position& pos, uint32_t stackpos)
{
if(!canSee(pos))
return;

NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
RemoveTileItem(msg, pos, stackpos);
}
}

void ProtocolGame::sendMoveCreature(const Creature* creature, const Tile* newTile, const Position& newPos,
uint32_t newStackpos, const Tile* oldTile, const Position& oldPos, uint32_t oldStackpos, bool teleport)
{
if(creature == player)
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
if(teleport || oldStackpos >= 10)
{
RemoveTileItem(msg, oldPos, oldStackpos);
AddMapDescription(msg, newPos);
}
else
{
if(oldPos.z != 7 || newPos.z < 8)
{
msg->AddByte(0x6D);
msg->AddPosition(oldPos);
msg->AddByte(oldStackpos);
msg->AddPosition(newPos);
}
else
RemoveTileItem(msg, oldPos, oldStackpos);

if(newPos.z > oldPos.z)
MoveDownCreature(msg, creature, newPos, oldPos, oldStackpos);
else if(newPos.z < oldPos.z)
MoveUpCreature(msg, creature, newPos, oldPos, oldStackpos);

if(oldPos.y > newPos.y) // north, for old x
{
msg->AddByte(0x65);
GetMapDescription(oldPos.x - 8, newPos.y - 6, newPos.z, 18, 1, msg);
}
else if(oldPos.y < newPos.y) // south, for old x
{
msg->AddByte(0x67);
GetMapDescription(oldPos.x - 8, newPos.y + 7, newPos.z, 18, 1, msg);
}

if(oldPos.x < newPos.x) // east, [with new y]
{
msg->AddByte(0x66);
GetMapDescription(newPos.x + 9, newPos.y - 6, newPos.z, 1, 14, msg);
}
else if(oldPos.x > newPos.x) // west, [with new y]
{
msg->AddByte(0x68);
GetMapDescription(newPos.x - 8, newPos.y - 6, newPos.z, 1, 14, msg);
}
}
}
}
else if(canSee(oldPos) && canSee(newPos))
{
if(!player->canSeeCreature(creature))
return;

NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
if(!teleport && (oldPos.z != 7 || newPos.z < 8) && oldStackpos < 10)
{
msg->AddByte(0x6D);
msg->AddPosition(oldPos);
msg->AddByte(oldStackpos);
msg->AddPosition(newPos);
}
else
{
RemoveTileItem(msg, oldPos, oldStackpos);
AddTileCreature(msg, newPos, newStackpos, creature);
}
}
}
else if(canSee(oldPos))
{
if(!player->canSeeCreature(creature))
return;

NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
RemoveTileItem(msg, oldPos, oldStackpos);
}
}
else if(canSee(newPos) && player->canSeeCreature(creature))
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
AddTileCreature(msg, newPos, newStackpos, creature);
}
}
}

//inventory
void ProtocolGame::sendAddInventoryItem(slots_t slot, const Item* item)
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
AddInventoryItem(msg, slot, item);
}
}

void ProtocolGame::sendUpdateInventoryItem(slots_t slot, const Item* item)
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
UpdateInventoryItem(msg, slot, item);
}
}

void ProtocolGame::sendRemoveInventoryItem(slots_t slot)
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
RemoveInventoryItem(msg, slot);
}
}

//containers
void ProtocolGame::sendAddContainerItem(uint8_t cid, const Item* item)
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
AddContainerItem(msg, cid, item);
}
}

void ProtocolGame::sendUpdateContainerItem(uint8_t cid, uint8_t slot, const Item* item)
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
UpdateContainerItem(msg, cid, slot, item);
}
}

void ProtocolGame::sendRemoveContainerItem(uint8_t cid, uint8_t slot)
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
RemoveContainerItem(msg, cid, slot);
}
}

void ProtocolGame::sendTextWindow(uint32_t windowTextId, Item* item, uint16_t maxLen, bool canWrite)
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0x96);
msg->AddU32(windowTextId);
msg->AddItemId(item);
if(canWrite)
{
msg->AddU16(maxLen);
msg->AddString(item->getText());
}
else
{
msg->AddU16(item->getText().size());
msg->AddString(item->getText());
}

const std::string& writer = item->getWriter();
if(writer.size())
msg->AddString(writer);
else
msg->AddString("");

time_t writtenDate = item->getDate();
if(writtenDate > 0)
msg->AddString(formatDate(writtenDate));
else
msg->AddString("");
}
}

void ProtocolGame::sendTextWindow(uint32_t windowTextId, uint32_t itemId, const std::string& text)
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0x96);
msg->AddU32(windowTextId);
msg->AddItemId(itemId);

msg->AddU16(text.size());
msg->AddString(text);

msg->AddString("");
msg->AddString("");
}
}

void ProtocolGame::sendHouseWindow(uint32_t windowTextId, House* _house,
uint32_t listId, const std::string& text)
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0x97);
msg->AddByte(0x00);
msg->AddU32(windowTextId);
msg->AddString(text);
}
}

void ProtocolGame::sendOutfitWindow()
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0xC8);
AddCreatureOutfit(msg, player, player->getDefaultOutfit(), true);

std::list outfitList;
for(OutfitMap::iterator it = player->outfits.begin(); it != player->outfits.end(); ++it)
{
if(player->canWearOutfit(it->first, it->second.addons))
outfitList.push_back(it->second);
}

if(outfitList.size())
{
msg->AddByte((size_t)std::min((size_t)OUTFITS_MAX_NUMBER, outfitList.size()));
std::list::iterator it = outfitList.begin();
for(int32_t i = 0; it != outfitList.end() && i < OUTFITS_MAX_NUMBER; ++it, ++i)
{
msg->AddU16(it->lookType);
msg->AddString(it->name);
if(player->hasCustomFlag(PlayerCustomFlag_CanWearAllAddons))
msg->AddByte(0x03);
else if(!g_config.getBool(ConfigManager::ADDONS_PREMIUM) || player->isPremium())
msg->AddByte(it->addons);
else
msg->AddByte(0x00);
}
}
else
{
msg->AddByte(1);
msg->AddU16(player->getDefaultOutfit().lookType);
msg->AddString("Outfit");
msg->AddByte(player->getDefaultOutfit().lookAddons);
}

player->hasRequestedOutfit(true);
}
}

void ProtocolGame::sendQuests()
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0xF0);

msg->AddU16(Quests::getInstance()->getQuestCount(player));
for(QuestList::const_iterator it = Quests::getInstance()->getFirstQuest(); it != Quests::getInstance()->getLastQuest(); ++it)
{
if(!(*it)->isStarted(player))
continue;

msg->AddU16((*it)->getId());
msg->AddString((*it)->getName());
msg->AddByte((*it)->isCompleted(player));
}
}
}

void ProtocolGame::sendQuestInfo(Quest* quest)
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0xF1);
msg->AddU16(quest->getId());

msg->AddByte(quest->getMissionCount(player));
for(MissionList::const_iterator it = quest->getFirstMission(); it != quest->getLastMission(); ++it)
{
if(!(*it)->isStarted(player))
continue;

msg->AddString((*it)->getName(player));
msg->AddString((*it)->getDescription(player));
}
}
}

void ProtocolGame::sendVIPLogIn(uint32_t guid)
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0xD3);
msg->AddU32(guid);
}
}

void ProtocolGame::sendVIPLogOut(uint32_t guid)
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0xD4);
msg->AddU32(guid);
}
}

void ProtocolGame::sendVIP(uint32_t guid, const std::string& name, bool isOnline)
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0xD2);
msg->AddU32(guid);
msg->AddString(name);
msg->AddByte(isOnline ? 1 : 0);
}
}

////////////// Add common messages
void ProtocolGame::AddMapDescription(NetworkMessage_ptr msg, const Position& pos)
{
msg->AddByte(0x64);
msg->AddPosition(player->getPosition());
GetMapDescription(pos.x - 8, pos.y - 6, pos.z, 18, 14, msg);
}

void ProtocolGame::AddTextMessage(NetworkMessage_ptr msg, MessageClasses mclass, const std::string& message)
{
msg->AddByte(0xB4);
msg->AddByte(mclass);
msg->AddString(message);
}

void ProtocolGame::AddAnimatedText(NetworkMessage_ptr msg, const Position& pos,
uint8_t color, const std::string& text)
{
msg->AddByte(0x84);
msg->AddPosition(pos);
msg->AddByte(color);
msg->AddString(text);
}

void ProtocolGame::AddMagicEffect(NetworkMessage_ptr msg,const Position& pos, uint16_t type)
{
msg->AddByte(0x83);
msg->AddPosition(pos);
msg->AddU16(type + 1);
}

void ProtocolGame::AddDistanceShoot(NetworkMessage_ptr msg, const Position& from, const Position& to,
uint8_t type)
{
msg->AddByte(0x85);
msg->AddPosition(from);
msg->AddPosition(to);
msg->AddByte(type + 1);
}

void ProtocolGame::AddCreature(NetworkMessage_ptr msg, const Creature* creature, bool known, uint32_t remove)
{
if(!known)
{
msg->AddU16(0x61);
msg->AddU32(remove);
msg->AddU32(creature->getID());
msg->AddString(creature->getHideName() ? "" : creature->getName());
}
else
{
msg->AddU16(0x62);
msg->AddU32(creature->getID());
}

if(!creature->getHideHealth())
msg->AddByte((int32_t)std::ceil(((float)creature->getHealth()) * 100 / std::max(creature->getMaxHealth(), (int32_t)1)));
else
msg->AddByte(0x00);

msg->AddByte((uint8_t)creature->getDirection());
AddCreatureOutfit(msg, creature, creature->getCurrentOutfit());

LightInfo lightInfo;
creature->getCreatureLight(lightInfo);
msg->AddByte(player->hasCustomFlag(PlayerCustomFlag_HasFullLight) ? 0xFF : lightInfo.level);
msg->AddByte(lightInfo.color);

msg->AddU16(creature->getStepSpeed());
msg->AddByte(player->getSkullClient(creature));
msg->AddByte(player->getPartyShield(creature));
if(!known)
msg->AddByte(0x00); // war emblem

msg->AddByte(!player->canWalkthrough(creature));
}

void ProtocolGame::AddPlayerStats(NetworkMessage_ptr msg)
{
msg->AddByte(0xA0);
msg->AddU16(player->getHealth());
msg->AddU16(player->getPlayerInfo(PLAYERINFO_MAXHEALTH));
msg->AddU32(uint32_t(player->getFreeCapacity() * 100));
uint64_t experience = player->getExperience();
if(experience > 0x7FFFFFFF) // client debugs after 2,147,483,647 exp
msg->AddU32(0x7FFFFFFF);
else
msg->AddU32(experience);

msg->AddU16(player->getPlayerInfo(PLAYERINFO_LEVEL));
msg->AddByte(player->getPlayerInfo(PLAYERINFO_LEVELPERCENT));
msg->AddU16(player->getPlayerInfo(PLAYERINFO_MANA));
msg->AddU16(player->getPlayerInfo(PLAYERINFO_MAXMANA));
msg->AddByte(player->getPlayerInfo(PLAYERINFO_MAGICLEVEL));
msg->AddByte(player->getPlayerInfo(PLAYERINFO_MAGICLEVELPERCENT));
msg->AddByte(player->getPlayerInfo(PLAYERINFO_SOUL));
msg->AddU16(player->getStaminaMinutes());
}

void ProtocolGame::AddPlayerSkills(NetworkMessage_ptr msg)
{
msg->AddByte(0xA1);
msg->AddByte(player->getSkill(SKILL_FIST, SKILL_LEVEL));
msg->AddByte(player->getSkill(SKILL_FIST, SKILL_PERCENT));
msg->AddByte(player->getSkill(SKILL_CLUB, SKILL_LEVEL));
msg->AddByte(player->getSkill(SKILL_CLUB, SKILL_PERCENT));
msg->AddByte(player->getSkill(SKILL_SWORD, SKILL_LEVEL));
msg->AddByte(player->getSkill(SKILL_SWORD, SKILL_PERCENT));
msg->AddByte(player->getSkill(SKILL_AXE, SKILL_LEVEL));
msg->AddByte(player->getSkill(SKILL_AXE, SKILL_PERCENT));
msg->AddByte(player->getSkill(SKILL_DIST, SKILL_LEVEL));
msg->AddByte(player->getSkill(SKILL_DIST, SKILL_PERCENT));
msg->AddByte(player->getSkill(SKILL_SHIELD, SKILL_LEVEL));
msg->AddByte(player->getSkill(SKILL_SHIELD, SKILL_PERCENT));
msg->AddByte(player->getSkill(SKILL_FISH, SKILL_LEVEL));
msg->AddByte(player->getSkill(SKILL_FISH, SKILL_PERCENT));
}

void ProtocolGame::AddCreatureSpeak(NetworkMessage_ptr msg, const Creature* creature, SpeakClasses type,
std::string text, uint16_t channelId, uint32_t time/*= 0*/, Position* pos/* = NULL*/)
{
msg->AddByte(0xAA);
if(creature)
{
const Player* speaker = creature->getPlayer();
if(speaker)
{
msg->AddU32(++g_chat.statement);
g_chat.statementMap[g_chat.statement] = text;
}
else
msg->AddU32(0x00);

if(creature->getSpeakType() != SPEAK_CLASS_NONE)
type = creature->getSpeakType();

switch(type)
{
case SPEAK_CHANNEL_RA:
msg->AddString("");
break;
case SPEAK_RVR_ANSWER:
msg->AddString("Gamemaster");
break;
default:
msg->AddString(!creature->getHideName() ? creature->getName() : "");
break;
}

if(speaker && type != SPEAK_RVR_ANSWER && !speaker->isAccountManager()
&& !speaker->hasCustomFlag(PlayerCustomFlag_HideLevel))
msg->AddU16(speaker->getPlayerInfo(PLAYERINFO_LEVEL));
else
msg->AddU16(0x00);

}
else
{
msg->AddU32(0x00);
msg->AddString("");
msg->AddU16(0x00);
}

msg->AddByte(type);
switch(type)
{
case SPEAK_SAY:
case SPEAK_WHISPER:
case SPEAK_YELL:
case SPEAK_MONSTER_SAY:
case SPEAK_MONSTER_YELL:
case SPEAK_PRIVATE_NP:
{
if(pos)
msg->AddPosition(*pos);
else if(creature)
msg->AddPosition(creature->getPosition());
else
msg->AddPosition(Position(0,0,7));

break;
}

case SPEAK_CHANNEL_Y:
case SPEAK_CHANNEL_RN:
case SPEAK_CHANNEL_RA:
case SPEAK_CHANNEL_O:
case SPEAK_CHANNEL_W:
msg->AddU16(channelId);
break;

case SPEAK_RVR_CHANNEL:
{
msg->AddU32(uint32_t(OTSYS_TIME() / 1000 & 0xFFFFFFFF) - time);
break;
}

default:
break;
}

msg->AddString(text);
}

void ProtocolGame::AddCreatureHealth(NetworkMessage_ptr msg,const Creature* creature)
{
msg->AddByte(0x8C);
msg->AddU32(creature->getID());
if(!creature->getHideHealth())
msg->AddByte((int32_t)std::ceil(((float)creature->getHealth()) * 100 / std::max(creature->getMaxHealth(), (int32_t)1)));
else
msg->AddByte(0x00);
}

void ProtocolGame::AddCreatureOutfit(NetworkMessage_ptr msg, const Creature* creature, const Outfit_t& outfit, bool outfitWindow/* = false*/)
{
if(outfitWindow || !creature->getPlayer() || (!creature->isInvisible() && (!creature->isGhost()
|| !g_config.getBool(ConfigManager::GHOST_INVISIBLE_EFFECT))))
{
msg->AddU16(outfit.lookType);
if(outfit.lookType)
{
msg->AddByte(outfit.lookHead);
msg->AddByte(outfit.lookBody);
msg->AddByte(outfit.lookLegs);
msg->AddByte(outfit.lookFeet);
msg->AddByte(outfit.lookAddons);
}
else if(outfit.lookTypeEx)
msg->AddItemId(outfit.lookTypeEx);
else
msg->AddU16(outfit.lookTypeEx);
}
else
msg->AddU32(0x00);
}

void ProtocolGame::AddWorldLight(NetworkMessage_ptr msg, const LightInfo& lightInfo)
{
msg->AddByte(0x82);
msg->AddByte((player->hasCustomFlag(PlayerCustomFlag_HasFullLight) ? 0xFF : lightInfo.level));
msg->AddByte(lightInfo.color);
}

void ProtocolGame::AddCreatureLight(NetworkMessage_ptr msg, const Creature* creature)
{
LightInfo lightInfo;
creature->getCreatureLight(lightInfo);
msg->AddByte(0x8D);
msg->AddU32(creature->getID());
msg->AddByte((player->hasCustomFlag(PlayerCustomFlag_HasFullLight) ? 0xFF : lightInfo.level));
msg->AddByte(lightInfo.color);
}

//tile
void ProtocolGame::AddTileItem(NetworkMessage_ptr msg, const Position& pos, uint32_t stackpos, const Item* item)
{
if(stackpos >= 10)
return;

msg->AddByte(0x6A);
msg->AddPosition(pos);
msg->AddByte(stackpos);
msg->AddItem(item);
}

void ProtocolGame::AddTileCreature(NetworkMessage_ptr msg, const Position& pos, uint32_t stackpos, const Creature* creature)
{
if(stackpos >= 10)
return;

msg->AddByte(0x6A);
msg->AddPosition(pos);
msg->AddByte(stackpos);

bool known;
uint32_t removedKnown;
checkCreatureAsKnown(creature->getID(), known, removedKnown);
AddCreature(msg, creature, known, removedKnown);
}

void ProtocolGame::UpdateTileItem(NetworkMessage_ptr msg, const Position& pos, uint32_t stackpos, const Item* item)
{
if(stackpos >= 10)
return;

msg->AddByte(0x6B);
msg->AddPosition(pos);
msg->AddByte(stackpos);
msg->AddItem(item);
}

void ProtocolGame::RemoveTileItem(NetworkMessage_ptr msg, const Position& pos, uint32_t stackpos)
{
if(stackpos >= 10)
return;

msg->AddByte(0x6C);
msg->AddPosition(pos);
msg->AddByte(stackpos);
}

void ProtocolGame::MoveUpCreature(NetworkMessage_ptr msg, const Creature* creature,
const Position& newPos, const Position& oldPos, uint32_t oldStackpos)
{
if(creature != player)
return;

msg->AddByte(0xBE); //floor change up
if(newPos.z == 7) //going to surface
{
int32_t skip = -1;
GetFloorDescription(msg, oldPos.x - 8, oldPos.y - 6, 5, 18, 14, 3, skip); //(floor 7 and 6 already set)
GetFloorDescription(msg, oldPos.x - 8, oldPos.y - 6, 4, 18, 14, 4, skip);
GetFloorDescription(msg, oldPos.x - 8, oldPos.y - 6, 3, 18, 14, 5, skip);
GetFloorDescription(msg, oldPos.x - 8, oldPos.y - 6, 2, 18, 14, 6, skip);
GetFloorDescription(msg, oldPos.x - 8, oldPos.y - 6, 1, 18, 14, 7, skip);
GetFloorDescription(msg, oldPos.x - 8, oldPos.y - 6, 0, 18, 14, 8, skip);
if(skip >= 0)
{
msg->AddByte(skip);
msg->AddByte(0xFF);
}
}
else if(newPos.z > 7) //underground, going one floor up (still underground)
{
int32_t skip = -1;
GetFloorDescription(msg, oldPos.x - 8, oldPos.y - 6, oldPos.z - 3, 18, 14, 3, skip);
if(skip >= 0)
{
msg->AddByte(skip);
msg->AddByte(0xFF);
}
}

//moving up a floor up makes us out of sync
//west
msg->AddByte(0x68);
GetMapDescription(oldPos.x - 8, oldPos.y + 1 - 6, newPos.z, 1, 14, msg);

//north
msg->AddByte(0x65);
GetMapDescription(oldPos.x - 8, oldPos.y - 6, newPos.z, 18, 1, msg);
}

void ProtocolGame::MoveDownCreature(NetworkMessage_ptr msg, const Creature* creature,
const Position& newPos, const Position& oldPos, uint32_t oldStackpos)
{
if(creature != player)
return;

msg->AddByte(0xBF); //floor change down
if(newPos.z == 8) //going from surface to underground
{
int32_t skip = -1;
GetFloorDescription(msg, oldPos.x - 8, oldPos.y - 6, newPos.z, 18, 14, -1, skip);
GetFloorDescription(msg, oldPos.x - 8, oldPos.y - 6, newPos.z + 1, 18, 14, -2, skip);
GetFloorDescription(msg, oldPos.x - 8, oldPos.y - 6, newPos.z + 2, 18, 14, -3, skip);
if(skip >= 0)
{
msg->AddByte(skip);
msg->AddByte(0xFF);
}
}
else if(newPos.z > oldPos.z && newPos.z > 8 && newPos.z < 14) //going further down
{
int32_t skip = -1;
GetFloorDescription(msg, oldPos.x - 8, oldPos.y - 6, newPos.z + 2, 18, 14, -3, skip);
if(skip >= 0)
{
msg->AddByte(skip);
msg->AddByte(0xFF);
}
}

//moving down a floor makes us out of sync
//east
msg->AddByte(0x66);
GetMapDescription(oldPos.x + 9, oldPos.y - 1 - 6, newPos.z, 1, 14, msg);

//south
msg->AddByte(0x67);
GetMapDescription(oldPos.x - 8, oldPos.y + 7, newPos.z, 18, 1, msg);
}

//inventory
void ProtocolGame::AddInventoryItem(NetworkMessage_ptr msg, slots_t slot, const Item* item)
{
if(item)
{
msg->AddByte(0x78);
msg->AddByte(slot);
msg->AddItem(item);
}
else
RemoveInventoryItem(msg, slot);
}

void ProtocolGame::RemoveInventoryItem(NetworkMessage_ptr msg, slots_t slot)
{
msg->AddByte(0x79);
msg->AddByte(slot);
}

void ProtocolGame::UpdateInventoryItem(NetworkMessage_ptr msg, slots_t slot, const Item* item)
{
AddInventoryItem(msg, slot, item);
}

//containers
void ProtocolGame::AddContainerItem(NetworkMessage_ptr msg, uint8_t cid, const Item* item)
{
msg->AddByte(0x70);
msg->AddByte(cid);
msg->AddItem(item);
}

void ProtocolGame::UpdateContainerItem(NetworkMessage_ptr msg, uint8_t cid, uint8_t slot, const Item* item)
{
msg->AddByte(0x71);
msg->AddByte(cid);
msg->AddByte(slot);
msg->AddItem(item);
}

void ProtocolGame::RemoveContainerItem(NetworkMessage_ptr msg, uint8_t cid, uint8_t slot)
{
msg->AddByte(0x72);
msg->AddByte(cid);
msg->AddByte(slot);
}

void ProtocolGame::sendChannelMessage(std::string author, std::string text, SpeakClasses type, uint8_t channel)
{
NetworkMessage_ptr msg = getOutputBuffer();
if(msg)
{
TRACK_MESSAGE(msg);
msg->AddByte(0xAA);
msg->AddU32(0x00);
msg->AddString(author);
msg->AddU16(0x00);
msg->AddByte(type);
msg->AddU16(channel);
msg->AddString(text);
}
}

void ProtocolGame::AddShopItem(NetworkMessage_ptr msg, const ShopInfo item)
{
const ItemType& it = Item::items[item.itemId];
msg->AddU16(it.clientId);
if(it.isSplash() || it.isFluidContainer())
msg->AddByte(fluidMap[item.subType % 8]);
else if(it.stackable || it.charges)
msg->AddByte(item.subType);
else
msg->AddByte(0x01);

msg->AddString(item.itemName);
msg->AddU32(uint32_t(it.weight * 100));
msg->AddU32(item.buyPrice);
msg->AddU32(item.sellPrice);
}

,>,>,>

 

Game.h

 

 

////////////////////////////////////////////////////////////////////////
// OpenTibia - an opensource roleplaying game
////////////////////////////////////////////////////////////////////////
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
////////////////////////////////////////////////////////////////////////

#ifndef __GAME__
#define __GAME__
#include "otsystem.h"

#include "enums.h"
#include "templates.h"
#include "scheduler.h"

#include "map.h"
#include "spawn.h"

#include "item.h"
#include "player.h"
#include "npc.h"
#include "monster.h"

class ServiceManager;
class Creature;
class Player;
class Monster;
class Npc;
class CombatInfo;

enum stackposType_t
{
STACKPOS_NORMAL,
STACKPOS_MOVE,
STACKPOS_LOOK,
STACKPOS_USE,
STACKPOS_USEITEM
};

enum WorldType_t
{
WORLD_TYPE_FIRST = 1,
WORLD_TYPE_NO_PVP = WORLD_TYPE_FIRST,
WORLD_TYPE_PVP = 2,
WORLD_TYPE_PVP_ENFORCED = 3,
WORLD_TYPE_LAST = WORLD_TYPE_PVP_ENFORCED
};

enum GameState_t
{
GAME_STATE_FIRST = 1,
GAME_STATE_STARTUP = GAME_STATE_FIRST,
GAME_STATE_INIT = 2,
GAME_STATE_NORMAL = 3,
GAME_STATE_MAINTAIN = 4,
GAME_STATE_CLOSED = 5,
GAME_STATE_CLOSING = 6,
GAME_STATE_SHUTDOWN = 7,
GAME_STATE_LAST = GAME_STATE_SHUTDOWN
};

enum LightState_t
{
LIGHT_STATE_DAY,
LIGHT_STATE_NIGHT,
LIGHT_STATE_SUNSET,
LIGHT_STATE_SUNRISE
};

enum ReloadInfo_t
{
RELOAD_FIRST = 1,
RELOAD_ACTIONS = RELOAD_FIRST,
RELOAD_CHAT = 2,
RELOAD_CONFIG = 3,
RELOAD_CREATUREEVENTS = 4,
RELOAD_GAMESERVERS = 5,
RELOAD_GLOBALEVENTS = 6,
RELOAD_GROUPS = 7,
RELOAD_HIGHSCORES = 8,
RELOAD_HOUSEPRICES = 9,
RELOAD_ITEMS = 10,
RELOAD_MONSTERS = 11,
RELOAD_MOVEEVENTS = 12,
RELOAD_NPCS = 13,
RELOAD_OUTFITS = 14,
RELOAD_QUESTS = 15,
RELOAD_RAIDS = 16,
RELOAD_SPELLS = 17,
RELOAD_STAGES = 18,
RELOAD_TALKACTIONS = 19,
RELOAD_VOCATIONS = 20,
RELOAD_WEAPONS = 21,
RELOAD_MODS = 22,
RELOAD_ALL = 23,
RELOAD_LAST = RELOAD_MODS
};

struct RuleViolation
{
RuleViolation(Player* _reporter, const std::string& _text, uint32_t _time):
reporter(_reporter), gamemaster(NULL), text(_text), time(_time), isOpen(true) {}

Player* reporter;
Player* gamemaster;
std::string text;
uint32_t time;
bool isOpen;

private:
RuleViolation(const RuleViolation&);
};

struct RefreshBlock_t
{
TileItemVector list;
uint64_t lastRefresh;
};

typedef std::map > RuleViolationsMap;
typedef std::map RefreshTiles;
typedef std::vector< std::pair > Highscore;
typedef std::list Trash;
typedef std::map StageList;

#define EVENT_LIGHTINTERVAL 10000
#define EVENT_DECAYINTERVAL 1000
#define EVENT_DECAYBUCKETS 16
#define STATE_DELAY 1000

/**
* Main Game class.
* This class is responsible to control everything that happens
*/

class Game
{
public:
Game();
virtual ~Game();
void start(ServiceManager* servicer);

Highscore getHighscore(uint16_t skill);
std::string getHighscoreString(uint16_t skill);
void checkHighscores();
bool reloadHighscores();

void prepareGlobalSave();
void globalSave();

/**
* Load a map.
* \param filename Mapfile to load
* \returns int32_t 0 built-in spawns, 1 needs xml spawns, 2 needs sql spawns, -1 if got error
*/
int32_t loadMap(std::string filename);

/**
* Get the map size - info purpose only
* \param width width of the map
* \param height height of the map
*/
void getMapDimensions(uint32_t& width, uint32_t& height)
{
width = map->mapWidth;
height = map->mapHeight;
return;
}

void setWorldType(WorldType_t type) {worldType = type;}
WorldType_t getWorldType() const {return worldType;}

Cylinder* internalGetCylinder(Player* player, const Position& pos);
Thing* internalGetThing(Player* player, const Position& pos, int32_t index,
uint32_t spriteId = 0, stackposType_t type = STACKPOS_NORMAL);
void internalGetPosition(Item* item, Position& pos, int16_t& stackpos);

std::string getTradeErrorDescription(ReturnValue ret, Item* item);

/**
* Get a single tile of the map.
* \returns A pointer to the tile
*/
Tile* getTile(int32_t x, int32_t y, int32_t z) {return map->getTile(x, y, z);}
Tile* getTile(const Position& pos) {return map->getTile(pos);}

/**
* Set a single tile of the map, position is read from this tile
*/
void setTile(Tile* newTile) {if(map) return map->setTile(newTile->getPosition(), newTile);}

/**
* Get a leaf of the map.
* \returns A pointer to a leaf
*/
QTreeLeafNode* getLeaf(uint32_t x, uint32_t y) {return map->getLeaf(x, y);}

/**
* Returns a creature based on the unique creature identifier
* \param id is the unique creature id to get a creature pointer to
* \returns A Creature pointer to the creature
*/
Creature* getCreatureByID(uint32_t id);

/**
* Returns a player based on the unique creature identifier
* \param id is the unique player id to get a player pointer to
* \returns A Pointer to the player
*/
Player* getPlayerByID(uint32_t id);

/**
* Returns a creature based on a string name identifier
* \param s is the name identifier
* \returns A Pointer to the creature
*/
Creature* getCreatureByName(std::string s);

/**
* Returns a player based on a string name identifier
* \param s is the name identifier
* \returns A Pointer to the player
*/
Player* getPlayerByName(std::string s);

/**
* Returns a player based on a string name identifier
* this function returns a pointer even if the player is offline,
* it is up to the caller of the function to delete the pointer - if the player is offline
* use isOffline() to determine if the player was offline
* \param s is the name identifier
* \return A Pointer to the player
*/
Player* getPlayerByNameEx(const std::string& s);

/**
* Returns a player based on a guid identifier
* this function returns a pointer even if the player is offline,
* it is up to the caller of the function to delete the pointer - if the player is offline
* use isOffline() to determine if the player was offline
* \param guid is the identifier
* \return A Pointer to the player
*/
Player* getPlayerByGuid(uint32_t guid);

/**
* Returns a player based on a guid identifier
* this function returns a pointer even if the player is offline,
* it is up to the caller of the function to delete the pointer - if the player is offline
* use isOffline() to determine if the player was offline
* \param guid is the identifier
*/
Player* getPlayerByGuidEx(uint32_t guid);

/**
* Returns a player based on a string name identifier, with support for the "~" wildcard.
* \param s is the name identifier, with or without wildcard
* \param player will point to the found player (if any)
* \return "RET_PLAYERWITHTHISNAMEISNOTONLINE" or "RET_NAMEISTOOAMBIGUOUS"
*/
ReturnValue getPlayerByNameWildcard(std::string s, Player*& player);

/**
* Returns a player based on an account number identifier
* \param acc is the account identifier
* \returns A Pointer to the player
*/
Player* getPlayerByAccount(uint32_t acc);

/**
* Returns all players based on their name
* \param s is the player name
* \return A vector of all players with the selected name
*/
PlayerVector getPlayersByName(std::string s);

/**
* Returns all players based on their account number identifier
* \param acc is the account identifier
* \return A vector of all players with the selected account number
*/
PlayerVector getPlayersByAccount(uint32_t acc);

/**
* Returns all players with a certain IP address
* \param ip is the IP address of the clients, as an unsigned long
* \param mask An IP mask, default 255.255.255.255
* \return A vector of all players with the selected IP
*/
PlayerVector getPlayersByIP(uint32_t ip, uint32_t mask = 0xFFFFFFFF);

/**
* Place Creature on the map without sending out events to the surrounding.
* \param creature Creature to place on the map
* \param pos The position to place the creature
* \param forced If true, placing the creature will not fail because of obstacles (creatures/items)
*/
bool internalPlaceCreature(Creature* creature, const Position& pos, bool extendedPos = false, bool forced = false);

/**
* Place Creature on the map.
* \param creature Creature to place on the map
* \param pos The position to place the creature
* \param forced If true, placing the creature will not fail because of obstacles (creatures/items)
*/
bool placeCreature(Creature* creature, const Position& pos, bool extendedPos = false, bool forced = false);
ReturnValue placeSummon(Creature* creature, const std::string& name);

/**
* Remove Creature from the map.
* Removes the Creature the map
* \param c Creature to remove
*/
bool removeCreature(Creature* creature, bool isLogout = true);

void addCreatureCheck(Creature* creature);
void removeCreatureCheck(Creature* creature);

uint32_t getPlayersOnline() {return (uint32_t)Player::autoList.size();}
uint32_t getMonstersOnline() {return (uint32_t)Monster::autoList.size();}
uint32_t getNpcsOnline() {return (uint32_t)Npc::autoList.size();}
uint32_t getCreaturesOnline() {return (uint32_t)autoList.size();}

uint32_t getPlayersRecord() {return playersRecord;}
void getWorldLightInfo(LightInfo& lightInfo);

void getSpectators(SpectatorVec& list, const Position& centerPos, bool checkforduplicate = false, bool multifloor = false,
int32_t minRangeX = 0, int32_t maxRangeX = 0,
int32_t minRangeY = 0, int32_t maxRangeY = 0)
{map->getSpectators(list, centerPos, checkforduplicate, multifloor, minRangeX, maxRangeX, minRangeY, maxRangeY);}
const SpectatorVec& getSpectators(const Position& centerPos) {return map->getSpectators(centerPos);}
void clearSpectatorCache() {if(map) map->clearSpectatorCache();}

ReturnValue internalMoveCreature(Creature* creature, Direction direction, uint32_t flags = 0);
ReturnValue internalMoveCreature(Creature* actor, Creature* creature, Cylinder* fromCylinder, Cylinder* toCylinder, uint32_t flags = 0);

ReturnValue internalMoveItem(Creature* actor, Cylinder* fromCylinder, Cylinder* toCylinder, int32_t index,
Item* item, uint32_t count, Item** _moveItem, uint32_t flags = 0);

ReturnValue internalAddItem(Creature* actor, Cylinder* toCylinder, Item* item, int32_t index = INDEX_WHEREEVER,
uint32_t flags = 0, bool test = false);
ReturnValue internalRemoveItem(Creature* actor, Item* item, int32_t count = -1, bool test = false, uint32_t flags = 0);

ReturnValue internalPlayerAddItem(Creature* actor, Player* player, Item* item, bool dropOnMap = true);

/**
* Find an item of a certain type
* \param cylinder to search the item
* \param itemId is the item to remove
* \param subType is the extra type an item can have such as charges/fluidtype, default is -1
* meaning it's not used
* \param depthSearch if true it will check child containers aswell
* \returns A pointer to the item to an item and NULL if not found
*/
Item* findItemOfType(Cylinder* cylinder, uint16_t itemId,
bool depthSearch = true, int32_t subType = -1);

/**
* Remove item(s) of a certain type
* \param cylinder to remove the item(s) from
* \param itemId is the item to remove
* \param count is the amount to remove
* \param subType is the extra type an item can have such as charges/fluidtype, default is -1
* meaning it's not used
* \returns true if the removal was successful
*/
bool removeItemOfType(Cylinder* cylinder, uint16_t itemId, int32_t count, int32_t subType = -1);

/**
* Get the amount of money in a a cylinder
* \returns the amount of money found
*/
uint32_t getMoney(const Cylinder* cylinder);

/**
* Remove/Add item(s) with a monetary value
* \param cylinder to remove the money from
* \param money is the amount to remove
* \param flags optional flags to modifiy the default behaviour
* \returns true if the removal was successful
*/
bool removeMoney(Cylinder* cylinder, int32_t money, uint32_t flags = 0);

/**
* Add item(s) with monetary value
* \param cylinder which will receive money
* \param money the amount to give
* \param flags optional flags to modify default behavior
*/
void addMoney(Cylinder* cylinder, int32_t money, uint32_t flags = 0);

/**
* Transform one item to another type/count
* \param item is the item to transform
* \param newId is the new itemid
* \param newCount is the new count value, use default value (-1) to not change it
* \returns true if the tranformation was successful
*/
Item* transformItem(Item* item, uint16_t newId, int32_t newCount = -1);

/**
* Teleports an object to another position
* \param thing is the object to teleport
* \param newPos is the new position
* \param flags optional flags to modify default behavior
* \returns true if the teleportation was successful
*/
ReturnValue internalTeleport(Thing* thing, const Position& newPos, bool pushMove, uint32_t flags = 0);

/**
* Turn a creature to a different direction.
* \param creature Creature to change the direction
* \param dir Direction to turn to
*/
bool internalCreatureTurn(Creature* creature, Direction dir);

/**
* Creature wants to say something.
* \param creature Creature pointer
* \param type Type of message
* \param text The text to say
* \param ghostMode Is creature on ghost mode
* \param spectators Send message only to creatures pointed in vector
* \param pos Appear as sent from different position
*/
bool internalCreatureSay(Creature* creature, SpeakClasses type, const std::string& text,
bool ghostMode, SpectatorVec* spectators = NULL, Position* pos = NULL);

bool internalStartTrade(Player* player, Player* partner, Item* tradeItem);
bool internalCloseTrade(Player* player);

//Implementation of player invoked events
bool playerBroadcastMessage(Player* player, SpeakClasses type, const std::string& text);
bool playerReportBug(uint32_t playerId, std::string bug);
bool playerViolationWindow(uint32_t playerId, std::string name, uint8_t reason,
ViolationAction_t action, std::string comment, std::string statement,
uint32_t statementId, bool ipBanishment);
bool playerMoveThing(uint32_t playerId, const Position& fromPos, uint16_t spriteId,
int16_t fromStackpos, const Position& toPos, uint8_t count);
bool playerMoveCreature(uint32_t playerId, uint32_t movingCreatureId,
const Position& movingCreatureOrigPos, const Position& toPos);
bool playerMoveItem(uint32_t playerId, const Position& fromPos,
uint16_t spriteId, int16_t fromStackpos, const Position& toPos, uint8_t count);
bool playerMove(uint32_t playerId, Direction dir);
bool playerCreatePrivateChannel(uint32_t playerId);
bool playerChannelInvite(uint32_t playerId, const std::string& name);
bool playerChannelExclude(uint32_t playerId, const std::string& name);
bool playerRequestChannels(uint32_t playerId);
bool playerOpenChannel(uint32_t playerId, uint16_t channelId);
bool playerCloseChannel(uint32_t playerId, uint16_t channelId);
bool playerOpenPrivateChannel(uint32_t playerId, std::string& receiver);
bool playerCloseNpcChannel(uint32_t playerId);
bool playerProcessRuleViolation(uint32_t playerId, const std::string& name);
bool playerCloseRuleViolation(uint32_t playerId, const std::string& name);
bool playerCancelRuleViolation(uint32_t playerId);
bool playerReceivePing(uint32_t playerId);
bool playerAutoWalk(uint32_t playerId, std::list& listDir);
bool playerStopAutoWalk(uint32_t playerId);
bool playerUseItemEx(uint32_t playerId, const Position& fromPos, int16_t fromStackpos,
uint16_t fromSpriteId, const Position& toPos, int16_t toStackpos, uint16_t toSpriteId, bool isHotkey);
bool playerUseItem(uint32_t playerId, const Position& pos, int16_t stackpos,
uint8_t index, uint16_t spriteId, bool isHotkey);
bool playerUseBattleWindow(uint32_t playerId, const Position& fromPos,
int16_t fromStackpos, uint32_t creatureId, uint16_t spriteId, bool isHotkey);
bool playerCloseContainer(uint32_t playerId, uint8_t cid);
bool playerMoveUpContainer(uint32_t playerId, uint8_t cid);
bool playerUpdateContainer(uint32_t playerId, uint8_t cid);
bool playerUpdateTile(uint32_t playerId, const Position& pos);
bool playerRotateItem(uint32_t playerId, const Position& pos, int16_t stackpos, const uint16_t spriteId);
bool playerWriteItem(uint32_t playerId, uint32_t windowTextId, const std::string& text);
bool playerUpdateHouseWindow(uint32_t playerId, uint8_t listId, uint32_t windowTextId, const std::string& text);
bool playerRequestTrade(uint32_t playerId, const Position& pos, int16_t stackpos,
uint32_t tradePlayerId, uint16_t spriteId);
bool playerAcceptTrade(uint32_t playerId);
bool playerLookInTrade(uint32_t playerId, bool lookAtCounterOffer, int index);
bool playerPurchaseItem(uint32_t playerId, uint16_t spriteId, uint8_t count, uint8_t amount,
bool ignoreCap = false, bool inBackpacks = false);
bool playerSellItem(uint32_t playerId, uint16_t spriteId, uint8_t count, uint8_t amount);
bool playerCloseShop(uint32_t playerId);
bool playerLookInShop(uint32_t playerId, uint16_t spriteId, uint8_t count);
bool playerCloseTrade(uint32_t playerId);
bool playerSetAttackedCreature(uint32_t playerId, uint32_t creatureId);
bool playerFollowCreature(uint32_t playerId, uint32_t creatureId);
bool playerCancelAttackAndFollow(uint32_t playerId);
bool playerSetFightModes(uint32_t playerId, fightMode_t fightMode, chaseMode_t chaseMode, secureMode_t secureMode);
bool playerLookAt(uint32_t playerId, const Position& pos, uint16_t spriteId, int16_t stackpos);
bool playerQuests(uint32_t playerId);
bool playerQuestInfo(uint32_t playerId, uint16_t questId);
bool playerRequestAddVip(uint32_t playerId, const std::string& name);
bool playerRequestRemoveVip(uint32_t playerId, uint32_t guid);
bool playerTurn(uint32_t playerId, Direction dir);
bool playerRequestOutfit(uint32_t playerId);
bool playerSay(uint32_t playerId, uint16_t channelId, SpeakClasses type,
const std::string& receiver, const std::string& text);
bool playerChangeOutfit(uint32_t playerId, Outfit_t outfit);
bool playerInviteToParty(uint32_t playerId, uint32_t invitedId);
bool playerJoinParty(uint32_t playerId, uint32_t leaderId);
bool playerRevokePartyInvitation(uint32_t playerId, uint32_t invitedId);
bool playerPassPartyLeadership(uint32_t playerId, uint32_t newLeaderId);
bool playerLeaveParty(uint32_t playerId);
bool playerSharePartyExperience(uint32_t playerId, bool activate, uint8_t unknown);

void kickPlayer(uint32_t playerId, bool displayEffect);
bool broadcastMessage(const std::string& text, MessageClasses type);
void showHotkeyUseMessage(Player* player, Item* item);

int32_t getMotdId();
void loadMotd();
void loadPlayersRecord();
void checkPlayersRecord(Player* player);

bool reloadInfo(ReloadInfo_t reload, uint32_t playerId = 0);
void cleanup();
void shutdown();
void freeThing(Thing* thing);

bool canThrowObjectTo(const Position& fromPos, const Position& toPos, bool checkLineOfSight = true,
int32_t rangex = Map::maxClientViewportX, int32_t rangey = Map::maxClientViewportY);
bool isSightClear(const Position& fromPos, const Position& toPos, bool sameFloor);

bool getPathTo(const Creature* creature, const Position& destPos,
std::list& listDir, int32_t maxSearchDist /*= -1*/);

bool getPathToEx(const Creature* creature, const Position& targetPos, std::list& dirList,
const FindPathParams& fpp);

bool getPathToEx(const Creature* creature, const Position& targetPos, std::list& dirList,
uint32_t minTargetDist, uint32_t maxTargetDist, bool fullPathSearch = true,
bool clearSight = true, int32_t maxSearchDist = -1);

Position getClosestFreeTile(Creature* creature, Position pos, bool extended = false, bool ignoreHouse = true);
std::string getSearchString(const Position fromPos, const Position toPos, bool fromIsCreature = false, bool toIsCreature = false);

void changeLight(const Creature* creature);
void changeSpeed(Creature* creature, int32_t varSpeedDelta);
void internalCreatureChangeOutfit(Creature* creature, const Outfit_t& oufit, bool forced = false);
void internalCreatureChangeVisible(Creature* creature, Visible_t visible);
void updateCreatureSkull(Creature* creature);
void sendPublicSquare(Player* sender, SquareColor_t color);

GameState_t getGameState() const {return gameState;}
void setGameState(GameState_t newState);

void saveGameState(bool shallow);
void loadGameState();

void cleanMap(uint32_t& count);
void refreshMap(RefreshTiles::iterator* it = NULL, uint32_t limit = 0);
void proceduralRefresh(RefreshTiles::iterator* it = NULL);

void addTrash(Position pos) {trash.push_back(pos);}
void addRefreshTile(Tile* tile, RefreshBlock_t rb) {refreshTiles[tile] = rb;}

//Events
void checkCreatureWalk(uint32_t creatureId);
void updateCreatureWalk(uint32_t creatureId);
void checkCreatureAttack(uint32_t creatureId);
void checkCreatures();
void checkLight();

bool combatBlockHit(CombatType_t combatType, Creature* attacker, Creature* target,
int32_t& healthChange, bool checkDefense, bool checkArmor);

bool combatChangeHealth(CombatType_t combatType, Creature* attacker, Creature* target, int32_t healthChange,
MagicEffect_t hitEffect = MAGIC_EFFECT_UNKNOWN, TextColor_t hitColor = TEXTCOLOR_UNKNOWN, bool force = false);
bool combatChangeMana(Creature* attacker, Creature* target, int32_t manaChange);

//animation help functions
void addCreatureHealth(const Creature* target);
void addCreatureHealth(const SpectatorVec& list, const Creature* target);
void addAnimatedText(const Position& pos, uint8_t textColor, const std::string& text);
void addAnimatedText(const SpectatorVec& list, const Position& pos, uint8_t textColor, const std::string& text);
void addMagicEffect(const Position& pos, uint16_t effect, bool ghostMode = false);
void addMagicEffect(const SpectatorVec& list, const Position& pos, uint8_t effect, bool ghostMode = false);
void addDistanceEffect(const SpectatorVec& list, const Position& fromPos, const Position& toPos, uint8_t effect);
void addDistanceEffect(const Position& fromPos, const Position& toPos, uint8_t effect);

const RuleViolationsMap& getRuleViolations() const {return ruleViolations;}
bool cancelRuleViolation(Player* player);
bool closeRuleViolation(Player* player);

std::vector blacklist;
bool fetchBlacklist();

bool loadExperienceStages();
double getExperienceStage(uint32_t level, double divider = 1.);

inline StageList::const_iterator getFirstStage() const {return stages.begin();}
inline StageList::const_iterator getLastStage() const {return stages.end();}
size_t getStagesCount() const {return stages.size();}

void setGlobalSaveMessage(int16_t key, bool value) {globalSaveMessage[key] = value;}
bool getGlobalSaveMessage(int16_t key) const {return globalSaveMessage[key];}

Map* getMap() {return map;}
const Map* getMap() const {return map;}

int32_t getLightHour() {return lightHour;}
void startDecay(Item* item);

protected:
bool playerWhisper(Player* player, const std::string& text);
bool playerYell(Player* player, const std::string& text);
bool playerSpeakTo(Player* player, SpeakClasses type, const std::string& receiver, const std::string& text);
bool playerTalkToChannel(Player* player, SpeakClasses type, const std::string& text, uint16_t channelId);
bool playerSpeakToNpc(Player* player, const std::string& text);
bool playerReportRuleViolation(Player* player, const std::string& text);
bool playerContinueReport(Player* player, const std::string& text);

struct GameEvent
{
int64_t tick;
int32_t type;
void* data;
};

std::vector releaseThings;
std::map tradeItems;
AutoList autoList;
RuleViolationsMap ruleViolations;

size_t checkCreatureLastIndex;
std::vector checkCreatureVectors[EVENT_CREATURECOUNT];
std::vector toAddCheckCreatureVector;

void checkDecay();
void internalDecayItem(Item* item);

typedef std::list DecayList;
DecayList decayItems[EVENT_DECAYBUCKETS];
DecayList toDecayItems;
size_t lastBucket;

static const int32_t LIGHT_LEVEL_DAY = 250;
static const int32_t LIGHT_LEVEL_NIGHT = 40;
static const int32_t SUNSET = 1305;
static const int32_t SUNRISE = 430;
int32_t lightLevel, lightHour, lightHourDelta;
LightState_t lightState;

GameState_t gameState;
WorldType_t worldType;

ServiceManager* services;
Map* map;

std::string lastMotd;
int32_t lastMotdId;
uint32_t playersRecord;
uint32_t checkLightEvent, checkCreatureEvent, checkDecayEvent, saveEvent;
bool globalSaveMessage[2];

RefreshTiles refreshTiles;
Trash trash;

StageList stages;
uint32_t lastStageLevel;

Highscore highscoreStorage[9];
time_t lastHighscoreCheck;
};
#endif

*>*>*>*,>*>,>,>*,>,>

 

protocolgame.h

 

 

////////////////////////////////////////////////////////////////////////
// OpenTibia - an opensource roleplaying game
////////////////////////////////////////////////////////////////////////
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
////////////////////////////////////////////////////////////////////////

#ifndef __PROTOCOLGAME__
#define __PROTOCOLGAME__

#include "otsystem.h"
#include "enums.h"

#include "protocol.h"
#include "creature.h"

class NetworkMessage;
class Player;
class Game;
class House;
class Container;
class Tile;
class Connection;
class Quest;

typedef boost::shared_ptr NetworkMessage_ptr;
class ProtocolGame : public Protocol
{
public:
#ifdef __ENABLE_SERVER_DIAGNOSTIC__
static uint32_t protocolGameCount;
#endif
ProtocolGame(Connection_ptr connection): Protocol(connection)
{
#ifdef __ENABLE_SERVER_DIAGNOSTIC__
protocolGameCount++;
#endif
player = NULL;
m_eventConnect = 0;
m_debugAssertSent = m_acceptPackets = false;
}

virtual ~ProtocolGame()
{
#ifdef __ENABLE_SERVER_DIAGNOSTIC__
protocolGameCount--;
#endif
player = NULL;
}

enum {protocolId = 0x0A};
enum {isSingleSocket = true};
enum {hasChecksum = true};
static const char* protocolName() {return "game protocol";}

bool login(const std::string& name, uint32_t id, const std::string& password,
OperatingSystem_t operatingSystem, uint16_t version, bool gamemaster);
bool logout(bool displayEffect, bool forceLogout);

void setPlayer(Player* p);

private:
void disconnectClient(uint8_t error, const char* message);

std::list knownCreatureList;
void checkCreatureAsKnown(uint32_t id, bool& known, uint32_t& removedKnown);

bool connect(uint32_t playerId, OperatingSystem_t operatingSystem, uint16_t version);
void disconnect();

virtual void releaseProtocol();
virtual void deleteProtocolTask();

bool canSee(uint16_t x, uint16_t y, uint16_t z) const;
bool canSee(const Creature*) const;
bool canSee(const Position& pos) const;

virtual void onConnect();
virtual void onRecvFirstMessage(NetworkMessage& msg);

bool parseFirstPacket(NetworkMessage& msg);
virtual void parsePacket(NetworkMessage& msg);

//Parse methods
void parseLogout(NetworkMessage& msg);
void parseCancelMove(NetworkMessage& msg);

void parseReceivePing(NetworkMessage& msg);
void parseAutoWalk(NetworkMessage& msg);
void parseMove(NetworkMessage& msg, Direction dir);
void parseTurn(NetworkMessage& msg, Direction dir);

void parseRequestOutfit(NetworkMessage& msg);
void parseSetOutfit(NetworkMessage& msg);
void parseSay(NetworkMessage& msg);
void parseLookAt(NetworkMessage& msg);
void parseFightModes(NetworkMessage& msg);
void parseAttack(NetworkMessage& msg);
void parseFollow(NetworkMessage& msg);

void parseBugReport(NetworkMessage& msg);
void parseDebugAssert(NetworkMessage& msg);

void parseThrow(NetworkMessage& msg);
void parseUseItemEx(NetworkMessage& msg);
void parseBattleWindow(NetworkMessage& msg);
void parseUseItem(NetworkMessage& msg);
void parseCloseContainer(NetworkMessage& msg);
void parseUpArrowContainer(NetworkMessage& msg);
void parseUpdateTile(NetworkMessage& msg);
void parseUpdateContainer(NetworkMessage& msg);
void parseTextWindow(NetworkMessage& msg);
void parseHouseWindow(NetworkMessage& msg);

void parseLookInShop(NetworkMessage& msg);
void parsePlayerPurchase(NetworkMessage& msg);
void parsePlayerSale(NetworkMessage& msg);
void parseCloseShop(NetworkMessage& msg);

void parseQuests(NetworkMessage& msg);
void parseQuestInfo(NetworkMessage& msg);

void parseInviteToParty(NetworkMessage& msg);
void parseJoinParty(NetworkMessage& msg);
void parseRevokePartyInvite(NetworkMessage& msg);
void parsePassPartyLeadership(NetworkMessage& msg);
void parseLeaveParty(NetworkMessage& msg);
void parseSharePartyExperience(NetworkMessage& msg);

//trade methods
void parseRequestTrade(NetworkMessage& msg);
void parseLookInTrade(NetworkMessage& msg);
void parseAcceptTrade(NetworkMessage& msg);
void parseCloseTrade();

//VIP methods
void parseAddVip(NetworkMessage& msg);
void parseRemoveVip(NetworkMessage& msg);

void parseRotateItem(NetworkMessage& msg);

//Channel tabs
void parseCreatePrivateChannel(NetworkMessage& msg);
void parseChannelInvite(NetworkMessage& msg);
void parseChannelExclude(NetworkMessage& msg);
void parseGetChannels(NetworkMessage& msg);
void parseOpenChannel(NetworkMessage& msg);
void parseOpenPriv(NetworkMessage& msg);
void parseCloseChannel(NetworkMessage& msg);
void parseCloseNpc(NetworkMessage& msg);
void parseProcessRuleViolation(NetworkMessage& msg);
void parseCloseRuleViolation(NetworkMessage& msg);
void parseCancelRuleViolation(NetworkMessage& msg);

//Send functions
void sendChannelMessage(std::string author, std::string text, SpeakClasses type, uint8_t channel);
void sendClosePrivate(uint16_t channelId);
void sendCreatePrivateChannel(uint16_t channelId, const std::string& channelName);
void sendChannelsDialog();
void sendChannel(uint16_t channelId, const std::string& channelName);
void sendRuleViolationsChannel(uint16_t channelId);
void sendOpenPrivateChannel(const std::string& receiver);
void sendToChannel(const Creature* creature, SpeakClasses type, const std::string& text, uint16_t channelId, uint32_t time = 0);
void sendRemoveReport(const std::string& name);
void sendLockRuleViolation();
void sendRuleViolationCancel(const std::string& name);
void sendIcons(int32_t icons);
void sendFYIBox(const std::string& message);

void sendDistanceShoot(const Position& from, const Position& to, uint8_t type);
void sendMagicEffect(const Position& pos, uint16_t type);
void sendAnimatedText(const Position& pos, uint8_t color, std::string text);
void sendCreatureHealth(const Creature* creature);
void sendSkills();
void sendPing();
void sendCreatureTurn(const Creature* creature, int16_t stackpos);
void sendCreatureSay(const Creature* creature, SpeakClasses type, const std::string& text, Position* pos = NULL);

void sendCancel(const std::string& message);
void sendCancelWalk();
void sendChangeSpeed(const Creature* creature, uint32_t speed);
void sendCancelTarget();
void sendCreatureOutfit(const Creature* creature, const Outfit_t& outfit);
void sendStats();
void sendTextMessage(MessageClasses mclass, const std::string& message);
void sendReLoginWindow();

void sendTutorial(uint8_t tutorialId);
void sendAddMarker(const Position& pos, MapMarks_t markType, const std::string& desc);

void sendCreatureSkull(const Creature* creature);
void sendCreatureShield(const Creature* creature);

void sendShop(const ShopInfoList& shop);
void sendCloseShop();
void sendGoods(const ShopInfoList& shop);
void sendTradeItemRequest(const Player* player, const Item* item, bool ack);
void sendCloseTrade();

void sendTextWindow(uint32_t windowTextId, Item* item, uint16_t maxLen, bool canWrite);
void sendTextWindow(uint32_t windowTextId, uint32_t itemId, const std::string& text);
void sendHouseWindow(uint32_t windowTextId, House* house, uint32_t listId, const std::string& text);

void sendOutfitWindow();
void sendQuests();
void sendQuestInfo(Quest* quest);

void sendVIPLogIn(uint32_t guid);
void sendVIPLogOut(uint32_t guid);
void sendVIP(uint32_t guid, const std::string& name, bool isOnline);

void sendCreatureLight(const Creature* creature);
void sendWorldLight(const LightInfo& lightInfo);

void sendCreatureSquare(const Creature* creature, SquareColor_t color);

//tiles
void sendAddTileItem(const Tile* tile, const Position& pos, uint32_t stackpos, const Item* item);
void sendUpdateTileItem(const Tile* tile, const Position& pos, uint32_t stackpos, const Item* item);
void sendRemoveTileItem(const Tile* tile, const Position& pos, uint32_t stackpos);
void sendUpdateTile(const Tile* tile, const Position& pos);

void sendAddCreature(const Creature* creature, const Position& pos, uint32_t stackpos);
void sendRemoveCreature(const Creature* creature, const Position& pos, uint32_t stackpos);
void sendMoveCreature(const Creature* creature, const Tile* newTile, const Position& newPos, uint32_t newStackPos,
const Tile* oldTile, const Position& oldPos, uint32_t oldStackpos, bool teleport);

//containers
void sendAddContainerItem(uint8_t cid, const Item* item);
void sendUpdateContainerItem(uint8_t cid, uint8_t slot, const Item* item);
void sendRemoveContainerItem(uint8_t cid, uint8_t slot);

void sendContainer(uint32_t cid, const Container* container, bool hasParent);
void sendCloseContainer(uint32_t cid);

//inventory
void sendAddInventoryItem(slots_t slot, const Item* item);
void sendUpdateInventoryItem(slots_t slot, const Item* item);
void sendRemoveInventoryItem(slots_t slot);

//Help functions

// translate a tile to clientreadable format
void GetTileDescription(const Tile* tile, NetworkMessage_ptr msg);

// translate a floor to clientreadable format
void GetFloorDescription(NetworkMessage_ptr msg, int32_t x, int32_t y, int32_t z,
int32_t width, int32_t height, int32_t offset, int32_t& skip);

// translate a map area to clientreadable format
void GetMapDescription(int32_t x, int32_t y, int32_t z,
int32_t width, int32_t height, NetworkMessage_ptr msg);

void AddMapDescription(NetworkMessage_ptr msg, const Position& pos);
void AddTextMessage(NetworkMessage_ptr msg, MessageClasses mclass, const std::string& message);
void AddAnimatedText(NetworkMessage_ptr msg, const Position& pos, uint8_t color, const std::string& text);
void AddMagicEffect(NetworkMessage_ptr msg, const Position& pos, uint16_t type);
void AddDistanceShoot(NetworkMessage_ptr msg, const Position& from, const Position& to, uint8_t type);
void AddCreature(NetworkMessage_ptr msg, const Creature* creature, bool known, uint32_t remove);
void AddPlayerStats(NetworkMessage_ptr msg);
void AddCreatureSpeak(NetworkMessage_ptr msg, const Creature* creature, SpeakClasses type,
std::string text, uint16_t channelId, uint32_t time = 0, Position* pos = NULL);
void AddCreatureHealth(NetworkMessage_ptr msg, const Creature* creature);
void AddCreatureOutfit(NetworkMessage_ptr msg, const Creature* creature, const Outfit_t& outfit, bool outfitWindow = false);
void AddPlayerSkills(NetworkMessage_ptr msg);
void AddWorldLight(NetworkMessage_ptr msg, const LightInfo& lightInfo);
void AddCreatureLight(NetworkMessage_ptr msg, const Creature* creature);

//tiles
void AddTileItem(NetworkMessage_ptr msg, const Position& pos, uint32_t stackpos, const Item* item);
void AddTileCreature(NetworkMessage_ptr msg, const Position& pos, uint32_t stackpos, const Creature* creature);
void UpdateTileItem(NetworkMessage_ptr msg, const Position& pos, uint32_t stackpos, const Item* item);
void RemoveTileItem(NetworkMessage_ptr msg, const Position& pos, uint32_t stackpos);

void MoveUpCreature(NetworkMessage_ptr msg, const Creature* creature,
const Position& newPos, const Position& oldPos, uint32_t oldStackpos);
void MoveDownCreature(NetworkMessage_ptr msg, const Creature* creature,
const Position& newPos, const Position& oldPos, uint32_t oldStackpos);

//container
void AddContainerItem(NetworkMessage_ptr msg, uint8_t cid, const Item* item);
void UpdateContainerItem(NetworkMessage_ptr msg, uint8_t cid, uint8_t slot, const Item* item);
void RemoveContainerItem(NetworkMessage_ptr msg, uint8_t cid, uint8_t slot);

//inventory
void AddInventoryItem(NetworkMessage_ptr msg, slots_t slot, const Item* item);
void UpdateInventoryItem(NetworkMessage_ptr msg, slots_t slot, const Item* item);
void RemoveInventoryItem(NetworkMessage_ptr msg, slots_t slot);

//rule violation window
void parseViolationWindow(NetworkMessage& msg);

//shop
void AddShopItem(NetworkMessage_ptr msg, const ShopInfo item);

#define addGameTask(f, ...) addGameTaskInternal(0, boost::bind(f, &g_game, __VA_ARGS__))
#define addGameTaskTimed(delay, f, ...) addGameTaskInternal(delay, boost::bind(f, &g_game, __VA_ARGS__))
template
void addGameTaskInternal(uint32_t delay, const FunctionType&);

friend class Player;
Player* player;

uint32_t m_eventConnect;
bool m_debugAssertSent, m_acceptPackets;
};
#endif

 

 

player.h

 

 

////////////////////////////////////////////////////////////////////////
// OpenTibia - an opensource roleplaying game
////////////////////////////////////////////////////////////////////////
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
////////////////////////////////////////////////////////////////////////

#ifndef __PLAYER__
#define __PLAYER__

#include "otsystem.h"
#include "enums.h"

#include "creature.h"
#include "cylinder.h"

#include "container.h"
#include "depot.h"

#include "outfit.h"
#include "vocation.h"
#include "group.h"

#include "protocolgame.h"
#include "ioguild.h"
#include "party.h"
#include "npc.h"

class House;
class NetworkMessage;
class Weapon;
class ProtocolGame;
class Npc;
class Party;
class SchedulerTask;
class Quest;

enum skillsid_t
{
SKILL_LEVEL = 0,
SKILL_TRIES = 1,
SKILL_PERCENT = 2
};

enum playerinfo_t
{
PLAYERINFO_LEVEL,
PLAYERINFO_LEVELPERCENT,
PLAYERINFO_HEALTH,
PLAYERINFO_MAXHEALTH,
PLAYERINFO_MANA,
PLAYERINFO_MAXMANA,
PLAYERINFO_MAGICLEVEL,
PLAYERINFO_MAGICLEVELPERCENT,
PLAYERINFO_SOUL,
};

enum freeslot_t
{
SLOT_TYPE_NONE,
SLOT_TYPE_INVENTORY,
SLOT_TYPE_CONTAINER
};

enum chaseMode_t
{
CHASEMODE_STANDSTILL,
CHASEMODE_FOLLOW,
};

enum fightMode_t
{
FIGHTMODE_ATTACK,
FIGHTMODE_BALANCED,
FIGHTMODE_DEFENSE
};

enum secureMode_t
{
SECUREMODE_ON,
SECUREMODE_OFF
};

enum tradestate_t
{
TRADE_NONE,
TRADE_INITIATED,
TRADE_ACCEPT,
TRADE_ACKNOWLEDGE,
TRADE_TRANSFER
};

enum AccountManager_t
{
MANAGER_NONE,
MANAGER_NEW,
MANAGER_ACCOUNT,
MANAGER_NAMELOCK
};

enum GamemasterCondition_t
{
GAMEMASTER_INVISIBLE = 0,
GAMEMASTER_IGNORE = 1,
GAMEMASTER_TELEPORT = 2
};

enum Exhaust_t
{
EXHAUST_COMBAT = 1,
EXHAUST_HEALING = 2
};

typedef std::set VIPListSet;
typedef std::vector > ContainerVector;
typedef std::map > DepotMap;
typedef std::map MuteCountMap;
typedef std::list LearnedInstantSpellList;
typedef std::list InvitedToGuildsList;
typedef std::list PartyList;

#define SPEED_MAX 1500
#define SPEED_MIN 10
#define STAMINA_MAX (42 * 60 * 60 * 1000)
#define STAMINA_MULTIPLIER (60 * 1000)

class Player : public Creature, public Cylinder
{
public:
#ifdef __ENABLE_SERVER_DIAGNOSTIC__
static uint32_t playerCount;
#endif
Player(const std::string& name, ProtocolGame* p);
virtual ~Player();

virtual Player* getPlayer() {return this;}
virtual const Player* getPlayer() const {return this;}

static MuteCountMap muteCountMap;

virtual const std::string& getName() const {return name;}
virtual const std::string& getNameDescription() const {return nameDescription;}
virtual std::string getDescription(int32_t lookDistance) const;

const std::string& getSpecialDescription() const {return specialDescription;}
void setSpecialDescription(const std::string& desc) {specialDescription = desc;}

void manageAccount(const std::string& text);
bool isAccountManager() const {return (accountManager != MANAGER_NONE);}
void kickPlayer(bool displayEffect, bool forceLogout);

void setGUID(uint32_t _guid) {guid = _guid;}
uint32_t getGUID() const {return guid;}

static AutoList autoList;
virtual uint32_t rangeId() {return 0x10000000;}

void addList();
void removeList();

static uint64_t getExpForLevel(uint32_t lv)
{
lv--;
return ((50ULL * lv * lv * lv) - (150ULL * lv * lv) + (400ULL * lv)) / 3ULL;
}

uint32_t getPromotionLevel() const {return promotionLevel;}
void setPromotionLevel(uint32_t pLevel);

bool changeOutfit(Outfit_t outfit, bool checkList);
void hasRequestedOutfit(bool v) {requestedOutfit = v;}

Vocation* getVocation() const {return vocation;}
int32_t getPlayerInfo(playerinfo_t playerinfo) const;

void setParty(Party* _party) {party = _party;}
Party* getParty() const {return party;}
PartyShields_t getPartyShield(const Creature* creature) const;
bool isInviting(const Player* player) const;
bool isPartner(const Player* player) const;
void sendPlayerPartyIcons(Player* player);
bool addPartyInvitation(Party* party);
bool removePartyInvitation(Party* party);
void clearPartyInvitations();

uint32_t getGuildId() const {return guildId;}
void setGuildId(uint32_t newId) {guildId = newId;}
uint32_t getRankId() const {return rankId;}
void setRankId(uint32_t newId) {rankId = newId;}

GuildLevel_t getGuildLevel() const {return guildLevel;}
bool setGuildLevel(GuildLevel_t newLevel, uint32_t rank = 0);

const std::string& getGuildName() const {return guildName;}
void setGuildName(const std::string& newName) {guildName = newName;}
const std::string& getRankName() const {return rankName;}
void setRankName(const std::string& newName) {rankName = newName;}

const std::string& getGuildNick() const {return guildNick;}
void setGuildNick(const std::string& newNick) {guildNick = newNick;}

bool isGuildInvited(uint32_t guildId) const;
void leaveGuild();

void setFlags(uint64_t flags) {if(group) group->setFlags(flags);}
bool hasFlag(PlayerFlags value) const {return group != NULL && group->hasFlag(value);}
void setCustomFlags(uint64_t flags) {if(group) group->setCustomFlags(flags);}
bool hasCustomFlag(PlayerCustomFlags value) const {return group != NULL && group->hasCustomFlag(value);}

void addBlessing(int16_t blessing) {blessings += blessing;}
bool hasBlessing(int16_t value) const {return (blessings & ((int16_t)1 << value));}
uint16_t getBlessings() const;

OperatingSystem_t getOperatingSystem() const {return operatingSystem;}
void setOperatingSystem(OperatingSystem_t clientOs) {operatingSystem = clientOs;}
uint32_t getClientVersion() const {return clientVersion;}
void setClientVersion(uint32_t version) {clientVersion = version;}

bool hasClient() const {return client;}
bool isVirtual() const {return (getID() == 0);}
void disconnect() {if(client) client->disconnect();}
uint32_t getIP() const;
bool canOpenCorpse(uint32_t ownerId);

Container* getContainer(uint32_t cid);
int32_t getContainerID(const Container* container) const;

void addContainer(uint32_t cid, Container* container);
void closeContainer(uint32_t cid);

virtual bool setStorage(const uint32_t key, const std::string& value);
virtual void eraseStorage(const uint32_t key);

void generateReservedStorage();
bool transferMoneyTo(const std::string& name, uint64_t amount);
void increaseCombatValues(int32_t& min, int32_t& max, bool useCharges, bool countWeapon);

void setGroupId(int32_t newId);
int32_t getGroupId() const {return groupId;}
void setGroup(Group* newGroup);
Group* getGroup() const {return group;}

virtual bool isGhost() const {return hasCondition(CONDITION_GAMEMASTER, GAMEMASTER_INVISIBLE) || hasFlag(PlayerFlag_CannotBeSeen);}

void switchSaving() {saving = !saving;}
bool isSaving() const {return saving;}

uint32_t getIdleTime() const {return idleTime;}
void setIdleTime(uint32_t amount) {idleTime = amount;}

bool checkLoginDelay(uint32_t playerId) const;
bool isTrading() const {return tradePartner;}

uint32_t getAccount() const {return accountId;}
std::string getAccountName() const {return account;}
uint16_t getAccess() const {return group ? group->getAccess() : 0;}
uint16_t getGhostAccess() const {return group ? group->getGhostAccess() : 0;}

bool isPremium() const;
int32_t getPremiumDays() const {return premiumDays;}

uint32_t getLevel() const {return level;}
uint64_t getExperience() const {return experience;}
uint32_t getMagicLevel() const {return getPlayerInfo(PLAYERINFO_MAGICLEVEL);}
uint64_t getSpentMana() const {return manaSpent;}

uint32_t getVocationId() const {return vocation_id;}
void setVocation(uint32_t vocId);
uint16_t getSex(bool full) const {return full ? sex : sex % 2;}
void setSex(uint16_t);

uint64_t getStamina() const {return hasFlag(PlayerFlag_HasInfiniteStamina) ? STAMINA_MAX : stamina;}
void setStamina(uint64_t value) {stamina = std::min((uint64_t)STAMINA_MAX, (uint64_t)std::max((uint64_t)0, value));}
uint32_t getStaminaMinutes() const {return (uint32_t)(getStamina() / (uint64_t)STAMINA_MULTIPLIER);}
void setStaminaMinutes(uint32_t value) {setStamina((uint64_t)(value * STAMINA_MULTIPLIER));}
void useStamina(int64_t value) {stamina = std::min((int64_t)STAMINA_MAX, (int64_t)std::max((int64_t)0, ((int64_t)stamina + value)));}
uint64_t getSpentStamina() {return (uint64_t)STAMINA_MAX - stamina;}

int64_t getLastLoad() const {return lastLoad;}
time_t getLastLogin() const {return lastLogin;}
time_t getLastLogout() const {return lastLogout;}

Position getLoginPosition() const {return loginPosition;}

uint32_t getTown() const {return town;}
void setTown(uint32_t _town) {town = _town;}

virtual bool isPushable() const;
virtual int32_t getThrowRange() const {return 1;}

bool isMuted(uint16_t channelId, SpeakClasses type, uint32_t& time);
void addMessageBuffer();
void removeMessageBuffer();

double getCapacity() const {return capacity;}
void setCapacity(double newCapacity) {capacity = newCapacity;}

double getFreeCapacity() const
{
if(hasFlag(PlayerFlag_CannotPickupItem))
return 0.00;
else if(hasFlag(PlayerFlag_HasInfiniteCapacity))
return 10000.00;

return std::max(0.00, capacity - inventoryWeight);
}

virtual int32_t getSoul() const {return getPlayerInfo(PLAYERINFO_SOUL);}
virtual int32_t getMaxHealth() const {return getPlayerInfo(PLAYERINFO_MAXHEALTH);}
virtual int32_t getMaxMana() const {return getPlayerInfo(PLAYERINFO_MAXMANA);}
int32_t getSoulMax() const {return soulMax;}

Item* getInventoryItem(slots_t slot) const;
Item* getEquippedItem(slots_t slot) const;

bool isItemAbilityEnabled(slots_t slot) const {return inventoryAbilities[slot];}
void setItemAbility(slots_t slot, bool enabled) {inventoryAbilities[slot] = enabled;}

int32_t getVarSkill(skills_t skill) const {return varSkills[skill];}
void setVarSkill(skills_t skill, int32_t modifier) {varSkills[skill] += modifier;}

int32_t getVarStats(stats_t stat) const {return varStats[stat];}
void setVarStats(stats_t stat, int32_t modifier);
int32_t getDefaultStats(stats_t stat);

void setConditionSuppressions(uint32_t conditions, bool remove);

uint32_t getLossPercent(lossTypes_t lossType) const {return lossPercent[lossType];}
void setLossPercent(lossTypes_t lossType, uint32_t newPercent) {lossPercent[lossType] = newPercent;}

Depot* getDepot(uint32_t depotId, bool autoCreateDepot);
bool addDepot(Depot* depot, uint32_t depotId);
void useDepot(uint32_t depotId, bool value);

virtual bool canSee(const Position& pos) const;
virtual bool canSeeCreature(const Creature* creature) const;
virtual bool canWalkthrough(const Creature* creature) const;

virtual bool canSeeInvisibility() const {return hasFlag(PlayerFlag_CanSenseInvisibility);}

virtual RaceType_t getRace() const {return RACE_BLOOD;}

//safe-trade functions
void setTradeState(tradestate_t state) {tradeState = state;}
tradestate_t getTradeState() {return tradeState;}
Item* getTradeItem() {return tradeItem;}

//shop functions
void setShopOwner(Npc* owner, int32_t onBuy, int32_t onSell, ShopInfoList offer)
{
shopOwner = owner;
purchaseCallback = onBuy;
saleCallback = onSell;
shopOffer = offer;
}

Npc* getShopOwner(int32_t& onBuy, int32_t& onSell)
{
onBuy = purchaseCallback;
onSell = saleCallback;
return shopOwner;
}

const Npc* getShopOwner(int32_t& onBuy, int32_t& onSell) const
{
onBuy = purchaseCallback;
onSell = saleCallback;
return shopOwner;
}

//V.I.P. functions
void notifyLogIn(Player* loginPlayer);
void notifyLogOut(Player* logoutPlayer);
bool removeVIP(uint32_t guid);
bool addVIP(uint32_t guid, std::string& name, bool isOnline, bool internal = false);

//follow functions
virtual bool setFollowCreature(Creature* creature, bool fullPathSearch = false);

//follow events
virtual void onFollowCreature(const Creature* creature);

//walk events
virtual void onWalk(Direction& dir);
virtual void onWalkAborted();
virtual void onWalkComplete();

void stopWalk();
void openShopWindow();
void closeShopWindow(Npc* npc = NULL, int32_t onBuy = -1, int32_t onSell = -1);
bool canShopItem(uint16_t itemId, uint8_t subType, ShopEvent_t event);

void setChaseMode(chaseMode_t mode);
void setFightMode(fightMode_t mode) {fightMode = mode;}
void setSecureMode(secureMode_t mode) {secureMode = mode;}
secureMode_t getSecureMode() const {return secureMode;}

//combat functions
virtual bool setAttackedCreature(Creature* creature);
bool isImmune(CombatType_t type) const;
bool isImmune(ConditionType_t type) const;
bool hasShield() const;
virtual bool isAttackable() const;

virtual void changeHealth(int32_t healthChange);
virtual void changeMana(int32_t manaChange);
void changeSoul(int32_t soulChange);

bool isPzLocked() const {return pzLocked;}
void setPzLocked(bool v) {pzLocked = v;}
virtual BlockType_t blockHit(Creature* attacker, CombatType_t combatType, int32_t& damage,
bool checkDefense = false, bool checkArmor = false);
virtual void doAttacking(uint32_t interval);
virtual bool hasExtraSwing() {return lastAttack > 0 && ((OTSYS_TIME() - lastAttack) >= getAttackSpeed());}
int32_t getShootRange() const {return shootRange;}

int32_t getSkill(skills_t skilltype, skillsid_t skillinfo) const;
bool getAddAttackSkill() const {return addAttackSkillPoint;}
BlockType_t getLastAttackBlockType() const {return lastAttackBlockType;}

Item* getWeapon(bool ignoreAmmo = false);
virtual WeaponType_t getWeaponType();
int32_t getWeaponSkill(const Item* item) const;
void getShieldAndWeapon(const Item* &shield, const Item* &weapon) const;

virtual void drainHealth(Creature* attacker, CombatType_t combatType, int32_t damage);
virtual void drainMana(Creature* attacker, CombatType_t combatType, int32_t damage);

void addExperience(uint64_t exp);
void removeExperience(uint64_t exp, bool updateStats = true);
void addManaSpent(uint64_t amount, bool useMultiplier = true);
void addSkillAdvance(skills_t skill, uint32_t count, bool useMultiplier = true);
bool addUnjustifiedKill(const Player* attacked);

virtual int32_t getArmor() const;
virtual int32_t getDefense() const;
virtual float getAttackFactor() const;
virtual float getDefenseFactor() const;

void addExhaust(uint32_t ticks, Exhaust_t type);
void addInFightTicks(bool pzLock = false);
void addDefaultRegeneration(uint32_t addTicks);

virtual double getGainedExperience(Creature* attacker) const;

//combat event functions
virtual void onAddCondition(ConditionType_t type, bool hadCondition);
virtual void onAddCombatCondition(ConditionType_t type, bool hadCondition);
virtual void onEndCondition(ConditionType_t type);
virtual void onCombatRemoveCondition(const Creature* attacker, Condition* condition);
virtual void onTickCondition(ConditionType_t type, int32_t interval, bool& _remove);
virtual void onAttackedCreature(Creature* target);
virtual void onSummonAttackedCreature(Creature* summon, Creature* target);
virtual void onAttacked();
virtual void onAttackedCreatureDrain(Creature* target, int32_t points);
virtual void onSummonAttackedCreatureDrain(Creature* summon, Creature* target, int32_t points);
virtual void onTargetCreatureGainHealth(Creature* target, int32_t points);
virtual bool onKilledCreature(Creature* target, uint32_t& flags);
virtual void onGainExperience(double& gainExp, bool fromMonster, bool multiplied);
virtual void onGainSharedExperience(double& gainExp, bool fromMonster, bool multiplied);
virtual void onAttackedCreatureBlockHit(Creature* target, BlockType_t blockType);
virtual void onBlockHit(BlockType_t blockType);
virtual void onChangeZone(ZoneType_t zone);
virtual void onAttackedCreatureChangeZone(ZoneType_t zone);
virtual void onIdleStatus();
virtual void onPlacedCreature();

virtual void getCreatureLight(LightInfo& light) const;
Skulls_t getSkull() const;
Skulls_t getSkullClient(const Creature* creature) const;

bool hasAttacked(const Player* attacked) const;
void addAttacked(const Player* attacked);
void clearAttacked() {attackedSet.clear();}

time_t getSkullEnd() const {return skullEnd;}
void setSkullEnd(time_t _time, bool login, Skulls_t _skull);

bool addOutfit(uint32_t outfitId, uint32_t addons);
bool removeOutfit(uint32_t outfitId, uint32_t addons);

bool canWearOutfit(uint32_t outfitId, uint32_t addons);
bool canLogout(bool checkInfight);

//tile
//send methods
void sendAddTileItem(const Tile* tile, const Position& pos, const Item* item)
{if(client) client->sendAddTileItem(tile, pos, tile->getClientIndexOfThing(this, item), item);}
void sendUpdateTileItem(const Tile* tile, const Position& pos, const Item* oldItem, const Item* newItem)
{if(client) client->sendUpdateTileItem(tile, pos, tile->getClientIndexOfThing(this, oldItem), newItem);}
void sendRemoveTileItem(const Tile* tile, const Position& pos, uint32_t stackpos, const Item* item)
{if(client) client->sendRemoveTileItem(tile, pos, stackpos);}
void sendUpdateTile(const Tile* tile, const Position& pos)
{if(client) client->sendUpdateTile(tile, pos);}

void sendChannelMessage(std::string author, std::string text, SpeakClasses type, uint8_t channel)
{if(client) client->sendChannelMessage(author, text, type, channel);}
void sendCreatureAppear(const Creature* creature)
{if(client) client->sendAddCreature(creature, creature->getPosition(), creature->getTile()->getClientIndexOfThing(
this, creature));}
void sendCreatureDisappear(const Creature* creature, uint32_t stackpos)
{if(client) client->sendRemoveCreature(creature, creature->getPosition(), stackpos);}
void sendCreatureMove(const Creature* creature, const Tile* newTile, const Position& newPos,
const Tile* oldTile, const Position& oldPos, uint32_t oldStackpos, bool teleport)
{if(client) client->sendMoveCreature(creature, newTile, newPos, newTile->getClientIndexOfThing(
this, creature), oldTile, oldPos, oldStackpos, teleport);}

void sendCreatureTurn(const Creature* creature)
{if(client) client->sendCreatureTurn(creature, creature->getTile()->getClientIndexOfThing(this, creature));}
void sendCreatureSay(const Creature* creature, SpeakClasses type, const std::string& text, Position* pos = NULL)
{if(client) client->sendCreatureSay(creature, type, text, pos);}
void sendCreatureSquare(const Creature* creature, SquareColor_t color)
{if(client) client->sendCreatureSquare(creature, color);}
void sendCreatureChangeOutfit(const Creature* creature, const Outfit_t& outfit)
{if(client) client->sendCreatureOutfit(creature, outfit);}
void sendCreatureChangeVisible(const Creature* creature, Visible_t visible);
void sendCreatureLight(const Creature* creature)
{if(client) client->sendCreatureLight(creature);}
void sendCreatureShield(const Creature* creature)
{if(client) client->sendCreatureShield(creature);}

//container
void sendAddContainerItem(const Container* container, const Item* item);
void sendUpdateContainerItem(const Container* container, uint8_t slot, const Item* oldItem, const Item* newItem);
void sendRemoveContainerItem(const Container* container, uint8_t slot, const Item* item);
void sendContainer(uint32_t cid, const Container* container, bool hasParent)
{if(client) client->sendContainer(cid, container, hasParent);}

//inventory
void sendAddInventoryItem(slots_t slot, const Item* item)
{if(client) client->sendAddInventoryItem(slot, item);}
void sendUpdateInventoryItem(slots_t slot, const Item* oldItem, const Item* newItem)
{if(client) client->sendUpdateInventoryItem(slot, newItem);}
void sendRemoveInventoryItem(slots_t slot, const Item* item)
{if(client) client->sendRemoveInventoryItem(slot);}

//event methods
virtual void onUpdateTileItem(const Tile* tile, const Position& pos, const Item* oldItem,
const ItemType& oldType, const Item* newItem, const ItemType& newType);
virtual void onRemoveTileItem(const Tile* tile, const Position& pos,
const ItemType& iType, const Item* item);

virtual void onCreatureAppear(const Creature* creature);
virtual void onCreatureDisappear(const Creature* creature, bool isLogout);
virtual void onCreatureMove(const Creature* creature, const Tile* newTile, const Position& newPos,
const Tile* oldTile, const Position& oldPos, bool teleport);

virtual void onAttackedCreatureDisappear(bool isLogout);
virtual void onFollowCreatureDisappear(bool isLogout);

//cylinder implementations
virtual Cylinder* getParent() {return Creature::getParent();}
virtual const Cylinder* getParent() const {return Creature::getParent();}
virtual bool isRemoved() const {return Creature::isRemoved();}
virtual Position getPosition() const {return Creature::getPosition();}
virtual Tile* getTile() {return Creature::getTile();}
virtual const Tile* getTile() const {return Creature::getTile();}
virtual Item* getItem() {return NULL;}
virtual const Item* getItem() const {return NULL;}
virtual Creature* getCreature() {return this;}
virtual const Creature* getCreature() const {return this;}

//container
void onAddContainerItem(const Container* container, const Item* item);
void onUpdateContainerItem(const Container* container, uint8_t slot,
const Item* oldItem, const ItemType& oldType, const Item* newItem, const ItemType& newType);
void onRemoveContainerItem(const Container* container, uint8_t slot, const Item* item);

void onCloseContainer(const Container* container);
void onSendContainer(const Container* container);
void autoCloseContainers(const Container* container);

//inventory
void onAddInventoryItem(slots_t slot, Item* item) {}
void onUpdateInventoryItem(slots_t slot, Item* oldItem, const ItemType& oldType,
Item* newItem, const ItemType& newType);
void onRemoveInventoryItem(slots_t slot, Item* item);

void sendAnimatedText(const Position& pos, uint8_t color, std::string text) const
{if(client) client->sendAnimatedText(pos,color,text);}
void sendCancel(const std::string& msg) const
{if(client) client->sendCancel(msg);}
void sendCancelMessage(ReturnValue message) const;
void sendCancelTarget() const
{if(client) client->sendCancelTarget();}
void sendCancelWalk() const
{if(client) client->sendCancelWalk();}
void sendChangeSpeed(const Creature* creature, uint32_t newSpeed) const
{if(client) client->sendChangeSpeed(creature, newSpeed);}
void sendCreatureHealth(const Creature* creature) const
{if(client) client->sendCreatureHealth(creature);}
void sendDistanceShoot(const Position& from, const Position& to, uint8_t type) const
{if(client) client->sendDistanceShoot(from, to, type);}
void sendHouseWindow(House* house, uint32_t listId) const;
void sendOutfitWindow() const {if(client) client->sendOutfitWindow();}
void sendQuests() const {if(client) client->sendQuests();}
void sendQuestInfo(Quest* quest) const {if(client) client->sendQuestInfo(quest);}
void sendCreatureSkull(const Creature* creature) const
{if(client) client->sendCreatureSkull(creature);}
void sendFYIBox(std::string message)
{if(client) client->sendFYIBox(message);}
void sendCreatePrivateChannel(uint16_t channelId, const std::string& channelName)
{if(client) client->sendCreatePrivateChannel(channelId, channelName);}
void sendClosePrivate(uint16_t channelId) const
{if(client) client->sendClosePrivate(channelId);}
void sendIcons() const;
void sendMagicEffect(const Position& pos, uint16_t type) const
{if(client) client->sendMagicEffect(pos, type);}
void sendStats();
void sendSkills() const
{if(client) client->sendSkills();}
void sendTextMessage(MessageClasses type, const std::string& message) const
{if(client) client->sendTextMessage(type, message);}
void sendReLoginWindow() const
{if(client) client->sendReLoginWindow();}
void sendTextWindow(Item* item, uint16_t maxLen, bool canWrite) const
{if(client) client->sendTextWindow(windowTextId, item, maxLen, canWrite);}
void sendTextWindow(uint32_t itemId, const std::string& text) const
{if(client) client->sendTextWindow(windowTextId, itemId, text);}
void sendToChannel(Creature* creature, SpeakClasses type, const std::string& text, uint16_t channelId, uint32_t time = 0) const
{if(client) client->sendToChannel(creature, type, text, channelId, time);}
void sendShop() const
{if(client) client->sendShop(shopOffer);}
void sendGoods() const
{if(client) client->sendGoods(shopOffer);}
void sendCloseShop() const
{if(client) client->sendCloseShop();}
void sendTradeItemRequest(const Player* player, const Item* item, bool ack) const
{if(client) client->sendTradeItemRequest(player, item, ack);}
void sendTradeClose() const
{if(client) client->sendCloseTrade();}
void sendWorldLight(LightInfo& lightInfo)
{if(client) client->sendWorldLight(lightInfo);}
void sendChannelsDialog()
{if(client) client->sendChannelsDialog();}
void sendOpenPrivateChannel(const std::string& receiver)
{if(client) client->sendOpenPrivateChannel(receiver);}
void sendOutfitWindow()
{if(client) client->sendOutfitWindow();}
void sendCloseContainer(uint32_t cid)
{if(client) client->sendCloseContainer(cid);}
void sendChannel(uint16_t channelId, const std::string& channelName)
{if(client) client->sendChannel(channelId, channelName);}
void sendRuleViolationsChannel(uint16_t channelId)
{if(client) client->sendRuleViolationsChannel(channelId);}
void sendRemoveReport(const std::string& name)
{if(client) client->sendRemoveReport(name);}
void sendLockRuleViolation()
{if(client) client->sendLockRuleViolation();}
void sendRuleViolationCancel(const std::string& name)
{if(client) client->sendRuleViolationCancel(name);}
void sendTutorial(uint8_t tutorialId)
{if(client) client->sendTutorial(tutorialId);}
void sendAddMarker(const Position& pos, MapMarks_t markType, const std::string& desc)
{if (client) client->sendAddMarker(pos, markType, desc);}
void sendCritical() const;

void receivePing() {lastPong = OTSYS_TIME();}
virtual void onThink(uint32_t interval);
uint32_t getAttackSpeed();

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);

void setNextAction(int64_t time) {if(time > nextAction) {nextAction = time;}}
bool canDoAction() const {return nextAction <= OTSYS_TIME();}
uint32_t getNextActionTime() const;

Item* getWriteItem(uint32_t& _windowTextId, uint16_t& _maxWriteLen);
void setWriteItem(Item* item, uint16_t _maxWriteLen = 0);

House* getEditHouse(uint32_t& _windowTextId, uint32_t& _listId);
void setEditHouse(House* house, uint32_t listId = 0);

void learnInstantSpell(const std::string& name);
void unlearnInstantSpell(const std::string& name);
bool hasLearnedInstantSpell(const std::string& name) const;

VIPListSet VIPList;
ContainerVector containerVec;
InvitedToGuildsList invitedToGuildsList;
ConditionList storedConditionList;
DepotMap depots;

uint32_t marriage;
uint64_t balance;
double rates[sKILL__LAST + 1];
Container transferContainer;

protected:
void checkTradeState(const Item* item);

bool gainExperience(double& gainExp, bool fromMonster);
bool rateExperience(double& gainExp, bool fromMonster);
void updateBaseSpeed()
{
if(!hasFlag(PlayerFlag_SetMaxSpeed))
baseSpeed = vocation->getBaseSpeed() + (2 * (level - 1));
else
baseSpeed = SPEED_MAX;
}

void updateInventoryWeight();
void updateInventoryGoods(uint32_t itemId);
void updateItemsLight(bool internal = false);

void setNextWalkActionTask(SchedulerTask* task);
void setNextWalkTask(SchedulerTask* task);
void setNextActionTask(SchedulerTask* task);

virtual bool onDeath();
virtual Item* createCorpse(DeathList deathList);

virtual void dropCorpse(DeathList deathList);
virtual void dropLoot(Container* corpse);

//cylinder implementations
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);
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 Thing* __getThing(uint32_t index) const;
virtual int32_t __getIndexOfThing(const Thing* thing) const;
virtual int32_t __getFirstIndex() const;
virtual int32_t __getLastIndex() const;
virtual uint32_t __getItemTypeCount(uint16_t itemId, int32_t subType = -1,
bool itemCount = true) const;
virtual std::map& __getAllItemTypeCount(std::map uint32_t>& countMap, bool itemCount = true) const;

virtual void __internalAddThing(Thing* thing);
virtual void __internalAddThing(uint32_t index, Thing* thing);

uint32_t getVocAttackSpeed() const {return vocation->getAttackSpeed();}
virtual int32_t getStepSpeed() const
{
if(getSpeed() > SPEED_MAX)
return SPEED_MAX;

if(getSpeed() < SPEED_MIN)
return SPEED_MIN;

return getSpeed();
}

virtual uint32_t getDamageImmunities() const {return damageImmunities;}
virtual uint32_t getConditionImmunities() const {return conditionImmunities;}
virtual uint32_t getConditionSuppressions() const {return conditionSuppressions;}

virtual uint16_t getLookCorpse() const;
virtual uint64_t getLostExperience() const;

virtual void getPathSearchParams(const Creature* creature, FindPathParams& fpp) const;
static uint32_t getPercentLevel(uint64_t count, uint64_t nextLevelCount);

bool isPromoted(uint32_t pLevel = 1) const {return promotionLevel >= pLevel;}
bool hasCapacity(const Item* item, uint32_t count) const;

private:
bool talkState[13];
bool inventoryAbilities[11];
bool pzLocked;
bool saving;
bool isConnecting;
bool requestedOutfit;
bool outfitAttributes;
bool addAttackSkillPoint;

OperatingSystem_t operatingSystem;
AccountManager_t accountManager;
PlayerSex_t managerSex;
BlockType_t lastAttackBlockType;
chaseMode_t chaseMode;
fightMode_t fightMode;
secureMode_t secureMode;
tradestate_t tradeState;
GuildLevel_t guildLevel;

int16_t blessings;
uint16_t maxWriteLen;
uint16_t sex;

int32_t premiumDays;
int32_t soul;
int32_t soulMax;
int32_t vocation_id;
int32_t groupId;
int32_t managerNumber, managerNumber2;
int32_t purchaseCallback;
int32_t saleCallback;
int32_t varSkills[sKILL_LAST + 1];
int32_t varStats[sTAT_LAST + 1];
int32_t messageBuffer;
int32_t bloodHitCount;
int32_t shieldBlockCount;
int32_t shootRange;

uint32_t clientVersion;
uint32_t messageTicks;
uint32_t idleTime;
uint32_t accountId;
uint32_t lastIP;
uint32_t level;
uint32_t levelPercent;
uint32_t magLevel;
uint32_t magLevelPercent;
uint32_t damageImmunities;
uint32_t conditionImmunities;
uint32_t conditionSuppressions;
uint32_t condition; //?
uint32_t nextStepEvent;
uint32_t actionTaskEvent;
uint32_t walkTaskEvent;
uint32_t lossPercent[LOSS_LAST + 1];
uint32_t skills[sKILL_LAST + 1][3];
uint32_t guid;
uint32_t editListId;
uint32_t windowTextId;
uint32_t guildId;
uint32_t rankId;
uint32_t promotionLevel;
uint32_t town;

time_t skullEnd;
time_t lastLogin;
time_t lastLogout;
int64_t lastLoad;
int64_t lastPong;
int64_t lastPing;
int64_t nextAction;
uint64_t stamina;
uint64_t experience;
uint64_t manaSpent;
uint64_t lastAttack;

double inventoryWeight;
double capacity;
char managerChar[100];

std::string managerString, managerString2;
std::string account, password;
std::string name, nameDescription, specialDescription;
std::string guildName, rankName, guildNick;

Position loginPosition;
LightInfo itemsLight;

Vocation* vocation;
ProtocolGame* client;
SchedulerTask* walkTask;
Party* party;
Group* group;
Item* inventory[11];
Player* tradePartner;
Item* tradeItem;
Item* writeItem;
House* editHouse;
Npc* shopOwner;

typedef std::set AttackedSet;
AttackedSet attackedSet;
ShopInfoList shopOffer;
PartyList invitePartyList;
OutfitMap outfits;
LearnedInstantSpellList learnedInstantSpellList;

friend class Game;
friend class LuaScriptInterface;
friend class Npc;
friend class Map;
friend class Actions;
friend class IOLoginData;
friend class ProtocolGame;
};
#endif

,
,>*>,>,>

 

AE

Link para o comentário
Compartilhar em outros sites

Xtudomuito,

no game.h, você não mudou essa parte(esqueci de botar no tutorial):








void addMagicEffect(const SpectatorVec& list, const Position& pos, uint8_t effect, bool ghostMode = false);







Deveria ficar:








void addMagicEffect(const SpectatorVec& list, const Position& pos, uint16_t effect, bool ghostMode = false);

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

 

no client da cipsoft vc vai prescisar que alguem crie uma dll que mude de 8 para 16 para vc injetar no client, o unica cara que eu sei que faz isso e o Cristofer Martins e pode te certeza que ele vai cobra ^^

 

eu fiz uma dll que faz tal tarefa pra um amigo aqui do fórum, e cobrei baratinho! E a dll ainda exerce outras funções dentro do cliente, da pra fazer outros "bars" etc... Mas tudo muito simples.

 

@Sobre o christofer...

 

os preços dele são muito abusivos!

Link para o comentário
Compartilhar em outros sites

 

eu fiz uma dll que faz tal tarefa pra um amigo aqui do fórum, e cobrei baratinho! E a dll ainda exerce outras funções dentro do cliente, da pra fazer outros "bars" etc... Mas tudo muito simples.

 

@Sobre o christofer...

 

os preços dele são muito abusivos!

 

isso e vdd, moh careiro kkkkkkkkkkkkkkkkkkkkkkkkkk

 

queria saber como ele faz essas dll , parece que sao feitas em delph

Link para o comentário
Compartilhar em outros sites

×
×
  • Criar Novo...