Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //////////////////////////////////////////////////////////////////////
- // OpenTibia - an opensource roleplaying game
- //////////////////////////////////////////////////////////////////////
- // class representing the gamestate
- //////////////////////////////////////////////////////////////////////
- // 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 2
- // 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, write to the Free Software Foundation,
- // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- //////////////////////////////////////////////////////////////////////
- #include "patch.h"
- #include "definitions.h"
- #include <string>
- #include <sstream>
- #include <fstream>
- #include <ctime> //You may need to use ctime.h or time.h if this doesn't work.
- #include <map>
- //#include <algorithm>
- #ifdef __DEBUG_CRITICALSECTION__
- #include <iostream>
- #include <fstream>
- #endif
- #include <boost/config.hpp>
- #include <boost/bind.hpp>
- using namespace std;
- #include <stdio.h>
- #include "otsystem.h"
- #include "items.h"
- #include "commands.h"
- #include "creature.h"
- #include "player.h"
- #include "monster.h"
- #include "npc.h"
- #include "game.h"
- #include "tile.h"
- #include "spells.h"
- #include "actions.h"
- #include "ioplayer.h"
- #include "ioaccount.h"
- #include "chat.h"
- #include "status.h"
- #include "luascript.h"
- #include "templates.h"
- #include "houses.h"
- #include "summons.h"
- #include "pvparena.h"
- #include <ctype.h>
- #if defined __EXCEPTION_TRACER__
- #include "exception.h"
- extern OTSYS_THREAD_LOCKVAR maploadlock;
- #endif
- #define EVENT_CHECKCREATURE 123
- #define EVENT_CHECKCREATUREATTACKING 124
- extern LuaScript g_config;
- extern Spells spells;
- extern Actions actions;
- extern Commands commands;
- extern Chat g_chat;
- extern xmlMutexPtr xmlmutex;
- extern std::vector< std::pair<uint32_t, uint32_t> > bannedIPs;
- GameState::GameState(Game *game, const Range &range)
- {
- this->game = game;
- game->getSpectators(range, spectatorlist);
- }
- bool is_poof;
- #ifdef YUR_PVP_ARENA
- bool GameState::isPvpArena(Creature* c)
- {
- if (!c)
- return false;
- Tile *tile = game->map->getTile(c->pos);
- return tile && tile->isPvpArena();
- }
- #endif //YUR_PVP_ARENA
- #ifdef YUR_RINGS_AMULETS
- int32_t GameState::applyAmulets(Player* player, int32_t damage, attacktype_t atype)
- {
- if (!player || atype == ATTACK_NONE)
- return damage;
- double newDamage = (double)damage;
- Item* necklace = player->getItem(SLOT_NECKLACE);
- Item* ring = player->getItem(SLOT_RING);
- Item* armor = player->getItem(SLOT_ARMOR);
- if (necklace && necklace->getCharges() > 0)
- {
- if (necklace->getID() == ITEM_STONE_SKIN_AMULET)
- {
- newDamage *= 0.10;
- necklace->useCharge();
- }
- else if (necklace->getID() == ITEM_PROTECTION_AMULET)
- {
- newDamage *= 0.80;
- necklace->useCharge();
- }
- else if ((necklace->getID() == ITEM_DRAGON_NECKLACE && (atype & ATTACK_FIRE)) ||
- (necklace->getID() == ITEM_SILVER_AMULET && (atype & ATTACK_POISON)) ||
- (necklace->getID() == ITEM_STRANGE_TALISMAN && (atype & ATTACK_ENERGY)) ||
- (necklace->getID() == ITEM_ELVEN_AMULET))
- {
- newDamage *= 0.8;
- necklace->useCharge();
- }
- else if ((necklace->getID() == ITEM_MAGMA_AMULET && (atype & ATTACK_FIRE)))
- {
- newDamage *= 0.7;
- necklace->useCharge();
- }
- #ifdef YUR_DRAINS
- else if (necklace->getID() == ITEM_BRONZE_AMULET && (atype & ATTACK_MANADRAIN))
- {
- newDamage *= 0.5;
- necklace->useCharge();
- }
- else if (necklace->getID() == ITEM_GARLIC_NECKLACE && (atype & ATTACK_LIFEDRAIN))
- {
- newDamage = 0.5;
- necklace->useCharge();
- }
- #endif //YUR_DRAINS
- if (necklace->getCharges() <= 0)
- player->removeItemInventory(SLOT_NECKLACE);
- }
- if (ring && ring->getCharges() > 0)
- {
- if (ring->getID() == ITEM_MIGHT_RING)
- {
- newDamage *= 0.8;
- ring->useCharge();
- }
- if (ring->getCharges() <= 0)
- player->removeItemInventory(SLOT_RING);
- }
- #ifdef HUCZU_FIX
- if(armor)
- {
- if(armor->getID() == ITEM_FIRE_ARMOR && (atype & ATTACK_FIRE))
- newDamage *= 0.8;
- }
- #endif //HUCZU_FIX
- return (int32_t)newDamage;
- }
- #endif //YUR_RINGS_AMULETS
- void GameState::onAttack(Creature* attacker, const Position& pos, const MagicEffectClass* me)
- {
- Tile *tile = game->map->getTile(pos);
- if(!tile)
- return;
- #ifdef YUR_PVP_ARENA
- CreatureVector arenaLosers;
- #endif //YUR_PVP_ARENA
- CreatureVector::iterator cit;
- Player* attackPlayer = dynamic_cast<Player*>(attacker);
- Creature *targetCreature = NULL;
- Player *targetPlayer = NULL;
- for(cit = tile->creatures.begin(); cit != tile->creatures.end(); ++cit) {
- targetCreature = (*cit);
- targetPlayer = dynamic_cast<Player*>(targetCreature);
- bool pvpArena = false;
- #ifdef TR_SUMMONS
- bool targetIsSummon = (targetCreature && targetCreature->isPlayersSummon());
- bool summonVsPlayer = (attacker && attacker->isPlayersSummon() && targetPlayer);
- #endif //TR_SUMMONS
- int32_t damage = me->getDamage(targetCreature, attacker);
- int32_t manaDamage = 0;
- if(attackPlayer){
- if(!me->offensive && me->minDamage != 0 && g_config.getGlobalString("showHealingDamage") == "yes"){
- int32_t lecz = std::min(std::abs(damage), attackPlayer->healthmax - attackPlayer->health);
- std::stringstream anidamage;
- anidamage << "+" << lecz;
- if(lecz != 0)
- game->sendAnimatedTextExt(attackPlayer->pos, 96, anidamage.str().c_str());
- }
- }
- #ifdef YUR_RINGS_AMULETS
- damage = applyAmulets(targetPlayer, damage, me->attackType);
- #endif //YUR_RINGS_AMULETS
- if (damage > 0) {
- if(attackPlayer && attackPlayer->access < g_config.ACCESS_PROTECT) {
- if(targetPlayer && targetPlayer != attackPlayer && game->getWorldType() != WORLD_TYPE_NO_PVP)
- attackPlayer->pzLocked = true;
- }
- if(targetCreature->access < g_config.ACCESS_PROTECT && targetPlayer && game->getWorldType() != WORLD_TYPE_NO_PVP)
- {
- #ifdef YUR_CVS_MODS
- targetPlayer->inFightTicks = std::max(g_config.PZ_LOCKED, targetPlayer->inFightTicks);
- #else
- targetPlayer->inFightTicks = g_config.PZ_LOCKED;
- #endif //YUR_CVS_MODS
- targetPlayer->sendIcons();
- }
- #ifdef SURVIVAL_BLACKSQUARE
- if(damage > 0 && attackPlayer && targetPlayer && attackPlayer != targetPlayer){
- NetworkMessage attackedpmsg;
- attackedpmsg.AddPlayerAttacked(attacker);
- targetPlayer->sendNetworkMessage(&attackedpmsg);
- }
- #endif //SURVIVAL_BLACKSQUARE
- #ifdef YUR_PVP_ARENA
- pvpArena = isPvpArena(attacker) && isPvpArena(targetCreature);
- #endif //YUR_PVP_ARENA
- #ifdef TR_SUMMONS
- if ((game->getWorldType() == WORLD_TYPE_NO_PVP && !pvpArena && summonVsPlayer) ||
- (game->getWorldType() == WORLD_TYPE_NO_PVP && !pvpArena && attackPlayer && (targetPlayer || targetIsSummon) && attackPlayer->access < g_config.ACCESS_PROTECT)) {
- #else
- if(game->getWorldType() == WORLD_TYPE_NO_PVP && !pvpArena && attackPlayer && targetPlayer && attackPlayer->access < ACCESS_PROTECT){
- #endif //TR_SUMMONS
- damage = 0;
- }
- }
- if (damage != 0)
- {
- // Bedzie pro ustawione all
- #ifdef HUCZU_FIX
- if(attackPlayer){
- Item* armor = attackPlayer->getItem(SLOT_ARMOR);
- Item* legs = attackPlayer->getItem(SLOT_LEGS);
- Item* helmet = attackPlayer->getItem(SLOT_HEAD);
- Item* boots = attackPlayer->getItem(SLOT_FEET);
- Item* ring = attackPlayer->getItem(SLOT_RING);
- Item* amulet = attackPlayer->getItem(SLOT_NECKLACE);
- if(attackPlayer->vocation == 1 || attackPlayer->vocation == 2){
- if(armor){
- if(armor->getID() == ITEM_GLACIER_ROBE){
- double newdamage = damage*2/100.0;
- damage += (int32_t)newdamage;
- }
- else if(armor->getID() == ITEM_ARCHMAGE_COAT){
- double newdamage = damage*5/100.0;
- damage += (int32_t)newdamage;
- }
- else if(armor->getID() == ITEM_BMC){
- double newdamage = damage*3/100.0;
- damage += (int32_t)newdamage;
- }
- }
- if(legs){
- if(legs->getID() == ITEM_GLACIER_KIT){
- double newdamage = damage*2/100.0;
- damage += (int32_t)newdamage;
- }
- }
- }
- if(legs){
- if(legs->getID() == ITEM_ZS_LEGS){
- double newdamage = damage*10/100.0;
- damage += (int32_t)newdamage;
- }
- }
- if(g_config.MGITEMS){
- if(helmet && helmet->getID() == g_config.MGITEMHELMET){
- double newdamage = damage*g_config.ITEM_MDOWNHELMET/100.0;
- damage += (int32_t)newdamage;
- }
- if(armor && armor->getID() == g_config.MGITEMARMOR){
- double newdamage = damage*g_config.ITEM_MDOWNARMOR/100.0;
- damage += (int32_t)newdamage;
- }
- if(legs && legs->getID() == g_config.MGITEMLEGS){
- double newdamage = damage*g_config.ITEM_MDOWNLEGS/100.0;
- damage += (int32_t)newdamage;
- }
- if(boots && boots->getID() == g_config.MGITEMBOOTS){
- double newdamage = damage*g_config.ITEM_MDOWNBOOTS/100.0;
- damage += (int32_t)newdamage;
- }
- if(ring && ring->getID() == g_config.MGITEMRINGS){
- double newdamage = damage*g_config.ITEM_MDOWNRING/100.0;
- damage += (int32_t)newdamage;
- }
- if(amulet && amulet->getID() == g_config.MGITEMAMU){
- double newdamage = damage*g_config.ITEM_MDOWNAMU/100.0;
- damage += (int32_t)newdamage;
- }
- }
- }
- #endif //HUCZU_FIX i git w chuj
- #ifdef YUR_DRAINS
- if (me->attackType & ATTACK_MANADRAIN)
- {
- manaDamage = std::min(damage, targetCreature->mana);
- targetCreature->drainMana(manaDamage);
- damage = 0;
- }
- else
- #endif //YUR_DRAINS
- {
- game->creatureApplyDamage(targetCreature, damage, damage, manaDamage
- #ifdef YUR_PVP_ARENA
- , (pvpArena? &arenaLosers : NULL)
- #endif //YUR_PVP_ARENA
- );
- }
- #ifdef YUR_DRAINS
- if (me->attackType & ATTACK_LIFEDRAIN)
- {
- attacker->health = std::min(attacker->healthmax, attacker->health + damage);
- addCreatureState(tile, attacker, 0, 0, false); // update attacker health
- }
- #endif //YUR_DRAINS
- #ifdef YUR_INVISIBLE
- if (targetCreature && !targetPlayer)
- {
- targetCreature->setInvisible(0);
- game->creatureChangeOutfit(targetCreature);
- }
- #endif //YUR_INVISIBLE
- }
- #ifdef HUCZU_SKULLS
- if (me->offensive && game->getWorldType() == WORLD_TYPE_PVP)
- game->onPvP(attacker, targetCreature, targetCreature->health <= 0);
- #endif
- addCreatureState(tile, targetCreature, damage, manaDamage, me->drawblood);
- }
- //Solid ground items/Magic items (fire/poison/energy)
- MagicEffectItem *newmagicItem = me->getMagicItem(attacker, tile->isPz(),
- (tile->isBlocking(BLOCK_SOLID, true) != RET_NOERROR));
- if(newmagicItem) {
- MagicEffectItem *magicItem = tile->getFieldItem();
- if(magicItem) {
- //Replace existing magic field
- magicItem->transform(newmagicItem);
- int32_t stackpos = tile->getThingStackPos(magicItem);
- if(tile->removeThing(magicItem)) {
- SpectatorVec list;
- SpectatorVec::iterator it;
- game->getSpectators(Range(pos, true), list);
- //players
- for(it = list.begin(); it != list.end(); ++it) {
- if(dynamic_cast<Player*>(*it)) {
- (*it)->onThingDisappear(magicItem, stackpos);
- }
- }
- //none-players
- for(it = list.begin(); it != list.end(); ++it) {
- if(!dynamic_cast<Player*>(*it)) {
- (*it)->onThingDisappear(magicItem, stackpos);
- }
- }
- tile->addThing(magicItem);
- //players
- for(it = list.begin(); it != list.end(); ++it) {
- if(dynamic_cast<Player*>(*it)) {
- (*it)->onThingAppear(magicItem);
- }
- }
- //none-players
- for(it = list.begin(); it != list.end(); ++it) {
- if(!dynamic_cast<Player*>(*it)) {
- (*it)->onThingAppear(magicItem);
- }
- }
- }
- }
- else {
- magicItem = new MagicEffectItem(*newmagicItem);
- magicItem->useThing();
- magicItem->pos = pos;
- tile->addThing(magicItem);
- SpectatorVec list;
- SpectatorVec::iterator it;
- game->getSpectators(Range(pos, true), list);
- //players
- for(it = list.begin(); it != list.end(); ++it) {
- if(dynamic_cast<Player*>(*it)) {
- (*it)->onThingAppear(magicItem);
- }
- }
- //none-players
- for(it = list.begin(); it != list.end(); ++it) {
- if(!dynamic_cast<Player*>(*it)) {
- (*it)->onThingAppear(magicItem);
- }
- }
- magicItem->isRemoved = false;
- game->startDecay(magicItem);
- }
- }
- //Clean up
- for(CreatureStateVec::const_iterator csIt = creaturestates[tile].begin(); csIt != creaturestates[tile].end(); ++csIt) {
- onAttackedCreature(tile, attacker, csIt->first, csIt->second.damage, csIt->second.drawBlood);
- }
- if(attackPlayer && attackPlayer->access < g_config.ACCESS_PROTECT) {
- //Add exhaustion
- if(me->causeExhaustion(true) /*!areaTargetVec.empty())*/)
- {
- attackPlayer->exhaustedTicks = g_config.EXHAUSTED;
- }
- //Fight symbol
- if(me->offensive /*&& !areaTargetVec.empty()*/)
- {
- #ifdef YUR_CVS_MODS
- attackPlayer->inFightTicks = std::max(g_config.PZ_LOCKED, attackPlayer->inFightTicks);
- #else
- attackPlayer->inFightTicks = g_config.PZ_LOCKED;
- #endif //YUR_CVS_MODS
- }
- }
- #ifdef YUR_PVP_ARENA
- for (CreatureVector::iterator it = arenaLosers.begin(); it != arenaLosers.end(); ++it)
- {
- Tile* tile = game->getTile((*it)->pos);
- if (tile)
- {
- game->teleport(*it, tile->getPvpArenaExit());
- }
- if(Monster* monster = dynamic_cast<Monster*>(*it))
- {
- if(Tile *tile = game->map->getTile(monster->pos))
- {
- if(tile->isPvpArena())
- {
- game->removeCreature(monster);
- }
- }
- }
- }
- #endif //YUR_PVP_ARENA
- }
- void GameState::onAttack(Creature* attacker, const Position& pos, Creature* attackedCreature)
- {
- bool pvpArena = false;
- #ifdef YUR_PVP_ARENA
- CreatureVector arenaLosers;
- pvpArena = isPvpArena(attacker) && isPvpArena(attackedCreature);
- #endif //YUR_PVP_ARENA
- //TODO: Decent formulas and such...
- int32_t damage = attacker->getWeaponDamage();
- int32_t armor = attackedCreature->getArmor();
- int32_t defense = attackedCreature->getDefense();
- Player* attackPlayer = dynamic_cast<Player*>(attacker);
- Player* attackedPlayer = dynamic_cast<Player*>(attackedCreature);
- if(attackedPlayer)
- attackedPlayer->addSkillShieldTry(1);
- int32_t probability = rand() % 10000;
- #ifdef YUR_CVS_MODS
- if(probability * damage < defense * 3000)
- damage = 0;
- else
- damage -= (int32_t)((damage*(armor/50.0)*(rand()/(RAND_MAX+1.0))) + (armor*2) + defense/1.5);
- //damage -= (int32_t)((armor)*(rand()/(RAND_MAX+1.0))) + armor; // wik's
- #else
- if(probability * damage < defense * 10000)
- damage = 0;
- else
- {
- damage -= (armor * (10000 + rand() % 10000)) / 10000;
- }
- #endif //YUR_CVS_MODS
- int32_t manaDamage = 0;
- if(attackPlayer && attackedPlayer){
- damage -= (int32_t) damage / 2;
- }
- if (attacker->access >= g_config.ACCESS_PROTECT)
- damage += 1;
- Tile* tile = game->map->getTile(pos);
- bool blood;
- if(damage > 0)
- {
- // F-AXE,F-SWORD,P-DAGGER
- if(attackPlayer)
- {
- for (int32_t slot = SLOT_RIGHT; slot <= SLOT_LEFT; slot++)
- {
- if(g_config.EFFECT_ATACK && attackPlayer->getItem(slot) && (attackPlayer->getItem(slot)->getID() == ITEM_FAXE || attackPlayer->getItem(slot)->getID() == ITEM_FSWORD))
- {
- game->CreateCondition(attackedCreature, attacker, 199, NM_ME_HITBY_FIRE, NM_ME_HITBY_FIRE, ATTACK_FIRE, true, 5, 5, 2000, 1);
- }
- if(g_config.EFFECT_ATACK && attackPlayer->getItem(slot) && (attackPlayer->getItem(slot)->getID() == ITEM_PD))
- {
- game->CreateCondition(attackedCreature, attacker, 30, NM_ME_POISEN_RINGS, NM_ME_POISEN_RINGS, ATTACK_POISON, true, 5, 5, 2000, 3);
- }
- }
- }
- // P-BOLT ENERGY
- if(attackPlayer)
- {
- int32_t slot = SLOT_AMMO;
- if(g_config.EFFECT_ATACK && attackPlayer->getItem(slot) && (attackPlayer->getItem(slot)->getID() == 5260))
- {
- game->CreateCondition(attackedCreature, attacker, 35, NM_ME_ENERGY_DAMAGE, NM_ME_ENERGY_DAMAGE, ATTACK_ENERGY, true, 10, 10, 2000, 1);
- }
- }
- #ifdef YUR_ICE_RAPIER
- if (attackPlayer)
- for (int32_t slot = SLOT_RIGHT; slot <= SLOT_LEFT; slot++)
- if(attackPlayer->getItem(slot) && attackPlayer->getItem(slot)->getID() == ITEM_ICE_RAPIER)
- attackPlayer->removeItemInventory(slot);
- #endif //YUR_ICE_RAPIER
- #ifdef PALL_REQ_LVL
- if (attackPlayer){
- for (int32_t slot = SLOT_RIGHT; slot <= SLOT_LEFT; slot++){
- if(attackPlayer->getItem(slot) && attackPlayer->getItem(slot)->isWeapon() && attackPlayer->getItem(slot)->getReqLevel() > attackPlayer->getLevel())
- {
- int32_t newdamage = attackPlayer->getWeaponDamage() / random_range(4, 7);
- if (attackPlayer->getWeaponDamage() >= 7)
- damage = 0;
- else
- damage = newdamage;
- }
- if(attackPlayer->getItem(slot) && attackPlayer->getItem(slot)->getAmuType() != 0 && attackPlayer->getItem(slot)->getReqLevel() > attackPlayer->getLevel())
- {
- int32_t newdamage = attackPlayer->getWeaponDamage() / random_range(4, 7);
- if (attackPlayer->getWeaponDamage() >= 7)
- damage = 0;
- else
- damage = newdamage;
- }
- if(attackPlayer->getItem(slot) && attackPlayer->getItem(slot)->isWeapon() && attackPlayer->getItem(slot)->getReqVoc() != attackPlayer->getVocation() && attackPlayer->getItem(slot)->getReqVoc() > 0)
- {
- int32_t newdamage = attackPlayer->getWeaponDamage() / random_range(4, 9);
- if (attackPlayer->getWeaponDamage() >= 7)
- damage = 0;
- else
- damage = newdamage;
- }
- }
- }
- #endif //PALL_REQ_LVL
- if(attackPlayer && attackPlayer->getVocation() == VOCATION_PALADIN) {
- damage += damage * (0.01 * (double)g_config.PALADIN_RAISE);
- }
- if(attackPlayer && attackPlayer->getVocation() == VOCATION_KNIGHT) {
- damage = damage * (uint32_t)g_config.KNIGHT_LOOSE / 100;
- }
- #ifdef YUR_RINGS_AMULETS
- damage = applyAmulets(attackedPlayer, damage, ATTACK_PHYSICAL);
- #endif //YUR_RINGS_AMULETS
- #ifdef CHRIS_CRIT_HIT
- if(attackPlayer){
- int32_t critcial_hit;
- int32_t rand_hit = random_range(0, 700);
- switch(rand_hit){
- case 75:
- critcial_hit = random_range(50, 100);
- if (attackPlayer->vocation == 4)(game->sendAnimatedTextExt(attackPlayer->pos, 180, "CRITICAL"));
- break;
- case 87:
- critcial_hit = random_range(50, 100);
- if (attackPlayer->vocation == 4)(game->sendAnimatedTextExt(attackPlayer->pos, 180, "CRITICAL"));
- break;
- case 95:
- critcial_hit = random_range(50, 100);
- if (attackPlayer->vocation == 4)(game->sendAnimatedTextExt(attackPlayer->pos, 180, "CRITICAL"));
- break;
- case 113:
- critcial_hit = random_range(80, 130);
- if (attackPlayer->vocation == 4)(game->sendAnimatedTextExt(attackPlayer->pos, 180, "CRITICAL"));
- break;
- case 128:
- critcial_hit = random_range(80, 130);
- if (attackPlayer->vocation == 4)(game->sendAnimatedTextExt(attackPlayer->pos, 180, "CRITICAL"));
- break;
- case 133:
- critcial_hit = random_range(80, 130);
- if (attackPlayer->vocation == 4)(game->sendAnimatedTextExt(attackPlayer->pos, 180, "CRITICAL"));
- break;
- case 145:
- critcial_hit = random_range(80, 130);
- if (attackPlayer->vocation == 4)(game->sendAnimatedTextExt(attackPlayer->pos, 180, "CRITICAL"));
- break;
- case 157:
- critcial_hit = random_range(80, 130);
- if (attackPlayer->vocation == 4)(game->sendAnimatedTextExt(attackPlayer->pos, 180, "CRITICAL"));
- break;
- case 167:
- critcial_hit = random_range(80, 130);
- if (attackPlayer->vocation == 4)(game->sendAnimatedTextExt(attackPlayer->pos, 180, "CRITICAL"));
- break;
- case 187:
- critcial_hit = random_range(80, 130);
- if (attackPlayer->vocation == 4)(game->sendAnimatedTextExt(attackPlayer->pos, 180, "CRITICAL"));
- break;
- case 195:
- critcial_hit = random_range(80, 130);
- if (attackPlayer->vocation == 4)(game->sendAnimatedTextExt(attackPlayer->pos, 180, "CRITICAL"));
- break;
- case 202:
- critcial_hit = random_range(110, 160);
- if (attackPlayer->vocation == 4)(game->sendAnimatedTextExt(attackPlayer->pos, 180, "CRITICAL"));
- break;
- case 225:
- critcial_hit = random_range(110, 160);
- if (attackPlayer->vocation == 4)(game->sendAnimatedTextExt(attackPlayer->pos, 180, "CRITICAL"));
- break;
- case 238:
- critcial_hit = random_range(110, 160);
- if (attackPlayer->vocation == 4)(game->sendAnimatedTextExt(attackPlayer->pos, 180, "CRITICAL"));
- break;
- case 245:
- critcial_hit = random_range(110, 160);
- if (attackPlayer->vocation == 4)(game->sendAnimatedTextExt(attackPlayer->pos, 180, "CRITICAL"));
- break;
- case 268:
- critcial_hit = random_range(110, 160);
- if (attackPlayer->vocation == 4)(game->sendAnimatedTextExt(attackPlayer->pos, 180, "CRITICAL"));
- break;
- case 287:
- critcial_hit = random_range(110, 160);
- if (attackPlayer->vocation == 4)(game->sendAnimatedTextExt(attackPlayer->pos, 180, "CRITICAL"));
- break;
- case 298:
- critcial_hit = random_range(110, 160);
- if (attackPlayer->vocation == 4)(game->sendAnimatedTextExt(attackPlayer->pos, 180, "CRITICAL"));
- break;
- case 324:
- critcial_hit = random_range(140, 400);
- if (attackPlayer->vocation == 4)(game->sendAnimatedTextExt(attackPlayer->pos, 180, "CRITICAL"));
- break;
- case 356:
- critcial_hit = random_range(140, 190);
- if (attackPlayer->vocation == 4)(game->sendAnimatedTextExt(attackPlayer->pos, 180, "CRITICAL"));
- break;
- case 371:
- critcial_hit = random_range(140, 190);
- if (attackPlayer->vocation == 4)(game->sendAnimatedTextExt(attackPlayer->pos, 180, "CRITICAL"));
- break;
- case 380:
- critcial_hit = random_range(140, 190);
- if (attackPlayer->vocation == 4)(game->sendAnimatedTextExt(attackPlayer->pos, 180, "CRITICAL"));
- break;
- case 397:
- critcial_hit = random_range(140, 190);
- if (attackPlayer->vocation == 4)(game->sendAnimatedTextExt(attackPlayer->pos, 180, "CRITICAL"));
- break;
- case 399:
- critcial_hit = random_range(140, 190);
- if (attackPlayer->vocation == 4)(game->sendAnimatedTextExt(attackPlayer->pos, 180, "CRITICAL"));
- break;
- case 400:
- critcial_hit = random_range(170, 210);
- if (attackPlayer->vocation == 4)(game->sendAnimatedTextExt(attackPlayer->pos, 180, "CRITICAL"));
- break;
- case 428:
- critcial_hit = random_range(170, 210);
- if (attackPlayer->vocation == 4)(game->sendAnimatedTextExt(attackPlayer->pos, 180, "CRITICAL"));
- break;
- case 432:
- critcial_hit = random_range(170, 210);
- if (attackPlayer->vocation == 4)(game->sendAnimatedTextExt(attackPlayer->pos, 180, "CRITICAL"));
- break;
- case 444:
- critcial_hit = random_range(170, 210);
- if (attackPlayer->vocation == 4)(game->sendAnimatedTextExt(attackPlayer->pos, 180, "CRITICAL"));
- break;
- case 474:
- critcial_hit = random_range(170, 210);
- if (attackPlayer->vocation == 4)(game->sendAnimatedTextExt(attackPlayer->pos, 180, "CRITICAL"));
- break;
- default:
- critcial_hit = 0;
- break;
- }
- if (attackPlayer->vocation == 4){
- if(critcial_hit != 0){
- if(attackPlayer->level >= 150){
- if(attackPlayer && attackPlayer->items[SLOT_RIGHT] && attackPlayer->items[SLOT_RIGHT]->getID() == ITEM_RAINBOW){
- if(attackPlayer->items[SLOT_LEFT]){
- if(attackPlayer->items[SLOT_LEFT]->getID() != ITEM_RAINBOW)
- critcial_hit += critcial_hit*(25/100);
- game->CreateCondition(attackedCreature, attacker, 35, NM_ME_ENERGY_DAMAGE, NM_ME_ENERGY_DAMAGE, ATTACK_ENERGY, true, 25, 25, 1000, 1);
- }
- }
- }
- if(attackPlayer && attackPlayer->items[SLOT_LEFT] && attackPlayer->items[SLOT_LEFT]->getID() == ITEM_RAINBOW){
- if(attackPlayer->items[SLOT_RIGHT]){
- if(attackPlayer->items[SLOT_RIGHT]->getID() != ITEM_RAINBOW)
- critcial_hit += critcial_hit*(25/100);
- game->CreateCondition(attackedCreature, attacker, 35, NM_ME_ENERGY_DAMAGE, NM_ME_ENERGY_DAMAGE, ATTACK_ENERGY, true, 25, 25, 1000, 1);
- }
- }
- }
- damage += critcial_hit;
- }
- }
- #endif //CHRIS_CRIT_HIT
- game->creatureApplyDamage(attackedCreature, damage, damage, manaDamage
- #ifdef YUR_PVP_ARENA
- , (pvpArena? &arenaLosers : NULL)
- #endif //YUR_PVP_ARENA
- );
- #ifdef HUCZU_SKULLS
- if (game->getWorldType() == WORLD_TYPE_PVP)
- game->onPvP(attacker, attackedCreature, attackedCreature->health <= 0);
- #endif
- blood = true;
- if(attackPlayer && attackPlayer->maxDmg < damage) {
- attackPlayer->maxDmg = (int32_t) damage;
- std::stringstream MaxDmgMsg;
- MaxDmgMsg << "Your new best damage is " << attackPlayer->maxDmg << ".";
- attackPlayer->sendTextMessage(MSG_ADVANCE, MaxDmgMsg.str().c_str());
- }
- }
- else{//no draw blood
- blood = false;
- }
- addCreatureState(tile, attackedCreature, damage, manaDamage, blood);
- onAttackedCreature(tile, attacker, attackedCreature, damage, true);
- /*
- if (attackPlayer && attackPlayer->isUsingSpears() && random_range(1,100000) > g_config.SPEAR_LOSE_CHANCE)
- {
- Item* spear = Item::CreateItem(ITEM_SPEAR, 1);
- spear->pos = attackedCreature->pos;
- game->addThing(attackPlayer, spear->pos, spear);
- }
- */
- #ifdef YUR_PVP_ARENA
- for (CreatureVector::iterator it = arenaLosers.begin(); it != arenaLosers.end(); ++it){
- Tile* tile = game->getTile((*it)->pos);
- if (tile){
- game->teleport(*it, tile->getPvpArenaExit());
- }
- if(Monster* monster = dynamic_cast<Monster*>(*it)){
- if(Tile *tile = game->map->getTile(monster->pos)){
- if(tile->isPvpArena()){
- game->removeCreature(monster);
- }
- }
- }
- }
- #endif //YUR_PVP_ARENA
- }
- void GameState::addCreatureState(Tile* tile, Creature* attackedCreature, int32_t damage, int32_t manaDamage, bool drawBlood)
- {
- CreatureState cs;
- cs.damage = damage;
- cs.manaDamage = manaDamage;
- cs.drawBlood = drawBlood;
- creaturestates[tile].push_back( make_pair(attackedCreature, cs) );
- }
- void GameState::onAttackedCreature(Tile* tile, Creature *attacker, Creature* attackedCreature, int32_t damage, bool drawBlood)
- {
- Player *attackedplayer = dynamic_cast<Player*>(attackedCreature);
- Position CreaturePos = attackedCreature->pos;
- #ifdef TJ_MONSTER_BLOOD
- bool dead = false;
- #endif //TJ_MONSTER_BLOOD
- #ifdef TR_SUMMONS
- //Summon exp share by Yurez
- Player *player = dynamic_cast<Player*>(attacker);
- Creature* attackerMaster = attacker? attacker->getMaster() : NULL;
- if(attackerMaster && dynamic_cast<Player*>(attackerMaster)){//attacker is players summon
- attackedCreature->addInflictedDamage(attacker, damage/2);
- attackedCreature->addInflictedDamage(attackerMaster, damage/2);
- }// end summon exp share
- else if(player && player->party != 0){
- int32_t partySize = 0;
- SpectatorVec list;
- SpectatorVec::iterator it;
- game->getSpectators(Range(player->pos), list);
- /*Get all specatators around this player
- then check if they are in his party*/
- for(it = list.begin(); it != list.end(); ++it){//find number too div by
- Player* p = dynamic_cast<Player*>(*it);
- if(p && p->party == player->party)//huczu_fix
- partySize++;
- }
- for(it = list.begin(); it != list.end(); ++it){
- Player* p = dynamic_cast<Player*>(*it);
- if(p && p->party == player->party && partySize != 0/*dont div by 0*/)//same party add exp, huczu_fix
- attackedCreature->addInflictedDamage(p, damage/partySize);
- }
- }
- else
- attackedCreature->addInflictedDamage(attacker, damage);
- #endif //TR_SUMMONS
- if(attackedplayer){
- attackedplayer->sendStats();
- }
- //Remove player?
- if(attackedCreature->health <= 0 && attackedCreature->isRemoved == false)
- {
- #ifdef TJ_MONSTER_BLOOD
- dead = true;
- #endif //TJ_MONSTER_BLOOD
- #ifdef JD_DEATH_LIST
- if (attackedplayer && attacker)
- attackedplayer->addDeath(attacker->getName(), attackedplayer->level, time(0));
- #endif //JD_DEATH_LIST
- unsigned char stackpos = tile->getThingStackPos(attackedCreature);
- //tasksys
- Player* attackingplayer = dynamic_cast<Player*>(attacker);
- if(attackingplayer && attackedCreature->getName() == attackingplayer->taskmonster && attackingplayer->taskcount < attackingplayer->taskmax)
- {
- // attackingplayer->taskcount++;
- std::stringstream info;
- std::string mons = attackingplayer->taskmonster;
- std::transform(mons.begin(), mons.end(), mons.begin(), (int(*)(int))tolower);
- if(attackingplayer->taskcount < attackingplayer->taskmax)
- {
- info << "You have killed " << attackingplayer->taskcount << " out of " << attackingplayer->taskmax << " " << mons << "s.";
- }
- else
- {
- info << "You have finished task of killing " << mons << "s. ";
- }
- // attackingplayer->sendTextMessage(MSG_ORANGE, info.str().c_str());
- }
- //tasksys
- //Prepare body
- Item *corpseitem = Item::CreateItem(attackedCreature->getLookCorpse());
- corpseitem->pos = CreaturePos;
- tile->addThing(corpseitem);
- #ifdef _DEATH_EVENTS
- if (!attackedplayer)
- {
- Monster* monster = dynamic_cast<Monster*>(attackedCreature);
- Player* killer = dynamic_cast<Player*>(attacker);
- if (killer && monster && monster->getAction())
- {
- actions.onCreatureKill(killer, attackedCreature, corpseitem, monster->getAction());
- }
- }
- #endif //_DEATH_EVENTS
- #ifdef __MIZIAK_CREATURESCRIPTS__
- if(dynamic_cast<Player*>(attacker) && attackedCreature)
- actions.creatureEvent("kill", dynamic_cast<Player*>(attacker), attackedCreature, corpseitem, NULL);
- #endif //__MIZIAK_CREATURESCRIPTS__
- //remove creature
- if(attackedplayer){
- actions.luaWalkOff(attackedplayer,attackedplayer->pos,tile->ground->getID(),tile->ground->getUniqueId(),tile->ground->getActionId()); //CHANGE onWalk
- attackedplayer->onThingDisappear(attackedplayer,stackpos);
- #ifdef __MIZIAK_CREATURESCRIPTS__
- attackedplayer->dieorlogout = true;
- if(attacker)
- actions.creatureEvent("death", attackedplayer, attacker, corpseitem, NULL);
- #endif //__MIZIAK_CREATURESCRIPTS__
- attackedplayer->die(); //handles exp/skills/maglevel loss
- }
- //Add eventual loot
- Container *lootcontainer = dynamic_cast<Container*>(corpseitem);
- if(lootcontainer) {
- attackedCreature->dropLoot(lootcontainer);
- #ifdef HUCZU_LOOT_INFO
- Monster* monster = dynamic_cast<Monster*>(attackedCreature);
- Player* atakujacy = dynamic_cast<Player*>(attacker);
- if(monster && atakujacy){
- std::stringstream ss, info;
- //info << "Loot of " << monster->getName() << lootcontainer->getContentDescription() << ".";
- info << "Loot of " << monster->getName();
- ss << lootcontainer->getContentDescription() << ".";
- if(atakujacy->party != 0){
- for(AutoList<Player>::listiterator it = Player::listPlayer.list.begin(); it != Player::listPlayer.list.end(); ++it){
- if((*it).second->party == atakujacy->party){
- if((*it).second->getID() != atakujacy->getID()){
- (*it).second->sendToSpecialChannel(atakujacy, SPEAK_CHANNEL_O, ss.str().c_str(), 0x02, info.str().c_str());
- //(*it).second->sendTextMessage(MSG_INFO, info.str().c_str());
- }
- }
- }
- }else{
- //atakujacy->sendTextMessage(MSG_INFO, info.str().c_str());
- atakujacy->sendToSpecialChannel(atakujacy, SPEAK_CHANNEL_O, ss.str().c_str(), 0x02, info.str().c_str());
- }
- }
- #endif //HUCZU_LOOT_INFO
- }
- #ifdef HUCZU_MONSTER_QUEST
- Monster* monster = dynamic_cast<Monster*>(attackedCreature);
- Player* atakujacy = dynamic_cast<Player*>(attacker);
- int32_t value, kills;
- if(monster && atakujacy && monster->getQuestId() != 0){
- if(monster->getQuestId() == 2 && atakujacy->getStorageValue(100, value) == 1){
- int32_t killsprzed = atakujacy->getQuestKills(2);
- atakujacy->addQuestKills(2, killsprzed+1);
- }
- }
- #endif //HUCZU_MONSTER_QUEST
- game->removeCreature(attackedCreature);
- // Update attackedCreature pos because contains
- // temple position for players
- attackedCreature->pos = CreaturePos;
- //add body
- game->sendAddThing(NULL,corpseitem->pos,corpseitem);
- if(attackedplayer){
- std::stringstream ss;
- ss << corpseitem->getDescription(false);
- ss << "You recognize " << attackedplayer->getName() << ". ";
- if(attacker){
- ss << (attackedplayer->getSex() == PLAYERSEX_FEMALE ? "She" : "He") << " was killed by ";
- Player *attackerplayer = dynamic_cast<Player*>(attacker);
- if(attackerplayer) {
- ss << attacker->getName();
- }
- else {
- std::string creaturename = attacker->getName();
- std::transform(creaturename.begin(), creaturename.end(), creaturename.begin(), (int32_t(*)(int32_t))tolower);
- ss << article(creaturename);
- }
- }
- //set body special description
- corpseitem->setSpecialDescription(ss.str());
- //send corpse to the dead player. It is not in spectator list
- // because was removed
- attackedplayer->onThingAppear(corpseitem);
- }
- game->startDecay(corpseitem);
- //Get all creatures that will gain xp from this kill..
- CreatureState* attackedCreatureState = NULL;
- std::vector<long> creaturelist;
- if(!(dynamic_cast<Player*>(attackedCreature) && game->getWorldType() != WORLD_TYPE_PVP_ENFORCED)){
- creaturelist = attackedCreature->getInflicatedDamageCreatureList();
- CreatureStateVec& creatureStateVec = creaturestates[tile];
- for(CreatureStateVec::iterator csIt = creatureStateVec.begin(); csIt != creatureStateVec.end(); ++csIt) {
- if(csIt->first == attackedCreature) {
- attackedCreatureState = &csIt->second;
- break;
- }
- }
- }
- if(attackedCreatureState) { //should never be NULL..
- //Add experience
- for(std::vector<long>::const_iterator iit = creaturelist.begin(); iit != creaturelist.end(); ++iit) {
- Creature* gainExpCreature = game->getCreatureByID(*iit);
- if(gainExpCreature) {
- exp_t gainedExperience = attackedCreature->getGainedExperience(gainExpCreature);
- if(gainedExperience <= 0)
- continue;
- Player *gainExpPlayer = dynamic_cast<Player*>(gainExpCreature);
- if(gainExpPlayer) {
- gainExpPlayer->addExp(gainedExperience);
- if(gainExpPlayer && attackedCreature->getName() == gainExpPlayer->taskmonster && gainExpPlayer->taskcount < gainExpPlayer->taskmax)
- {
- gainExpPlayer->taskcount++;
- std::stringstream info;
- std::string mons = gainExpPlayer->taskmonster;
- std::transform(mons.begin(), mons.end(), mons.begin(), (int(*)(int))tolower);
- if(gainExpPlayer->taskcount < gainExpPlayer->taskmax)
- {
- info << "You have killed " << gainExpPlayer->taskcount << " out of " << gainExpPlayer->taskmax << " " << mons << "s.";
- }
- else
- {
- info << "You have finished task of killing " << mons << "s. ";
- }
- gainExpPlayer->sendTextMessage(MSG_ORANGE, info.str().c_str());
- }
- }
- //Need to add this creature and all that can see it to spectators, unless they already added
- SpectatorVec creaturelist;
- game->getSpectators(Range(gainExpCreature->pos, true), creaturelist);
- for(SpectatorVec::const_iterator cit = creaturelist.begin(); cit != creaturelist.end(); ++cit) {
- if(std::find(spectatorlist.begin(), spectatorlist.end(), *cit) == spectatorlist.end()) {
- spectatorlist.push_back(*cit);
- }
- }
- //Add creature to attackerlist
- attackedCreatureState->attackerlist.push_back(gainExpCreature);
- }
- }
- }
- Player *player = dynamic_cast<Player*>(attacker);
- if(player){
- player->sendStats();
- }
- if(attackedCreature && attackedCreature->getMaster() != NULL) {
- attackedCreature->getMaster()->removeSummon(attackedCreature);
- }
- }
- //Add blood?
- #ifdef TJ_MONSTER_BLOOD
- if((drawBlood || attackedCreature->health <= 0) && damage > 0 && attackedCreature->bloodsplash != 255) {
- Item* splash = Item::CreateItem(dead? ITEM_POOL : ITEM_SPLASH, attackedCreature->bloodsplash);
- game->addThing(NULL, CreaturePos, splash);
- game->startDecay(splash);
- game->updateTile(CreaturePos);
- }
- #else
- if((drawBlood || attackedCreature->health <= 0) && damage > 0) {
- Item* splash = Item::CreateItem(ITEM_SPLASH, FLUID_BLOOD);
- game->addThing(NULL, CreaturePos, splash);
- game->startDecay(splash);
- game->updateTile(CreaturePos);
- }
- #endif //TJ_MONSTER_BLOOD
- }
- Game::Game()
- {
- eventIdCount = 1000;
- this->game_state = GAME_STATE_NORMAL;
- this->map = NULL;
- this->worldType = WORLD_TYPE_PVP;
- OTSYS_THREAD_LOCKVARINIT(gameLock);
- OTSYS_THREAD_LOCKVARINIT(eventLock);
- OTSYS_THREAD_LOCKVARINIT(AutoID::autoIDLock);
- #if defined __EXCEPTION_TRACER__
- OTSYS_THREAD_LOCKVARINIT(maploadlock);
- #endif
- OTSYS_THREAD_SIGNALVARINIT(eventSignal);
- BufferedPlayers.clear();
- OTSYS_CREATE_THREAD(eventThread, this);
- #ifdef __DEBUG_CRITICALSECTION__
- OTSYS_CREATE_THREAD(monitorThread, this);
- #endif
- addEvent(makeTask(DECAY_INTERVAL, boost::bind(&Game::checkDecay,this,DECAY_INTERVAL)));
- #ifdef CVS_DAY_CYCLE
- int32_t daycycle = 3600;
- light_hour_delta = 1440*10/daycycle;
- light_hour = 0;
- lightlevel = LIGHT_LEVEL_NIGHT;
- light_state = LIGHT_STATE_NIGHT;
- addEvent(makeTask(10000, boost::bind(&Game::checkLight, this, 10000)));
- #endif //CVS_DAY_CYCLE
- }
- Game::~Game()
- {
- if(map) {
- delete map;
- }
- }
- void Game::setWorldType(enum_world_type type)
- {
- this->worldType = type;
- }
- enum_game_state Game::getGameState()
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::getGameState()");
- return game_state;
- }
- int32_t Game::loadMap(std::string filename, std::string filekind) {
- if(!map)
- map = new Map;
- max_players = atoi(g_config.getGlobalString("maxplayers").c_str());
- distanceToKill = atoi(g_config.getGlobalString("dist", "50").c_str());
- return map->loadMap(filename, filekind);
- }
- /*****************************************************************************/
- #ifdef __DEBUG_CRITICALSECTION__
- OTSYS_THREAD_RETURN Game::monitorThread(void *p)
- {
- Game* _this = (Game*)p;
- while (true) {
- OTSYS_SLEEP(6000);
- int32_t ret = OTSYS_THREAD_LOCKEX(_this->gameLock, 60 * 2 * 1000);
- if(ret != OTSYS_THREAD_TIMEOUT) {
- OTSYS_THREAD_UNLOCK(_this->gameLock, NULL);
- continue;
- }
- bool file = false;
- std::ostream *outdriver;
- std::cout << "Error: generating critical section file..." <<std::endl;
- std::ofstream output("deadlock.txt",std::ios_base::app);
- if(output.fail()){
- outdriver = &std::cout;
- file = false;
- }
- else{
- file = true;
- outdriver = &output;
- }
- time_t rawtime;
- time(&rawtime);
- *outdriver << "*****************************************************" << std::endl;
- *outdriver << "Error report - " << std::ctime(&rawtime) << std::endl;
- OTSYS_THREAD_LOCK_CLASS::LogList::iterator it;
- for(it = OTSYS_THREAD_LOCK_CLASS::loglist.begin(); it != OTSYS_THREAD_LOCK_CLASS::loglist.end(); ++it) {
- *outdriver << (it->lock ? "lock - " : "unlock - ") << it->str
- << " threadid: " << it->threadid
- << " time: " << it->time
- << " ptr: " << it->mutexaddr
- << std::endl;
- }
- *outdriver << "*****************************************************" << std::endl;
- if(file)
- ((std::ofstream*)outdriver)->close();
- std::cout << "Error report generated. Killing server." <<std::endl;
- exit(1); //force exit
- }
- }
- #endif
- OTSYS_THREAD_RETURN Game::eventThread(void *p)
- {
- #if defined __EXCEPTION_TRACER__
- ExceptionHandler eventExceptionHandler;
- eventExceptionHandler.InstallHandler();
- #endif
- Game* _this = (Game*)p;
- // basically what we do is, look at the first scheduled item,
- // and then sleep until it's due (or if there is none, sleep until we get an event)
- // of course this means we need to get a notification if there are new events added
- while (true)
- {
- #ifdef __DEBUG__EVENTSCHEDULER__
- std::cout << "schedulercycle start..." << std::endl;
- #endif
- SchedulerTask* task = NULL;
- bool runtask = false;
- // check if there are events waiting...
- OTSYS_THREAD_LOCK(_this->eventLock, "eventThread()")
- int32_t ret;
- if (_this->eventList.size() == 0) {
- // unlock mutex and wait for signal
- ret = OTSYS_THREAD_WAITSIGNAL(_this->eventSignal, _this->eventLock);
- } else {
- // unlock mutex and wait for signal or timeout
- ret = OTSYS_THREAD_WAITSIGNAL_TIMED(_this->eventSignal, _this->eventLock, _this->eventList.top()->getCycle());
- }
- // the mutex is locked again now...
- if (ret == OTSYS_THREAD_TIMEOUT) {
- // ok we had a timeout, so there has to be an event we have to execute...
- #ifdef __DEBUG__EVENTSCHEDULER__
- std::cout << "event found at " << OTSYS_TIME() << " which is to be scheduled at: " << _this->eventList.top()->getCycle() << std::endl;
- #endif
- task = _this->eventList.top();
- _this->eventList.pop();
- }
- if(task) {
- std::map<uint32_t, SchedulerTask*>::iterator it = _this->eventIdMap.find(task->getEventId());
- if(it != _this->eventIdMap.end()) {
- _this->eventIdMap.erase(it);
- runtask = true;
- }
- }
- OTSYS_THREAD_UNLOCK(_this->eventLock, "eventThread()");
- if (task) {
- if(runtask) {
- (*task)(_this);
- }
- delete task;
- }
- }
- #if defined __EXCEPTION_TRACER__
- eventExceptionHandler.RemoveHandler();
- #endif
- }
- uint32_t Game::addEvent(SchedulerTask* event) {
- bool do_signal = false;
- OTSYS_THREAD_LOCK(eventLock, "addEvent()")
- if(event->getEventId() == 0) {
- ++eventIdCount;
- event->setEventId(eventIdCount);
- }
- #ifdef __DEBUG__EVENTSCHEDULER__
- std::cout << "addEvent - " << event->getEventId() << std::endl;
- #endif
- eventIdMap[event->getEventId()] = event;
- /*
- if (eventList.empty() || *event < *eventList.top())
- do_signal = true;
- */
- bool isEmpty = eventList.empty();
- eventList.push(event);
- if(isEmpty || *event < *eventList.top())
- do_signal = true;
- /*
- if (eventList.empty() || *event < *eventList.top())
- do_signal = true;
- */
- OTSYS_THREAD_UNLOCK(eventLock, "addEvent()")
- if (do_signal)
- OTSYS_THREAD_SIGNAL_SEND(eventSignal);
- return event->getEventId();
- }
- bool Game::stopEvent(uint32_t eventid) {
- if(eventid == 0)
- return false;
- OTSYS_THREAD_LOCK(eventLock, "stopEvent()")
- std::map<uint32_t, SchedulerTask*>::iterator it = eventIdMap.find(eventid);
- if(it != eventIdMap.end()) {
- #ifdef __DEBUG__EVENTSCHEDULER__
- std::cout << "stopEvent - eventid: " << eventid << "/" << it->second->getEventId() << std::endl;
- #endif
- //it->second->setEventId(0); //invalidate the event
- eventIdMap.erase(it);
- OTSYS_THREAD_UNLOCK(eventLock, "stopEvent()")
- return true;
- }
- OTSYS_THREAD_UNLOCK(eventLock, "stopEvent()")
- return false;
- }
- /*****************************************************************************/
- uint32_t Game::getPlayersOnline() {return (uint32_t)Player::listPlayer.list.size();};
- uint32_t Game::getMonstersOnline() {return (uint32_t)Monster::listMonster.list.size();};
- uint32_t Game::getNpcsOnline() {return (uint32_t)Npc::listNpc.list.size();};
- uint32_t Game::getCreaturesOnline() {return (uint32_t)listCreature.list.size();};
- Tile* Game::getTile(unsigned short _x, unsigned short _y, unsigned char _z)
- {
- return map->getTile(_x, _y, _z);
- }
- Tile* Game::getTile(const Position& pos)
- {
- return map->getTile(pos);
- }
- void Game::setTile(unsigned short _x, unsigned short _y, unsigned char _z, unsigned short groundId)
- {
- map->setTile(_x, _y, _z, groundId);
- }
- Creature* Game::getCreatureByID(uint32_t id)
- {
- if(id == 0)
- return NULL;
- AutoList<Creature>::listiterator it = listCreature.list.find(id);
- if(it != listCreature.list.end()) {
- return (*it).second;
- }
- return NULL; //just in case the player doesnt exist
- }
- Player* Game::getPlayerByID(uint32_t id)
- {
- if(id == 0)
- return NULL;
- AutoList<Player>::listiterator it = Player::listPlayer.list.find(id);
- if(it != Player::listPlayer.list.end()) {
- return (*it).second;
- }
- return NULL; //just in case the player doesnt exist
- }
- Creature* Game::getCreatureByName(const std::string &s)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::getCreatureByName()");
- std::string txt1 = s;
- std::transform(txt1.begin(), txt1.end(), txt1.begin(), upchar);
- for(AutoList<Creature>::listiterator it = listCreature.list.begin(); it != listCreature.list.end(); ++it){
- std::string txt2 = (*it).second->getName();
- std::transform(txt2.begin(), txt2.end(), txt2.begin(), upchar);
- if(txt1 == txt2)
- return it->second;
- }
- return NULL; //just in case the creature doesnt exist
- }
- Player* Game::getPlayerByName(const std::string &s)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::getPlayerByName()");
- std::string txt1 = s;
- std::transform(txt1.begin(), txt1.end(), txt1.begin(), upchar);
- for(AutoList<Player>::listiterator it = Player::listPlayer.list.begin(); it != Player::listPlayer.list.end(); ++it){
- std::string txt2 = (*it).second->getName();
- std::transform(txt2.begin(), txt2.end(), txt2.begin(), upchar);
- if(txt1 == txt2)
- return it->second;
- }
- return NULL; //just in case the player doesnt exist
- }
- bool Game::placeCreature(Position &pos, Creature* c
- #ifdef YUR_LOGIN_QUEUE
- , int32_t* placeInQueue
- #endif //YUR_LOGIN_QUEUE
- )
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::placeCreature()");
- bool success = false;
- Player *p = dynamic_cast<Player*>(c);
- Monster *monsterzin = dynamic_cast<Monster*>(c);
- #ifdef YUR_LOGIN_QUEUE
- if (!p || c->access >= g_config.ACCESS_ENTER ||
- #ifdef YUR_PREMIUM_PROMOTION
- (p->isPremmium() && !g_config.QUEUE_PREMMY) ||
- #endif //YUR_PREMIUM_PROMOTION
- loginQueue.login(p->accountNumber, getPlayersOnline(), max_players, placeInQueue))
- {
- #else //YUR_LOGIN_QUEUE
- if (!p || c->access >= g_config.ACCESS_ENTER || getPlayersOnline() < max_players)
- {
- #endif //YUR_LOGIN_QUEUE
- success = map->placeCreature(pos, c);
- if(success)
- {
- c->useThing();
- c->setID();
- //std::cout << "place: " << c << " " << c->getID() << std::endl;
- listCreature.addList(c);
- c->addList();
- c->isRemoved = false;
- sendAddThing(NULL,c->pos,c);
- if(p)
- {
- checkRecord();
- #ifdef __DEBUG_PLAYERS__
- std::cout << (uint32_t)getPlayersOnline() << " players online." << std::endl;
- #endif
- #ifdef YUR_GUILD_SYSTEM
- Guilds::ReloadGuildInfo(p);
- #endif //YUR_GUILD_SYSTEM
- /*#ifdef ELEM_VIP_LIST
- vipLogin(p);
- #endif //ELEM_VIP_LIST*/
- }
- if(p){
- c->eventCheck = addEvent(makeTask(1000, std::bind2nd(std::mem_fun(&Game::checkCreature), c->getID())));
- }
- else{
- c->eventCheck = addEvent(makeTask(1000, std::bind2nd(std::mem_fun(&Game::checkCreature), c->getID())));
- }
- //c->eventCheckAttacking = addEvent(makeTask(2000, std::bind2nd(std::mem_fun(&Game::checkCreatureAttacking), c->getID())));
- }
- }
- else {
- //we cant add the player, server is full
- success = false;
- }
- #ifdef __MIZIAK_CREATURESCRIPTS__
- if(p)
- actions.creatureEvent("login", p, NULL, NULL, NULL);
- #endif //__MIZIAK_CREATURESCRIPTS__
- if(monsterzin){
- c->masterPos.x = c->pos.x;
- c->masterPos.y = c->pos.y;
- c->masterPos.z = c->pos.z;
- }
- return success;
- }
- bool Game::removeCreature(Creature* c)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::removeCreature()");
- if(c->isRemoved == true)
- return false;
- #ifdef __DEBUG__
- std::cout << "removing creature "<< std::endl;
- #endif
- #ifdef __MIZIAK_CREATURESCRIPTS__
- Player* pc = dynamic_cast<Player*>(c);
- if(pc)
- if(!pc->dieorlogout)
- actions.creatureEvent("logout", pc, NULL, NULL, NULL);
- #endif //__MIZIAK_CREATURESCRIPTS__
- if(!removeThing(NULL,c->pos,c))
- return false;
- //std::cout << "remove: " << c << " " << c->getID() << std::endl;
- listCreature.removeList(c->getID());
- c->removeList();
- c->isRemoved = true;
- if(g_config.SUMMON_BODIES){
- c->isRemoved = true;
- Creature *summon = NULL;
- for(std::list<Creature*>::iterator cit = c->summons.begin(); cit != c->summons.end(); ++cit) {
- summon = (*cit);
- Position CreaturePos = summon->pos;
- Tile *tile = map->getTile(CreaturePos);
- Item *corpseitem = Item::CreateItem(summon->getLookCorpse());
- corpseitem->pos = CreaturePos; /*summoned bodies by Cayan*/
- tile->addThing(corpseitem);
- removeCreature(summon);
- updateTile(CreaturePos);
- }
- }
- else
- {
- c->isRemoved = true;
- //for(std::list<Creature*>::iterator cit = c->summons.begin(); cit != c->summons.end(); ++cit) {
- //removeCreature(*cit);
- //}
- }
- stopEvent(c->eventCheck);
- stopEvent(c->eventCheckAttacking);
- stopEvent(c->eventCheckFollow);
- Player* player = dynamic_cast<Player*>(c);
- if(player){
- #ifdef HUCZU_SKULLS
- for(AutoList<Player>::listiterator it = Player::listPlayer.list.begin(); it != Player::listPlayer.list.end(); ++it){
- Player *on = dynamic_cast<Player*>(it->second);
- if(on && player->isYellowTo(on)){
- on->removeFromYellowList(player);
- }
- if(on && on->hasAttacked(player)){
- on->removeFromAttakedList(player);
- }
- player->clearAttakedList();
- player->clearYellowList();
- }
- if(player->party != 0)
- LeaveParty(player);
- #endif //HUCZU_SKULLS
- if(player->tradePartner != 0) {
- playerCloseTrade(player);
- }
- if(player->eventAutoWalk)
- stopEvent(player->eventAutoWalk);
- Tile* fromT = getTile(player->pos);
- if(fromT && fromT->ground)
- actions.luaWalkOff(player,player->pos,fromT->ground->getID(),fromT->ground->getUniqueId(),fromT->ground->getActionId());
- g_chat.removeUserFromAllChannels(player);
- if(!IOPlayer::instance()->savePlayer(player)){
- std::cout << "Error while saving player: " << player->getName() << std::endl;
- }
- std::cout << (uint32_t)getPlayersOnline() << " players online." << std::endl;
- /*#ifdef ELEM_VIP_LIST
- vipLogout(c->getName());
- #endif //ELEM_VIP_LIST*/
- }
- this->FreeThing(c);
- return true;
- }
- void Game::thingMove(Creature *creature, Thing *thing,
- unsigned short to_x, unsigned short to_y, unsigned char to_z, unsigned char count)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::thingMove() - 1");
- Tile *fromTile = map->getTile(thing->pos);
- if (fromTile)
- {
- int32_t oldstackpos = fromTile->getThingStackPos(thing);
- thingMoveInternal(creature, thing->pos.x, thing->pos.y, thing->pos.z, oldstackpos, 0, to_x, to_y, to_z, count);
- }
- }
- void Game::thingMove(Creature *creature, unsigned short from_x, unsigned short from_y, unsigned char from_z,
- unsigned char stackPos, unsigned short itemid, unsigned short to_x, unsigned short to_y, unsigned char to_z, unsigned char count)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::thingMove() - 2");
- Tile *fromTile = getTile(from_x, from_y, from_z);
- if(!fromTile)
- return;
- #ifdef FIXY
- if(dynamic_cast<Player*>(creature) && fromTile && !fromTile->ground) {
- dynamic_cast<Player*>(creature)->sendCancelWalk();
- return;
- }
- #endif //FIXY
- Tile *toTile = getTile(to_x, to_y, to_z);
- if(!toTile)
- return;
- #ifdef FIXY
- if (toTile->isHouse() && !fromTile->isHouse())
- return;
- #endif //FIXY
- Thing* thing = fromTile->getThingByStackPos(stackPos);
- if(!thing)
- return;
- Item* item = dynamic_cast<Item*>(thing);
- if(item && (item->getID() != itemid || item != fromTile->getTopDownItem()))
- return;
- thingMoveInternal(creature, from_x, from_y, from_z, stackPos, itemid, to_x, to_y, to_z, count);
- }
- //container/inventory to container/inventory
- void Game::thingMove(Player *player,
- unsigned char from_cid, unsigned char from_slotid, unsigned short itemid, bool fromInventory,
- unsigned char to_cid, unsigned char to_slotid, bool toInventory,
- unsigned char count)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::thingMove() - 3");
- thingMoveInternal(player, from_cid, from_slotid, itemid, fromInventory,
- to_cid, to_slotid, toInventory, count);
- }
- //container/inventory to ground
- void Game::thingMove(Player *player,
- unsigned char from_cid, unsigned char from_slotid, unsigned short itemid, bool fromInventory,
- const Position& toPos, unsigned char count)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::thingMove() - 4");
- Container *fromContainer = player->getContainer(from_cid);
- if(fromContainer && !fromContainer->shop.empty())
- return;
- #ifdef FIXY
- Tile *toTile = getTile(toPos.x, toPos.y, toPos.z);
- if(!toTile)
- return;
- if (player) {
- Tile *fromTile = getTile(player->pos);
- if(!fromTile->isHouse() && toTile->isHouse())
- return;
- }
- #endif //FIXY
- thingMoveInternal(player, from_cid, from_slotid, itemid, fromInventory, toPos, count);
- }
- //ground to container/inventory
- void Game::thingMove(Player *player,
- const Position& fromPos, unsigned char stackPos, unsigned short itemid,
- unsigned char to_cid, unsigned char to_slotid, bool toInventory,
- unsigned char count)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::thingMove() - 5");
- thingMoveInternal(player, fromPos, stackPos, itemid, to_cid, to_slotid, toInventory, count);
- }
- #ifdef FIXY
- bool Game::onPrepareMoveThing(Creature* player, /*const*/ Thing* thing,
- const Position& fromPos, const Position& toPos, int32_t count)
- {
- const Creature* movingCreature = dynamic_cast<const Creature*>(thing);
- Player *playa = dynamic_cast<Player*>(thing);
- if ((player->access < g_config.ACCESS_REMOTE || dynamic_cast<const Player*>(thing)) &&
- ((abs(player->pos.x - fromPos.x) > 1) || (abs(player->pos.y - fromPos.y) > 1) || (player->pos.z != fromPos.z)))
- {
- player->sendCancel("Destination is out of reach.");
- return false;
- }
- //RZUCANIE GM PO EKRANIE?
- else if( ((abs(fromPos.x - toPos.x) > thing->throwRange) || (abs(fromPos.y - toPos.y) > thing->throwRange)
- || (fromPos.z != toPos.z)) && player->access >= g_config.ACCESS_REMOTE) {
- if(player == thing){
- teleport(player,toPos);
- if(!playa->gmInvisible){
- globalMagicEffect(fromPos, NM_ME_PUFF);
- globalMagicEffect(toPos, NM_ME_ENERGY_AREA);
- }
- else
- {
- playa->sendMagicEffect(fromPos, NM_ME_PUFF);
- playa->sendMagicEffect(toPos, NM_ME_ENERGY_AREA);
- }
- }
- else
- teleport(thing,toPos);
- }
- else if ((player->access < g_config.ACCESS_REMOTE || dynamic_cast<const Player*>(thing)) && ((abs(fromPos.x - toPos.x) > thing->throwRange || abs(fromPos.y - toPos.y) > thing->throwRange || (abs(fromPos.z - toPos.z+1) > thing->throwRange)))) {
- player->sendCancel("Destination is out of reach.");
- return false;
- }
- else if(player->access < g_config.ACCESS_REMOTE && movingCreature && fromPos.z != toPos.z){
- player->sendCancel("Destination is out of reach.");
- return false;
- }
- else {
- const Item* item = dynamic_cast<const Item*>(thing);
- if(item) {
- if(item->getID() == ITEM_FOOTBALL &&
- player->access < g_config.getGlobalNumber("accessfootball", 3) && (
- (abs(player->pos.x - toPos.x) > 2) ||
- (abs(player->pos.y - toPos.y) > 2) ||
- (player->pos.z != fromPos.z))
- ){
- player->sendCancel("Nie mozesz tak daleko kopnac.");
- return false;
- }
- int32_t blockstate = 0;
- if(item->isBlocking())
- blockstate |= BLOCK_SOLID;
- if(item->isPickupable() || !item->isNotMoveable())
- blockstate |= BLOCK_PICKUPABLE;
- if(blockstate != 0) {
- switch(map->canThrowObjectTo(fromPos, toPos, blockstate)) {
- case RET_NOERROR:
- return true;
- break;
- case RET_CANNOTTHROW:
- player->sendCancel("Nie mozesz tam rzucic.");
- return false;
- break;
- case RET_CREATUREBLOCK:
- case RET_NOTENOUGHROOM:
- #ifdef KOSZ
- if(item->getID() != ITEM_DUSTBIN){
- player->sendCancel("Przykro mi, nie ma miejsca.");
- return false;
- }
- #else
- player->sendCancel("Przykro mi, nie ma miejsca.");
- return false;
- #endif //KOSZ
- break;
- default:
- player->sendCancel("Sorry not possible.");
- return false;
- break;
- }
- }
- }
- }
- return true;
- }
- #else //FIXY
- bool Game::onPrepareMoveThing(Creature* player, const Thing* thing,
- const Position& fromPos, const Position& toPos, int32_t count)
- {
- if ((player->access < g_config.ACCESS_REMOTE || dynamic_cast<const Player*>(thing)) &&
- ((abs(player->pos.x - fromPos.x) > 1) || (abs(player->pos.y - fromPos.y) > 1) || (player->pos.z != fromPos.z)))
- {
- player->sendCancel("Za daleko...");
- return false;
- }
- else if ((player->access < g_config.ACCESS_REMOTE || dynamic_cast<const Player*>(thing)) &&
- ((abs(fromPos.x - toPos.x) > thing->throwRange) || (abs(fromPos.y - toPos.y) > thing->throwRange)
- || (fromPos.z != toPos.z) /*TODO: Make it possible to throw items to different floors ))*/
- {
- player->sendCancel("Destination is out of reach.");
- return false;
- }
- else {
- const Item* item = dynamic_cast<const Item*>(thing);
- if(item) {
- int32_t blockstate = 0;
- if(item->isBlocking())
- blockstate |= BLOCK_SOLID;
- if(item->isPickupable() || !item->isNotMoveable())
- blockstate |= BLOCK_PICKUPABLE;
- if(blockstate != 0) {
- switch(map->canThrowObjectTo(fromPos, toPos, blockstate)) {
- case RET_NOERROR:
- return true;
- break;
- case RET_CANNOTTHROW:
- player->sendCancel("Nie mozesz tam rzucic.");
- return false;
- break;
- case RET_CREATUREBLOCK:
- case RET_NOTENOUGHROOM:
- player->sendCancel("Przykro mi, nie ma miejsca.");
- return false;
- break;
- default:
- player->sendCancel("Sorry not possible.");
- return false;
- break;
- }
- }
- }
- }
- return true;
- }
- #endif //FIXY
- /*ground -> ground*/
- bool Game::onPrepareMoveThing(Creature* creature, const Thing* thing,
- const Tile* fromTile, const Tile *toTile, int32_t count)
- {
- const Player* player = dynamic_cast<const Player*>(creature);
- const Item *item = dynamic_cast<const Item*>(thing);
- const Creature* movingCreature = dynamic_cast<const Creature*>(thing);
- const Player* movingPlayer = dynamic_cast<const Player*>(thing);
- /* if(movingCreature){
- addEvent(makeTask(2000, std::mem_fun(&Game::onPrepareMoveCreature, creature, movingCreature, fromTile, toTile))));
- }*/
- if(item && !item->canMovedTo(toTile)) {
- creature->sendCancel("Sorry, not possible.");
- return false;
- }
- else if(movingCreature && !movingCreature->canMovedTo(toTile)) {
- if(player && player->eventCheckFollow == 0) {
- player->sendTextMessage(MSG_SMALLINFO, "Sorry, not possible.");
- player->sendCancelWalk();
- }
- return false;
- }
- else if(!movingPlayer && toTile && toTile->floorChange()) {
- creature->sendCancel("Sorry, not possible.");
- return false;
- }
- else if(movingCreature && toTile && !toTile->ground) {
- if(player) {
- player->sendTextMessage(MSG_SMALLINFO, "Sorry, not possible.");
- player->sendCancelWalk();
- }
- return false;
- }
- if (fromTile && fromTile->splash == thing && fromTile->splash->isNotMoveable()) {
- creature->sendCancel("You cannot move this object.");
- #ifdef __DEBUG__
- cout << creature->getName() << " is trying to move a splash item!" << std::endl;
- #endif
- return false;
- }
- else if (item && item->isNotMoveable()) {
- creature->sendCancel("You cannot move this object.");
- #ifdef __DEBUG__
- cout << creature->getName() << " is trying to move an unmoveable item!" << std::endl;
- #endif
- return false;
- }
- #ifdef TLM_HOUSE_SYSTEM
- if (item && toTile && toTile->isHouse())
- {
- const Container* container = dynamic_cast<const Container*>(item);
- int32_t moving = container? container->getItemHoldingCount() : 1;
- if (moving + toTile->getItemHoldingCount() > g_config.MAX_HOUSE_TILE_ITEMS)
- {
- creature->sendCancel("You cannot put more items on a house tile.");
- return false;
- }
- }
- #endif //TLM_HOUSE_SYSTEM
- return true; //return thing->canMovedTo(toTile);
- }
- /*inventory -> container*/
- bool Game::onPrepareMoveThing(Player* player, const Item* fromItem, slots_t fromSlot,
- const Container* toContainer, const Item* toItem, int32_t count)
- {
- if(toContainer && !toContainer->shop.empty()){
- creatureUseShop(player, fromItem->getID(), count, "toShop");
- return false;
- }
- if(toContainer && toContainer->getParent() && !toContainer->getParent()->shop.empty())
- return false;
- if(!fromItem->isPickupable()) {
- player->sendCancel("Sorry, not possible.");
- return false;
- }
- else {
- const Container *itemContainer = dynamic_cast<const Container*>(fromItem);
- if(itemContainer) {
- if(itemContainer->isHoldingItem(toContainer) || (toContainer == itemContainer)) {
- player->sendCancel("To jest niemozliwe!");
- return false;
- }
- }
- if((!fromItem->isStackable() || !toItem || fromItem->getID() != toItem->getID() || toItem->getItemCountOrSubtype() >= 100) && toContainer->size() + 1 > toContainer->capacity()) {
- player->sendCancel("Przykro mi, nie ma miejsca.");
- return false;
- }
- Container const *topContainer = toContainer->getTopParent();
- int32_t itemsToadd;
- if(!topContainer)
- topContainer = toContainer;
- Container const *fromContainer = dynamic_cast<const Container*>(fromItem);
- if(fromContainer)
- itemsToadd = fromContainer->getItemHoldingCount() + 1;
- else
- itemsToadd = 1;
- if(topContainer->depot != 0 && player->max_depot_items != 0 && topContainer->getItemHoldingCount() + itemsToadd >= player->max_depot_items){
- player->sendCancel("Nie mozesz polozyc wiecej przedmiotow w depo.");
- return false;
- }
- }
- return true;
- }
- /*container -> container*/
- /*ground -> container*/
- bool Game::onPrepareMoveThing(Player* player,
- const Position& fromPos, const Container* fromContainer, const Item* fromItem,
- const Position& toPos, const Container* toContainer, const Item* toItem, int32_t count)
- {
- if(fromContainer && toContainer && (!fromContainer->shop.empty() || !toContainer->shop.empty())){
- creatureUseShop(player, fromItem->getID(), count, (!fromContainer->shop.empty() ? "fromShop" : "toShop"));
- return false;
- }
- if(!fromContainer && toContainer && !toContainer->shop.empty())
- return false;
- if(toContainer && toContainer->getParent() && !toContainer->getParent()->shop.empty())
- return false;
- if (player->access < g_config.ACCESS_REMOTE &&
- ((abs(player->pos.x - fromPos.x) > 1) || (abs(player->pos.y - fromPos.y) > 1) || (player->pos.z != fromPos.z)))
- {
- player->sendCancel("Za daleko...");
- return false;
- }
- else if (player->access < g_config.ACCESS_REMOTE &&
- ((abs(fromPos.x - toPos.x) > fromItem->throwRange) || (abs(fromPos.y - toPos.y) > fromItem->throwRange)
- || (fromPos.z != toPos.z)))
- {
- player->sendCancel("Destination is out of reach.");
- return false;
- }
- if(!fromItem->isPickupable()) {
- player->sendCancel("You cannot move this object.");
- return false;
- }
- else {
- if((!fromItem->isStackable() || !toItem || fromItem->getID() != toItem->getID() || toItem->getItemCountOrSubtype() >= 100) && toContainer->size() + 1 > toContainer->capacity()) {
- player->sendCancel("Przykro mi, nie ma miejsca.");
- return false;
- }
- const Container *itemContainer = dynamic_cast<const Container*>(fromItem);
- if(itemContainer) {
- if(itemContainer->isHoldingItem(toContainer) || (toContainer == itemContainer) || (fromContainer && fromContainer == itemContainer)) {
- player->sendCancel("To jest niemozliwe!");
- return false;
- }
- }
- double itemWeight = (fromItem->isStackable() ? Item::items[fromItem->getID()].weight * std::max(1, count) : fromItem->getWeight());
- if((!fromContainer || !player->isHoldingContainer(fromContainer)) && player->isHoldingContainer(toContainer)) {
- if(player->access < g_config.ACCESS_PROTECT && player->getFreeCapacity() < itemWeight) {
- player->sendCancel("Ten przedmiot jest za ciezki.");
- return false;
- }
- }
- Container const *topContainer = toContainer->getTopParent();
- int32_t itemsToadd;
- if(!topContainer)
- topContainer = toContainer;
- Container const *fromContainer = dynamic_cast<const Container*>(fromItem);
- if(fromContainer)
- itemsToadd = fromContainer->getItemHoldingCount() + 1;
- else
- itemsToadd = 1;
- if(topContainer->depot != 0 && player->max_depot_items != 0 && topContainer->getItemHoldingCount() >= player->max_depot_items){
- player->sendCancel("Nie mozesz polozyc wiecej przedmiotow w depo.");
- return false;
- }
- }
- return true;
- }
- /*ground -> ground*/
- bool Game::onPrepareMoveCreature(Creature *creature, const Creature* creatureMoving,
- const Tile *fromTile, const Tile *toTile)
- {
- const Player* playerMoving = dynamic_cast<const Player*>(creatureMoving);
- Player* player = dynamic_cast<Player*>(creature);
- #ifdef _BBK_PUSH_DELAY
- if(player && player != creatureMoving && player->pushDelay > 0)
- {
- player->sendCancel("Wait a moment.");
- return false;
- }
- else if(player)
- player->pushDelay = 2*1000; //2 sec
- //wypychanie z depo
- if(player && playerMoving && player != playerMoving && fromTile->isPz() && !toTile->isPz())
- {
- player->sendCancel("Sorry, not possible.");
- return false;
- }
- //wepchanie do depo
- if(player && playerMoving && playerMoving->pzLocked && toTile->isPz())
- {
- player->sendCancel("Sorry, not possible.");
- player->sendCancelWalk();
- return false;
- }
- //wchodzenie do depo
- if(player && player->pzLocked && toTile->isPz())
- {
- player->sendCancel("You can not enter a protection zone after attacking another player.");
- player->sendCancelWalk();
- return false;
- }
- #endif //_BBK_PUSH_DELAY
- if (creature->access < g_config.ACCESS_PROTECT && creature != creatureMoving && !creatureMoving->isPushable())
- {
- creature->sendCancel("Sorry, not possible.");
- return false;
- }
- else if(creature != creatureMoving && toTile->floorChange()){
- creature->sendCancel("Sorry, not possible.");
- return false;
- }
- else if(creature != creatureMoving && toTile->getTeleportItem()){
- creature->sendCancel("Sorry, not possible.");
- return false;
- }
- return true;
- }
- /*ground -> inventory*/
- bool Game::onPrepareMoveThing(Player *player, const Position& fromPos, const Item *item,
- slots_t toSlot, int32_t count)
- {
- if (player->access < g_config.ACCESS_REMOTE &&
- ((abs(player->pos.x - fromPos.x) > 1) || (abs(player->pos.y - fromPos.y) > 1) || (player->pos.z != fromPos.z)))
- {
- player->sendCancel("It's too far.");
- return false;
- }
- else if(!item->isPickupable()) {
- player->sendCancel("You cannot move this object.");
- return false;
- }
- double itemWeight = (item->isStackable() ? Item::items[item->getID()].weight * std::max(1, count) : item->getWeight());
- if(player->access < g_config.ACCESS_PROTECT && player->getFreeCapacity() < itemWeight) {
- player->sendCancel("This object is too heavy.");
- return false;
- }
- return true;
- }
- /*inventory -> inventory*/
- bool Game::onPrepareMoveThing(Player *player, slots_t fromSlot, const Item *fromItem,
- slots_t toSlot, const Item *toItem, int32_t count)
- {
- if(toItem && (!toItem->isStackable() || toItem->getID() != fromItem->getID())) {
- player->sendCancel("There is not enough room.");
- return false;
- }
- return true;
- }
- /*container -> inventory*/
- bool Game::onPrepareMoveThing(Player *player, const Container *fromContainer, const Item *fromItem,
- slots_t toSlot, const Item *toItem, int32_t count)
- {
- if(fromContainer && !fromContainer->shop.empty()){
- creatureUseShop(player, fromItem->getID(), count, "fromShop");
- return false;
- }
- #ifdef _REX_FIGHT_MOD_
- if (toItem && (toItem->getID() == fromItem->getID() && !toItem->isStackable())){
- #else
- if(toItem && (!toItem->isStackable() || toItem->getID() != fromItem->getID())) {
- #endif //Segundo em container -> inventory
- player->sendCancel("There is not enough room.");
- return false;
- }
- double itemWeight = (fromItem->isStackable() ? Item::items[fromItem->getID()].weight * std::max(1, count) : fromItem->getWeight());
- if(player->access < g_config.ACCESS_PROTECT && !player->isHoldingContainer(fromContainer) &&
- player->getFreeCapacity() < itemWeight) {
- player->sendCancel("This object is too heavy.");
- return false;
- }
- return true;
- }
- /*->inventory*/
- bool Game::onPrepareMoveThing(Player *player, const Item *item,
- slots_t toSlot, int32_t count)
- {
- switch(toSlot)
- {
- case SLOT_HEAD:
- if(item->getSlotPosition() & SLOTP_HEAD)
- return true;
- break;
- case SLOT_NECKLACE:
- if(item->getSlotPosition() & SLOTP_NECKLACE)
- return true;
- break;
- case SLOT_BACKPACK:
- if(item->getSlotPosition() & SLOTP_BACKPACK)
- return true;
- break;
- case SLOT_ARMOR:
- if(item->getSlotPosition() & SLOTP_ARMOR)
- return true;
- break;
- case SLOT_RIGHT:
- if(item->getSlotPosition() & SLOTP_RIGHT){
- #ifdef _REX_CVS_MOD_
- //One weapon for hand by ReX
- if(item && item->isWeapon() && item->getWeaponType() != SHIELD && player->items[SLOT_LEFT] != NULL && player->items[SLOT_LEFT]->isWeapon() && player->items[SLOT_LEFT]->getWeaponType() != SHIELD){
- player->sendCancel("You may use only one weapon.");
- return false;
- }
- #endif
- else if(item->getSlotPosition() & SLOTP_TWO_HAND){
- if(player->items[SLOT_LEFT] != NULL){
- player->sendCancel("First remove the two-handed item.");
- return false;
- }
- return true ;
- }
- else{
- if(player->items[SLOT_LEFT]){
- #ifdef _REX_CVS_MOD_
- //One weapon for hand by ReX
- if(item && item->isWeapon() && item->getWeaponType() != SHIELD && player->items[SLOT_LEFT] != NULL && player->items[SLOT_LEFT]->isWeapon() && player->items[SLOT_LEFT]->getWeaponType() != SHIELD){
- player->sendCancel("You may use only one weapon.");
- return false;
- }
- #endif
- else if(player->items[SLOT_LEFT]->getSlotPosition() & SLOTP_TWO_HAND){
- player->sendCancel("First remove the two-handed item.");
- return false;
- }
- return true;
- }
- return true;
- }
- }
- break;
- case SLOT_LEFT:
- if(item->getSlotPosition() & SLOTP_LEFT){
- #ifdef _REX_CVS_MOD_
- //One weapon for hand by ReX
- if(item && item->isWeapon() && item->getWeaponType() != SHIELD && player->items[SLOT_RIGHT] != NULL && player->items[SLOT_RIGHT]->isWeapon() && player->items[SLOT_RIGHT]->getWeaponType() != SHIELD){
- player->sendCancel("You may use only one weapon.");
- return false;
- }
- #endif
- else if(item->getSlotPosition() & SLOTP_TWO_HAND){
- if(player->items[SLOT_RIGHT] != NULL){
- player->sendCancel("First remove the two-handed item.");
- return false;
- }
- return true ;
- }
- else{
- if(player->items[SLOT_RIGHT]){
- #ifdef _REX_CVS_MOD_
- //One weapon for hand by ReX
- if(item && item->isWeapon() && item->getWeaponType() != SHIELD && player->items[SLOT_RIGHT] != NULL && player->items[SLOT_RIGHT]->isWeapon() && player->items[SLOT_RIGHT]->getWeaponType() != SHIELD){
- player->sendCancel("You may use only one weapon.");
- return false;
- }
- #endif
- else if(player->items[SLOT_RIGHT]->getSlotPosition() & SLOTP_TWO_HAND){
- player->sendCancel("First remove the two-handed item.");
- return false;
- }
- return true;
- }
- return true;
- }
- }
- break;
- case SLOT_LEGS:
- if(item->getSlotPosition() & SLOTP_LEGS)
- return true;
- break;
- case SLOT_FEET:
- if(item->getSlotPosition() & SLOTP_FEET)
- return true;
- break;
- case SLOT_RING:
- if(item->getSlotPosition() & SLOTP_RING
- #ifdef _REX_CVS_MOD_
- || item->getID() == 2208
- #endif
- )
- return true;
- break;
- case SLOT_AMMO:
- if(item->getSlotPosition() & SLOTP_AMMO)
- return true;
- break;
- }
- player->sendCancel("You cannot put that object in that place.");
- return false;
- }
- //container/inventory to container/inventory
- void Game::thingMoveInternal(Player *player,
- unsigned short from_cid, unsigned short from_slotid, unsigned short itemid,
- bool fromInventory,unsigned short to_cid, unsigned short to_slotid, bool toInventory,
- unsigned short count)
- {
- Container *fromContainer = NULL;
- Container *toContainer = NULL;
- Item *fromItem = NULL;
- Item *toItem = NULL;
- if(fromInventory) {
- fromItem = player->getItem(from_cid);
- fromContainer = dynamic_cast<Container *>(fromItem);
- }
- else {
- fromContainer = player->getContainer(from_cid);
- if(fromContainer) {
- if(from_slotid >= fromContainer->size())
- return;
- fromItem = fromContainer->getItem(from_slotid);
- }
- }
- if(toInventory) {
- toItem = player->getItem(to_cid);
- toContainer = dynamic_cast<Container *>(toItem);
- }
- else {
- toContainer = player->getContainer(to_cid);
- if(toContainer) {
- if(to_slotid >= toContainer->capacity())
- return;
- toItem = toContainer->getItem(to_slotid);
- Container *toSlotContainer = dynamic_cast<Container*>(toItem);
- if(toSlotContainer) {
- toContainer = toSlotContainer;
- toItem = NULL;
- }
- }
- }
- if(!fromItem || (toItem == fromItem) || (fromItem->isStackable() && count > fromItem->getItemCountOrSubtype()) || fromItem->getID() != itemid)
- return;
- //Container to container
- if(!fromInventory && fromContainer && toContainer) {
- Position fromPos = (fromContainer->pos.x == 0xFFFF ? player->pos : fromContainer->pos);
- Position toPos = (toContainer->pos.x == 0xFFFF ? player->pos : toContainer->pos);
- if(onPrepareMoveThing(player, fromPos, fromContainer, fromItem, toPos, toContainer, toItem, count)) {
- autoCloseTrade(fromItem, true);
- int32_t oldFromCount = fromItem->getItemCountOrSubtype();
- int32_t oldToCount = 0;
- //move around an item in a container
- if(fromItem->isStackable()) {
- if(toItem && toItem != fromItem && toItem->getID() == fromItem->getID())
- {
- oldToCount = toItem->getItemCountOrSubtype();
- int32_t newToCount = std::min(100, oldToCount + count);
- toItem->setItemCountOrSubtype(newToCount);
- if(oldToCount != newToCount) {
- autoCloseTrade(toItem);
- }
- int32_t subcount = oldFromCount - count;
- fromItem->setItemCountOrSubtype(subcount);
- int32_t surplusCount = oldToCount + count - 100;
- if(surplusCount > 0) {
- Item *surplusItem = Item::CreateItem(fromItem->getID(), surplusCount);
- if(onPrepareMoveThing(player, fromPos, fromContainer, surplusItem, toPos, toContainer, NULL, count)) {
- autoCloseTrade(toContainer);
- toContainer->addItem(surplusItem);
- }
- else {
- delete surplusItem;
- count -= surplusCount; //re-define the actual amount we move.
- fromItem->setItemCountOrSubtype(fromItem->getItemCountOrSubtype() + surplusCount);
- }
- }
- }
- else if(count < oldFromCount) {
- int32_t subcount = oldFromCount - count;
- fromItem->setItemCountOrSubtype(subcount);
- Item* moveItem = Item::CreateItem(fromItem->getID(), count);
- toContainer->addItem(moveItem);
- autoCloseTrade(toContainer);
- }
- else {
- if(fromContainer == toContainer) {
- fromContainer->moveItem(from_slotid, 0);
- }
- else if(fromContainer->removeItem(fromItem)) {
- autoCloseTrade(toContainer);
- toContainer->addItem(fromItem);
- }
- }
- if(fromItem->getItemCountOrSubtype() == 0) {
- fromContainer->removeItem(fromItem);
- this->FreeThing(fromItem);
- }
- }
- else {
- if(fromContainer == toContainer) {
- fromContainer->moveItem(from_slotid, 0);
- }
- else if(fromContainer->removeItem(fromItem)) {
- autoCloseTrade(toContainer);
- toContainer->addItem(fromItem);
- }
- }
- if(player->isHoldingContainer(fromContainer) != player->isHoldingContainer(toContainer)) {
- player->updateInventoryWeigth();
- }
- SpectatorVec list;
- SpectatorVec::iterator it;
- if(fromPos == toPos) {
- getSpectators(Range(fromPos, false), list);
- }
- else {
- getSpectators(Range(fromPos, toPos), list);
- }
- if(!list.empty()) {
- //players
- for(it = list.begin(); it != list.end(); ++it) {
- if(dynamic_cast<Player*>(*it)) {
- (*it)->onThingMove(player, fromContainer, from_slotid, fromItem, oldFromCount, toContainer, to_slotid, toItem, oldToCount, count);
- }
- }
- //none-players
- for(it = list.begin(); it != list.end(); ++it) {
- if(!dynamic_cast<Player*>(*it)) {
- (*it)->onThingMove(player, fromContainer, from_slotid, fromItem, oldFromCount, toContainer, to_slotid, toItem, oldToCount, count);
- }
- }
- }
- else
- player->onThingMove(player, fromContainer, from_slotid, fromItem, oldFromCount, toContainer, to_slotid, toItem, oldToCount, count);
- }
- }
- else {
- //inventory to inventory
- if(fromInventory && toInventory && !toContainer) {
- Position fromPos = player->pos;
- Position toPos = player->pos;
- if(onPrepareMoveThing(player, fromItem, (slots_t)to_cid, count) && onPrepareMoveThing(player, (slots_t)from_cid, fromItem, (slots_t)to_cid, toItem, count)) {
- autoCloseTrade(fromItem, true);
- int32_t oldFromCount = fromItem->getItemCountOrSubtype();
- int32_t oldToCount = 0;
- //bbk 2020
- std::cout << "inventory to inventory" << std::endl;
- if(fromItem && (slots_t)to_cid == SLOT_RING) fromItem->setGlimmer();
- if(toItem && (slots_t)from_cid == SLOT_RING) toItem->removeGlimmer();
- if(fromItem->isStackable()) {
- if(toItem && toItem != fromItem && toItem->getID() == fromItem->getID())
- {
- oldToCount = toItem->getItemCountOrSubtype();
- int32_t newToCount = std::min(100, oldToCount + count);
- toItem->setItemCountOrSubtype(newToCount);
- if(oldToCount != newToCount) {
- autoCloseTrade(toItem);
- }
- int32_t subcount = oldFromCount - count;
- fromItem->setItemCountOrSubtype(subcount);
- int32_t surplusCount = oldToCount + count - 100;
- if(surplusCount > 0) {
- fromItem->setItemCountOrSubtype(fromItem->getItemCountOrSubtype() + surplusCount);
- player->sendCancel("There is not enough room.");
- }
- if(fromItem->getItemCountOrSubtype() == 0) {
- player->removeItemInventory(from_cid, true);
- this->FreeThing(fromItem);
- }
- }
- else if(count < oldFromCount) {
- int32_t subcount = oldFromCount - count;
- fromItem->setItemCountOrSubtype(subcount);
- autoCloseTrade(toItem);
- player->removeItemInventory(to_cid, true);
- player->addItemInventory(Item::CreateItem(fromItem->getID(), count), to_cid, true);
- if(fromItem->getItemCountOrSubtype() == 0) {
- player->removeItemInventory(from_cid, true);
- this->FreeThing(fromItem);
- }
- }
- else {
- if(player->removeItemInventory(from_cid, true)) {
- player->removeItemInventory(to_cid, true);
- player->addItemInventory(fromItem, to_cid, true);
- }
- }
- }
- else if(player->removeItemInventory(from_cid, true)) {
- player->removeItemInventory(to_cid, true);
- player->addItemInventory(fromItem, to_cid, true);
- }
- player->onThingMove(player, (slots_t)from_cid, fromItem, oldFromCount, (slots_t)to_cid, toItem, oldToCount, count);
- }
- }
- //container to inventory
- else if(!fromInventory && fromContainer && toInventory) {
- if(onPrepareMoveThing(player, fromItem, (slots_t)to_cid, count) && onPrepareMoveThing(player, fromContainer, fromItem, (slots_t)to_cid, toItem, count)) {
- autoCloseTrade(fromItem, true);
- int32_t oldFromCount = fromItem->getItemCountOrSubtype();
- int32_t oldToCount = 0;
- //bbk 2020
- std::cout << "container to inventory" << std::endl;
- if(fromItem) fromItem->removeGlimmer();
- if(toItem ) toItem->removeGlimmer();
- if(fromItem->isStackable()) {
- if(toItem && toItem != fromItem && toItem->getID() == fromItem->getID())
- {
- oldToCount = toItem->getItemCountOrSubtype();
- int32_t newToCount = std::min(100, oldToCount + count);
- toItem->setItemCountOrSubtype(newToCount);
- if(oldToCount != newToCount) {
- autoCloseTrade(toItem);
- }
- int32_t subcount = oldFromCount - count;
- fromItem->setItemCountOrSubtype(subcount);
- int32_t surplusCount = oldToCount + count - 100;
- if(surplusCount > 0) {
- fromItem->setItemCountOrSubtype(fromItem->getItemCountOrSubtype() + surplusCount);
- player->sendCancel("There is not enough room.");
- }
- if(fromItem->getItemCountOrSubtype() == 0) {
- fromContainer->removeItem(fromItem);
- this->FreeThing(fromItem);
- }
- }
- else if(count < oldFromCount) {
- int32_t subcount = oldFromCount - count;
- fromItem->setItemCountOrSubtype(subcount);
- player->removeItemInventory(to_cid, true);
- player->addItemInventory(Item::CreateItem(fromItem->getID(), count), to_cid, true);
- if(toItem) {
- fromContainer->addItem(toItem);
- }
- if(fromItem->getItemCountOrSubtype() == 0) {
- fromContainer->removeItem(fromItem);
- this->FreeThing(fromItem);
- }
- }
- else {
- if(fromContainer->removeItem(fromItem)) {
- player->removeItemInventory(to_cid, true);
- player->addItemInventory(fromItem, to_cid, true);
- if(toItem) {
- fromContainer->addItem(toItem);
- }
- }
- }
- }
- else if(fromContainer->removeItem(fromItem)) {
- player->removeItemInventory(to_cid, true);
- player->addItemInventory(fromItem, to_cid, true);
- if(toItem) {
- fromContainer->addItem(toItem);
- }
- }
- if(!player->isHoldingContainer(fromContainer)) {
- player->updateInventoryWeigth();
- }
- //if(fromContainer->pos.x != 0xFFFF) {
- if(fromContainer->getTopParent()->pos.x != 0xFFFF) {
- SpectatorVec list;
- SpectatorVec::iterator it;
- getSpectators(Range(fromContainer->getTopParent()->pos, false), list);
- //players
- for(it = list.begin(); it != list.end(); ++it) {
- if(dynamic_cast<Player*>(*it)) {
- (*it)->onThingMove(player, fromContainer, from_slotid, fromItem, oldFromCount, (slots_t)to_cid, toItem, oldToCount, count);
- }
- }
- //none-players
- for(it = list.begin(); it != list.end(); ++it) {
- if(!dynamic_cast<Player*>(*it)) {
- (*it)->onThingMove(player, fromContainer, from_slotid, fromItem, oldFromCount, (slots_t)to_cid, toItem, oldToCount, count);
- }
- }
- }
- else
- player->onThingMove(player, fromContainer, from_slotid, fromItem, oldFromCount, (slots_t)to_cid, toItem, oldToCount, count);
- }
- }
- //inventory to container
- else if(fromInventory && toContainer) {
- Position fromPos = player->pos;
- Position toPos = (toContainer->pos.x == 0xFFFF ? player->pos : toContainer->pos);
- int32_t oldFromCount = fromItem->getItemCountOrSubtype();
- int32_t oldToCount = 0;
- //bbk 2020
- std::cout << "inventory to container" << std::endl;
- if(fromItem) fromItem->removeGlimmer();
- if(toItem) toItem->removeGlimmer();
- if(onPrepareMoveThing(player, fromItem, (slots_t)from_cid, toContainer, toItem, count)) {
- autoCloseTrade(fromItem, true);
- if(fromItem->isStackable()) {
- if(toItem && toItem != fromItem && toItem->getID() == fromItem->getID())
- {
- oldToCount = toItem->getItemCountOrSubtype();
- int32_t newToCount = std::min(100, oldToCount + count);
- toItem->setItemCountOrSubtype(newToCount);
- if(oldToCount != newToCount) {
- autoCloseTrade(toItem);
- }
- int32_t subcount = oldFromCount - count;
- fromItem->setItemCountOrSubtype(subcount);
- int32_t surplusCount = oldToCount + count - 100;
- if(surplusCount > 0) {
- Item *surplusItem = Item::CreateItem(fromItem->getID(), surplusCount);
- if(onPrepareMoveThing(player, fromPos, NULL, surplusItem, toPos, toContainer, NULL, count)) {
- autoCloseTrade(toContainer);
- toContainer->addItem(surplusItem);
- }
- else {
- delete surplusItem;
- count -= surplusCount; //re-define the actual amount we move.
- fromItem->setItemCountOrSubtype(fromItem->getItemCountOrSubtype() + surplusCount);
- }
- }
- }
- else if(count < oldFromCount) {
- int32_t subcount = oldFromCount - count;
- fromItem->setItemCountOrSubtype(subcount);
- autoCloseTrade(toContainer);
- toContainer->addItem(Item::CreateItem(fromItem->getID(), count));
- }
- else {
- if(player->removeItemInventory((slots_t)from_cid, true)) {
- autoCloseTrade(toContainer);
- toContainer->addItem(fromItem);
- if(player->isHoldingContainer(toContainer)) {
- player->updateInventoryWeigth();
- }
- }
- }
- if(fromItem->getItemCountOrSubtype() == 0) {
- player->removeItemInventory(from_cid, true);
- this->FreeThing(fromItem);
- }
- }
- else if(player->removeItemInventory(from_cid, true)) {
- autoCloseTrade(toContainer);
- toContainer->addItem(fromItem);
- if(player->isHoldingContainer(toContainer)) {
- player->updateInventoryWeigth();
- }
- }
- if(!player->isHoldingContainer(toContainer)) {
- player->updateInventoryWeigth();
- }
- if(toContainer->getTopParent()->pos.x != 0xFFFF) {
- SpectatorVec list;
- SpectatorVec::iterator it;
- getSpectators(Range(toContainer->getTopParent()->pos, false), list);
- //players
- for(it = list.begin(); it != list.end(); ++it) {
- if(dynamic_cast<Player*>(*it)) {
- (*it)->onThingMove(player, (slots_t)from_cid, fromItem, oldFromCount, toContainer, to_slotid, toItem, oldToCount, count);
- }
- }
- //none-players
- for(it = list.begin(); it != list.end(); ++it) {
- if(!dynamic_cast<Player*>(*it)) {
- (*it)->onThingMove(player, (slots_t)from_cid, fromItem, oldFromCount, toContainer, to_slotid, toItem, oldToCount, count);
- }
- }
- }
- else
- player->onThingMove(player, (slots_t)from_cid, fromItem, oldFromCount, toContainer, to_slotid, toItem, oldToCount, count);
- }
- }
- }
- }
- //container/inventory to ground
- void Game::thingMoveInternal(Player *player,
- unsigned char from_cid, unsigned char from_slotid, unsigned short itemid, bool fromInventory,
- const Position& toPos, unsigned char count)
- {
- Container *fromContainer = NULL;
- Tile *toTile = map->getTile(toPos);
- if(!toTile)
- return;
- /*container to ground*/
- if(!fromInventory) {
- fromContainer = player->getContainer(from_cid);
- if(!fromContainer)
- return;
- Position fromPos = (fromContainer->pos.x == 0xFFFF ? player->pos : fromContainer->pos);
- Item *fromItem = dynamic_cast<Item*>(fromContainer->getItem(from_slotid));
- Item* toItem = dynamic_cast<Item*>(toTile->getTopDownItem());
- if(!fromItem || (toItem == fromItem) || (fromItem->isStackable() && count > fromItem->getItemCountOrSubtype()) || fromItem->getID() != itemid)
- return;
- if(onPrepareMoveThing(player, fromItem, fromPos, toPos, count) && onPrepareMoveThing(player, fromItem, NULL, toTile, count)) {
- autoCloseTrade(fromItem, true);
- int32_t oldFromCount = fromItem->getItemCountOrSubtype();
- int32_t oldToCount = 0;
- //Do action...
- #ifdef TP_TRASH_BINS
- if (toItem && toItem->isDeleter())
- {
- fromContainer->removeItem(fromItem);
- FreeThing(fromItem);
- }
- else if(fromItem->isStackable()) {
- #else
- if(fromItem->isStackable()) {
- #endif //TP_TRASH_BINS
- if(toItem && toItem->getID() == fromItem->getID())
- {
- oldToCount = toItem->getItemCountOrSubtype();
- int32_t newToCount = std::min(100, oldToCount + count);
- toItem->setItemCountOrSubtype(newToCount);
- if(oldToCount != newToCount) {
- autoCloseTrade(toItem);
- }
- int32_t subcount = oldFromCount - count;
- fromItem->setItemCountOrSubtype(subcount);
- int32_t surplusCount = oldToCount + count - 100;
- if(surplusCount > 0) {
- Item *surplusItem = Item::CreateItem(fromItem->getID(), surplusCount);
- surplusItem->pos = toPos;
- toTile->addThing(surplusItem);
- }
- if(fromItem->getItemCountOrSubtype() == 0) {
- fromContainer->removeItem(fromItem);
- this->FreeThing(fromItem);
- }
- }
- else if(count < oldFromCount) {
- int32_t subcount = oldFromCount - count;
- fromItem->setItemCountOrSubtype(subcount);
- Item *moveItem = Item::CreateItem(fromItem->getID(), count);
- moveItem->pos = toPos;
- toTile->addThing(moveItem);
- if(fromItem->getItemCountOrSubtype() == 0) {
- fromContainer->removeItem(fromItem);
- this->FreeThing(fromItem);
- }
- }
- else if(fromContainer->removeItem(fromItem)) {
- fromItem->pos = toPos;
- toTile->addThing(fromItem);
- }
- }
- else if(fromContainer->removeItem(fromItem)) {
- fromItem->pos = toPos;
- toTile->addThing(fromItem);
- }
- if(player->isHoldingContainer(fromContainer)) {
- player->updateInventoryWeigth();
- }
- SpectatorVec list;
- SpectatorVec::iterator it;
- getSpectators(Range(fromPos, false), list);
- SpectatorVec tolist;
- getSpectators(Range(toPos, true), tolist);
- for(it = tolist.begin(); it != tolist.end(); ++it) {
- if(std::find(list.begin(), list.end(), *it) == list.end()) {
- list.push_back(*it);
- }
- }
- //players
- for(it = list.begin(); it != list.end(); ++it) {
- if(dynamic_cast<Player*>(*it)) {
- (*it)->onThingMove(player, fromContainer, from_slotid, fromItem, oldFromCount, toPos, toItem, oldToCount, count);
- }
- }
- //none-players
- for(it = list.begin(); it != list.end(); ++it) {
- if(!dynamic_cast<Player*>(*it)) {
- (*it)->onThingMove(player, fromContainer, from_slotid, fromItem, oldFromCount, toPos, toItem, oldToCount, count);
- }
- }
- }
- }
- else /*inventory to ground*/{
- Item *fromItem = player->getItem(from_cid);
- if(!fromItem || (fromItem->isStackable() && count > fromItem->getItemCountOrSubtype()) || fromItem->getID() != itemid)
- return;
- if(onPrepareMoveThing(player, fromItem, player->pos, toPos, count) && onPrepareMoveThing(player, fromItem, NULL, toTile, count)) {
- autoCloseTrade(fromItem, true);
- Item* toItem = dynamic_cast<Item*>(toTile->getTopDownItem());
- int32_t oldFromCount = fromItem->getItemCountOrSubtype();
- int32_t oldToCount = 0;
- //bbk 2020
- std::cout << "inventory to ground" << std::endl;
- if(fromItem) fromItem->removeGlimmer();
- //Do action...
- #ifdef TP_TRASH_BINS
- if(toItem && toItem->isDeleter())
- {
- player->removeItemInventory(from_cid, true);
- FreeThing(fromItem);
- }
- else if(fromItem->isStackable()) {
- #else
- if(fromItem->isStackable()) {
- #endif //TP_TRASH_BINS
- if(toItem && toItem->getID() == fromItem->getID())
- {
- oldToCount = toItem->getItemCountOrSubtype();
- int32_t newToCount = std::min(100, oldToCount + count);
- toItem->setItemCountOrSubtype(newToCount);
- if(oldToCount != newToCount) {
- autoCloseTrade(toItem);
- }
- int32_t subcount = oldFromCount - count;
- fromItem->setItemCountOrSubtype(subcount);
- int32_t surplusCount = oldToCount + count - 100;
- if(surplusCount > 0) {
- Item *surplusItem = Item::CreateItem(fromItem->getID(), surplusCount);
- surplusItem->pos = toPos;
- toTile->addThing(surplusItem);
- }
- if(fromItem->getItemCountOrSubtype() == 0) {
- player->removeItemInventory(from_cid, true);
- this->FreeThing(fromItem);
- }
- }
- else if(count < oldFromCount) {
- int32_t subcount = oldFromCount - count;
- fromItem->setItemCountOrSubtype(subcount);
- Item *moveItem = Item::CreateItem(fromItem->getID(), count);
- moveItem->pos = toPos;
- toTile->addThing(moveItem);
- if(fromItem->getItemCountOrSubtype() == 0) {
- player->removeItemInventory(from_cid, true);
- this->FreeThing(fromItem);
- }
- }
- else if(player->removeItemInventory(from_cid, true)) {
- fromItem->pos = toPos;
- toTile->addThing(fromItem);
- }
- }
- else if(player->removeItemInventory(from_cid, true)) {
- fromItem->pos = toPos;
- toTile->addThing(fromItem);
- }
- player->updateInventoryWeigth();
- SpectatorVec list;
- SpectatorVec::iterator it;
- getSpectators(Range(player->pos, false), list);
- SpectatorVec tolist;
- getSpectators(Range(toPos, true), tolist);
- for(it = tolist.begin(); it != tolist.end(); ++it) {
- if(std::find(list.begin(), list.end(), *it) == list.end()) {
- list.push_back(*it);
- }
- }
- //players
- for(it = list.begin(); it != list.end(); ++it) {
- if(dynamic_cast<Player*>(*it)) {
- (*it)->onThingMove(player, (slots_t)from_cid, fromItem, oldFromCount, toPos, toItem, oldToCount, count);
- }
- }
- //none-players
- for(it = list.begin(); it != list.end(); ++it) {
- if(!dynamic_cast<Player*>(*it)) {
- (*it)->onThingMove(player, (slots_t)from_cid, fromItem, oldFromCount, toPos, toItem, oldToCount, count);
- }
- }
- }
- }
- }
- //ground to container/inventory
- void Game::thingMoveInternal(Player *player, const Position& fromPos, unsigned char stackPos,
- uint16_t itemid, unsigned char to_cid, unsigned char to_slotid, bool toInventory, unsigned char count)
- {
- Tile *fromTile = map->getTile(fromPos);
- if(!fromTile)
- return;
- Container *toContainer = NULL;
- Item* fromItem = dynamic_cast<Item*>(fromTile->getTopDownItem());
- Item *toItem = NULL;
- if(!fromItem || (fromItem->getID() != itemid) || (fromItem != fromTile->getTopDownItem()))
- return;
- if(toInventory)
- {
- toItem = player->getItem(to_cid);
- toContainer = dynamic_cast<Container*>(toItem);
- }
- else
- {
- toContainer = player->getContainer(to_cid);
- if(!toContainer)
- return;
- toItem = toContainer->getItem(to_slotid);
- Container *toSlotContainer = dynamic_cast<Container*>(toItem);
- if(toSlotContainer)
- {
- toContainer = toSlotContainer;
- toItem = NULL;
- }
- }
- if((toItem == fromItem) || (fromItem->isStackable() && count > fromItem->getItemCountOrSubtype()))
- return;
- /*ground to container*/
- if(toContainer)
- {
- /*if(onPrepareMoveThing(player, fromItem, fromPos, player->pos, count) &&
- onPrepareMoveThing(player, fromItem, NULL, toContainer, toItem, count))*/
- Position toPos = (toContainer->pos.x == 0xFFFF ? player->pos : toContainer->pos);
- if(onPrepareMoveThing(player, fromPos, NULL, fromItem, toPos, toContainer, toItem, count))
- {
- autoCloseTrade(fromItem, true);
- int32_t oldFromCount = fromItem->getItemCountOrSubtype();
- int32_t oldToCount = 0;
- int32_t stackpos = fromTile->getThingStackPos(fromItem);
- if(fromItem->isStackable())
- {
- if(toItem && toItem->getID() == fromItem->getID())
- {
- oldToCount = toItem->getItemCountOrSubtype();
- int32_t newToCount = std::min(100, oldToCount + count);
- toItem->setItemCountOrSubtype(newToCount);
- if(oldToCount != newToCount)
- {
- autoCloseTrade(toItem);
- }
- int32_t subcount = oldFromCount - count;
- fromItem->setItemCountOrSubtype(subcount);
- int32_t surplusCount = oldToCount + count - 100;
- if(surplusCount > 0)
- {
- Item *surplusItem = Item::CreateItem(fromItem->getID(), surplusCount);
- if(onPrepareMoveThing(player, fromPos, NULL, surplusItem, toPos, toContainer, NULL, count))
- {
- autoCloseTrade(toContainer);
- toContainer->addItem(surplusItem);
- }
- else
- {
- delete surplusItem;
- count -= surplusCount; //re-define the actual amount we move.
- fromItem->setItemCountOrSubtype(fromItem->getItemCountOrSubtype() + surplusCount);
- }
- }
- if(fromItem->getItemCountOrSubtype() == 0)
- {
- if(fromTile->removeThing(fromItem))
- {
- this->FreeThing(fromItem);
- }
- }
- }
- else if(count < oldFromCount)
- {
- int32_t subcount = oldFromCount - count;
- fromItem->setItemCountOrSubtype(subcount);
- autoCloseTrade(toContainer);
- toContainer->addItem(Item::CreateItem(fromItem->getID(), count));
- if(fromItem->getItemCountOrSubtype() == 0)
- {
- if(fromTile->removeThing(fromItem))
- {
- this->FreeThing(fromItem);
- }
- }
- }
- else if(fromTile->removeThing(fromItem))
- {
- autoCloseTrade(toContainer);
- toContainer->addItem(fromItem);
- }
- }
- else
- {
- if(fromTile->removeThing(fromItem))
- {
- autoCloseTrade(toContainer);
- toContainer->addItem(fromItem);
- }
- }
- if(player->isHoldingContainer(toContainer))
- {
- player->updateInventoryWeigth();
- }
- SpectatorVec list;
- SpectatorVec::iterator it;
- getSpectators(Range(fromPos, true), list);
- //players
- for(it = list.begin(); it != list.end(); ++it)
- {
- if(dynamic_cast<Player*>(*it))
- {
- (*it)->onThingMove(player, fromPos, stackpos, fromItem, oldFromCount, toContainer, to_slotid, toItem, oldToCount, count);
- }
- }
- //none-players
- for(it = list.begin(); it != list.end(); ++it)
- {
- if(!dynamic_cast<Player*>(*it))
- {
- (*it)->onThingMove(player, fromPos, stackpos, fromItem, oldFromCount, toContainer, to_slotid, toItem, oldToCount, count);
- }
- }
- }
- }
- //ground to inventory
- else if(toInventory)
- {
- if(onPrepareMoveThing(player, fromPos, fromItem, (slots_t)to_cid, count) && onPrepareMoveThing(player, fromItem, (slots_t)to_cid, count))
- {
- autoCloseTrade(fromItem, true);
- int32_t oldFromCount = fromItem->getItemCountOrSubtype();
- int32_t oldToCount = 0;
- int32_t stackpos = fromTile->getThingStackPos(fromItem);
- //bbk 2020
- std::cout << "ground to inventory" << std::endl;
- if(fromItem && (slots_t)to_cid == SLOT_RING) {
- fromItem->setGlimmer();
- if(toItem) toItem->removeGlimmer();
- }
- if(fromItem->isStackable())
- {
- if(toItem && toItem->getID() == fromItem->getID())
- {
- oldToCount = toItem->getItemCountOrSubtype();
- int32_t newToCount = std::min(100, oldToCount + count);
- toItem->setItemCountOrSubtype(newToCount);
- if(oldToCount != newToCount)
- {
- autoCloseTrade(toItem);
- }
- int32_t subcount = oldFromCount - count;
- fromItem->setItemCountOrSubtype(subcount);
- int32_t surplusCount = oldToCount + count - 100;
- if(surplusCount > 0)
- {
- fromItem->setItemCountOrSubtype(fromItem->getItemCountOrSubtype() + surplusCount);
- player->sendCancel("Sorry not enough room.");
- }
- if(fromItem->getItemCountOrSubtype() == 0)
- {
- if(fromTile->removeThing(fromItem))
- {
- this->FreeThing(fromItem);
- }
- }
- }
- else if(count < oldFromCount)
- {
- int32_t subcount = oldFromCount - count;
- fromItem->setItemCountOrSubtype(subcount);
- player->removeItemInventory(to_cid, true);
- player->addItemInventory(Item::CreateItem(fromItem->getID(), count), to_cid, true);
- if(toItem)
- {
- autoCloseTrade(toItem);
- fromTile->addThing(toItem);
- toItem->pos = fromPos;
- }
- if(fromItem->getItemCountOrSubtype() == 0)
- {
- if(fromTile->removeThing(fromItem))
- {
- this->FreeThing(fromItem);
- }
- }
- }
- else
- {
- if(fromTile->removeThing(fromItem))
- {
- player->removeItemInventory(to_cid, true);
- player->addItemInventory(fromItem, to_cid, true);
- if(toItem)
- {
- autoCloseTrade(toItem);
- fromTile->addThing(toItem);
- toItem->pos = fromPos;
- }
- }
- }
- }
- else
- {
- if(fromTile->removeThing(fromItem))
- {
- player->removeItemInventory(to_cid, true);
- player->addItemInventory(fromItem, to_cid, true);
- if(toItem)
- {
- autoCloseTrade(toItem);
- fromTile->addThing(toItem);
- toItem->pos = fromPos;
- }
- }
- }
- player->updateInventoryWeigth();
- SpectatorVec list;
- SpectatorVec::iterator it;
- getSpectators(Range(fromPos, true), list);
- //players
- for(it = list.begin(); it != list.end(); ++it)
- {
- if(dynamic_cast<Player*>(*it))
- {
- (*it)->onThingMove(player, fromPos, stackpos, fromItem, oldFromCount, (slots_t)to_cid, toItem, oldToCount, count);
- }
- }
- //none-players
- for(it = list.begin(); it != list.end(); ++it)
- {
- if(!dynamic_cast<Player*>(*it))
- {
- (*it)->onThingMove(player, fromPos, stackpos, fromItem, oldFromCount, (slots_t)to_cid, toItem, oldToCount, count);
- }
- }
- }
- }
- }
- //ground to ground
- void Game::thingMoveInternal(Creature *creature, unsigned short from_x, unsigned short from_y, unsigned char from_z,
- unsigned char stackPos, unsigned short itemid, unsigned short to_x, unsigned short to_y, unsigned char to_z, unsigned char count)
- {
- Tile *fromTile = getTile(from_x, from_y, from_z);
- if(!fromTile)
- return;
- if(dynamic_cast<Player*>(creature) && fromTile && !fromTile->ground) {
- dynamic_cast<Player*>(creature)->sendCancelWalk();
- return;
- }
- Tile *toTile = getTile(to_x, to_y, to_z);
- /*
- if(!toTile){
- if(dynamic_cast<Player*>(player))
- dynamic_cast<Player*>(player)->sendCancelWalk("Sorry, not possible...");
- return;
- }
- */
- Thing *thing = fromTile->getThingByStackPos(stackPos);
- if (!thing)
- return;
- Item* item = dynamic_cast<Item*>(thing);
- Creature* creatureMoving = dynamic_cast<Creature*>(thing);
- Player* playerMoving = dynamic_cast<Player*>(creatureMoving);
- Player* player = dynamic_cast<Player*>(creature);
- Position oldPos;
- oldPos.x = from_x;
- oldPos.y = from_y;
- oldPos.z = from_z;
- #ifdef TP_TRASH_BINS
- if(toTile)
- {
- Thing *tothing = toTile->getThingByStackPos(stackPos);
- Item *toItem = dynamic_cast<Item*>(tothing);
- if(item && toItem && !playerMoving && !creature && toItem->isDeleter())
- {
- fromTile->removeThing(item);
- this->FreeThing(item);
- //creatureBroadcastTileUpdated(oldPos);
- sendRemoveThing(player, item->pos, item, stackPos);
- return;
- }
- }
- #endif //TP_TRASH_BINS
- /* if (toTile){
- ItemVector::iterator brn;
- for (brn = toTile->downItems.begin(); brn != toTile->downItems.end(); brn++)
- {
- if (playerMoving && (*brn)->getID() == 1397 && player != thing || playerMoving && (*brn)->getID() == 1487 && player != thing || playerMoving && (*brn)->getID() == 1488 && player != thing || playerMoving && (*brn)->getID() == 1490 && player != thing || playerMoving && (*brn)->getID() == 1491 && player != thing || playerMoving && (*brn)->getID() == 1492 && player != thing || playerMoving && (*brn)->getID() == 1493 && player != thing || playerMoving && (*brn)->getID() == 1495 && player != thing || playerMoving && (*brn)->getID() == 1496 && player != thing || playerMoving && (*brn)->getID() == 1500 && player != thing || playerMoving && (*brn)->getID() == 1501 && player != thing || playerMoving && (*brn)->getID() == 1503 && player != thing || playerMoving && (*brn)->getID() == 1504 && player != thing || playerMoving && (*brn)->getID() == 1505 && player != thing || playerMoving && (*brn)->getID() == 1506 && player != thing || playerMoving && (*brn)->getID() == 1507 && player != thing || playerMoving && (*brn)->getID() == 1423 && player != thing || playerMoving && (*brn)->getID() == 1424 && player != thing || playerMoving && (*brn)->getID() == 1425 && player != thing)
- */
- if(toTile && player && playerMoving && playerMoving != player && toTile->getFieldItem())
- {
- player->sendCancel("Sorry, not possible.");
- return;
- }
- // *** Creature moving itself to a non-tile
- if(!toTile && creatureMoving && creatureMoving == creature){
- //change level begin
- Tile* downTile = getTile(to_x, to_y, to_z+1);
- //diagonal begin
- if(!downTile)
- {
- if(player) {
- player->sendTextMessage(MSG_SMALLINFO, "Sorry, not possible.");
- player->sendCancelWalk();
- }
- return;
- }
- if(downTile->floorChange(NORTH) && downTile->floorChange(EAST)){
- teleport(creatureMoving, Position(creatureMoving->pos.x-2, creatureMoving->pos.y+2, creatureMoving->pos.z+1));
- }
- else if(downTile->floorChange(NORTH) && downTile->floorChange(WEST)){
- teleport(creatureMoving, Position(creatureMoving->pos.x+2, creatureMoving->pos.y+2, creatureMoving->pos.z+1));
- }
- else if(downTile->floorChange(SOUTH) && downTile->floorChange(EAST)){
- teleport(creatureMoving, Position(creatureMoving->pos.x-2, creatureMoving->pos.y-2, creatureMoving->pos.z+1));
- }
- else if(downTile->floorChange(SOUTH) && downTile->floorChange(WEST)){
- teleport(creatureMoving, Position(creatureMoving->pos.x+2, creatureMoving->pos.y-2, creatureMoving->pos.z+1));
- }
- //diagonal end
- else if(downTile->floorChange(NORTH)){
- teleport(creatureMoving, Position(to_x, to_y + 1, creatureMoving->pos.z+1));
- }
- else if(downTile->floorChange(SOUTH)){
- teleport(creatureMoving, Position(to_x, to_y - 1, creatureMoving->pos.z+1));
- }
- else if(downTile->floorChange(EAST)){
- teleport(creatureMoving, Position(to_x - 1, to_y, creatureMoving->pos.z+1));
- }
- else if(downTile->floorChange(WEST)){
- teleport(creatureMoving, Position(to_x + 1, to_y, creatureMoving->pos.z+1));
- }
- else
- if(player) {
- player->sendTextMessage(MSG_SMALLINFO, "Sorry, not possible.");
- player->sendCancelWalk();
- }
- //change level end
- return;
- }
- #ifdef DT_PREMMY
- if(player && playerMoving && !player->premmium == true){
- if(!premmytiles.empty()){
- for(int32_t o = 0; o < premmytiles.size(); o++) {
- if((premmytiles[o].second.x != 0) &&
- (premmytiles[o].second.y != 0) && (premmytiles[o].second.z != 0)){
- if(Position(to_x, to_y, to_z) == premmytiles[o].first) {
- player->sendCancelWalk();
- teleport(playerMoving,
- Position(premmytiles[o].second.x, premmytiles[o].second.y,
- premmytiles[o].second.z));
- player->sendMagicEffect(player->pos,
- NM_ME_MAGIC_ENERGIE);
- return;
- }
- }
- else{
- if(Position(to_x, to_y, to_z) == premmytiles[o].first) {
- player->sendCancelWalk();
- break;
- }
- }
- }
- }
- }
- #endif //DT_PREMMY
- // *** Checking if the thing can be moved around
- if(!toTile)
- return;
- if(!onPrepareMoveThing(creature, thing, oldPos, Position(to_x, to_y, to_z), count))
- return;
- if(creatureMoving && !onPrepareMoveCreature(creature, creatureMoving, fromTile, toTile))
- return;
- if(!onPrepareMoveThing(creature, thing, fromTile, toTile, count))
- return;
- Position to_pos;
- to_pos.x = to_x;
- to_pos.y = to_y;
- to_pos.z = to_z;
- Item* fromItem = dynamic_cast<Item*>(getThing(oldPos, stackPos, player));
- Item* toItem = dynamic_cast<Item*>(toTile->getTopDownItem());
- if(fromItem && fromItem->isStackable()){
- if(fromItem->getItemCountOrSubtype() < count)
- {
- player->sendCancel("Sorry, not possible.");
- return;
- }
- if((abs(player->pos.x - oldPos.x) > 1) || (abs(player->pos.y - oldPos.y) > 1) || (player->pos.z != oldPos.z)){
- player->sendCancel("It's far away.");
- return;
- }
- if(toItem && fromItem->getID() == toItem->getID()){
- int32_t oldToCount = toItem->getItemCountOrSubtype();
- int32_t oldFromCount = fromItem->getItemCountOrSubtype();
- int32_t newToCount = std::min(100, oldToCount + count);
- toItem->setItemCountOrSubtype(newToCount);
- if(oldToCount != newToCount) {
- autoCloseTrade(toItem);
- }
- int32_t subcount = oldFromCount - count;
- fromItem->setItemCountOrSubtype(subcount);
- int32_t surplusCount = oldToCount + count - 100;
- if(surplusCount > 0) {
- Item *surplusItem = Item::CreateItem(fromItem->getID(), surplusCount);
- surplusItem->pos = to_pos;
- toTile->addThing(surplusItem);
- }
- if(fromItem->getItemCountOrSubtype() == 0) {
- if(removeThing(player, oldPos, fromItem))
- player->updateInventoryWeigth();
- }
- creatureBroadcastTileUpdated(to_pos);
- creatureBroadcastTileUpdated(oldPos);
- return;
- }
- else if(count < fromItem->getItemCountOrSubtype()) {
- int32_t subcount = fromItem->getItemCountOrSubtype() - count;
- fromItem->setItemCountOrSubtype(subcount);
- Item *moveItem = Item::CreateItem(fromItem->getID(), count);
- moveItem->pos = to_pos;
- toTile->addThing(moveItem);
- if(fromItem->getItemCountOrSubtype() == 0) {
- if(removeThing(player, oldPos, fromItem))
- player->updateInventoryWeigth();
- }
- creatureBroadcastTileUpdated(to_pos);
- creatureBroadcastTileUpdated(oldPos);
- return;
- }
- else{
- Item *moveItem = Item::CreateItem(fromItem->getID(), fromItem->getItemCountOrSubtype());
- moveItem->pos = to_pos;
- toTile->addThing(moveItem);
- if(removeThing(player, oldPos, fromItem))
- player->updateInventoryWeigth();
- creatureBroadcastTileUpdated(to_pos);
- creatureBroadcastTileUpdated(oldPos);
- return;
- }
- return;
- }
- /*
- if(item && (item->getID() != itemid || item != fromTile->getTopDownItem()))
- return;
- */
- // *** If the destiny is a teleport item, teleport the thing
- const Teleport *teleportitem = toTile->getTeleportItem();
- if(teleportitem) {
- Player *player = dynamic_cast<Player*>(thing);
- teleport(thing, teleportitem->getDestPos());
- if(player) {
- globalMagicEffect(player->pos, NM_ME_ENERGY_AREA);
- }
- return;
- }
- Monster* monsterMoving = dynamic_cast<Monster*>(creatureMoving);
- if (monsterMoving && toTile->isPz()){
- return;
- }
- #ifdef TLM_HOUSE_SYSTEM
- if (playerMoving && toTile->getHouse() &&
- (fromTile->getHouse() != toTile->getHouse() || playerMoving->houseRightsChanged))
- {
- if (playerMoving->access < g_config.ACCESS_HOUSE &&
- toTile->getHouse()->getPlayerRights(playerMoving->getName()) == HOUSE_NONE)
- {
- playerMoving->sendTextMessage(MSG_SMALLINFO, "You are not invited.");
- playerMoving->sendCancelWalk();
- return;
- }
- else
- playerMoving->houseRightsChanged = false; // if we are invited stop checking rights
- }
- #endif //TLM_HOUSE_SYSTEM
- // *** Normal moving
- if(creatureMoving)
- {
- // we need to update the direction the player is facing to...
- // otherwise we are facing some problems in turning into the
- // direction we were facing before the movement
- // check y first cuz after a diagonal move we lock to east or west
- if (to_y < oldPos.y) creatureMoving->direction = NORTH;
- if (to_y > oldPos.y) creatureMoving->direction = SOUTH;
- if (to_x > oldPos.x) creatureMoving->direction = EAST;
- if (to_x < oldPos.x) creatureMoving->direction = WEST;
- }
- int32_t oldstackpos = fromTile->getThingStackPos(thing);
- if (fromTile->removeThing(thing))
- {
- toTile->addThing(thing);
- thing->pos.x = to_x;
- thing->pos.y = to_y;
- thing->pos.z = to_z;
- SpectatorVec list;
- SpectatorVec::iterator it;
- getSpectators(Range(oldPos, Position(to_x, to_y, to_z)), list);
- #ifdef TRS_GM_INVISIBLE
- if(playerMoving && playerMoving->gmInvisible)
- {
- for(it = list.begin(); it != list.end(); ++it)
- {
- if(playerMoving == (*it) || (*it)->access >= playerMoving->access)
- {
- if(Player* p = dynamic_cast<Player*>(*it))
- {
- if(p->attackedCreature == creature->getID())
- {
- autoCloseAttack(p, creature);
- }
- (*it)->onThingMove(creature, thing, &oldPos, oldstackpos, 1, 1);
- }
- }
- }
- }
- else if(playerMoving && !playerMoving->gmInvisible)
- {
- for(it = list.begin(); it != list.end(); ++it)
- {
- if(Player* p = dynamic_cast<Player*>(*it))
- {
- if(p->attackedCreature == creature->getID())
- {
- autoCloseAttack(p, creature);
- }
- (*it)->onThingMove(creature, thing, &oldPos, oldstackpos, 1, 1);
- }
- }
- }
- else
- {
- for(it = list.begin(); it != list.end(); ++it)
- {
- if(Player* p = dynamic_cast<Player*>(*it))
- {
- if(p->attackedCreature == creature->getID())
- {
- autoCloseAttack(p, creature);
- }
- (*it)->onThingMove(creature, thing, &oldPos, oldstackpos, 1, 1);
- }
- }
- }
- #else //TRS_GM_INVISIBLE
- //players
- for(it = list.begin(); it != list.end(); ++it)
- {
- if(Player* p = dynamic_cast<Player*>(*it)) {
- if(p->attackedCreature == creature->getID()) {
- autoCloseAttack(p, creature);
- }
- (*it)->onThingMove(creature, thing, &oldPos, oldstackpos, 1, 1);
- }
- }
- #endif //TRS_GM_INVISIBLE
- //none-players
- for(it = list.begin(); it != list.end(); ++it)
- {
- if(!dynamic_cast<Player*>(*it)) {
- (*it)->onThingMove(creature, thing, &oldPos, oldstackpos, 1, 1);
- }
- }
- autoCloseTrade(item, true);
- //depot tiles
- if(playerMoving && toTile && fromTile && toTile->isPz() && fromTile->isPz() && (toTile->ground->getID() == 426))
- {
- int32_t e = 0;
- Container* c = playerMoving->getDepot(1);
- std::stringstream s;
- e += getDepot(c, e);
- s << "Your depot contains " << e;
- if(e > 1)
- s << " items.";
- else
- s << " item.";
- playerMoving->sendTextMessage(MSG_EVENT, s.str().c_str());
- }
- if(playerMoving && toTile && fromTile && toTile->isPz() && fromTile->isPz() && (toTile->ground->getID() == 416))
- {
- int32_t e = 0;
- Container* c = playerMoving->getDepot(2);
- std::stringstream s;
- e += getDepot(c, e);
- s << "Your depot contains " << e;
- if(e > 1)
- s << " items.";
- else
- s << " item.";
- playerMoving->sendTextMessage(MSG_EVENT, s.str().c_str());
- }
- if(playerMoving && toTile && fromTile && toTile->isPz() && fromTile->isPz() && (toTile->ground->getID() == 446))
- {
- int32_t e = 0;
- Container* c = playerMoving->getDepot(3);
- std::stringstream s;
- e += getDepot(c, e);
- s << "Your depot contains " << e;
- if(e > 1)
- s << " items.";
- else
- s << " item.";
- playerMoving->sendTextMessage(MSG_EVENT, s.str().c_str());
- }
- if(playerMoving && toTile && fromTile && toTile->isPz() && fromTile->isPz() && (toTile->ground->getID() == 3216))
- {
- int32_t e = 0;
- Container* c = playerMoving->getDepot(4);
- std::stringstream s;
- e += getDepot(c, e);
- s << "Your depot contains " << e;
- if(e > 1)
- s << " items.";
- else
- s << " item.";
- playerMoving->sendTextMessage(MSG_EVENT, s.str().c_str());
- }
- if(playerMoving && toTile && fromTile)
- {
- actions.luaWalk(playerMoving,playerMoving->pos,toTile->ground->getID(),toTile->ground->getUniqueId(),toTile->ground->getActionId()); //CHANGE onWalk
- }
- if(playerMoving && toTile && fromTile)
- {
- actions.luaWalkOff(playerMoving,oldPos,fromTile->ground->getID(),fromTile->ground->getUniqueId(),fromTile->ground->getActionId()); //CHANGE onWalk
- }
- if(playerMoving && fromTile && toTile && player == playerMoving)
- switch(toTile->ground->getID())
- {
- case 416:
- {
- toTile->removeThing(toTile->ground);
- toTile->addThing(new Item(417));
- creature->onTileUpdated(Position(to_x,to_y,to_z));
- }
- break;
- case 426:
- {
- toTile->removeThing(toTile->ground);
- toTile->addThing(new Item(425));
- creature->onTileUpdated(Position(to_x,to_y,to_z));
- }
- break;
- case 3216:
- {
- toTile->removeThing(toTile->ground);
- toTile->addThing(new Item(3217));
- creature->onTileUpdated(Position(to_x,to_y,to_z));
- }
- break;
- case 446:
- {
- toTile->removeThing(toTile->ground);
- toTile->addThing(new Item(447));
- creature->onTileUpdated(Position(to_x,to_y,to_z));
- }
- break;
- case 293:
- {
- toTile->removeThing(toTile->ground);
- toTile->addThing(new Item(294));
- creature->onTileUpdated(Position(to_x,to_y,to_z));
- }
- break;
- }
- switch(fromTile->ground->getID())
- {
- case 3217:
- {
- fromTile->removeThing(fromTile->ground);
- fromTile->addThing(new Item(3216));
- creature->onTileUpdated(Position(from_x,from_y,from_z));
- break;
- }
- case 417:
- {
- fromTile->removeThing(fromTile->ground);
- fromTile->addThing(new Item(416));
- creature->onTileUpdated(Position(from_x,from_y,from_z));
- break;
- }
- case 425:
- {
- fromTile->removeThing(fromTile->ground);
- fromTile->addThing(new Item(426));
- creature->onTileUpdated(Position(from_x,from_y,from_z));
- break;
- }
- case 447:
- {
- fromTile->removeThing(fromTile->ground);
- fromTile->addThing(new Item(446));
- creature->onTileUpdated(Position(from_x,from_y,from_z));
- break;
- }
- }
- //end depot tiles-+
- if (playerMoving)
- {
- if(playerMoving->attackedCreature != 0) {
- Creature* attackedCreature = getCreatureByID(creatureMoving->attackedCreature);
- if(attackedCreature){
- autoCloseAttack(playerMoving, attackedCreature);
- }
- }
- if(playerMoving->tradePartner != 0) {
- Player* tradePartner = getPlayerByID(playerMoving->tradePartner);
- if(tradePartner) {
- if((std::abs(playerMoving->pos.x - tradePartner->pos.x) > 2) ||
- (std::abs(playerMoving->pos.y - tradePartner->pos.y) > 2) || (playerMoving->pos.z != tradePartner->pos.z)
- #ifdef HUCZU_FIX
- || (fromTile->isHouse() && !toTile->isHouse())
- #endif //HUCZU_FIX
- ){
- playerCloseTrade(playerMoving);
- }
- }
- }
- //change level begin
- if(toTile->floorChangeDown())
- {
- Tile* downTile = getTile(to_x, to_y, to_z+1);
- if(downTile){
- //diagonal begin
- if(downTile->floorChange(NORTH) && downTile->floorChange(EAST)){
- teleport(playerMoving, Position(playerMoving->pos.x-1, playerMoving->pos.y+1, playerMoving->pos.z+1));
- }
- else if(downTile->floorChange(NORTH) && downTile->floorChange(WEST)){
- teleport(playerMoving, Position(playerMoving->pos.x+1, playerMoving->pos.y+1, playerMoving->pos.z+1));
- }
- else if(downTile->floorChange(SOUTH) && downTile->floorChange(EAST)){
- teleport(playerMoving, Position(playerMoving->pos.x-1, playerMoving->pos.y-1, playerMoving->pos.z+1));
- }
- else if(downTile->floorChange(SOUTH) && downTile->floorChange(WEST)){
- teleport(playerMoving, Position(playerMoving->pos.x+1, playerMoving->pos.y-1, playerMoving->pos.z+1));
- }
- //diagonal end
- else if(downTile->floorChange(NORTH)){
- teleport(playerMoving, Position(playerMoving->pos.x, playerMoving->pos.y+1, playerMoving->pos.z+1));
- }
- else if(downTile->floorChange(SOUTH)){
- teleport(playerMoving, Position(playerMoving->pos.x, playerMoving->pos.y-1, playerMoving->pos.z+1));
- }
- else if(downTile->floorChange(EAST)){
- teleport(playerMoving, Position(playerMoving->pos.x-1, playerMoving->pos.y, playerMoving->pos.z+1));
- }
- else if(downTile->floorChange(WEST)){
- teleport(playerMoving, Position(playerMoving->pos.x+1, playerMoving->pos.y, playerMoving->pos.z+1));
- }
- else { //allow just real tiles to be hole'like
- // TODO: later can be changed to check for piled items like chairs, boxes
- teleport(playerMoving, Position(playerMoving->pos.x, playerMoving->pos.y, playerMoving->pos.z+1));
- }
- }
- }
- //diagonal begin
- else if(toTile->floorChange(NORTH) && toTile->floorChange(EAST)){
- teleport(playerMoving, Position(playerMoving->pos.x+1, playerMoving->pos.y-1, playerMoving->pos.z-1));
- }
- else if(toTile->floorChange(NORTH) && toTile->floorChange(WEST)){
- teleport(playerMoving, Position(playerMoving->pos.x-1, playerMoving->pos.y-1, playerMoving->pos.z-1));
- }
- else if(toTile->floorChange(SOUTH) && toTile->floorChange(EAST)){
- teleport(playerMoving, Position(playerMoving->pos.x+1, playerMoving->pos.y+1, playerMoving->pos.z-1));
- }
- else if(toTile->floorChange(SOUTH) && toTile->floorChange(WEST)){
- teleport(playerMoving, Position(playerMoving->pos.x-1, playerMoving->pos.y+1, playerMoving->pos.z-1));
- }
- //diagonal end
- else if(toTile->floorChange(NORTH)){
- teleport(playerMoving, Position(playerMoving->pos.x, playerMoving->pos.y-1, playerMoving->pos.z-1));
- }
- else if(toTile->floorChange(SOUTH)){
- teleport(playerMoving, Position(playerMoving->pos.x, playerMoving->pos.y+1, playerMoving->pos.z-1));
- }
- else if(toTile->floorChange(EAST)){
- teleport(playerMoving, Position(playerMoving->pos.x+1, playerMoving->pos.y, playerMoving->pos.z-1));
- }
- else if(toTile->floorChange(WEST)){
- teleport(playerMoving, Position(playerMoving->pos.x-1, playerMoving->pos.y, playerMoving->pos.z-1));
- }
- //change level end
- }
- // Magic Field in destiny field
- #ifdef HUCZU_FIX
- if(toTile && playerMoving && playerMoving->access < g_config.ACCESS_PROTECT && !toTile->downItems.empty() && !toTile->isPvpArena())
- #else
- if(toTile && playerMoving && playerMoving->access < g_config.ACCESS_PROTECT && !toTile->downItems.empty() || toTile && creatureMoving && creatureMoving->access < g_config.ACCESS_PROTECT && !toTile->downItems.empty())
- #endif //HUCZU_FIX
- {
- ItemVector::iterator iit;
- for (iit = toTile->downItems.begin(); iit != toTile->downItems.end(); iit++)
- {
- if(toTile->isPvpArena()) break;
- if(!(*iit)) continue;
- Item *item = dynamic_cast<Item*>(*iit);
- if(!item) continue;
- if(!creatureMoving || creatureMoving->isRemoved || creatureMoving->health <= 0) break;
- if (item->getID() == 1492 || item->getID() == 1423 || item->getID() == 1487 || item->getID() == 1500){//Fire - Big
- doFieldDamage(creatureMoving, 199 , NM_ME_HITBY_FIRE, NM_ME_HITBY_FIRE, ATTACK_FIRE, true, 20);
- // creature DamageColor, damageEffect, hitEffect attackType, offensive, damage
- if(creatureMoving && !creatureMoving->isRemoved && creatureMoving->health > 0)
- CreateCondition(creatureMoving, NULL, 199, NM_ME_HITBY_FIRE, NM_ME_HITBY_FIRE, ATTACK_FIRE, true, 10, 10, 2000, 10);
- }
- else if(item->getID() == 1493 || item->getID() == 1424 || item->getID() == 1488 || item->getID() == 1501){//Fire Medium
- doFieldDamage(creatureMoving, 199, NM_ME_HITBY_FIRE, NM_ME_HITBY_FIRE, ATTACK_FIRE, true, 10);
- if(creatureMoving && !creatureMoving->isRemoved && creatureMoving->health > 0)
- CreateCondition(creatureMoving, NULL, 199, NM_ME_HITBY_FIRE, NM_ME_HITBY_FIRE, ATTACK_FIRE, true, 10, 10, 2000, 10);
- }
- else if(item->getID() == 1495 || item->getID() == 1491 || item->getID() == 1504){//Energy
- doFieldDamage(creatureMoving, 71, NM_ME_ENERGY_DAMAGE, NM_ME_ENERGY_DAMAGE, ATTACK_ENERGY, true, 30);
- if(creatureMoving && !creatureMoving->isRemoved && creatureMoving->health > 0)
- CreateCondition(creatureMoving, NULL, 71, NM_ME_ENERGY_DAMAGE, NM_ME_ENERGY_DAMAGE, ATTACK_ENERGY, true, 30, 30, 2000, 3);
- }
- else if(item->getID() == 1496 || item->getID() == 1490 || item->getID() == 1503 || item->getID() == 1505){//Poison
- doFieldDamage(creatureMoving, 30, NM_ME_POISEN, NM_ME_POISEN, ATTACK_POISON, true, 10);
- if(creatureMoving && !creatureMoving->isRemoved && creatureMoving->health > 0)
- CreateCondition(creatureMoving, NULL, 30, NM_ME_POISEN, NM_ME_POISEN_RINGS, ATTACK_POISON, true, 10, 10, 2000, 10);
- }
- }
- }
- }
- if(creatureMoving && !toTile->isPvpArena())
- {
- const MagicEffectItem* fieldItem = toTile->getFieldItem();
- if(fieldItem) {
- const MagicEffectTargetCreatureCondition *magicTargetCondition = fieldItem->getCondition();
- if(!(getWorldType() == WORLD_TYPE_NO_PVP && playerMoving && magicTargetCondition && magicTargetCondition->getOwnerID() != 0)) {
- fieldItem->getDamage(creatureMoving);
- }
- if(magicTargetCondition && ((magicTargetCondition->attackType == ATTACK_FIRE) ||
- (magicTargetCondition->attackType == ATTACK_POISON) ||
- (magicTargetCondition->attackType == ATTACK_ENERGY))) {
- Creature *c = getCreatureByID(magicTargetCondition->getOwnerID());
- creatureMakeMagic(c, thing->pos, magicTargetCondition);
- }
- }
- }
- }
- void Game::getSpectators(const Range& range, SpectatorVec& list)
- {
- map->getSpectators(range, list);
- }
- void Game::creatureTurn(Creature *creature, Direction dir)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::creatureTurn()");
- if (creature->direction != dir) {
- creature->direction = dir;
- int32_t stackpos = map->getTile(creature->pos)->getThingStackPos(creature);
- SpectatorVec list;
- SpectatorVec::iterator it;
- map->getSpectators(Range(creature->pos, true), list);
- //players
- for(it = list.begin(); it != list.end(); ++it) {
- if(dynamic_cast<Player*>(*it)) {
- (*it)->onCreatureTurn(creature, stackpos);
- }
- }
- //none-players
- for(it = list.begin(); it != list.end(); ++it) {
- if(!dynamic_cast<Player*>(*it)) {
- (*it)->onCreatureTurn(creature, stackpos);
- }
- }
- }
- }
- void Game::addCommandTag(std::string tag){
- bool found = false;
- for(size_t i=0;i< commandTags.size() ;i++){
- if(commandTags[i] == tag){
- found = true;
- break;
- }
- }
- if(!found){
- commandTags.push_back(tag);
- }
- }
- void Game::resetCommandTag(){
- commandTags.clear();
- }
- void Game::creatureSay(Creature *creature, SpeakClasses type, const std::string &text)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::creatureSay()");
- using std::string;
- string spoken=text;
- std::transform(spoken.begin(), spoken.end(), spoken.begin(), (int32_t(*)(int32_t))std::tolower);
- bool GMcommand = false;
- // First, check if this was a GM command
- for(size_t i=0;i< commandTags.size() ;i++){
- if(commandTags[i] == text.substr(0,1)){
- if(commands.exeCommand(creature,text)){
- GMcommand = true;
- }
- break;
- }
- }
- Player* p = dynamic_cast<Player*>(creature);
- Player* player = dynamic_cast<Player*>(creature);
- #ifdef HUCZU_FIX
- if (player && spoken == "exevo grav vita" && (!g_config.LEARN_SPELLS || player->knowsSpell("exevo grav vita")))
- {
- Tile *tile = NULL;
- Position wgpos;
- wgpos.z = player->pos.z;
- switch(player->direction)
- {
- case NORTH:
- wgpos.x = player->pos.x;
- wgpos.y = player->pos.y-1;
- break;
- case SOUTH:
- wgpos.x = player->pos.x;
- wgpos.y = player->pos.y+1;
- break;
- case EAST:
- wgpos.x = player->pos.x+1;
- wgpos.y = player->pos.y;
- break;
- case WEST:
- wgpos.x = player->pos.x-1;
- wgpos.y = player->pos.y;
- break;
- default:
- break;
- }
- tile = getTile(wgpos.x, wgpos.y, wgpos.z);
- if(!tile || tile->isBlocking(BLOCK_SOLID,false,false) || tile->isPz())
- {
- player->sendMagicEffect(player->pos, NM_ME_PUFF);
- player->sendTextMessage(MSG_SMALLINFO, "Sorry, not possible.");
- return;
- }
- if(player->access < 2)
- {
- if(player->mana < 220)
- {
- player->sendCancel("You do not have enough mana.");
- player->sendMagicEffect(player->pos, NM_ME_PUFF);
- return;
- }
- if(!player->premmium)
- {
- player->sendMagicEffect(player->pos, NM_ME_PUFF);
- player->sendCancel("You need buy a premmium account for use this spell");
- return;
- }
- if(player->maglevel < 26){
- player->sendCancel("You do not have the magic level.");
- player->sendMagicEffect(player->pos, NM_ME_PUFF);
- return;
- }
- if(player->vocation != 2)
- {
- player->sendTextMessage(MSG_SMALLINFO, "You do not have the required vocation.");
- player->sendMagicEffect(player->pos, 2);
- return;
- }
- if (player->exhaustedTicks >= 1000)
- {
- player->sendMagicEffect(player->pos, NM_ME_PUFF);
- player->sendTextMessage(MSG_SMALLINFO, "You are exhausted.");
- return;
- }
- }
- player->mana -= 220;
- player->addManaSpent(220);
- player->exhaustedTicks = g_config.EXHAUSTED;
- Item* Tree = Item::CreateItem(ITEM_WILDGROWTH, 1);
- addThing(NULL, wgpos, Tree);
- startDecay(Tree);
- SpectatorVec list;
- SpectatorVec::iterator it;
- getSpectators(Range(player->pos), list);
- for(it = list.begin(); it != list.end(); ++it) {
- Player* playerek = dynamic_cast<Player*>(*it);
- if(playerek)
- playerek->sendMagicEffect(playerek->pos, NM_ME_MAGIC_POISEN);
- }
- player->sendMagicEffect(player->pos, NM_ME_MAGIC_ENERGIE);
- }
- #endif //HUCZU_FIX
- if(spoken=="exana pox"){
- MagicEffectClass pox;
- pox.animationColor = 0;
- pox.damageEffect = NM_ME_MAGIC_ENERGIE;
- pox.hitEffect = 255;
- pox.attackType = ATTACK_NONE;
- pox.maxDamage = 0;
- pox.minDamage = 0;
- pox.offensive = false;
- pox.manaCost = 30;
- if(creatureMakeMagic(creature, creature->pos, &pox)){
- creature->removeCondition(ATTACK_POISON);
- if(player)
- player->sendIcons();
- }
- }
- if(!GMcommand){
- Player* player = dynamic_cast<Player*>(creature);
- if(text=="!besthit")
- {
- std::stringstream info;
- if(player->maxDmg>0){
- info << "Your best hit: " << player->maxDmg;}
- else{
- info << "You didn't any damage.";}
- player->sendTextMessage(MSG_EVENT,info.str().c_str());
- }
- if(player && (text[0] == 'e' || text[0] == 'E') && (text[1] == 'x' || text[1] == 'X') && (text[2] == 'a' || text[2] == 'A') && (text[3] == 'n' || text[3] == 'N') && (text[4] == 'a' || text[4] == 'A') && (text[5] == ' ') && (text[6] == 'a' || text[6] == 'A') && (text[7] == 'n' || text[7] == 'N') && (text[8] == 'i' || text[8] == 'i')) {
- if(player->mana < 200) {
- player->sendCancel("You do not have enough mana.");
- player->sendMagicEffect(player->pos, NM_ME_PUFF);
- return;
- }
- if(player->maglevel < 15) {
- player->sendCancel("You do not have the magic level.");
- player->sendMagicEffect(player->pos, NM_ME_PUFF);
- return;
- }
- if(player->vocation != 1)
- {
- player->sendTextMessage(MSG_SMALLINFO, "You do not have the required vocation.");
- player->sendMagicEffect(player->pos, 2);
- return;
- }
- player->mana -= 200;
- player->addManaSpent(200);
- SpectatorVec list;
- SpectatorVec::iterator it;
- getSpectators(Range(creature->pos), list);
- for(it = list.begin(); it != list.end(); ++it) {
- if(Creature *c = dynamic_cast<Creature*>(*it)) {
- if(c)
- {
- c->setInvisible(0);
- creatureChangeOutfit(c);
- }
- }
- player->sendMagicEffect(player->pos, NM_ME_MAGIC_ENERGIE);
- }
- }
- if (player)
- checkSpell(player, type, text);
- // It was no command, or it was just a player
- SpectatorVec list;
- SpectatorVec::iterator it;
- getSpectators(Range(creature->pos), list);
- //players
- for(it = list.begin(); it != list.end(); ++it) {
- if(dynamic_cast<Player*>(*it)) {
- (*it)->onCreatureSay(creature, type, text);
- }
- }
- //none-players
- for(it = list.begin(); it != list.end(); ++it) {
- if(!dynamic_cast<Player*>(*it)) {
- (*it)->onCreatureSay(creature, type, text);
- }
- }
- }
- }
- void Game::teleport(Thing *thing, const Position& newPos)
- {
- if (newPos == thing->pos)
- return;
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::teleport()");
- //Tile *toTile = getTile( newPos.x, newPos.y, newPos.z );
- Tile *toTile = map->getTile(newPos);
- if (toTile)
- {
- Creature *creature = dynamic_cast<Creature*>(thing);
- if (creature)
- {
- //Tile *fromTile = getTile( thing->pos.x, thing->pos.y, thing->pos.z );
- Tile *fromTile = map->getTile(thing->pos);
- if (!fromTile)
- return;
- int osp = fromTile->getThingStackPos(thing);
- if (!fromTile->removeThing(thing))
- return;
- toTile->addThing(thing);
- Position oldPos = thing->pos;
- SpectatorVec list;
- SpectatorVec::iterator it;
- getSpectators(Range(thing->pos, true), list);
- //players
- for (it = list.begin(); it != list.end(); ++it)
- {
- if (Player* p = dynamic_cast<Player*>(*it))
- {
- if (p->attackedCreature == creature->getID())
- {
- autoCloseAttack(p, creature);
- }
- (*it)->onCreatureDisappear(creature, osp, true);
- }
- }
- //none-players
- for (it = list.begin(); it != list.end(); ++it)
- {
- if (!dynamic_cast<Player*>(*it))
- {
- (*it)->onCreatureDisappear(creature, osp, true);
- }
- }
- if (newPos.y < oldPos.y)
- creature->direction = NORTH;
- if (newPos.y > oldPos.y)
- creature->direction = SOUTH;
- if (newPos.x > oldPos.x && (std::abs(newPos.x - oldPos.x) >= std::abs(newPos.y - oldPos.y)))
- creature->direction = EAST;
- if (newPos.x < oldPos.x && (std::abs(newPos.x - oldPos.x) >= std::abs(newPos.y - oldPos.y)))
- creature->direction = WEST;
- thing->pos = newPos;
- Player *player = dynamic_cast<Player*>(creature);
- if (player && player->attackedCreature != 0)
- {
- Creature* attackedCreature = getCreatureByID(player->attackedCreature);
- if (attackedCreature)
- {
- autoCloseAttack(player, attackedCreature);
- }
- }
- list.clear();
- getSpectators(Range(thing->pos, true), list);
- #ifdef TRS_GM_INVISIBLE
- //players
- for (it = list.begin(); it != list.end(); ++it)
- {
- if (player)
- {
- if (player->gmInvisible && player == (*it))
- {
- if (Player* p = dynamic_cast<Player*>(*it))
- {
- if (p->attackedCreature == creature->getID())
- {
- autoCloseAttack(p, creature);
- }
- (*it)->onTeleport(creature, &oldPos, osp);
- }
- }
- else if (player->gmInvisible && player != (*it) && (*it)->access < player->access)
- {
- // Nothing Because he is invisible...
- }
- else
- {
- if (Player* p = dynamic_cast<Player*>(*it))
- {
- if (p->attackedCreature == creature->getID())
- {
- autoCloseAttack(p, creature);
- }
- (*it)->onTeleport(creature, &oldPos, osp);
- }
- }
- }
- else
- creatureBroadcastTileUpdated(newPos);
- }
- #else //TRS_GM_INVISIBLE
- //players
- for (it = list.begin(); it != list.end(); ++it)
- {
- if (Player* p = dynamic_cast<Player*>(*it))
- {
- if (p->attackedCreature == creature->getID())
- {
- autoCloseAttack(p, creature);
- }
- (*it)->onTeleport(creature, &oldPos, osp);
- }
- }
- #endif //TRS_GM_INVISIBLE
- //none-players
- for (it = list.begin(); it != list.end(); ++it)
- {
- if (!dynamic_cast<Player*>(*it))
- {
- (*it)->onTeleport(creature, &oldPos, osp);
- }
- }
- }
- else
- {
- if (removeThing(NULL, thing->pos, thing, false))
- {
- addThing(NULL, newPos, thing);
- }
- }
- }//if(toTile)
- }
- void Game::creatureChangeOutfit(Creature *creature)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::creatureChangeOutfit()");
- SpectatorVec list;
- SpectatorVec::iterator it;
- getSpectators(Range(creature->pos, true), list);
- //players
- for(it = list.begin(); it != list.end(); ++it) {
- if(dynamic_cast<Player*>(*it)) {
- (*it)->onCreatureChangeOutfit(creature);
- }
- }
- //none-players
- for(it = list.begin(); it != list.end(); ++it) {
- if(!dynamic_cast<Player*>(*it)) {
- (*it)->onCreatureChangeOutfit(creature);
- }
- }
- }
- void Game::creatureWhisper(Creature *creature, const std::string &text)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::creatureWhisper()");
- SpectatorVec list;
- SpectatorVec::iterator it;
- getSpectators(Range(creature->pos), list);
- //players
- for(it = list.begin(); it != list.end(); ++it) {
- if(dynamic_cast<Player*>(*it)) {
- if(abs(creature->pos.x - (*it)->pos.x) > 1 || abs(creature->pos.y - (*it)->pos.y) > 1)
- (*it)->onCreatureSay(creature, SPEAK_WHISPER, std::string("pspsps"));
- else
- (*it)->onCreatureSay(creature, SPEAK_WHISPER, text);
- }
- }
- //none-players
- for(it = list.begin(); it != list.end(); ++it) {
- if(!dynamic_cast<Player*>(*it)) {
- if(abs(creature->pos.x - (*it)->pos.x) > 1 || abs(creature->pos.y - (*it)->pos.y) > 1)
- (*it)->onCreatureSay(creature, SPEAK_WHISPER, std::string("pspsps"));
- else
- (*it)->onCreatureSay(creature, SPEAK_WHISPER, text);
- }
- }
- }
- void Game::creatureYell(Creature *creature, std::string &text)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::creatureYell()");
- if(!creature)
- return;
- #ifdef HUCZU_FIX
- if(creature->level < 2 && creature->access < 2){
- return;
- }
- #endif //HUCZU_FIX
- std::transform(text.begin(), text.end(), text.begin(), upchar);
- SpectatorVec list;
- SpectatorVec::iterator it;
- getSpectators(Range(creature->pos, 18, 18, 14, 14), list);
- for(it = list.begin(); it != list.end(); ++it){
- if(*it)
- (*it)->onCreatureSay(creature, SPEAK_YELL, text);
- }
- }
- //ZBÊ„NE
- /*void Game::creatureYell(Creature *creature, std::string &text)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::creatureYell()");
- Player* player = dynamic_cast<Player*>(creature);
- #ifdef HUCZU_FIX
- if(player && player->level < 2 && player->access < 2){
- player->sendTextMessage(MSG_SMALLINFO, "You cannot yell.");
- return;
- }
- #endif //HUCZU_FIX
- if (player && player->access < g_config.ACCESS_PROTECT && player->exhaustedTicks >= 1000)
- {
- player->exhaustedTicks += g_config.EXHAUSTED_ADD;
- player->sendTextMessage(MSG_SMALLINFO, "You are exhausted.");
- }
- else {
- creature->exhaustedTicks = g_config.EXHAUSTED;
- std::transform(text.begin(), text.end(), text.begin(), upchar);
- SpectatorVec list;
- SpectatorVec::iterator it;
- getSpectators(Range(creature->pos, 18, 18, 14, 14), list);
- //players
- for(it = list.begin(); it != list.end(); ++it) {
- if(dynamic_cast<Player*>(*it)) {
- (*it)->onCreatureSay(creature, SPEAK_YELL, text);
- }
- }
- }
- }*/
- void Game::creatureSpeakTo(Creature *creature, SpeakClasses type,const std::string &receiver, const std::string &text)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::creatureSpeakTo");
- Player* player = dynamic_cast<Player*>(creature);
- if(!player)
- return;
- Player* toPlayer = getPlayerByName(receiver);
- if(!toPlayer) {
- player->sendTextMessage(MSG_SMALLINFO, "A player with this name is not online.");
- return;
- }
- if(creature->access < g_config.ACCESS_TALK){
- type = SPEAK_PRIVATE;
- }
- if(!toPlayer){
- player->onCreatureSay(player, type, text);
- }
- time_t ticks = time(0);
- tm* now = localtime(&ticks);
- char buf[32];
- strftime(buf, sizeof(buf), "%d/%m/%Y %H:%M", now);
- std::ofstream out2("data/logs/private.log", std::ios::app);
- out2 << '[' << buf << "] " << toPlayer->getName() << " from " << player->getName() << ": " << text << std::endl;
- out2.close();
- toPlayer->onCreatureSay(player, type, text);
- std::stringstream ss;
- ss << "Message sent to " << toPlayer->getName() << ".";
- player->sendTextMessage(MSG_SMALLINFO, ss.str().c_str());
- }
- void Game::creatureTalkToChannel(Player *player, SpeakClasses type, std::string &text, uint16_t channelId)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::creatureTalkToChannel");
- if(player->access < g_config.ACCESS_TALK){
- type = SPEAK_CHANNEL_Y;
- }
- if(player->guildStatus == GUILD_LEADER && channelId == 0x00)
- type = SPEAK_CHANNEL_R1;
- if(player->guildStatus == GUILD_VICE && channelId == 0x00)
- type = SPEAK_CHANNEL_O;
- g_chat.talkToChannel(player, type, text, channelId);
- }
- void Game::creatureMonsterYell(Monster* monster, const std::string& text)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::creatureMonsterYell()");
- SpectatorVec list;
- SpectatorVec::iterator it;
- map->getSpectators(Range(monster->pos, 18, 18, 14, 14), list);
- //players
- for(it = list.begin(); it != list.end(); ++it) {
- if(dynamic_cast<Player*>(*it)) {
- (*it)->onCreatureSay(monster, SPEAK_MONSTER1, text);
- }
- }
- }
- void Game::creatureBroadcastMessage(Creature *creature, const std::string &text)
- {
- if(creature->access < g_config.ACCESS_TALK)
- return;
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::creatureBroadcastMessage()");
- for(AutoList<Player>::listiterator it = Player::listPlayer.list.begin(); it != Player::listPlayer.list.end(); ++it)
- {
- (*it).second->onCreatureSay(creature, SPEAK_BROADCAST, text);
- }
- }
- /** \todo Someone _PLEASE_ clean up this mess */
- bool Game::creatureMakeMagic(Creature *creature, const Position& centerpos, const MagicEffectClass* me, bool isparal = false)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::creatureMakeMagic()");
- #ifdef __DEBUG__
- cout << "creatureMakeMagic: " << (creature ? creature->getName() : "No name") << ", x: " << centerpos.x << ", y: " << centerpos.y << ", z: " << centerpos.z << std::endl;
- #endif
- Position frompos;
- if(creature) {
- frompos = creature->pos;
- if(!creatureOnPrepareMagicAttack(creature, centerpos, me, isparal))
- {
- return false;
- }
- }
- else {
- frompos = centerpos;
- }
- MagicAreaVec tmpMagicAreaVec;
- me->getArea(centerpos, tmpMagicAreaVec);
- std::vector<Position> poslist;
- Position topLeft(0xFFFF, 0xFFFF, frompos.z), bottomRight(0, 0, frompos.z);
- //Filter out the tiles we actually can work on
- for(MagicAreaVec::iterator maIt = tmpMagicAreaVec.begin(); maIt != tmpMagicAreaVec.end(); ++maIt) {
- Tile *t = map->getTile(maIt->x, maIt->y, maIt->z);
- if(t && (!creature || (creature->access >= g_config.ACCESS_PROTECT || !me->offensive || !t->isPz()) ) ) {
- if((t->isBlocking(BLOCK_PROJECTILE) == RET_NOERROR) && (me->isIndirect() ||
- //(map->canThrowItemTo(frompos, (*maIt), false, true) && !t->floorChange()))) {
- ((map->canThrowObjectTo(centerpos, (*maIt), BLOCK_PROJECTILE) == RET_NOERROR) && !t->floorChange()))) {
- if(maIt->x < topLeft.x)
- topLeft.x = maIt->x;
- if(maIt->y < topLeft.y)
- topLeft.y = maIt->y;
- if(maIt->x > bottomRight.x)
- bottomRight.x = maIt->x;
- if(maIt->y > bottomRight.y)
- bottomRight.y = maIt->y;
- poslist.push_back(*maIt);
- }
- }
- }
- topLeft.z = frompos.z;
- bottomRight.z = frompos.z;
- if(topLeft.x == 0xFFFF || topLeft.y == 0xFFFF || bottomRight.x == 0 || bottomRight.y == 0){
- return false;
- }
- #ifdef __DEBUG__
- printf("top left %d %d %d\n", topLeft.x, topLeft.y, topLeft.z);
- printf("bottom right %d %d %d\n", bottomRight.x, bottomRight.y, bottomRight.z);
- #endif
- //We do all changes against a GameState to keep track of the changes,
- //need some more work to work for all situations...
- GameState gamestate(this, Range(topLeft, bottomRight));
- //Tile *targettile = getTile(centerpos.x, centerpos.y, centerpos.z);
- Tile *targettile = map->getTile(centerpos);
- bool bSuccess = false;
- bool hasTarget = false;
- bool isBlocking = true;
- if(targettile){
- hasTarget = !targettile->creatures.empty();
- isBlocking = (targettile->isBlocking(BLOCK_SOLID, true) != RET_NOERROR);
- }
- if(targettile && me->canCast(isBlocking, !targettile->creatures.empty())) {
- bSuccess = true;
- //Apply the permanent effect to the map
- std::vector<Position>::const_iterator tlIt;
- for(tlIt = poslist.begin(); tlIt != poslist.end(); ++tlIt) {
- gamestate.onAttack(creature, Position(*tlIt), me);
- }
- }
- if(bSuccess) {
- if(isparal == true) {
- Player* player = dynamic_cast<Player*>(creature);
- if(player) {
- player->mana -= me->manaCost;
- std::cout << "isparal, creatureMakeMagic: " << isparal << std::endl;
- //player->manaspent += me->manaCost;
- player->addManaSpent(me->manaCost);
- }
- }
- }
- SpectatorVec spectatorlist = gamestate.getSpectators();
- SpectatorVec::iterator it;
- for(it = spectatorlist.begin(); it != spectatorlist.end(); ++it) {
- Player* spectator = dynamic_cast<Player*>(*it);
- if(!spectator)
- continue;
- if(bSuccess) {
- me->getDistanceShoot(spectator, creature, centerpos, hasTarget);
- std::vector<Position>::const_iterator tlIt;
- for(tlIt = poslist.begin(); tlIt != poslist.end(); ++tlIt) {
- Position pos = *tlIt;
- //Tile *tile = getTile(pos.x, pos.y, pos.z);
- Tile *tile = map->getTile(pos);
- const CreatureStateVec& creatureStateVec = gamestate.getCreatureStateList(tile);
- if(creatureStateVec.empty()) { //no targets
- me->getMagicEffect(spectator, creature, NULL, pos, 0, targettile->isPz(), isBlocking);
- }
- else {
- for(CreatureStateVec::const_iterator csIt = creatureStateVec.begin(); csIt != creatureStateVec.end(); ++csIt) {
- Creature *target = csIt->first;
- const CreatureState& creatureState = csIt->second;
- me->getMagicEffect(spectator, creature, target, target->pos, creatureState.damage, tile->isPz(), false);
- //could be death due to a magic damage with no owner (fire/poison/energy)
- if(creature && target->isRemoved == true) {
- for(std::vector<Creature*>::const_iterator cit = creatureState.attackerlist.begin(); cit != creatureState.attackerlist.end(); ++cit) {
- Creature* gainExpCreature = *cit;
- if(dynamic_cast<Player*>(gainExpCreature))
- dynamic_cast<Player*>(gainExpCreature)->sendStats();
- if(spectator->CanSee(gainExpCreature->pos.x, gainExpCreature->pos.y, gainExpCreature->pos.z)){
- std::stringstream exp;
- exp << target->getGainedExperience(gainExpCreature);
- spectator->sendAnimatedText(gainExpCreature->pos, 0xD7, exp.str());
- }
- }
- }
- if(spectator->CanSee(target->pos.x, target->pos.y, target->pos.z))
- {
- if(creatureState.damage != 0) {
- std::stringstream dmg;
- dmg << std::abs(creatureState.damage);
- #ifdef TJ_MONSTER_BLOOD
- if (me->attackType & ATTACK_PHYSICAL)
- spectator->sendAnimatedText(target->pos, target->bloodcolor, dmg.str());
- else
- #endif //TJ_MONSTER_BLOOD
- spectator->sendAnimatedText(target->pos, me->animationColor, dmg.str());
- }
- if(creatureState.manaDamage > 0){
- spectator->sendMagicEffect(target->pos, NM_ME_LOOSE_ENERGY);
- std::stringstream manaDmg;
- manaDmg << std::abs(creatureState.manaDamage);
- spectator->sendAnimatedText(target->pos, 2, manaDmg.str());
- }
- if (target->health > 0)
- spectator->sendCreatureHealth(target);
- if (spectator == target){
- CreateManaDamageUpdate(target, creature, creatureState.manaDamage);
- CreateDamageUpdate(target, creature, creatureState.damage);
- }
- }
- }
- }
- }
- }
- else {
- me->FailedToCast(spectator, creature, isBlocking, hasTarget);
- }
- }
- return bSuccess;
- }
- void Game::creatureApplyDamage(Creature *creature, int32_t damage, int32_t &outDamage, int32_t &outManaDamage
- #ifdef YUR_PVP_ARENA
- , CreatureVector* arenaLosers
- #endif //YUR_PVP_ARENA
- )
- {
- outDamage = damage;
- outManaDamage = 0;
- if (damage > 0)
- {
- if (creature->manaShieldTicks >= 1000 && (damage < creature->mana) ) {
- outManaDamage = damage;
- outDamage = 0;
- }
- else if (creature->manaShieldTicks >= 1000 && (damage > creature->mana) ) {
- outManaDamage = creature->mana;
- outDamage -= outManaDamage;
- }
- else if((creature->manaShieldTicks < 1000) && (damage > creature->health))
- outDamage = creature->health;
- else if (creature->manaShieldTicks >= 1000 && (damage > (creature->health + creature->mana))) {
- outDamage = creature->health;
- outManaDamage = creature->mana;
- }
- if(creature->manaShieldTicks < 1000 || (creature->mana == 0))
- #ifdef YUR_PVP_ARENA
- creature->drainHealth(outDamage, arenaLosers);
- #else
- creature->drainHealth(outDamage);
- #endif //YUR_PVP_ARENA
- else if(outManaDamage > 0)
- {
- #ifdef YUR_PVP_ARENA
- creature->drainHealth(outDamage, arenaLosers);
- #else
- creature->drainHealth(outDamage);
- #endif //YUR_PVP_ARENA
- creature->drainMana(outManaDamage);
- }
- else
- creature->drainMana(outDamage);
- }
- else {
- int32_t newhealth = creature->health - damage;
- if(newhealth > creature->healthmax)
- newhealth = creature->healthmax;
- creature->health = newhealth;
- outDamage = creature->health - newhealth;
- outManaDamage = 0;
- }
- }
- bool Game::creatureCastSpell(Creature *creature, const Position& centerpos, const MagicEffectClass& me)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::creatureCastSpell()");
- std::cout << "Game::creatureCastSpell " << creature->getName() << std::endl;
- // if(me.offensive == false && me.damageEffect > 0 && creature->conditions.hasCondition(ATTACK_PARALYZE))
- if(/*(*/me.damageEffect <= 0 /* || me.damageEffect == NM_ME_MAGIC_ENERGIE)*/ && creature->conditions.hasCondition(ATTACK_PARALYZE))
- {
- creature->removeCondition(ATTACK_PARALYZE);
- changeSpeed(creature->getID(), creature->getNormalSpeed()+creature->hasteSpeed);
- Player *player = dynamic_cast<Player*>(creature);
- if(player)
- player->sendIcons();
- }
- return creatureMakeMagic(creature, centerpos, &me);
- }
- bool Game::creatureThrowRune(Creature *creature, const Position& centerpos, const MagicEffectClass& me, bool isparal = false) {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::creatureThrowRune()");
- bool ret = false;
- #ifdef HUCZU_FIX
- int32_t dist_x = std::abs(creature->pos.x - centerpos.x);
- int32_t dist_y = std::abs(creature->pos.y - centerpos.y);
- #endif //HUCZU_FIX
- if(creature->pos.z != centerpos.z) {
- creature->sendCancel("You need to be on the same floor.");
- }
- #ifdef HUCZU_FIX
- else if(dist_x > 7 || dist_y > 6)
- return TOO_FAR;
- #endif //HUCZU_FIX
- //else if(!map->canThrowItemTo(creature->pos, centerpos, false, true)) {
- else if(map->canThrowObjectTo(creature->pos, centerpos, BLOCK_PROJECTILE) != RET_NOERROR) {
- creature->sendCancel("You cannot throw there.");
- }
- else
- ret = creatureMakeMagic(creature, centerpos, &me, isparal);
- return ret;
- }
- bool Game::creatureOnPrepareAttack(Creature *creature, Position pos)
- {
- if(creature){
- Player* player = dynamic_cast<Player*>(creature);
- //Tile* tile = (Tile*)getTile(creature->pos.x, creature->pos.y, creature->pos.z);
- Tile* tile = map->getTile(creature->pos);
- //Tile* targettile = getTile(pos.x, pos.y, pos.z);
- Tile* targettile = map->getTile(pos);
- if(creature->access < g_config.ACCESS_PROTECT) {
- if(tile && tile->isPz()) {
- if(player) {
- player->sendTextMessage(MSG_SMALLINFO, "You may not attack a person while you are in a protection zone.");
- playerSetAttackedCreature(player, 0);
- }
- return false;
- }
- else if(targettile && targettile->isPz()) {
- if(player) {
- player->sendTextMessage(MSG_SMALLINFO, "You may not attack a person in a protection zone.");
- playerSetAttackedCreature(player, 0);
- }
- return false;
- }
- }
- return true;
- }
- return false;
- }
- bool Game::creatureOnPrepareMagicAttack(Creature *creature, Position pos, const MagicEffectClass* me, bool isparal = false)
- {
- if(!me->offensive || me->isIndirect() || creatureOnPrepareAttack(creature, pos)) {
- /*
- if(creature->access < ACCESS_PROTECT) {
- if(!((std::abs(creature->pos.x-centerpos.x) <= 8) && (std::abs(creature->pos.y-centerpos.y) <= 6) &&
- (creature->pos.z == centerpos.z)))
- return false;
- }
- */
- Player* player = dynamic_cast<Player*>(creature);
- if(player) {
- if(player->access < g_config.ACCESS_PROTECT) {
- if(player->exhaustedTicks >= 1000 && me->causeExhaustion(true)) {
- if(me->offensive) {
- player->sendTextMessage(MSG_SMALLINFO, "You are exhausted.",player->pos, NM_ME_PUFF);
- player->exhaustedTicks += g_config.EXHAUSTED_ADD;
- }
- return false;
- }
- else if(player->mana < me->manaCost) {
- player->sendTextMessage(MSG_SMALLINFO, "You do not have enough mana.",player->pos, NM_ME_PUFF);
- return false;
- }
- else {
- if(isparal != true) {
- player->mana -= me->manaCost;
- //player->manaspent += me->manaCost;
- std::cout << "isparal, creatureOnPrepareMagicAttack: " << isparal << std::endl;
- player->addManaSpent(me->manaCost);
- }
- }
- }
- }
- return true;
- }
- return false;
- }
- void Game::creatureMakeDamage(Creature *creature, Creature *attackedCreature, fight_t damagetype)
- {
- if(!creatureOnPrepareAttack(creature, attackedCreature->pos))
- return;
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::creatureMakeDamage()");
- Player* player = dynamic_cast<Player*>(creature);
- Player* attackedPlayer = dynamic_cast<Player*>(attackedCreature);
- //Attack limiter
- if(player) {
- if (player->lastAttack == 0) {
- player->lastAttack = OTSYS_TIME() - 1000 - 1;
- }
- if ((OTSYS_TIME() - player->lastAttack) < 1000) {
- return;
- }
- }
- #ifdef ANTI_MISS
- if(player && player->atkMode == 1 && player->access <= g_config.ACCESS_PROTECT && attackedPlayer && attackedPlayer->skullType == 0) {
- player->sendCancelAttacking();
- player->sendTextMessage(MSG_SMALLINFO, "Turn secure mode off if you really want to attack unmarked players.");
- return;
- }
- #endif //ANTI_MISS
- //Tile* targettile = getTile(attackedCreature->pos.x, attackedCreature->pos.y, attackedCreature->pos.z);
- Tile* targettile = map->getTile(attackedCreature->pos);
- //can the attacker reach the attacked?
- bool inReach = false;
- switch(damagetype){
- case FIGHT_MELEE:
- if((std::abs(creature->pos.x-attackedCreature->pos.x) <= 1) &&
- (std::abs(creature->pos.y-attackedCreature->pos.y) <= 1) &&
- (creature->pos.z == attackedCreature->pos.z))
- inReach = true;
- break;
- case FIGHT_DIST:
- if((std::abs(creature->pos.x-attackedCreature->pos.x) <= 8) &&
- (std::abs(creature->pos.y-attackedCreature->pos.y) <= 5) &&
- (creature->pos.z == attackedCreature->pos.z)) {
- //if(map->canThrowItemTo(creature->pos, attackedCreature->pos, false, true))
- if(map->canThrowObjectTo(creature->pos, attackedCreature->pos, BLOCK_PROJECTILE) == RET_NOERROR)
- inReach = true;
- }
- break;
- case FIGHT_MAGICDIST:
- if((std::abs(creature->pos.x-attackedCreature->pos.x) <= 8) &&
- (std::abs(creature->pos.y-attackedCreature->pos.y) <= 5) &&
- (creature->pos.z == attackedCreature->pos.z)) {
- //if(map->canThrowItemTo(creature->pos, attackedCreature->pos, false, true))
- if(map->canThrowObjectTo(creature->pos, attackedCreature->pos, BLOCK_PROJECTILE) == RET_NOERROR)
- inReach = true;
- }
- break;
- }
- if (player && player->access < g_config.ACCESS_PROTECT)
- {
- #ifdef YUR_CVS_MODS
- player->inFightTicks = std::max(g_config.PZ_LOCKED, player->inFightTicks);
- #else
- player->inFightTicks = g_config.PZ_LOCKED;
- #endif //YUR_CVS_MODS
- player->sendIcons();
- if(attackedPlayer)
- player->pzLocked = true;
- }
- if(attackedPlayer && attackedPlayer->access < g_config.ACCESS_PROTECT)
- {
- #ifdef YUR_CVS_MODS
- attackedPlayer->inFightTicks = std::max(g_config.PZ_LOCKED, attackedPlayer->inFightTicks);
- #else
- attackedPlayer->inFightTicks = g_config.PZ_LOCKED;
- #endif //YUR_CVS_MODS
- attackedPlayer->sendIcons();
- }
- if(!inReach){
- return;
- }
- //We do all changes against a GameState to keep track of the changes,
- //need some more work to work for all situations...
- GameState gamestate(this, Range(creature->pos, attackedCreature->pos));
- gamestate.onAttack(creature, attackedCreature->pos, attackedCreature);
- const CreatureStateVec& creatureStateVec = gamestate.getCreatureStateList(targettile);
- const CreatureState& creatureState = creatureStateVec[0].second;
- if(player && (creatureState.damage > 0 || creatureState.manaDamage > 0)) {
- #ifdef WANDS_JIDDO
- if(player && ((player->items[SLOT_RIGHT] && (!player->items[SLOT_RIGHT]->getWand())) || (!player->items[SLOT_RIGHT] && !player->items[SLOT_LEFT]) || (player->items[SLOT_LEFT] && (!player->items[SLOT_LEFT]->getWand()))))
- player->addSkillTry(2);
- #else
- player->addSkillTry(2);
- #endif
- }
- else if(player){
- #ifdef WANDS_JIDDO
- if(player && ((player->items[SLOT_RIGHT] && (!player->items[SLOT_RIGHT]->getWand())) || (!player->items[SLOT_RIGHT] && !player->items[SLOT_LEFT]) || (player->items[SLOT_LEFT] && (!player->items[SLOT_LEFT]->getWand()))))
- player->addSkillTry(1);
- #else
- player->addSkillTry(1);
- #endif
- }
- if(attackedPlayer){
- NetworkMessage msg;
- msg.AddByte(0x86);
- msg.AddU32(creature->getID());
- msg.AddByte(0x00);
- attackedPlayer->sendNetworkMessage(&msg);
- }
- SpectatorVec spectatorlist = gamestate.getSpectators();
- SpectatorVec::iterator it;
- for(it = spectatorlist.begin(); it != spectatorlist.end(); ++it) {
- Player* spectator = dynamic_cast<Player*>(*it);
- if(!spectator)
- continue;
- if(damagetype != FIGHT_MELEE){
- spectator->sendDistanceShoot(creature->pos, attackedCreature->pos, creature->getSubFightType());
- }
- if (attackedCreature->manaShieldTicks < 1000 && (creatureState.damage == 0) &&
- (spectator->CanSee(attackedCreature->pos.x, attackedCreature->pos.y, attackedCreature->pos.z))) {
- spectator->sendMagicEffect(attackedCreature->pos, NM_ME_PUFF);
- }
- else if (attackedCreature->manaShieldTicks < 1000 && (creatureState.damage < 0) &&
- (spectator->CanSee(attackedCreature->pos.x, attackedCreature->pos.y, attackedCreature->pos.z))) {
- spectator->sendMagicEffect(attackedCreature->pos, NM_ME_BLOCKHIT);
- }
- else {
- for(std::vector<Creature*>::const_iterator cit = creatureState.attackerlist.begin(); cit != creatureState.attackerlist.end(); ++cit) {
- Creature* gainexpCreature = *cit;
- if(dynamic_cast<Player*>(gainexpCreature))
- dynamic_cast<Player*>(gainexpCreature)->sendStats();
- if(spectator->CanSee(gainexpCreature->pos.x, gainexpCreature->pos.y, gainexpCreature->pos.z)) {
- char exp[128];
- #ifdef YUR_HIGH_LEVELS // TODO: format like this: 1,000,000
- sprintf(exp,"%lld",attackedCreature->getGainedExperience(gainexpCreature));
- spectator->sendAnimatedText(gainexpCreature->pos, 0xD7, exp);
- #else
- itoa(attackedCreature->getGainedExperience(gainexpCreature), exp, 10);
- #endif //YUR_HIGH_LEVLES
- spectator->sendAnimatedText(gainexpCreature->pos, 0xD7, exp);
- }
- }
- if (spectator->CanSee(attackedCreature->pos.x, attackedCreature->pos.y, attackedCreature->pos.z))
- {
- if(creatureState.damage > 0) {
- std::stringstream dmg;
- dmg << std::abs(creatureState.damage);
- #ifdef TJ_MONSTER_BLOOD
- spectator->sendAnimatedText(attackedCreature->pos, attackedCreature->bloodcolor, dmg.str());
- spectator->sendMagicEffect(attackedCreature->pos, attackedCreature->bloodeffect);
- #else
- spectator->sendAnimatedText(attackedCreature->pos, 0xB4, dmg.str());
- spectator->sendMagicEffect(attackedCreature->pos, NM_ME_DRAW_BLOOD);
- #endif //TJ_MONSTER_BLOOD
- }
- if(creatureState.manaDamage >0) {
- std::stringstream manaDmg;
- manaDmg << std::abs(creatureState.manaDamage);
- spectator->sendMagicEffect(attackedCreature->pos, NM_ME_LOOSE_ENERGY);
- spectator->sendAnimatedText(attackedCreature->pos, 2, manaDmg.str());
- }
- if (attackedCreature->health > 0)
- spectator->sendCreatureHealth(attackedCreature);
- if (spectator == attackedCreature) {
- CreateManaDamageUpdate(attackedCreature, creature, creatureState.manaDamage);
- CreateDamageUpdate(attackedCreature, creature, creatureState.damage);
- }
- if(player)
- player->lastAttack = OTSYS_TIME();
- }
- }
- }
- if(damagetype != FIGHT_MELEE && player) {
- player->removeDistItem();
- }
- }
- std::list<Position> Game::getPathTo(Creature *creature, Position start, Position to, bool creaturesBlock){
- return map->getPathTo(creature, start, to, creaturesBlock);
- }
- std::list<Position> Game::getPathToEx(Creature *creature, Position start, Position to, bool creaturesBlock){
- return map->getPathToEx(creature, start, to, creaturesBlock);
- }
- void Game::checkPlayerWalk(uint32_t id)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::checkPlayerWalk");
- Player *player = getPlayerByID(id);
- if(!player)
- return;
- if(player->pathlist.empty()){
- stopEvent(player->eventAutoWalk);
- player->eventAutoWalk = 0;
- return;
- }
- Position pos = player->pos;
- Direction dir = player->pathlist.front();
- player->pathlist.pop_front();
- switch (dir) {
- case NORTH:
- pos.y--;
- break;
- case EAST:
- pos.x++;
- break;
- case SOUTH:
- pos.y++;
- break;
- case WEST:
- pos.x--;
- break;
- case NORTHEAST:
- pos.x++;
- pos.y--;
- break;
- case NORTHWEST:
- pos.x--;
- pos.y--;
- break;
- case SOUTHWEST:
- pos.x--;
- pos.y++;
- break;
- case SOUTHEAST:
- pos.x++;
- pos.y++;
- break;
- }
- /*
- #ifdef __DEBUG__
- std::cout << "move to: " << dir << std::endl;
- #endif
- */
- player->lastmove = OTSYS_TIME();
- thingMove(player, player, pos.x, pos.y, pos.z, 1);
- flushSendBuffers();
- if(!player->pathlist.empty()){
- int ticks = (int)player->getSleepTicks();
- player->eventAutoWalk = addEvent(makeTask(ticks, std::bind2nd(std::mem_fun(&Game::checkPlayerWalk), id)));
- }
- else
- {
- stopEvent(player->eventAutoWalk);//?
- player->eventAutoWalk = 0;
- }
- }
- void Game::checkCreature(uint32_t id)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::checkCreature()");
- Creature *creature = getCreatureByID(id);
- if (creature && creature->isRemoved == false)
- {
- int32_t thinkTicks = 0;
- int32_t oldThinkTicks = creature->onThink(thinkTicks);
- if(thinkTicks > 0) {
- creature->eventCheck = addEvent(makeTask(thinkTicks, std::bind2nd(std::mem_fun(&Game::checkCreature), id)));
- }
- else
- creature->eventCheck = 0;
- Player* player = dynamic_cast<Player*>(creature);
- if(player)
- {
- //Tile *tile = getTile(player->pos.x, player->pos.y, player->pos.z);
- Tile *tile = map->getTile(player->pos);
- if(tile == NULL){
- std::cout << "CheckPlayer NULL tile: " << player->getName() << std::endl;
- return;
- }
- #ifdef _REX_CVS_MOD_
- if(player->tradeTicks >= 1000)
- player->tradeTicks -= thinkTicks;
- #endif
- #ifdef CVS_DAY_CYCLE
- player->sendWorldLightLevel(lightlevel, 0xD7);
- #endif //CVS_DAY_CYCLE
- #ifdef REX_MUTED
- #endif //REX_MUTED
- #ifdef TR_ANTI_AFK
- player->checkAfk(thinkTicks);
- #endif //TR_ANTI_AF
- #ifdef YUR_BOH
- player->checkBoh();
- #endif //YUR_BOH
- #ifdef YUR_WH
- player->checkWh();
- #endif //YUR_WH
- #ifdef YUR_RINGS_AMULETS
- player->checkRing(thinkTicks);
- #endif //YUR_RINGS_AMULETS
- //SOFT BOOTS
- if(player->softTicks >= 2) {
- if(player->items[SLOT_FEET] && player->items[SLOT_FEET]->getID() == ITEM_SOFT_BOOTS && !tile->isPz()){
- player->mana += min(g_config.SOFT_MANA, player->manamax - player->mana);
- player->health += min(g_config.SOFT_HEALTH, player->healthmax - player->health);
- }
- player->softTicks = 0;
- } else {
- player->softTicks++;
- }
- // LIFE RING
- if(player->items[SLOT_RING] && player->items[SLOT_RING]->getID() == ITEM_LIFE_RING_IN_USE && !tile->isPz()){
- player->mana += min(g_config.LR_MANA, player->manamax - player->mana);
- player->health += min(g_config.LR_HEALTH, player->healthmax - player->health);
- }
- // ROH
- if(player->items[SLOT_RING] && player->items[SLOT_RING]->getID() == ITEM_RING_OF_HEALING_IN_USE && !tile->isPz()){
- player->mana += min(g_config.ROH_MANA, player->manamax - player->mana);
- player->health += min(g_config.ROH_HEALTH, player->healthmax - player->health);
- }
- // ROAH
- // ROH 240
- if(player->items[SLOT_RING] && player->items[SLOT_RING]->getID() == ITEM_STEALTH_RING_IN_USE && !tile->isPz()){
- player->mana += min(g_config.ROAH_MANA, player->manamax - player->mana);
- player->health += min(g_config.ROAH_HEALTH, player->healthmax - player->health);
- }
- // RAINBOW SHIELD
- if(player->level >= 150){
- if(player->items[SLOT_RIGHT] && player->items[SLOT_RIGHT]->getID() == ITEM_RAINBOW && !tile->isPz()){
- if(player->items[SLOT_LEFT]){
- if(player->items[SLOT_LEFT]->getID() != ITEM_RAINBOW)
- if(player->mana > g_config.getGlobalNumber("rainbow_mana", 4) && player->health < player->healthmax){
- player->mana -= g_config.getGlobalNumber("rainbow_mana", 1);
- player->health += min(g_config.getGlobalNumber("rainbow_health", 1), player->healthmax - player->health);
- player->addManaSpent(g_config.getGlobalNumber("rainbow_mana",5));
- }
- }else{
- if(player->mana > g_config.getGlobalNumber("rainbow_mana", 4) && player->health < player->healthmax){
- player->mana -= g_config.getGlobalNumber("rainbow_mana", 1);
- player->health += min(g_config.getGlobalNumber("rainbow_health", 1), player->healthmax - player->health);
- player->addManaSpent(g_config.getGlobalNumber("rainbow_mana",5));
- }
- }
- }
- if(player->items[SLOT_LEFT] && player->items[SLOT_LEFT]->getID() == ITEM_RAINBOW && !tile->isPz()){
- if(player->items[SLOT_RIGHT]){
- if(player->items[SLOT_RIGHT]->getID() != ITEM_RAINBOW)
- if(player->mana > g_config.getGlobalNumber("rainbow_mana", 4) && player->health < player->healthmax){
- player->mana -= g_config.getGlobalNumber("rainbow_mana", 1);
- player->health += min(g_config.getGlobalNumber("rainbow_health", 1), player->healthmax - player->health);
- player->addManaSpent(g_config.getGlobalNumber("rainbow_mana",5));
- }
- }else{
- if(player->mana > g_config.getGlobalNumber("rainbow_mana", 4) && player->health < player->healthmax){
- player->mana -= g_config.getGlobalNumber("rainbow_mana", 1);
- player->health += min(g_config.getGlobalNumber("rainbow_health", 1), player->healthmax - player->health);
- player->addManaSpent(g_config.getGlobalNumber("rainbow_mana",5));
- }
- }
- }
- }
- // RING OF THE SKY
- if(player->level >= 30 && player->items[SLOT_RING] && player->items[SLOT_RING]->getID() == ITEM_ROTS && !tile->isPz())
- player->mana += min(1, player->manamax - player->mana);
- // ORSHABAAL HEART
- if(player->name == "Ekudron" || player->name == "Agecik" && player->items[SLOT_AMMO] && player->items[SLOT_AMMO]->getID() == ITEM_ORSHABAAL_HEARTH && !tile->isPz())
- player->mana += min(4, player->manamax - player->mana);
- #ifdef HUCZU_FIX
- if(player->items[SLOT_FEET] && player->items[SLOT_FEET]->getID() == ITEM_SPECTRE_BOOTS)
- player->immunities = ATTACK_PARALYZE;
- else
- player->immunities -= ATTACK_PARALYZE;
- #endif //HUCZU_FIX
- #ifdef YUR_LIGHT_ITEM
- player->checkLightItem(thinkTicks);
- #endif //YUR_LIGHT_ITEM
- #ifdef HUCZU_EXHAUSTED
- if(player->mmo > 0)
- player->mmo -= 1;
- else
- player->mmo = 0;
- if(player->lookex > 0)
- player->lookex -= 1;
- else
- player->lookex = 0;
- if(player->antyrainbow > 0)
- player->antyrainbow -= 1;
- else
- player->antyrainbow = 0;
- if(player->antyrainbow2 > 0)
- player->antyrainbow2 -= 1;
- else
- player->antyrainbow2 = 0;
- if(player->clin > 0)
- player->clin -= 1;
- else
- player->clin = 0;
- if(player->shut_d > 0)
- player->shut_d -= 1;
- else
- player->shut_d = 0;
- if(player->houseTicks > 0)
- player->houseTicks -= 1;
- else
- player->houseTicks = 0;
- #endif //HUCZU_EXHAUSTED
- if(player->flamTicks >= 1000){
- player->flamTicks -= thinkTicks;
- if(player->flamTicks == 0){
- player->flamBool = false;
- }
- }
- if(player->items[SLOT_RIGHT] && player->items[SLOT_LEFT]){
- if((player->items[SLOT_RIGHT]->getID() == ITEM_BOW || player->items[SLOT_RIGHT]->getID() == ITEM_XBOW) && (player->items[SLOT_LEFT]->getWeaponType() == SHIELD || player->items[SLOT_LEFT]->getWeaponType() == SWORD || player->items[SLOT_LEFT]->getWeaponType() == AXE || player->items[SLOT_LEFT]->getWeaponType() == CLUB)){
- player->removeItemInventory(SLOT_RIGHT);
- }
- if((player->items[SLOT_LEFT]->getID() == ITEM_BOW || player->items[SLOT_LEFT]->getID() == ITEM_XBOW) && (player->items[SLOT_RIGHT]->getWeaponType() == SHIELD || player->items[SLOT_RIGHT]->getWeaponType() == SWORD || player->items[SLOT_RIGHT]->getWeaponType() == AXE || player->items[SLOT_RIGHT]->getWeaponType() == CLUB)){
- player->removeItemInventory(SLOT_LEFT);
- }
- }
- if(player->items[SLOT_RIGHT] && player->items[SLOT_LEFT]){
- if((player->items[SLOT_RIGHT]->getID() == ITEM_SPEAR || player->items[SLOT_RIGHT]->getID() == ITEM_KNIFE || player->items[SLOT_RIGHT]->getID() == ITEM_STONE || player->items[SLOT_RIGHT]->getID() == ITEM_SNOWBALL || player->items[SLOT_RIGHT]->getID() == ITEM_STAR) && (player->items[SLOT_LEFT]->getWeaponType() == SWORD || player->items[SLOT_LEFT]->getWeaponType() == AXE || player->items[SLOT_LEFT]->getWeaponType() == CLUB)){
- player->removeItemInventory(SLOT_RIGHT);
- }
- if((player->items[SLOT_LEFT]->getID() == ITEM_SPEAR || player->items[SLOT_LEFT]->getID() == ITEM_KNIFE || player->items[SLOT_LEFT]->getID() == ITEM_STONE || player->items[SLOT_LEFT]->getID() == ITEM_SNOWBALL || player->items[SLOT_LEFT]->getID() == ITEM_STAR) && (player->items[SLOT_RIGHT]->getWeaponType() == SWORD || player->items[SLOT_RIGHT]->getWeaponType() == AXE || player->items[SLOT_RIGHT]->getWeaponType() == CLUB)){
- player->removeItemInventory(SLOT_LEFT);
- }
- }
- #ifdef HUCZU_SKULLS
- if (player->checkSkull(thinkTicks))
- Skull(player);
- #endif //HUCZU_SKULLS
- #ifdef YUR_INVISIBLE
- if (player->checkInvisible(thinkTicks))
- creatureChangeOutfit(player);
- #endif //YUR_INVISIBLE
- #ifdef _BBK_PUSH_DELAY
- if(player->pushDelay >= 1000)
- {
- player->pushDelay -= thinkTicks;
- if(player->pushDelay < 0)
- player->pushDelay = 0;
- }
- #endif //_BBK_PUSH_DELAY
- if(player->training == true){
- if(player->trainingTicks >= 1000){
- player->trainingTicks -= thinkTicks;
- if(player->trainingTicks < 0)
- player->trainingTicks = 0;
- }
- if(player->trainingTicks == 0 && player->rewriteTicks == 0){
- int code = random_range(47,99) * random_range(47,99);
- player->rewriteCode = code;
- player->needrewrite = true;
- player->rewriteTicks = g_config.REWRITE_TICKS;
- std::ostringstream info;
- player->sendTextMessage(MSG_BLUE_TEXT,"You are training here pretty long.Are you using bot?");
- info << "Please rewrite code: " << player->rewriteCode << std::ends;
- player->sendTextMessage(MSG_BLUE_TEXT, info.str().c_str());
- std::ostringstream info2;
- info2 << "Use this command !train 1234. You have " << player->rewriteTicks/1000 << " seconds!" << std::ends;
- player->sendTextMessage(MSG_BLUE_TEXT, info2.str().c_str());
- }
- if(player->needrewrite != false){
- if(player->rewriteTicks >= 1000){
- player->rewriteTicks -= thinkTicks;
- }
- if(player->rewriteTicks == 0){
- this->teleport(player, player->masterPos);
- player->training = false;
- player->trainingTicks = 0;
- player->needrewrite = false;
- player->rewriteCode = 0;
- player->rewriteTicks = 0;
- player->kickPlayer();
- //player->sendLogout();
- }
- }
- }
- #ifdef HUCZU_FIX
- if(player->gainHealthTick()){
- SpectatorVec list;
- SpectatorVec::iterator it;
- getSpectators(Range(creature->pos), list);
- for(it = list.begin(); it != list.end(); ++it) {
- Player* p = dynamic_cast<Player*>(*it);
- if(p)
- p->sendCreatureHealth(player);
- }
- }
- #endif //HUCZU_FIX
- if(player->lightTicks >= 1000){
- player->lightTicks -= thinkTicks;
- if(player->lightTicks <= 1000){
- player->lightTicks = 1;
- }
- }
- else if(player->lightTicks == 1){
- if(player->lightlevel > 0){
- creatureChangeLight(player, 0, player->lightlevel-1, 0xD7);
- }
- else{
- creatureChangeLight(player, 0, 0, 0xD7);
- player->lightTicks = 0;
- player->lightItem = 0;
- }
- if(player->lightTries > 0){
- player->lightTicks = 3*60*1000;
- player->lightTries -= 1;
- }
- }
- #ifdef HUCZU_SKULLS
- checkSkullTime(player);
- #endif //HUCZU_SKULLS
- if(!tile->isPz()){
- if(player->food > 1000){
- player->gainManaTick();
- player->food -= thinkTicks;
- if(player->healthmax - player->health > 0){
- if(player->gainHealthTick()){
- SpectatorVec list;
- SpectatorVec::iterator it;
- getSpectators(Range(creature->pos), list);
- for(it = list.begin(); it != list.end(); ++it) {
- Player* p = dynamic_cast<Player*>(*it);
- if(p)
- p->sendCreatureHealth(player);
- }
- }
- }
- }
- }
- //send stast only if have changed
- if(player->NeedUpdateStats()){
- player->sendStats();
- }
- player->sendPing(thinkTicks);
- if(player->inFightTicks >= 1000) {
- player->inFightTicks -= thinkTicks;
- if(player->inFightTicks < 1000)
- player->pzLocked = false;
- player->sendIcons();
- }
- if(player->drunkTicks >= 1000) {
- int32_t random = random_range(1,100);
- if(random <= 25){
- creatureSay(creature, SPEAK_SAY, "Hicks!");
- Position pos;
- int32_t randomwalk = random_range(1,4);
- switch(randomwalk){
- case 1:pos.x++;break;
- case 2:pos.x--;break;
- case 3:pos.y++;break;
- case 4:pos.y--;break;
- }
- Tile* toTile = getTile(pos.x, pos.y, pos.z);
- //make sure they don't get teleported into a place they shouldn't
- if(toTile &&
- !toTile->isBlocking(1, false, false) &&
- !toTile->isBlocking(2, false, false) &&
- !toTile->isBlocking(4, false, false) &&
- !toTile->isBlocking(8, false, false) &&
- !toTile->isBlocking(16, false, false))
- teleport(player,pos);
- }
- player->drunkTicks -= thinkTicks;
- player->sendIcons();
- }
- if(player->exhaustedTicks >= 1000){
- player->exhaustedTicks -= thinkTicks;
- if(player->exhaustedTicks < 0)
- player->exhaustedTicks = 0;
- }
- if(player->manaShieldTicks >=1000){
- player->manaShieldTicks -= thinkTicks;
- if(player->manaShieldTicks < 1000)
- player->sendIcons();
- }
- if(player->dwarvenTicks > 0){
- player->drunkTicks = 0;
- player->sendIcons();
- }
- if(player->dwarvenTicks = 0){
- player->drunkTicks = 4000;
- player->sendIcons();
- }
- if(player->hasteTicks >=1000)
- player->hasteTicks -= thinkTicks;
- }else{
- if(creature->manaShieldTicks >=1000){
- creature->manaShieldTicks -= thinkTicks;
- }
- if(creature->hasteTicks >=1000){
- creature->hasteTicks -= thinkTicks;
- }
- #ifdef YUR_INVISIBLE
- if (creature->checkInvisible(thinkTicks))
- creatureChangeOutfit(creature);
- #endif //YUR_INVISIBLE
- }
- Conditions& conditions = creature->getConditions();
- for(Conditions::iterator condIt = conditions.begin(); condIt != conditions.end(); ++condIt) {
- if(condIt->first == ATTACK_FIRE || condIt->first == ATTACK_ENERGY || condIt->first == ATTACK_POISON) {
- ConditionVec &condVec = condIt->second;
- if(condVec.empty())
- continue;
- CreatureCondition& condition = condVec[0];
- if(condition.onTick(oldThinkTicks)) {
- const MagicEffectTargetCreatureCondition* magicTargetCondition = condition.getCondition();
- Creature* c = getCreatureByID(magicTargetCondition->getOwnerID());
- creatureMakeMagic(c, creature->pos, magicTargetCondition);
- if(condition.getCount() <= 0) {
- condVec.erase(condVec.begin());
- if(dynamic_cast<Player*>(creature))
- player->sendIcons();
- }
- }
- }
- if(condIt->first == ATTACK_PARALYZE)
- {
- ConditionVec &condVec = condIt->second;
- if(condVec.empty())
- continue;
- CreatureCondition& condition = condVec[0];
- if(condition.onTick(oldThinkTicks))
- {
- //Player* player = dynamic_cast<Player*>(creature);
- if(creature->getImmunities() != ATTACK_PARALYZE)
- {
- changeSpeed(creature->getID(), 100);
- if(player)
- {
- player->sendTextMessage(MSG_SMALLINFO, "You are paralyzed.");
- player->sendIcons();
- }
- }
- if(condition.getCount() <= 0)
- {
- condVec.erase(condVec.begin());
- changeSpeed(creature->getID(), creature->getNormalSpeed()+creature->hasteSpeed);
- if(player)
- {
- player->sendIcons();
- }
- }
- }
- }
- }
- flushSendBuffers();
- }
- }
- void Game::changeOutfit(uint32_t id, int32_t looktype){
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::changeOutfit()");
- Creature *creature = getCreatureByID(id);
- if(creature){
- creature->looktype = looktype;
- if(creature->lookfeet_master != 0 || creature->lookhead_master != 0 ||
- creature->looklegs_master != 0 || creature->lookbody_master != 0 ){
- creature->lookhead = creature->lookhead_master;
- creature->lookbody = creature->lookbody_master;
- creature->looklegs = creature->looklegs_master;
- creature->lookfeet = creature->lookfeet_master;
- creature->lookhead_master = 0;
- creature->lookbody_master = 0;
- creature->looklegs_master = 0;
- creature->lookfeet_master = 0;
- }
- creatureChangeOutfit(creature);
- }
- }
- void Game::changeOutfitAfter(uint32_t id, int32_t looktype, long time)
- {
- addEvent(makeTask(time, boost::bind(&Game::changeOutfit, this,id, looktype)));
- }
- void Game::changeSpeed(uint32_t id, unsigned short speed)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::changeSpeed()");
- Creature *creature = getCreatureByID(id);
- if(creature && /*creature->hasteTicks < 1000 && */creature->speed != speed)
- {
- creature->speed = speed;
- Player* player = dynamic_cast<Player*>(creature);
- if(player){
- player->sendChangeSpeed(creature);
- player->sendIcons();
- }
- SpectatorVec list;
- SpectatorVec::iterator it;
- getSpectators(Range(creature->pos), list);
- //for(uint32_t i = 0; i < list.size(); i++)
- for(it = list.begin(); it != list.end(); ++it) {
- Player* p = dynamic_cast<Player*>(*it);
- if(p)
- p->sendChangeSpeed(creature);
- }
- }
- }
- void Game::checkCreatureAttacking(uint32_t id)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::checkCreatureAttacking()");
- Creature *creature = getCreatureByID(id);
- if (creature != NULL && creature->isRemoved == false)
- {
- creature->eventCheckAttacking = 0;
- Player *player = dynamic_cast<Player*>(creature);
- Monster *monster = dynamic_cast<Monster*>(creature);
- if (monster) {
- monster->onAttack();
- }
- else {
- if (creature->attackedCreature != 0)
- {
- Creature *attackedCreature = getCreatureByID(creature->attackedCreature);
- if (attackedCreature)
- {
- // canAttack system BRY
- Player *attacker = dynamic_cast<Player*>(creature);
- Player *attacked = dynamic_cast<Player*>(attackedCreature);
- bool canAttack = false;
- if(attacker && attacked)
- {
- Tile* tile = getTile(attacker->pos.x,attacker->pos.y, attacker->pos.z);
- if(attacked->level >= 1 && attacked->level < 30 && attacker->level >= 1 && attacker->level < 30)
- canAttack = false;
- else if(attacked->level >= 30 && attacked->level < 80 && attacker->level >= 30 && attacker->level < 80)
- canAttack = true;
- else if(attacked->level >= 80 && attacked->level < 999 && attacker->level >= 80 && attacker->level < 999)
- canAttack = true;
- else if(tile && tile->isPvpArena())
- canAttack = true;
- }
- if(attacker && attacked && !canAttack)
- {
- attacker->sendCancelAttacking();
- attacker->sendCancel("You may not attack this player yet.");
- playerSetAttackedCreature(attacker, 0);
- return;
- }
- //Tile* fromtile = getTile(creature->pos.x, creature->pos.y, creature->pos.z);
- Tile* fromtile = map->getTile(creature->pos);
- if(fromtile == NULL) {
- std::cout << "checkCreatureAttacking NULL tile: " << creature->getName() << std::endl;
- //return;
- }
- Player* attackedPlayer = dynamic_cast<Player*>(attackedCreature);
- if (!attackedCreature->isAttackable() == 0 && fromtile && fromtile->isPz() && creature->access < g_config.ACCESS_PROTECT)
- {
- Player* player = dynamic_cast<Player*>(creature);
- if (player) {
- player->sendTextMessage(MSG_SMALLINFO, "You may not attack a person in a protection zone.");
- //player->sendCancelAttacking();
- playerSetAttackedCreature(player, 0);
- return;
- }
- }
- #ifdef YUR_INVISIBLE
- if (attackedCreature->isInvisible())
- {
- Player* player = dynamic_cast<Player*>(creature);
- Player* attackedPlayer = dynamic_cast<Player*>(attackedCreature);
- if (player && !attackedPlayer) {
- player->sendTextMessage(MSG_SMALLINFO, "Target lost.");
- playerSetAttackedCreature(player, 0);
- return;
- }
- }
- #endif //YUR_INVISIBLE
- else
- {
- if (attackedCreature != NULL && attackedCreature->isRemoved == false)
- {
- #ifdef ZS_SWORDS
- int32_t swordid = player->getSwordId();
- if (swordid > 0)
- useSword(player, attackedCreature, swordid);
- #endif //ZS_SWORDS
- if(player && player->followMode == 0x01) {
- player->followCreature = attackedCreature->getID();
- playerAttackSetFollowCreature(player, attackedCreature->getID());
- playerFollowAttacking(player, attackedCreature);
- long long delay = player->getSleepTicks();
- player->eventCheckFollow = addEvent(makeTask(delay, std::bind2nd(std::mem_fun(&Game::checkCreatureFollowAttack), player->getID())));
- }
- #ifdef WANDS_JIDDO
- Player* player = dynamic_cast<Player*>(creature);
- int32_t wandid = 0;
- if(player && ((player->items[SLOT_RIGHT] && (wandid = player->items[SLOT_RIGHT]->getWand())) || (player->items[SLOT_LEFT] && (wandid = player->items[SLOT_LEFT]->getWand())))) {
- useWand(creature, attackedCreature, wandid);
- } else {
- #endif
- Player* player = dynamic_cast<Player*>(creature);
- if (player)
- {
- #ifdef SD_BURST_ARROW
- if (player->isUsingBurstArrows())
- burstArrow(player, attackedCreature->pos);
- #endif //SD_BURST_ARROW
- if(player->flamBool == true){
- Blasting(player, attackedCreature, attackedCreature->pos);
- player->flamBool = false;
- }
- }
- this->creatureMakeDamage(creature, attackedCreature, creature->getFightType());
- #ifdef WANDS_JIDDO
- }
- #endif
- }
- }
- if (player->vocation == 0) {
- int32_t speed = int32_t(g_config.NO_VOC_SPEED * 1000);
- creature->eventCheckAttacking = addEvent(makeTask(speed, std::bind2nd(std::mem_fun(&Game::checkCreatureAttacking), id)));
- }
- else if (player->vocation == 1) {
- int32_t speed = int32_t(g_config.SORC_SPEED * 1000);
- creature->eventCheckAttacking = addEvent(makeTask(speed, std::bind2nd(std::mem_fun(&Game::checkCreatureAttacking), id)));
- }
- else if (player->vocation == 2) {
- int32_t speed = int32_t(g_config.DRUID_SPEED * 1000);
- creature->eventCheckAttacking = addEvent(makeTask(speed, std::bind2nd(std::mem_fun(&Game::checkCreatureAttacking), id)));
- }
- else if (player->vocation == 3) {
- int32_t speed = int32_t(g_config.PALLY_SPEED * 1000);
- creature->eventCheckAttacking = addEvent(makeTask(speed, std::bind2nd(std::mem_fun(&Game::checkCreatureAttacking), id)));
- }
- else if (player->vocation == 4) {
- int32_t speed = int32_t(g_config.KNIGHT_SPEED * 1000);
- creature->eventCheckAttacking = addEvent(makeTask(speed, std::bind2nd(std::mem_fun(&Game::checkCreatureAttacking), id)));
- }
- else { //change the 2000 to whatever you want; 2000 = 2 seconds per attack
- creature->eventCheckAttacking = addEvent(makeTask(1000, std::bind2nd(std::mem_fun(&Game::checkCreatureAttacking), id)));
- }
- }
- }
- }
- flushSendBuffers();
- }
- }
- void Game::checkDecay(int32_t t)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::checkDecay()");
- addEvent(makeTask(DECAY_INTERVAL, boost::bind(&Game::checkDecay,this,DECAY_INTERVAL)));
- list<decayBlock*>::iterator it;
- for(it = decayVector.begin();it != decayVector.end();){
- (*it)->decayTime -= t;
- if((*it)->decayTime <= 0){
- list<Item*>::iterator it2;
- for(it2 = (*it)->decayItems.begin(); it2 != (*it)->decayItems.end(); it2++){
- /*todo: Decaying item could be in a container carried by a player,
- should all items have a pointer to their parent (like containers)?*/
- Item* item = *it2;
- item->isDecaying = false;
- if(item->canDecay()){
- if(item->pos.x != 0xFFFF){
- Tile *tile = map->getTile(item->pos);
- if(tile){
- Position pos = item->pos;
- Item* newitem = item->decay();
- if(newitem){
- int32_t stackpos = tile->getThingStackPos(item);
- if(newitem == item){
- sendUpdateThing(NULL,pos,newitem,stackpos);
- }
- else{
- if(tile->removeThing(item)){
- //autoclose containers
- if(dynamic_cast<Container*>(item)){
- SpectatorVec list;
- SpectatorVec::iterator it;
- getSpectators(Range(pos, true), list);
- for(it = list.begin(); it != list.end(); ++it) {
- Player* spectator = dynamic_cast<Player*>(*it);
- if(spectator)
- spectator->onThingRemove(item);
- }
- }
- tile->insertThing(newitem, stackpos);
- sendUpdateThing(NULL,pos,newitem,stackpos);
- FreeThing(item);
- }
- }
- startDecay(newitem);
- }
- else{
- if(removeThing(NULL,pos,item)){
- FreeThing(item);
- }
- }//newitem
- }//tile
- }//pos != 0xFFFF
- }//item->canDecay()
- FreeThing(item);
- }//for it2
- delete *it;
- it = decayVector.erase(it);
- }//(*it)->decayTime <= 0
- else{
- it++;
- }
- }//for it
- flushSendBuffers();
- }
- void Game::startDecay(Item* item){
- if(item->isDecaying)
- return;//dont add 2 times the same item
- //get decay time
- item->isDecaying = true;
- uint32_t dtime = item->getDecayTime();
- if(dtime == 0)
- return;
- //round time
- if(dtime < DECAY_INTERVAL)
- dtime = DECAY_INTERVAL;
- dtime = (dtime/DECAY_INTERVAL)*DECAY_INTERVAL;
- item->useThing();
- //search if there are any block with this time
- list<decayBlock*>::iterator it;
- for(it = decayVector.begin();it != decayVector.end();it++){
- if((*it)->decayTime == dtime){
- (*it)->decayItems.push_back(item);
- return;
- }
- }
- //we need a new decayBlock
- decayBlock* db = new decayBlock;
- db->decayTime = dtime;
- db->decayItems.clear();
- db->decayItems.push_back(item);
- decayVector.push_back(db);
- }
- void Game::checkSpawns(int32_t t)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::checkSpawns()");
- SpawnManager::instance()->checkSpawns(t);
- this->addEvent(makeTask(t, std::bind2nd(std::mem_fun(&Game::checkSpawns), t)));
- }
- void Game::CreateDamageUpdate(Creature* creature, Creature* attackCreature, int32_t damage)
- {
- Player* player = dynamic_cast<Player*>(creature);
- Player* attackPlayer = dynamic_cast<Player*>(attackCreature);
- if(!player)
- return;
- //player->sendStats();
- //msg.AddPlayerStats(player);
- if (damage > 0) {
- std::stringstream dmgmesg, info;
- if(damage == 1) {
- dmgmesg << "You lose 1 hitpoint";
- }
- else
- dmgmesg << "You lose " << damage << " hitpoints";
- if(attackPlayer) {
- dmgmesg << " due to an attack by " << attackCreature->getName();
- }
- else if(attackCreature) {
- std::string strname = attackCreature->getName();
- std::transform(strname.begin(), strname.end(), strname.begin(), (int32_t(*)(int32_t))tolower);
- dmgmesg << " due to an attack by a " << strname;
- }
- dmgmesg <<".";
- player->sendTextMessage(MSG_EVENT, dmgmesg.str().c_str());
- //msg.AddTextMessage(MSG_EVENT, dmgmesg.str().c_str());
- }
- if (player->isRemoved == true){
- player->sendTextMessage(MSG_ADVANCE, "You are dead.");
- }
- }
- void Game::CreateManaDamageUpdate(Creature* creature, Creature* attackCreature, int32_t damage)
- {
- Player* player = dynamic_cast<Player*>(creature);
- if(!player)
- return;
- if (damage > 0) {
- std::stringstream dmgmesg;
- dmgmesg << "You lose " << damage << " mana";
- if(attackCreature) {
- dmgmesg << " blocking an attack by " << attackCreature->getName();
- }
- dmgmesg <<".";
- player->sendTextMessage(MSG_EVENT, dmgmesg.str().c_str());
- }
- }
- bool Game::creatureSaySpell(Creature *creature, const std::string &text, bool say)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::creatureSaySpell()");
- bool ret = false;
- Player* player = dynamic_cast<Player*>(creature);
- std::string temp, var;
- uint32_t loc = (uint32_t)text.find( "\"", 0 );
- if( loc != string::npos && loc >= 0){
- temp = std::string(text, 0, loc-1);
- var = std::string(text, (loc+1), text.size()-loc-1);
- }
- else {
- temp = text;
- var = std::string("");
- }
- std::transform(temp.begin(), temp.end(), temp.begin(), (int32_t(*)(int32_t))tolower);
- if(creature->access >= g_config.ACCESS_PROTECT || !player){
- std::map<std::string, Spell*>::iterator sit = spells.getAllSpells()->find(temp);
- if (sit != spells.getAllSpells()->end()){
- sit->second->getSpellScript()->castSpell(creature, creature->pos, var);
- if (creature->access >= g_config.ACCESS_PROTECT && say == true)
- this->creatureSay(creature, SPEAK_MONSTER1, text);
- ret = true;
- }
- }
- else if(player){
- std::map<std::string, Spell*>* tmp = spells.getVocSpells(player->vocation);
- if(tmp){
- std::map<std::string, Spell*>::iterator sit = tmp->find(temp);
- if(sit != tmp->end()){
- if(player->maglevel >= sit->second->getMagLv()){
- #ifdef YUR_LEARN_SPELLS
- if (g_config.LEARN_SPELLS && !player->knowsSpell(temp))
- ret = false;
- else
- #endif //YUR_LEARN_SPELLS
- {
- if(sit->second->getSpellScript()->castSpell(creature, creature->pos, var) && say == true)
- this->creatureSay(player, SPEAK_MONSTER1, text);
- ret = true;
- }
- }
- }
- }
- }
- return ret;
- }
- void Game::playerAutoWalk(Player* player, std::list<Direction>& path)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::playerAutoWalk()");
- stopEvent(player->eventAutoWalk);
- player->eventAutoWalk = 0;
- if(player->isRemoved)
- return;
- player->pathlist = path;
- int32_t ticks = (int32_t)player->getSleepTicks();
- /*
- #ifdef __DEBUG__
- std::cout << "playerAutoWalk - " << ticks << std::endl;
- #endif
- */
- if(!player->pathlist.empty())
- player->eventAutoWalk = addEvent(makeTask(ticks, std::bind2nd(std::mem_fun(&Game::checkPlayerWalk), player->getID())));
- // then we schedule the movement...
- // the interval seems to depend on the speed of the char?
- //player->eventAutoWalk = addEvent(makeTask<Direction>(0, MovePlayer(player->getID()), path, 400, StopMovePlayer(player->getID())));
- //player->pathlist = path;
- }
- bool Game::playerUseItemEx(Player *player, const Position& posFrom,const unsigned char stack_from,
- const Position &posTo,const unsigned char stack_to, const unsigned short itemid)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::playerUseItemEx()");
- if(player->isRemoved)
- return false;
- bool ret = false;
- Position thingpos = getThingMapPos(player, posFrom);
- Item *item = dynamic_cast<Item*>(getThing(posFrom, stack_from, player));
- Container* container = player->getContainer(player->shop_index);
- if(container && item && !container->shop.empty() && container->isHoldingItem(item))
- return false;
- if(item) {
- //Runes
- std::map<unsigned short, Spell*>::iterator sit = spells.getAllRuneSpells()->find(item->getID());
- if(sit != spells.getAllRuneSpells()->end()) {
- #ifdef PALL_REQ_LVL
- std::stringstream ss;
- if(item->getReqLevel() > player->getLevel()){
- ss << "\n Musisz miec " << item->getReqLevel() << " poziom aby tego uzyc.";
- ret = false;
- }
- if(item->isWeapon() && item->getReqVoc() != player->getVocation()){
- switch(item->getReqVoc()){
- case 1:
- ss << "\n You must be a sorcerer to use this weapon.";
- ret = false;
- break;
- case 2:
- ss << "\n You must be a druid to use this weapon.";
- ret = false;
- break;
- case 3:
- ss << "\n You must be a paladin to use this weapon.";
- ret = false;
- break;
- case 4:
- ss << "\n You must be a knight to use this weapon.";
- ret = false;
- break;
- }
- }
- player->sendTextMessage(MSG_SMALLINFO, ss.str().c_str());
- #endif //PALL_REQ_LVL
- if( (abs(thingpos.x - player->pos.x) > 1) || (abs(thingpos.y - player->pos.y) > 1) ) {
- player->sendCancel("Too far away.");
- ret = false;
- }
- else {
- std::string var = std::string("");
- if(player->access >= g_config.ACCESS_PROTECT || sit->second->getMagLv() <= player->maglevel)
- {
- bool success = sit->second->getSpellScript()->castSpell(player, posTo, var);
- ret = success;
- if(success) {
- autoCloseTrade(item);
- item->setItemCharge(std::max((int32_t)item->getItemCharge() - 1, 0) );
- if(item->getItemCharge() == 0) {
- if(removeThing(player,posFrom,item)){
- FreeThing(item);
- }
- }
- }
- }
- else
- {
- player->sendCancel("You don't have the required magic level to use that rune.");
- }
- }
- }
- else{
- actions.UseItemEx(player,posFrom,stack_from,posTo,stack_to,itemid);
- ret = true;
- }
- }
- return ret;
- }
- bool Game::playerUseItem(Player *player, const Position& pos, const unsigned char stackpos, const unsigned short itemid, unsigned char index)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::playerUseItem()");
- if(itemid == 2273 || itemid == 2275 ){
- MagicEffectClass pox;
- pox.animationColor = 0;
- pox.damageEffect = NM_ME_MAGIC_ENERGIE;
- pox.hitEffect = 255;
- pox.attackType = ATTACK_NONE;
- pox.maxDamage = 0;
- pox.minDamage = 0;
- pox.offensive = false;
- pox.manaCost = 0;
- if(creatureMakeMagic(player, player->pos, &pox)){
- player->removeCondition(ATTACK_PARALYZE);
- int32_t newspeed = player->getNormalSpeed()+player->hasteSpeed;
- changeSpeed(player->getID(), (unsigned short)newspeed);
- if(player)
- player->sendIcons();
- }
- else{
- player->sendCancel("Sorry, not possible.");
- return false;
- }
- }
- if(player->isRemoved)
- return false;
- actions.UseItem(player,pos,stackpos,itemid,index);
- return true;
- }
- bool Game::playerUseBattleWindow(Player *player, Position &posFrom, unsigned char stackpos, unsigned short itemid, uint32_t creatureid)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::playerUseBattleWindow");
- if(player->isRemoved)
- return false;
- Creature *creature = getCreatureByID(creatureid);
- if(!creature || dynamic_cast<Player*>(creature))
- return false;
- if(std::abs(creature->pos.x - player->pos.x) > 7 || std::abs(creature->pos.y - player->pos.y) > 5 || creature->pos.z != player->pos.z)
- return false;
- bool ret = false;
- Position thingpos = getThingMapPos(player, posFrom);
- Item *item = dynamic_cast<Item*>(getThing(posFrom, stackpos, player));
- Container* container = player->getContainer(player->shop_index);
- if(container && item && !container->shop.empty() && container->isHoldingItem(item))
- return false;
- if(item) {
- //Runes
- std::map<unsigned short, Spell*>::iterator sit = spells.getAllRuneSpells()->find(item->getID());
- if(sit != spells.getAllRuneSpells()->end()) {
- if( (abs(thingpos.x - player->pos.x) > 1) || (abs(thingpos.y - player->pos.y) > 1) ) {
- player->sendCancel("Too far away.");
- }
- else {
- std::string var = std::string("");
- if(player->access >= g_config.ACCESS_PROTECT || sit->second->getMagLv() <= player->maglevel)
- {
- bool success = sit->second->getSpellScript()->castSpell(player, creature->pos, var);
- ret = success;
- if(success){
- autoCloseTrade(item);
- item->setItemCharge(std::max((int32_t)item->getItemCharge() - 1, 0) );
- if(item->getItemCharge() == 0){
- if(removeThing(player,posFrom,item)){
- FreeThing(item);
- }
- }
- }
- }
- else
- {
- player->sendCancel("You don't have the required magic level to use that rune.");
- }
- }
- }
- }
- return ret;
- }
- bool Game::playerRotateItem(Player *player, const Position& pos, const unsigned char stackpos, const unsigned short itemid)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::playerRotateItem()");
- if(player->isRemoved)
- return false;
- if(std::abs(player->pos.x - pos.x) > 1 || std::abs(player->pos.y - pos.y) > 1 || player->pos.z != pos.z){
- player->sendCancel("Too far away.");
- return false;
- }
- Item *item = dynamic_cast<Item*>(getThing(pos, stackpos, player));
- if(item && item->rotate()){
- sendUpdateThing(player, pos, item, stackpos);
- }
- return false;
- }
- void Game::playerRequestTrade(Player* player, const Position& pos,
- const unsigned char stackpos, const unsigned short itemid, uint32_t playerid)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::playerRequestTrade()");
- if(player->isRemoved)
- return;
- Player *tradePartner = getPlayerByID(playerid);
- if(!tradePartner || tradePartner == player) {
- player->sendTextMessage(MSG_INFO, "Sorry, not possible.");
- return;
- }
- if(player->tradeState != TRADE_NONE && !(player->tradeState == TRADE_ACKNOWLEDGE && player->tradePartner == playerid)) {
- player->sendCancel("You are already trading.");
- return;
- }
- else if(tradePartner->tradeState != TRADE_NONE && tradePartner->tradePartner != player->getID()) {
- player->sendCancel("This player is already trading.");
- return;
- }
- Item *tradeItem = dynamic_cast<Item*>(getThing(pos, stackpos, player));
- if(!tradeItem || tradeItem->getID() != itemid || !tradeItem->isPickupable()) {
- player->sendCancel("Sorry, not possible.");
- return;
- }
- #ifdef __KIRO_AKT__
- if(tradeItem->getID() == ITEM_AKT)
- {
- Tile* tile = getTile(player->pos);
- House* house = tile? tile->getHouse() : NULL;
- if(!house)
- {
- player->sendCancel("You must stay in house!");
- return;
- }
- if(house->getOwner() != player->getName())
- {
- player->sendCancel("You must stay in your house!");
- return;
- }
- }
- #endif
- if(!player->removeItem(tradeItem, true)) {
- /*if( (abs(player->pos.x - pos.x) > 1) || (abs(player->pos.y - pos.y) > 1) ) {
- player->sendCancel("To far away...");
- return;
- }*/
- player->sendCancel("Sorry, not possible.");
- return;
- }
- std::map<Item*, uint32_t>::const_iterator it;
- const Container* container = NULL;
- for(it = tradeItems.begin(); it != tradeItems.end(); it++) {
- if(tradeItem == it->first ||
- ((container = dynamic_cast<const Container*>(tradeItem)) && container->isHoldingItem(it->first)) ||
- ((container = dynamic_cast<const Container*>(it->first)) && container->isHoldingItem(tradeItem)))
- {
- player->sendTextMessage(MSG_INFO, "This item is already beeing traded.");
- return;
- }
- }
- Container* tradeContainer = dynamic_cast<Container*>(tradeItem);
- if(tradeContainer && tradeContainer->getItemHoldingCount() + 1 > 100){
- player->sendTextMessage(MSG_INFO, "You cannot trade more than 100 items.");
- return;
- }
- player->tradePartner = playerid;
- player->tradeItem = tradeItem;
- player->tradeState = TRADE_INITIATED;
- tradeItem->useThing();
- tradeItems[tradeItem] = player->getID();
- player->sendTradeItemRequest(player, tradeItem, true);
- if(tradePartner->tradeState == TRADE_NONE){
- std::stringstream trademsg;
- trademsg << player->getName() <<" wants to trade with you.";
- tradePartner->sendTextMessage(MSG_INFO, trademsg.str().c_str());
- tradePartner->tradeState = TRADE_ACKNOWLEDGE;
- tradePartner->tradePartner = player->getID();
- }
- else {
- Item* counterOfferItem = tradePartner->tradeItem;
- player->sendTradeItemRequest(tradePartner, counterOfferItem, false);
- tradePartner->sendTradeItemRequest(player, tradeItem, false);
- }
- }
- void Game::playerAcceptTrade(Player* player)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::playerAcceptTrade()");
- if(player->isRemoved)
- return;
- player->setAcceptTrade(true);
- Player *tradePartner = getPlayerByID(player->tradePartner);
- if(tradePartner && tradePartner->getAcceptTrade()) {
- Item *tradeItem1 = player->tradeItem;
- Item *tradeItem2 = tradePartner->tradeItem;
- player->sendCloseTrade();
- tradePartner->sendCloseTrade();
- #ifdef __KIRO_AKT__
- if(tradeItem1->getID() == ITEM_AKT)
- {
- Tile* tile = getTile(player->pos);
- House* house = tile? tile->getHouse() : NULL;
- Tile* tile2 = getTile(tradePartner->pos);
- Creature* creature = getCreatureByName(house->getOwner());
- Player* prevOwner = creature? dynamic_cast<Player*>(creature) : NULL;
- if(!house || !tile->isHouse())
- {
- player->sendCancel("You must stay in house!");
- return;
- }
- if(!tile->isHouse() && !tile2->isHouse() && player->tradeState != TRADE_INITIATED){
- player->sendCancel("You can only sell act if you are in house and you are the owner!");
- return;
- }
- if(house->getOwner() != player->getName())
- {
- player->sendCancel("You must stay in your house!");
- return;
- }
- if(house && house->checkHouseCount(tradePartner) >= g_config.getGlobalNumber("maxhouses", 0)){
- std::stringstream textmsg;
- textmsg << "You cannot have more than " << g_config.getGlobalNumber("maxhouses", 1) << " house.";
- tradePartner->sendTextMessage(MSG_ADVANCE, textmsg.str().c_str());
- return;
- }
- if (house && tradePartner->level < g_config.getGlobalNumber("buyhouselvlrook",1) && tradePartner->vocation == 0)
- {
- player->sendCancel("This player have too low level to buy house!");
- std::stringstream textmsg;
- textmsg << "You have too low level to buy house! You must have " << g_config.getGlobalNumber("buyhouselvlrook",2) << " level.";
- tradePartner->sendTextMessage(MSG_ADVANCE, textmsg.str().c_str());
- return;
- }
- if (house && tradePartner->level < g_config.getGlobalNumber("houselevel", 0) && tradePartner->vocation != 0)
- {
- player->sendCancel("This player have too low level to buy house!");
- std::stringstream textmsg;
- textmsg << "You have too low level to buy house! You must have " << g_config.getGlobalNumber("houselevel", 0) << " level.";
- tradePartner->sendTextMessage(MSG_ADVANCE, textmsg.str().c_str());
- return;
- }
- if(tradePartner->getFreeCapacity() < tradeItem1->getWeight())
- {
- return;
- }
- if(player->addItem(tradeItem2, true) && tradePartner->addItem(tradeItem1, true) &&
- player->removeItem(tradeItem1, true) && tradePartner->removeItem(tradeItem2, true)){
- player->removeItem(tradeItem1);
- tradePartner->removeItem(tradeItem2);
- player->onThingRemove(tradeItem1);
- tradePartner->onThingRemove(tradeItem2);
- player->addItem(tradeItem2);
- tradePartner->addItem(tradeItem1);
- }
- else{
- player->sendTextMessage(MSG_SMALLINFO, "Sorry, you don't have space.");
- tradePartner->sendTextMessage(MSG_SMALLINFO, "Sorry, you don't have space.");
- return;
- }
- player->removeItem(tradeItem1, true);
- tradePartner->addItem(tradeItem1, true);
- player->addItem(tradeItem2, true);
- house->setOwner(tradePartner->getName());
- teleport(player,tradePartner->pos);
- if (prevOwner)
- prevOwner->houseRightsChanged = true;
- tradePartner->houseRightsChanged = true;
- }
- else if(tradeItem2->getID() == ITEM_AKT)
- {
- Tile* tile = getTile(tradePartner->pos);
- House* house = tile? tile->getHouse() : NULL;
- Tile* tile2 = getTile(player->pos);
- Creature* creature = getCreatureByName(house->getOwner());
- Player* prevOwner = creature? dynamic_cast<Player*>(creature) : NULL;
- if(!house || !tile->isHouse())
- {
- tradePartner->sendCancel("You must stay in house!");
- return;
- }
- if(!tile->isHouse() && !tile2->isHouse() && player->tradeState != TRADE_INITIATED){
- player->sendCancel("You can only sell act if you are in house and you are the owner!");
- return;
- }
- if(house->getOwner() != tradePartner->getName())
- {
- tradePartner->sendCancel("You must stay in your house!");
- return;
- }
- if(house && house->checkHouseCount(player) >= g_config.getGlobalNumber("maxhouses", 0)){
- std::stringstream textmsg;
- textmsg << " You cannot have more than " << g_config.getGlobalNumber("maxhouses", 1) << " house.";
- tradePartner->sendTextMessage(MSG_ADVANCE, textmsg.str().c_str());
- return;
- }
- if (house && tradePartner->level < g_config.getGlobalNumber("buyhouselvlrook",1) && tradePartner->vocation == 0)
- {
- player->sendCancel("This player have too low level to buy house!");
- std::stringstream textmsg;
- textmsg << "You have too low level to buy house! You must have " << g_config.getGlobalNumber("buyhouselvlrook",2) << " level.";
- tradePartner->sendTextMessage(MSG_ADVANCE, textmsg.str().c_str());
- return;
- }
- if (house && tradePartner->level < g_config.getGlobalNumber("houselevel", 0) && tradePartner->vocation != 0)
- {
- player->sendCancel("This player have too low level to buy house!");
- std::stringstream textmsg;
- textmsg << "You have too low level to buy house! You must have " << g_config.getGlobalNumber("houselevel", 0) << " level.";
- tradePartner->sendTextMessage(MSG_ADVANCE, textmsg.str().c_str());
- return;
- }
- if(tradePartner->getFreeCapacity() < tradeItem1->getWeight())
- {
- return;
- }
- if(player->addItem(tradeItem2, true) && tradePartner->addItem(tradeItem1, true) &&
- player->removeItem(tradeItem1, true) && tradePartner->removeItem(tradeItem2, true)){
- player->removeItem(tradeItem1);
- tradePartner->removeItem(tradeItem2);
- player->onThingRemove(tradeItem1);
- tradePartner->onThingRemove(tradeItem2);
- player->addItem(tradeItem2);
- tradePartner->addItem(tradeItem1);
- }
- else{
- player->sendTextMessage(MSG_SMALLINFO, "Sorry, you don't have space.");
- tradePartner->sendTextMessage(MSG_SMALLINFO, "Sorry, you don't have space.");
- return;
- }
- tradePartner->removeItem(tradeItem1, true);
- player->addItem(tradeItem1, true);
- tradePartner->addItem(tradeItem2, true);
- house->setOwner(player->getName());
- teleport(tradePartner,player->pos);
- if (prevOwner)
- prevOwner->houseRightsChanged = true;
- player->houseRightsChanged = true;
- }
- #endif
- if(player->addItem(tradeItem2, true) && tradePartner->addItem(tradeItem1, true) &&
- player->removeItem(tradeItem1, true) && tradePartner->removeItem(tradeItem2, true)){
- player->removeItem(tradeItem1);
- tradePartner->removeItem(tradeItem2);
- player->onThingRemove(tradeItem1);
- tradePartner->onThingRemove(tradeItem2);
- player->addItem(tradeItem2);
- tradePartner->addItem(tradeItem1);
- }
- else{
- player->sendTextMessage(MSG_SMALLINFO, "Sorry not possible.");
- tradePartner->sendTextMessage(MSG_SMALLINFO, "Sorry not possible.");
- }
- std::map<Item*, uint32_t>::iterator it;
- it = tradeItems.find(tradeItem1);
- if(it != tradeItems.end()) {
- FreeThing(it->first);
- tradeItems.erase(it);
- }
- it = tradeItems.find(tradeItem2);
- if(it != tradeItems.end()) {
- FreeThing(it->first);
- tradeItems.erase(it);
- }
- player->setAcceptTrade(false);
- tradePartner->setAcceptTrade(false);
- }
- }
- void Game::playerLookInTrade(Player* player, bool lookAtCounterOffer, int32_t index)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::playerLookInTrade()");
- Player *tradePartner = getPlayerByID(player->tradePartner);
- if(!tradePartner)
- return;
- Item *tradeItem = NULL;
- if(lookAtCounterOffer)
- tradeItem = tradePartner->getTradeItem();
- else
- tradeItem = player->getTradeItem();
- if(!tradeItem)
- return;
- #ifdef __KIRO_AKT__
- if(tradeItem->getID() == ITEM_AKT)
- {
- Tile* tile = getTile(tradePartner->pos);
- House* house = tile? tile->getHouse() : NULL;
- if(house && house->getOwner() == tradePartner->getName())
- {
- stringstream ss;
- ss << "You see " << tradeItem->getDescription(true) << " applies to: " << house->getName() << ".";
- player->sendTextMessage(MSG_INFO, ss.str().c_str());
- return;
- }
- }
- #endif
- if(index == 0) {
- stringstream ss;
- ss << "You see " << tradeItem->getDescription(true);
- player->sendTextMessage(MSG_INFO, ss.str().c_str());
- return;
- }
- Container *tradeContainer = dynamic_cast<Container*>(tradeItem);
- if(!tradeContainer || index > tradeContainer->getItemHoldingCount())
- return;
- bool foundItem = false;
- std::list<const Container*> stack;
- stack.push_back(tradeContainer);
- ContainerList::const_iterator it;
- while(!foundItem && stack.size() > 0) {
- const Container *container = stack.front();
- stack.pop_front();
- for (it = container->getItems(); it != container->getEnd(); ++it) {
- Container *container = dynamic_cast<Container*>(*it);
- if(container) {
- stack.push_back(container);
- }
- --index;
- if(index == 0) {
- tradeItem = *it;
- foundItem = true;
- break;
- }
- }
- }
- if(foundItem) {
- stringstream ss;
- ss << "You see " << tradeItem->getDescription(true);
- player->sendTextMessage(MSG_INFO, ss.str().c_str());
- }
- }
- void Game::playerCloseTrade(Player* player)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::playerCloseTrade()");
- Player* tradePartner = getPlayerByID(player->tradePartner);
- std::vector<Item*>::iterator it;
- if(player->getTradeItem()) {
- std::map<Item*, uint32_t>::iterator it = tradeItems.find(player->getTradeItem());
- if(it != tradeItems.end()) {
- FreeThing(it->first);
- tradeItems.erase(it);
- }
- }
- player->setAcceptTrade(false);
- player->sendTextMessage(MSG_SMALLINFO, "Trade cancelled.");
- player->sendCloseTrade();
- if(tradePartner) {
- if(tradePartner->getTradeItem()) {
- std::map<Item*, uint32_t>::iterator it = tradeItems.find(tradePartner->getTradeItem());
- if(it != tradeItems.end()) {
- FreeThing(it->first);
- tradeItems.erase(it);
- }
- }
- tradePartner->setAcceptTrade(false);
- tradePartner->sendTextMessage(MSG_SMALLINFO, "Trade cancelled.");
- tradePartner->sendCloseTrade();
- }
- }
- void Game::autoCloseTrade(const Item* item, bool itemMoved /*= false*/)
- {
- if(!item)
- return;
- std::map<Item*, uint32_t>::const_iterator it;
- const Container* container = NULL;
- for(it = tradeItems.begin(); it != tradeItems.end(); it++) {
- if(item == it->first ||
- (itemMoved && (container = dynamic_cast<const Container*>(item)) && container->isHoldingItem(it->first)) ||
- ((container = dynamic_cast<const Container*>(it->first)) && container->isHoldingItem(item)))
- {
- Player* player = getPlayerByID(it->second);
- if(player){
- playerCloseTrade(player);
- }
- break;
- }
- }
- }
- void Game::autoCloseAttack(Player* player, Creature* target)
- {
- if((std::abs(player->pos.x - target->pos.x) > 7) ||
- (std::abs(player->pos.y - target->pos.y) > 5) || (player->pos.z != target->pos.z)){
- player->sendTextMessage(MSG_SMALLINFO, "Target lost.");
- playerSetAttackedCreature(player, 0);
- }
- }
- void Game::playerSetAttackedCreature(Player* player, uint32_t creatureid)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::playerSetAttackedCreature()");
- if(player->isRemoved)
- return;
- if(player->attackedCreature != 0 && creatureid == 0) {
- player->sendCancelAttacking();
- }
- Creature* attackedCreature = NULL;
- if(creatureid != 0) {
- attackedCreature = getCreatureByID(creatureid);
- }
- Player* attackedPlayer = dynamic_cast<Player*>(attackedCreature);
- bool pvpArena = false, rook = false, attackedIsSummon = false;
- #ifdef YUR_PVP_ARENA
- if (player && attackedCreature)
- {
- Tile *t1 = map->getTile(player->pos), *t2 = map->getTile(attackedCreature->pos);
- pvpArena = t1 && t2 && t1->isPvpArena() && t2->isPvpArena();
- }
- #endif //YUR_PVP_ARENA
- #ifdef YUR_ROOKGARD
- rook = player && player->isRookie() && attackedPlayer && attackedPlayer->isRookie();
- #endif //YUR_ROOKGARD
- #ifdef TR_SUMMONS
- attackedIsSummon = (attackedCreature && attackedCreature->isPlayersSummon() && attackedCreature->getMaster() != player);
- #endif //TR_SUMMONS
- if(!attackedCreature || (attackedCreature->access >= g_config.ACCESS_PROTECT || ((getWorldType() == WORLD_TYPE_NO_PVP || rook) &&
- !pvpArena && player->access < g_config.ACCESS_PROTECT && (dynamic_cast<Player*>(attackedCreature) || attackedIsSummon)))) {
- if(attackedCreature) {
- player->sendTextMessage(MSG_SMALLINFO, "You may not attack this player.");
- }
- player->sendCancelAttacking();
- player->setAttackedCreature(NULL);
- stopEvent(player->eventCheckAttacking);
- player->eventCheckAttacking = 0;
- }
- else if(attackedCreature) {
- player->setAttackedCreature(attackedCreature);
- stopEvent(player->eventCheckAttacking);
- if(player->followCreature != 0)
- player->eventCheckAttacking = addEvent(makeTask(200, std::bind2nd(std::mem_fun(&Game::checkCreatureAttacking), player->getID())));
- else
- player->eventCheckAttacking = addEvent(makeTask(g_config.getGlobalNumber("firstattack", 2000), std::bind2nd(std::mem_fun(&Game::checkCreatureAttacking), player->getID())));
- }
- }
- void Game::flushSendBuffers()
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::flushSendBuffers()");
- for(std::vector<Player*>::iterator it = BufferedPlayers.begin(); it != BufferedPlayers.end(); ++it) {
- (*it)->flushMsg();
- (*it)->SendBuffer = false;
- (*it)->releaseThing();
- /*
- #ifdef __DEBUG__
- std::cout << "flushSendBuffers() - releaseThing()" << std::endl;
- #endif
- */
- }
- BufferedPlayers.clear();
- //free memory
- for(std::vector<Thing*>::iterator it = ToReleaseThings.begin(); it != ToReleaseThings.end(); ++it){
- (*it)->releaseThing();
- }
- ToReleaseThings.clear();
- return;
- }
- void Game::addPlayerBuffer(Player* p)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::addPlayerBuffer()");
- /*
- #ifdef __DEBUG__
- std::cout << "addPlayerBuffer() - useThing()" << std::endl;
- #endif
- */
- if(p->SendBuffer == false){
- p->useThing();
- BufferedPlayers.push_back(p);
- p->SendBuffer = true;
- }
- return;
- }
- void Game::FreeThing(Thing* thing){
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::FreeThing()");
- //std::cout << "freeThing() " << thing <<std::endl;
- ToReleaseThings.push_back(thing);
- return;
- }
- /*
- ADD
- container(player,pos-cid,thing)
- inventory(player,pos-i,[ignored])
- ground([ignored],postion,thing)
- REMOVE
- container(player,pos-cid,thing,autoclose?)
- inventory(player,pos-i,thing,autoclose?)
- ground([ignored],postion,thing,autoclose?,stackpos)
- UPDATE
- container(player,pos-cid,thing)
- inventory(player,pos-i,[ignored])
- ground([ignored],postion,thing,stackpos)
- */
- void Game::sendAddThing(Player* player,const Position &pos,const Thing* thing){
- if(pos.x == 0xFFFF) {
- if(!player)
- return;
- if(pos.y & 0x40) { //container
- if(!thing)
- return;
- const Item *item = dynamic_cast<const Item*>(thing);
- if(!item)
- return;
- unsigned char containerid = pos.y & 0x0F;
- Container* container = player->getContainer(containerid);
- if(!container)
- return;
- SpectatorVec list;
- SpectatorVec::iterator it;
- Position centerpos = (container->pos.x == 0xFFFF ? player->pos : container->pos);
- getSpectators(Range(centerpos,2,2,2,2,false), list);
- if(!list.empty()) {
- for(it = list.begin(); it != list.end(); ++it) {
- Player *spectator = dynamic_cast<Player*>(*it);
- if(spectator)
- spectator->onItemAddContainer(container,item);
- }
- }
- else
- player->onItemAddContainer(container,item);
- }
- else //inventory
- {
- player->sendInventory(pos.y);
- }
- }
- else //ground
- {
- if(!thing)
- return;
- #ifdef SM_SUMMON_ATTACK
- Monster* monster = dynamic_cast<Monster*>(const_cast<Thing*>(thing));
- #endif //SM_SUMMON_ATTACK
- SpectatorVec list;
- SpectatorVec::iterator it;
- getSpectators(Range(pos,true), list);
- //players
- for(it = list.begin(); it != list.end(); ++it) {
- if(dynamic_cast<Player*>(*it)) {
- (*it)->onThingAppear(thing);
- #ifdef SM_SUMMON_ATTACK
- if (monster && !monster->isSummon())
- monster->onThingAppear(*it);
- #endif //SM_SUMMON_ATTACK
- }
- }
- //none-players
- for(it = list.begin(); it != list.end(); ++it) {
- if(!dynamic_cast<Player*>(*it)) {
- (*it)->onThingAppear(thing);
- }
- }
- }
- }
- void Game::sendRemoveThing(Player* player,const Position &pos,const Thing* thing,const unsigned char stackpos /*=1*/ ,const bool autoclose/* =false*/){
- if(!thing)
- return;
- const Item *item = dynamic_cast<const Item*>(thing);
- bool perform_autoclose = false;
- if(autoclose && item){
- const Container *container = dynamic_cast<const Container*>(item);
- if(container)
- perform_autoclose = true;
- }
- if(pos.x == 0xFFFF) {
- if(!player)
- return;
- if(pos.y & 0x40) { //container
- if(!item)
- return;
- unsigned char containerid = pos.y & 0x0F;
- Container* container = player->getContainer(containerid);
- if(!container)
- return;
- //check that item is in the container
- unsigned char slot = container->getSlotNumberByItem(item);
- SpectatorVec list;
- SpectatorVec::iterator it;
- Position centerpos = (container->pos.x == 0xFFFF ? player->pos : container->pos);
- getSpectators(Range(centerpos,2,2,2,2,false), list);
- if(!list.empty()) {
- for(it = list.begin(); it != list.end(); ++it) {
- Player *spectator = dynamic_cast<Player*>(*it);
- if(spectator){
- spectator->onItemRemoveContainer(container,slot);
- if(perform_autoclose){
- spectator->onThingRemove(thing);
- }
- }
- }
- }
- else{
- player->onItemRemoveContainer(container,slot);
- if(perform_autoclose){
- player->onThingRemove(thing);
- }
- }
- }
- else //inventory
- {
- player->removeItemInventory(pos.y);
- if(perform_autoclose){
- player->onThingRemove(thing);
- }
- }
- }
- else //ground
- {
- SpectatorVec list;
- SpectatorVec::iterator it;
- getSpectators(Range(pos,true), list);
- //players
- for(it = list.begin(); it != list.end(); ++it) {
- Player *spectator = dynamic_cast<Player*>(*it);
- if(spectator) {
- spectator->onThingDisappear(thing,stackpos);
- if(perform_autoclose){
- spectator->onThingRemove(thing);
- }
- }
- }
- //none-players
- for(it = list.begin(); it != list.end(); ++it) {
- if(!dynamic_cast<Player*>(*it)) {
- (*it)->onThingDisappear(thing,stackpos);
- }
- }
- }
- }
- void Game::sendUpdateThing(Player* player,const Position &pos,const Thing* thing,const unsigned char stackpos/*=1*/){
- if(pos.x == 0xFFFF) {
- if(!player)
- return;
- if(pos.y & 0x40) { //container
- if(!thing)
- return;
- const Item *item = dynamic_cast<const Item*>(thing);
- if(!item)
- return;
- unsigned char containerid = pos.y & 0x0F;
- Container* container = player->getContainer(containerid);
- if(!container)
- return;
- //check that item is in the container
- unsigned char slot = container->getSlotNumberByItem(item);
- SpectatorVec list;
- SpectatorVec::iterator it;
- Position centerpos = (container->pos.x == 0xFFFF ? player->pos : container->pos);
- getSpectators(Range(centerpos,2,2,2,2,false), list);
- if(!list.empty()) {
- for(it = list.begin(); it != list.end(); ++it) {
- Player *spectator = dynamic_cast<Player*>(*it);
- if(spectator)
- spectator->onItemUpdateContainer(container,item,slot);
- }
- }
- else{
- //never should be here
- std::cout << "Error: sendUpdateThing" << std::endl;
- //player->onItemUpdateContainer(container,item,slot);
- }
- }
- else //inventory
- {
- player->sendInventory(pos.y);
- }
- }
- else //ground
- {
- if(!thing)
- return;
- SpectatorVec list;
- SpectatorVec::iterator it;
- getSpectators(Range(pos,true), list);
- //players
- for(it = list.begin(); it != list.end(); ++it) {
- if(dynamic_cast<Player*>(*it)) {
- (*it)->onThingTransform(thing,stackpos);
- }
- }
- //none-players
- for(it = list.begin(); it != list.end(); ++it) {
- if(!dynamic_cast<Player*>(*it)) {
- (*it)->onThingTransform(thing,stackpos);
- }
- }
- }
- }
- void Game::addThing(Player* player,const Position &pos,Thing* thing)
- {
- if(!thing)
- return;
- Item *item = dynamic_cast<Item*>(thing);
- if(pos.x == 0xFFFF) {
- if(!player || !item)
- return;
- if(pos.y & 0x40) { //container
- unsigned char containerid = pos.y & 0x0F;
- Container* container = player->getContainer(containerid);
- if(!container)
- return;
- container->addItem(item);
- sendAddThing(player,pos,thing);
- }
- else //inventory
- {
- player->addItemInventory(item,pos.y,true);
- sendAddThing(player,pos,thing);
- }
- }
- else //ground
- {
- if(!thing)
- return;
- //Tile *tile = map->getTile(pos.x, pos.y, pos.z);
- Tile *tile = map->getTile(pos);
- if(tile){
- thing->pos = pos;
- if(item && item->isSplash()){
- if(tile->splash){
- int32_t oldstackpos = tile->getThingStackPos(tile->splash);
- Item *oldsplash = tile->splash;
- oldsplash->isRemoved = true;
- FreeThing(oldsplash);
- tile->splash = item;
- sendUpdateThing(NULL, pos, item, oldstackpos);
- }
- else{
- tile->splash = item;
- sendAddThing(NULL,pos,tile->splash);
- }
- }
- else if(item && item->isGroundTile()){
- tile->ground = item;
- SpectatorVec list;
- SpectatorVec::iterator it;
- getSpectators(Range(thing->pos, true), list);
- //players
- for(it = list.begin(); it != list.end(); ++it) {
- if(dynamic_cast<Player*>(*it)) {
- (*it)->onTileUpdated(pos);
- }
- }
- //none-players
- for(it = list.begin(); it != list.end(); ++it) {
- if(!dynamic_cast<Player*>(*it)) {
- (*it)->onTileUpdated(pos);
- }
- }
- //Game::creatureBroadcastTileUpdated(thing->pos);
- }
- else if(item && item->isStackable()){
- Item *topitem = tile->getTopDownItem();
- if(topitem && topitem->getID() == item->getID() &&
- topitem->getItemCountOrSubtype() + item->getItemCountOrSubtype() <= 100){
- topitem->setItemCountOrSubtype(topitem->getItemCountOrSubtype() + item->getItemCountOrSubtype());
- int32_t stackpos = tile->getThingStackPos(topitem);
- sendUpdateThing(NULL,topitem->pos,topitem,stackpos);
- item->pos.x = 0xFFFF;
- FreeThing(item);
- }
- else{
- tile->addThing(thing);
- sendAddThing(player,pos,thing);
- }
- }
- else{
- tile->addThing(thing);
- sendAddThing(player,pos,thing);
- }
- }
- }
- }
- bool Game::removeThing(Player* player,const Position &pos,Thing* thing, bool setRemoved /*= true*/)
- {
- if(!thing)
- return false;
- Item *item = dynamic_cast<Item*>(thing);
- if(pos.x == 0xFFFF) {
- if(!player || !item)
- return false;
- if(pos.y & 0x40) { //container
- unsigned char containerid = pos.y & 0x0F;
- Container* container = player->getContainer(containerid);
- if(!container)
- return false;
- sendRemoveThing(player,pos,thing,0,true);
- if(!container->removeItem(item))
- return false;
- if(player && player->isHoldingContainer(container)) {
- player->updateInventoryWeigth();
- player->sendStats();
- }
- }
- else //inventory
- {
- //sendRemoveThing(player,pos,thing,0,true);
- if(!player->removeItemInventory(pos.y))
- return false;
- player->onThingRemove(thing);
- //player->removeItemInventory(pos.y,true);
- }
- if(setRemoved)
- item->isRemoved = true;
- return true;
- }
- else //ground
- {
- //Tile *tile = map->getTile(pos.x, pos.y, pos.z);
- Tile *tile = map->getTile(pos);
- if(tile){
- unsigned char stackpos = tile->getThingStackPos(thing);
- if(!tile->removeThing(thing))
- return false;
- sendRemoveThing(NULL,pos,thing,stackpos,true);
- }
- else{
- return false;
- }
- if(item && setRemoved){
- item->isRemoved = true;
- }
- return true;
- }
- }
- Position Game::getThingMapPos(Player *player, const Position &pos)
- {
- if(pos.x == 0xFFFF){
- Position dummyPos(0,0,0);
- if(!player)
- return dummyPos;
- if(pos.y & 0x40) { //from container
- unsigned char containerid = pos.y & 0x0F;
- const Container* container = player->getContainer(containerid);
- if(!container){
- return dummyPos;
- }
- while(container->getParent() != NULL) {
- container = container->getParent();
- }
- if(container->pos.x == 0xFFFF)
- return player->pos;
- else
- return container->pos;
- }
- else //from inventory
- {
- return player->pos;
- }
- }
- else{
- return pos;
- }
- }
- Thing* Game::getThing(const Position &pos,unsigned char stack, Player* player /*=NULL*/)
- {
- if(pos.x == 0xFFFF) {
- if(!player)
- return NULL;
- if(pos.y & 0x40) { //from container
- unsigned char containerid = pos.y & 0x0F;
- Container* container = player->getContainer(containerid);
- if(!container)
- return NULL;
- return container->getItem(pos.z);
- }
- else //from inventory
- {
- return player->getItem(pos.y);
- }
- }
- else //from ground
- {
- //Tile *t = getTile(pos.x, pos.y, pos.z);
- Tile *t = map->getTile(pos);
- if(!t)
- return NULL;
- return t->getThingByStackPos(stack);
- }
- }
- int32_t Game::getDepot(Container* c, int32_t e)
- {
- for(int32_t a = 0; a < c->size(); a++)
- {
- Container* x = dynamic_cast<Container*>(dynamic_cast<Item*>(c->getItem(a)));
- Item* i = dynamic_cast<Item*>(c->getItem(a));
- if(i)
- e++;
- if(x)
- e = getDepot(x, e);
- }
- return e;
- }
- #ifdef WOLV_LOAD_NPC
- bool Game::loadNpcs()
- {
- xmlDocPtr doc;
- doc = xmlParseFile((g_config.DATA_DIR + "world/npc.xml").c_str());
- if (!doc)
- return false;
- xmlNodePtr root, npcNode;
- root = xmlDocGetRootElement(doc);
- if (xmlStrcmp(root->name, (const xmlChar*)"npclist"))
- {
- xmlFreeDoc(doc);
- return false;
- }
- npcNode = root->children;
- while (npcNode)
- {
- if (strcmp((const char*) npcNode->name, "npc") == 0)
- {
- std::string name = (const char*)xmlGetProp(npcNode, (const xmlChar *) "name");
- int32_t x = atoi((const char*) xmlGetProp(npcNode, (const xmlChar*) "x"));
- int32_t y = atoi((const char*) xmlGetProp(npcNode, (const xmlChar*) "y"));
- int32_t z = atoi((const char*) xmlGetProp(npcNode, (const xmlChar*) "z"));
- Npc* mynpc = new Npc(name, this);
- mynpc->pos = Position(x, y, z);
- if (!placeCreature(mynpc->pos, mynpc))
- {
- std::cout << "Could not place " << name << "!" << std::endl;
- xmlFreeDoc(doc);
- return false;
- }
- const char* tmp = (const char*)xmlGetProp(npcNode, (const xmlChar*) "dir");
- if (tmp)
- mynpc->setDirection((Direction)atoi(tmp));
- }
- npcNode = npcNode->next;
- }
- xmlFreeDoc(doc);
- return true;
- }
- #endif //WOLV_LOAD_NPC
- #ifdef TLM_SERVER_SAVE
- void Game::serverSave()
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::serverSave()");
- std::cout << ":: zapis serwera :: " << std::endl;
- timer();
- AutoList<Player>::listiterator it = Player::listPlayer.list.begin();
- while (it != Player::listPlayer.list.end())
- {
- IOPlayer::instance()->savePlayer(it->second);
- ++it;
- }
- std::cout << ":: Gracze [" << timer() << " s]" << std::endl;
- Guilds::Save();
- std::cout << "Gildie [" << timer() << " s]" << std::endl;
- Houses::Save(this);
- std::cout << ":: Domki [" << timer() << " s]" << std::endl;
- loginQueue.save();
- std::cout << ":: Kolejki [" << timer() << " s]" << std::endl;
- for(AutoList<Player>::listiterator it = Player::listPlayer.list.begin(); it != Player::listPlayer.list.end(); ++it);
- }
- void Game::autoServerSave()
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::autoServerSave()");
- serverSave();
- addEvent(makeTask(g_config.getGlobalNumber("autosave", 1)*60000, std::mem_fun(&Game::autoServerSave)));
- }
- #endif //TLM_SERVER_SAVE
- #ifdef ELEM_VIP_LIST
- /*void Game::vipLogin(Player* player)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::vipLogin()");
- std::string vipname = player->getName();
- #ifdef _NG_BBK_VIP_SYSTEM__
- std::transform(vipname.begin(), vipname.end(), vipname.begin(), (int32_t(*)(int32_t)) std::tolower);
- #endif //_NG_BBK_VIP_SYSTEM__
- for(AutoList<Creature>::listiterator cit = listCreature.list.begin(); cit != listCreature.list.end(); ++cit)
- {
- Player* player = dynamic_cast<Player*>((*cit).second);
- if (player)
- player->sendVipLogin(vipname);
- }
- }
- void Game::vipLogout(std::string vipname)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::vipLogout()");
- #ifdef _NG_BBK_VIP_SYSTEM__
- std::transform(vipname.begin(), vipname.end(), vipname.begin(), (int32_t(*)(int32_t)) std::tolower);
- #endif //_NG_BBK_VIP_SYSTEM__
- for(AutoList<Creature>::listiterator cit = listCreature.list.begin(); cit != listCreature.list.end(); ++cit)
- {
- Player* player = dynamic_cast<Player*>((*cit).second);
- if (player)
- player->sendVipLogout(vipname);
- }
- }*/
- bool Game::isPlayer(std::string name)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::isPlayer()");
- extern xmlMutexPtr xmlmutex;
- std::string datadir = g_config.getGlobalString("datadir");
- std::string filenamecheck = datadir + "players/" + name + ".xml";
- std::transform(filenamecheck.begin(),filenamecheck.end(), filenamecheck.begin(), (int32_t(*)(int32_t))tolower);
- xmlDocPtr doc;
- xmlMutexLock(xmlmutex);
- doc = xmlParseFile(filenamecheck.c_str());
- if (doc)
- {
- xmlMutexUnlock(xmlmutex);
- xmlFreeDoc(doc);
- return true;
- }
- else
- {
- xmlMutexUnlock(xmlmutex);
- xmlFreeDoc(doc);
- return false;
- }
- }
- #endif //ELEM_VIP_LIST
- void Game::checkSpell(Player* player, SpeakClasses type, std::string text)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::checkSpell()");
- if (player->isRookie())
- return;
- #ifdef TLM_HOUSE_SYSTEM
- else if (text == "aleta gom") // edit owner
- {
- Tile* tile = getTile(player->pos);
- House* house = tile? tile->getHouse() : NULL;
- if (house && house->getPlayerRights(player->getName()) == HOUSE_OWNER)
- {
- player->sendHouseWindow(house, player->pos, HOUSE_OWNER);
- }
- else
- {
- player->sendMagicEffect(player->pos, NM_ME_PUFF);
- player->sendTextMessage(MSG_SMALLINFO, "Sorry, not possible.");
- }
- }
- else if (text == "aleta grav") // edit door owners
- {
- bool last = false;
- for (int32_t x = player->pos.x-1; x <= player->pos.x+1 && !last; x++)
- {
- for(int32_t y = player->pos.y-1; y <= player->pos.y+1 && !last; y++)
- {
- Position doorPos(x, y, player->pos.z);
- Tile* tile = getTile(doorPos);
- House* house = tile? tile->getHouse() : NULL;
- if (house && house->getPlayerRights(doorPos, player->getName()) == HOUSE_OWNER)
- {
- Item *item = dynamic_cast<Item*>(tile->getThingByStackPos(tile->getThingCount()-1));
- if (item && Item::items[item->getID()].isDoor)
- {
- player->sendHouseWindow(house, doorPos, HOUSE_DOOROWNER);
- last = true;
- }
- }
- }
- }
- }
- else if (text == "!buyhouse" || text == "!buyhome")
- {
- uint32_t money = player->getMoney();
- bool last = false;
- #ifdef HUCZU_EXHAUSTED
- if(player->houseTicks > 0){
- player->sendCancel("You're exhausted.");
- return;
- }
- else
- player->houseTicks += 5;
- #endif //HUCZU_EXHAUSTED
- int32_t houselevel = g_config.getGlobalNumber("houselevel", 0);
- if(!player->premmium){
- player->sendCancel("You must have a premium to buy house!");
- return;
- }
- if( player->getLevel() < houselevel ){
- std::stringstream textmsg2;
- textmsg2 << " You need level " << houselevel << "+ to buy a house! ";
- player->sendTextMessage(MSG_ADVANCE, textmsg2.str().c_str());
- }
- else{
- for (int32_t x = player->pos.x-1; x <= player->pos.x+1 && !last; x++)
- {
- for(int32_t y = player->pos.y-1; y <= player->pos.y+1 && !last; y++)
- {
- Position doorPos(x, y, player->pos.z);
- Tile* tile = getTile(doorPos);
- House* house = tile? tile->getHouse() : NULL;
- if(house){
- if(house->getPlayerRights(player->getName()) == HOUSE_OWNER){
- player->sendTextMessage(MSG_ADVANCE, "You own this house.");
- return;
- }
- if(house->isBought()){
- player->sendTextMessage(MSG_ADVANCE, "This house already has an owner.");
- return;
- }
- if(house->checkHouseCount(player) >= g_config.getGlobalNumber("maxhouses", 0)){
- std::stringstream textmsg;
- textmsg << " You cant have more than " << g_config.getGlobalNumber("maxhouses", 1) << " houses ";
- player->sendTextMessage(MSG_ADVANCE, textmsg.str().c_str());
- return;
- }
- if(house->getPlayerRights(doorPos, player->getName()) == HOUSE_NONE && !house->isBought() && house->checkHouseCount(player) < g_config.getGlobalNumber("maxhouses", 1))
- {
- Item *item = dynamic_cast<Item*>(tile->getThingByStackPos(tile->getThingCount()-1));
- long price = g_config.getGlobalNumber("priceforsqm", 0) * house->getHouseSQM(house->getName());
- if (item && Item::items[item->getID()].isDoor && price <= money)
- {
- player->substractMoney(price);
- house->setOwner(player->getName());
- house->save();
- player->sendTextMessage(MSG_ADVANCE, "You bought a house.");
- last = true;
- }
- else{
- player->sendMagicEffect(player->pos, NM_ME_PUFF);
- player->sendTextMessage(MSG_SMALLINFO, "You dont have enough money to buy this house.");
- }
- }
- }
- }
- }
- }
- }
- else if (text == "aleta sio") // edit guests
- {
- Tile* tile = getTile(player->pos);
- House* house = tile? tile->getHouse() : NULL;
- if (house && house->getPlayerRights(player->getName()) >= HOUSE_SUBOWNER)
- {
- player->sendHouseWindow(house, player->pos, HOUSE_GUEST);
- }
- else
- {
- player->sendMagicEffect(player->pos, NM_ME_PUFF);
- player->sendTextMessage(MSG_SMALLINFO, "Sorry, not possible.");
- }
- }
- else if (text == "aleta som") // edit subowners
- {
- Tile* tile = getTile(player->pos);
- House* house = tile? tile->getHouse() : NULL;
- if (house && house->getPlayerRights(player->getName()) == HOUSE_OWNER)
- {
- player->sendHouseWindow(house, player->pos, HOUSE_SUBOWNER);
- }
- else
- {
- player->sendMagicEffect(player->pos, NM_ME_PUFF);
- player->sendTextMessage(MSG_SMALLINFO, "Sorry, not possible.");
- }
- }
- else if (text == "alana sio") // kick me
- {
- Tile* tile = getTile(player->pos);
- House* house = tile? tile->getHouse() : NULL;
- if (house)
- {
- teleport(player, house->getFrontDoor());
- player->sendMagicEffect(player->pos, NM_ME_ENERGY_AREA);
- }
- else
- {
- player->sendMagicEffect(player->pos, NM_ME_PUFF);
- player->sendTextMessage(MSG_SMALLINFO, "You are not in a house.");
- }
- }
- else if (text.substr(0, 11) == "alana sio \"") // kick someone
- {
- Creature* c = getCreatureByName(text.substr(11).c_str());
- Player *target = c? dynamic_cast<Player*>(c) : NULL;
- if (target)
- {
- Tile* tile = getTile(player->pos);
- Tile* targetTile = getTile(target->pos);
- House* house = tile? tile->getHouse() : NULL;
- House* targetHouse = targetTile? targetTile->getHouse() : NULL;
- if (house && targetHouse && house == targetHouse &&
- house->getPlayerRights(player->getName()) >= HOUSE_SUBOWNER)
- {
- Position pos = house->getFrontDoor();
- if (pos.x != 0xFFFF && pos.y != 0xFFFF && pos.z != 0xFF)
- {
- teleport(target, pos);
- player->sendMagicEffect(target->pos, NM_ME_ENERGY_AREA);
- }
- else
- {
- player->sendMagicEffect(player->pos, NM_ME_PUFF);
- player->sendTextMessage(MSG_SMALLINFO, "Sorry, not possible.");
- }
- }
- else
- player->sendTextMessage(MSG_SMALLINFO, "Sorry, not possible.");
- }
- else
- {
- player->sendMagicEffect(player->pos, NM_ME_PUFF);
- player->sendTextMessage(MSG_SMALLINFO, "This player does not exist.");
- }
- }
- #endif //TLM_HOUSE_SYSTEM
- #ifdef TR_SUMMONS
- else if (text.substr(0, 11) == "utevo res \"" &&
- (!g_config.LEARN_SPELLS || player->knowsSpell("utevo res")))
- {
- if (player->vocation == VOCATION_DRUID || player->vocation == VOCATION_SORCERER ||
- (g_config.SUMMONS_ALL_VOC && player->vocation != VOCATION_NONE))
- {
- std::string name = text.substr(11);
- int32_t reqMana = Summons::getRequiredMana(name);
- Tile* tile = getTile(player->pos);
- if (!tile)
- {
- player->sendMagicEffect(player->pos, NM_ME_PUFF);
- player->sendCancel("Sorry, not possible.");
- }
- else if (reqMana < 0)
- {
- player->sendMagicEffect(player->pos, NM_ME_PUFF);
- player->sendCancel("You cannot summon this creature.");
- }
- else if (tile->isPz())
- {
- player->sendMagicEffect(player->pos, NM_ME_PUFF);
- player->sendCancel("You cannot summon creatures in protection zone.");
- }
- #ifdef YUR_PVP_ARENA
- else if (tile->isPvpArena())
- {
- player->sendMagicEffect(player->pos, NM_ME_PUFF);
- player->sendCancel("You cannot summon creatures on arena.");
- }
- #endif //YUR_PVP_ARENA
- else if (player->getSummonCount() >= g_config.MAX_SUMMONS)
- {
- player->sendMagicEffect(player->pos, NM_ME_PUFF);
- player->sendCancel("You cannot have more summons.");
- }
- else if (player->getMana() < reqMana)
- {
- player->sendMagicEffect(player->pos, NM_ME_PUFF);
- player->sendCancel("Not enough mana.");
- }
- else if (!placeSummon(player, name))
- {
- player->sendMagicEffect(player->pos, NM_ME_PUFF);
- player->sendCancel("Not enough room");
- }
- else
- {
- player->mana -= reqMana;
- player->addManaSpent(reqMana);
- }
- }
- }
- #endif //TR_SUMMONS
- /*
- #ifdef HUCZU_FIX
- else if (text == "exevo flam sio" &&
- (!g_config.LEARN_SPELLS || player->knowsSpell("exevo flam sio")))
- {
- const int32_t REQ_MANA = 200;
- if (player->mana < REQ_MANA)
- {
- player->sendMagicEffect(player->pos, NM_ME_PUFF);
- player->sendTextMessage(MSG_SMALLINFO, "Not enough mana.");
- }
- else if (player->maglevel < 15)
- {
- player->sendMagicEffect(player->pos, NM_ME_PUFF);
- player->sendTextMessage(MSG_SMALLINFO, "You don't have the required magic level.");
- }
- else if (player->exhaustedTicks >= 1000 && player->access < g_config.ACCESS_PROTECT)
- {
- player->sendMagicEffect(player->pos, NM_ME_PUFF);
- player->sendTextMessage(MSG_SMALLINFO, "You are exhausted.");
- }
- else if (player->flamTicks != 0 && player->access < g_config.ACCESS_PROTECT)
- {
- player->sendMagicEffect(player->pos, NM_ME_PUFF);
- player->sendTextMessage(MSG_SMALLINFO, "Not ready yet.");
- }
- else
- {
- player->flamBool = true;
- player->exhaustedTicks = 2*1000;
- player->sendMagicEffect(player->pos, NM_ME_MAGIC_BLOOD);
- }
- }
- #endif //HUCZU_FIX
- */
- else if (text.substr(0,7) == "exiva \"" &&
- (!g_config.LEARN_SPELLS || player->knowsSpell("exiva")))
- {
- std::string name = text.substr(7);
- Creature *c = getCreatureByName(name);
- if (dynamic_cast<Player*>(c))
- {
- if(player->mana >= 20)
- {
- player->mana -= 20;
- player->addManaSpent(20);
- }
- else if (player->exhaustedTicks >= 1000 && player->access < g_config.ACCESS_PROTECT)
- {
- player->sendMagicEffect(player->pos, NM_ME_PUFF);
- player->sendTextMessage(MSG_SMALLINFO, "You are exhausted.");
- }
- else
- {
- player->sendMagicEffect(player->pos, NM_ME_PUFF);
- player->sendTextMessage(MSG_SMALLINFO, "Not enough mana.");
- return;
- }
- int32_t x = c->pos.x - player->pos.x;
- int32_t y = c->pos.y - player->pos.y;
- int32_t z = c->pos.z - player->pos.z;
- std::stringstream position;
- position << name;
- if(c->access < 3) {
- if((x > 96 && y > 48) || (x > 48 && y > 94) || (x > 74 && y > 74))
- position << " is very far to the south-east.";
- else if((x > 96 && y < -48) || (x > 48 && y < -96) || (x > 74 && y < -74))
- position << " is very far to the north-east.";
- else if((x < -96 && y > 48) || (x < -48 && y > 96) || (x < -74 && y > 74))
- position << " is very far to the south-west.";
- else if((x < -96 && y < -48) || (x < -48 && y < -96) || (x < -74 && y < -74))
- position << " is very far to the north-west.";
- else if((x > 48 && y > 24) || (x > 24 && y > 48) || (x > 36 && y > 36))
- position << " is far to the south-east.";
- else if((x > 48 && y < -24) || (x > 24 && y < -48) || (x > 36 && y < -36))
- position << " is far to the north-east.";
- else if((x < -48 && y > 24) || (x < -24 && y > 48) || (x < -36 && y > 36))
- position << " is far to the south-west.";
- else if((x < -48 && y < -24) || (x < -24 && y < -48) || (x < -36 && y < -36))
- position << " is far to the north-west.";
- else if((x > 6 && y > 12 && z > 0) || (x > 12 && y > 6 && z > 0) || (x > 9 && y > 9 && z > 0))
- position << " is on a lower lvl to the south-east.";
- else if((x > 6 && y < -12 && z > 0) || (x > 12 && y < -6 && z > 0) || (x > 9 && y < -9 && z > 0))
- position << " is on a lower lvl to the north-east.";
- else if((x < -6 && y > 12 && z > 0) || (x < -12 && y > 6 && z > 0) || (x < -9 && y > 9 && z > 0))
- position << " is on a lower lvl to the south-west.";
- else if((x < -6 && y < -12 && z > 0) || (x < -12 && y < -6 && z > 0) || (x < -9 && y < -9 && z > 0))
- position << " is on a lower lvl to the north-west.";
- else if((x > 6 && y > 12 && z < 0) || (x > 12 && y > 6 && z < 0) || (x > 9 && y > 9 && z < 0))
- position << " is on a higher lvl to the south-east.";
- else if((x > 6 && y < -12 && z < 0) || (x > 12 && y < -6 && z < 0) || (x > 9 && y < -9 && z < 0))
- position << " is on a higher lvl to the north-east.";
- else if((x < -6 && y > 12 && z < 0) || (x < -12 && y > 6 && z < 0) || (x < -9 && y > 9 && z < 0))
- position << " is on a higher lvl to the south-west.";
- else if((x < -6 && y < -12 && z < 0) || (x < -12 && y < -6 && z < 0) || (x < -9 && y < -9 && z < 0))
- position << " is on a higher lvl to the north-west.";
- else if((x > 6 && y > 12 && z == 0) || (x > 12 && y > 6 && z == 0) || (x > 9 && y > 9 && z == 0))
- position << " is to the south-east.";
- else if((x > 6 && y < -12 && z == 0) || (x > 12 && y < -6 && z == 0) || (x > 9 && y < -9 && z == 0))
- position << " is to the north-east.";
- else if((x < -6 && y > 12 && z == 0) || (x < -12 && y > 6 && z == 0) || (x < -9 && y > 9 && z == 0))
- position << " is to the south-west.";
- else if((x < -6 && y < -12 && z == 0) || (x < -12 && y < -6 && z == 0) || (x < -9 && y < -9 && z == 0))
- position << " is to the north-west.";
- else if(x > 74)
- position << " is very far to the east.";
- else if(x < -74)
- position << " is very far to the west.";
- else if(y > 74)
- position << " is very far to the south.";
- else if(y < -74)
- position << " is very far to the north.";
- else if(x > 36)
- position << " is far to the east.";
- else if(x < -36)
- position << " is far to the west.";
- else if(y > 36)
- position << " is far to the south.";
- else if(y < -36)
- position << " is far to the north.";
- else if(x > 3 && z < 0)
- position << " is on a higher lvl to the east.";
- else if(x < -3 && z < 0)
- position << " is on a higher lvl to the west.";
- else if(y > 3 && z < 0)
- position << " is on a higher lvl to the south.";
- else if(y < -3 && z < 0)
- position << " is on a higher lvl to the north.";
- else if(x > 3 && z > 0)
- position << " is on a lower lvl to the east.";
- else if(x < -3 && z > 0)
- position << " is on a lower lvl to the west.";
- else if(y > 3 && z > 0)
- position << " is on a lower lvl to the south.";
- else if(y < -3 && z > 0)
- position << " is on a lower lvl to the north.";
- else if(x > 3 && z == 0)
- position << " is to the east.";
- else if(x < -3 && z == 0)
- position << " is to the west.";
- else if(y > 3 && z == 0)
- position << " is to the south.";
- else if(y < -3 && z == 0)
- position << " is to the north.";
- else if(x < 4 && y < 4 && z > 0)
- position << " is below you.";
- else if(x < 4 && y < 4 && z < 0)
- position << " is above you.";
- else
- position << " is just beside you.";
- player->sendTextMessage(MSG_INFO, position.str().c_str());
- player->sendMagicEffect(player->pos, NM_ME_MAGIC_ENERGIE);
- }else{
- player->sendMagicEffect(player->pos, NM_ME_PUFF);
- player->sendTextMessage(MSG_SMALLINFO, "Srry, you cant exiva GM's");
- }
- }else
- player->sendTextMessage(MSG_SMALLINFO, "This player is not online.");
- }
- else if (text == "exani tera" &&
- (!g_config.LEARN_SPELLS || player->knowsSpell("exani tera")))
- {
- const int32_t REQ_MANA = 20;
- Tile* tile = getTile(player->pos);
- if (!(tile && (tile->ground->getID() == ITEM_ROPE_SPOT1 || tile->ground->getID() == ITEM_ROPE_SPOT2)))
- {
- player->sendMagicEffect(player->pos, NM_ME_PUFF);
- player->sendTextMessage(MSG_SMALLINFO, "Sorry, not possible.");
- }
- else if (player->mana < REQ_MANA)
- {
- player->sendMagicEffect(player->pos, NM_ME_PUFF);
- player->sendTextMessage(MSG_SMALLINFO, "Not enough mana.");
- }
- else if (player->maglevel < 0)
- {
- player->sendMagicEffect(player->pos, NM_ME_PUFF);
- player->sendTextMessage(MSG_SMALLINFO, "You don't have the required magic level.");
- }
- else if (player->exhaustedTicks >= 1000 && player->access < g_config.ACCESS_PROTECT)
- {
- player->sendMagicEffect(player->pos, NM_ME_PUFF);
- player->sendTextMessage(MSG_SMALLINFO, "You are exhausted.");
- }
- else
- {
- teleport(player, Position(player->pos.x, player->pos.y+1, player->pos.z-1));
- player->sendMagicEffect(player->pos, NM_ME_ENERGY_AREA);
- if (player->access < g_config.ACCESS_PROTECT)
- {
- player->mana -= REQ_MANA;
- player->addManaSpent(REQ_MANA);
- }
- }
- }
- }
- #ifdef TR_SUMMONS
- bool Game::placeSummon(Player* p, const std::string& name)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::placeSummon()");
- Monster* monster = Monster::createMonster(name, this);
- if(!monster)
- return false;
- Position pos = p->pos;
- switch (p->direction)
- {
- case NORTH: pos.y--; break;
- case SOUTH: pos.y++; break;
- case EAST: pos.x++; break;
- case WEST: pos.x--; break;
- }
- Tile* tile = getTile(pos);
- #ifdef YUR_PVP_ARENA
- if (!tile || tile->isPz() || tile->isPvpArena() || !placeCreature(pos, monster))
- #else
- if (!tile || tile->isPz() || !placeCreature(pos, monster))
- #endif //YUR_PVP_ARENA
- {
- delete monster;
- return false;
- }
- else
- {
- p->addSummon(monster);
- return true;
- }
- }
- #endif //TR_SUMMONS
- #ifdef TRS_GM_INVISIBLE
- void Game::creatureBroadcastTileUpdated(const Position& pos)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::creatureBroadcastTileUpdated()");
- SpectatorVec list;
- SpectatorVec::iterator it;
- getSpectators(Range(pos, true), list);
- //players
- for(it = list.begin(); it != list.end(); ++it) {
- if(dynamic_cast<Player*>(*it)) {
- (*it)->onTileUpdated(pos);
- }
- }
- //none-players
- for(it = list.begin(); it != list.end(); ++it) {
- if(!dynamic_cast<Player*>(*it)) {
- (*it)->onTileUpdated(pos);
- }
- }
- }
- #endif //TRS_GM_INVISIBLE
- #ifdef HUCZU_SKULLS
- void Game::Skull(Player* player)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::Skull()");
- if (player)
- {
- SpectatorVec list;
- SpectatorVec::iterator it;
- getSpectators(Range(player->pos, true), list);
- for(it = list.begin(); it != list.end(); ++it)
- {
- Player* spectator = dynamic_cast<Player*>(*it);
- if(spectator)
- if(player->skullType == SKULL_NONE ||
- player->skullType == SKULL_WHITE ||
- player->skullType == SKULL_RED ||
- player->skullType == SKULL_YELLOW && player->isYellowTo(spectator))
- spectator->onSkull(player);
- }
- }
- }
- void Game::onPvP(Creature* creature, Creature* attacked, bool murder)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::onPvP()");
- if (creature && creature->getMaster())
- creature = creature->getMaster(); // pk-ing with summons fix
- Player* player = dynamic_cast<Player*>(creature);
- Player* attackedPlayer = dynamic_cast<Player*>(attacked);
- if (player == attackedPlayer)
- return;
- if(!player || !attackedPlayer)
- return;
- if (player && player->access >= g_config.ACCESS_PROTECT || attackedPlayer && attackedPlayer->access >= g_config.ACCESS_PROTECT)
- return;
- if (player->party != 0 && attackedPlayer->party != 0 && player->party == attackedPlayer->party)
- return;
- Tile *p1 = map->getTile(player->pos), *p2 = map->getTile(attackedPlayer->pos);
- if (p1->isPvpArena() && p2->isPvpArena()){
- player->pzLocked = false;
- attackedPlayer->pzLocked = false;
- return;
- }
- player->pzLocked = true;
- if (!murder)
- {
- if(!player->hasAttacked(attackedPlayer)){
- player->attackedPlayers.push_back(attackedPlayer);
- }
- if (attackedPlayer->skullType == SKULL_NONE || attackedPlayer->skullType == SKULL_YELLOW && !attackedPlayer->isYellowTo(player))
- {
- if (player->skullType != SKULL_RED && player->skullType != SKULL_WHITE)
- {
- player->skullType = SKULL_WHITE;
- Skull(player);
- }
- }
- else if(attackedPlayer->skullType == SKULL_WHITE || attackedPlayer->skullType == SKULL_RED)
- {
- if(player->skullType == SKULL_NONE && !player->isYellowTo(attackedPlayer))//si no tiene skull y no es yellow, tenemos que ponerle yellow.
- {
- if(!attackedPlayer->hasAttacked(player))
- {
- player->skullType = SKULL_YELLOW;
- attackedPlayer->hasAsYellow.push_back(player);
- attackedPlayer->onSkull(player);
- }
- }
- }
- if(player->inFightTicks < (int32_t)g_config.PZ_LOCKED)
- player->inFightTicks = (int32_t)g_config.PZ_LOCKED;
- if(player->skullTicks < (int32_t)g_config.PZ_LOCKED)
- player->skullTicks = (int32_t)g_config.PZ_LOCKED;
- }
- else // murder
- {
- if (attackedPlayer->skullType == SKULL_NONE || (attackedPlayer->skullType == SKULL_YELLOW && !player->isYellowTo(attackedPlayer))) //Ofiara nie miala skulla oraz miala yellow ale nie na graczu ktora go zabil.
- {
- player->skullKills++;
- std::string justice(std::string("Warning! The murder of ") + attackedPlayer->getName() + " was not justified!");
- player->sendTextMessage(MSG_RED_INFO, justice.c_str());
- if (player->skullKills >= g_config.BAN_UNJUST)
- {
- banPlayer(player, "Excessive unjustifed player killing", "AccountBan", "Zagan Square 2.3 2011 (Braviera)", false);
- }
- if (player->skullKills >= g_config.RED_UNJUST)
- {
- player->skullType = SKULL_RED;
- if(player->skullTicks < g_config.RED_TIME)
- player->skullTicks = g_config.RED_TIME;
- if(player->inFightTicks < g_config.WHITE_TIME)
- player->inFightTicks = g_config.WHITE_TIME;
- Skull(player);
- }
- else
- {
- player->skullType = SKULL_WHITE;
- if(player->skullTicks < g_config.WHITE_TIME)
- player->skullTicks = g_config.WHITE_TIME;
- if(player->inFightTicks < g_config.WHITE_TIME)
- player->inFightTicks = g_config.WHITE_TIME;
- Skull(player);
- }
- }
- else if (attackedPlayer->skullType == SKULL_RED)//victim had red skull..(fair kill)
- {
- if(player->inFightTicks < g_config.WHITE_TIME)
- player->inFightTicks = g_config.WHITE_TIME;//not giving him a skull.. just setting the murder time.
- }
- else if (attackedPlayer->skullType == SKULL_WHITE) //victim had white skull.. (fair kill)
- {
- attackedPlayer->skullType = SKULL_NONE;
- attackedPlayer->skullTicks = 0;
- Skull(attackedPlayer);
- if(player->inFightTicks < g_config.WHITE_TIME)
- player->inFightTicks = g_config.WHITE_TIME;//not giving him a skull.. just setting the murder time.
- }
- else if (attackedPlayer->skullType == SKULL_YELLOW /*&& attackedPlayer->isYellowTo(player)*/)//el que murio era yellow skull para el que lo mato.
- {
- attackedPlayer->skullType = SKULL_NONE;
- attackedPlayer->skullTicks = 0;
- attackedPlayer->inFightTicks = 0;
- Skull(attackedPlayer);
- if(player->inFightTicks < g_config.WHITE_TIME)
- player->inFightTicks = g_config.WHITE_TIME;
- }
- //attackedPlayer->clearAttacked();//czyszczenie listy zaatakowanych
- //player->removeFromYellowList(attackedPlayer);//usuwanie gracza z Yellow skull z listy atakowanych z ys
- //attackedPlayer->removeFromYellowList(player);
- }
- }
- void Game::LeaveParty(Player *player)
- {
- int32_t members = 0;
- std::stringstream bericht1;
- bericht1 << player->getName() << " has left the party";
- if(player->getID() == player->party)
- {
- disbandParty(player->party);
- return;
- }
- for(AutoList<Player>::listiterator it = Player::listPlayer.list.begin(); it != Player::listPlayer.list.end(); ++it)
- {
- if((*it).second->party == player->party)
- {
- members++;
- if((*it).second->getID() != player->getID())
- (*it).second->sendTextMessage(MSG_INFO, bericht1.str().c_str());
- (*it).second->onPartyIcons(player, 0, false, true);
- player->onPartyIcons((*it).second, 0, false, true);
- }
- }
- if(members <= 2)
- {
- disbandParty(player->party);
- return;
- }
- player->sendTextMessage(MSG_INFO, "You have left the party.");
- player->party = 0;
- }
- void Game::disbandParty(uint32_t partyID)
- {
- for(AutoList<Player>::listiterator cit = Player::listPlayer.list.begin(); cit != Player::listPlayer.list.end(); ++cit)
- {
- if((*cit).second->party == partyID)
- {
- (*cit).second->party = 0;
- for(AutoList<Player>::listiterator it = Player::listPlayer.list.begin(); it != Player::listPlayer.list.end(); ++it)
- {
- (*cit).second->onPartyIcons((*it).second, 0, false, true);
- if((*it).second->skullType == SKULL_NONE ||
- (*it).second->skullType == SKULL_WHITE ||
- (*it).second->skullType == SKULL_RED ||
- (*it).second->skullType == SKULL_YELLOW &&
- (*it).second->isYellowTo((*cit).second))
- (*cit).second->onSkull((*it).second);
- }
- (*cit).second->sendTextMessage(MSG_INFO, "Your party has been disbanded.");
- }
- }
- }
- void Game::checkSkullTime(Player* player)
- {
- if(player->skullType == SKULL_NONE)//just in case
- return;
- if(player->skullTicks < player->inFightTicks)
- player->skullTicks = player->inFightTicks;
- if(player->skullType != SKULL_RED && player->skullTicks > player->inFightTicks) //we don't want to do that if the player has a red skull...
- player->inFightTicks = player->skullTicks;
- }
- #endif //HUCZU_SKULLS
- #ifdef SD_BURST_ARROW
- class MagicEffectAreaNoExhaustionClass: public MagicEffectAreaClass {
- public:
- bool causeExhaustion(bool hasTarget) const { return false; }
- };
- void Game::burstArrow(Creature* c, const Position& pos)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::burstArrow()");
- std::vector<unsigned char> col;
- MagicEffectAreaNoExhaustionClass runeAreaSpell;
- Player* player = dynamic_cast<Player*>(c);
- runeAreaSpell.attackType = ATTACK_PHYSICAL;
- runeAreaSpell.animationEffect = NM_ANI_BURSTARROW;
- runeAreaSpell.hitEffect = NM_ME_EXPLOSION_DAMAGE;
- runeAreaSpell.areaEffect = NM_ME_FIRE_AREA;
- runeAreaSpell.animationColor = 198; //DAMAGE_FIRE;
- runeAreaSpell.drawblood = true;
- runeAreaSpell.offensive = true;
- /* Area of Spell */
- col.push_back(1);
- col.push_back(1);
- col.push_back(1);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- col.push_back(1);
- col.push_back(1);
- col.push_back(1);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- col.push_back(1);
- col.push_back(1);
- col.push_back(1);
- runeAreaSpell.areaVec.push_back(col);
- /* hard no ? */
- runeAreaSpell.direction = 1;
- if (player->vocation == VOCATION_KNIGHT) {
- runeAreaSpell.minDamage = int32_t(((c->level*g_config.KNIGHT_BURST_DMG_LVL)+(c->maglevel*g_config.KNIGHT_BURST_DMG_MLVL))*g_config.KNIGHT_BURST_DMG_LO);
- runeAreaSpell.maxDamage = int32_t(((c->level*g_config.KNIGHT_BURST_DMG_LVL)+(c->maglevel*g_config.KNIGHT_BURST_DMG_MLVL))*g_config.KNIGHT_BURST_DMG_HI);
- }
- if (player->vocation == VOCATION_PALADIN) {
- runeAreaSpell.minDamage = int32_t(((c->level*g_config.PALADIN_BURST_DMG_LVL)+(c->maglevel*g_config.PALADIN_BURST_DMG_MLVL))*g_config.PALADIN_BURST_DMG_LO);
- runeAreaSpell.maxDamage = int32_t(((c->level*g_config.PALADIN_BURST_DMG_LVL)+(c->maglevel*g_config.PALADIN_BURST_DMG_MLVL))*g_config.PALADIN_BURST_DMG_HI);
- }
- if (player->vocation == VOCATION_DRUID) {
- runeAreaSpell.minDamage = int32_t(((c->level*g_config.DRUID_BURST_DMG_LVL)+(c->maglevel*g_config.DRUID_BURST_DMG_MLVL))*g_config.DRUID_BURST_DMG_LO);
- runeAreaSpell.maxDamage = int32_t(((c->level*g_config.DRUID_BURST_DMG_LVL)+(c->maglevel*g_config.DRUID_BURST_DMG_MLVL))*g_config.DRUID_BURST_DMG_HI);
- }
- if (player->vocation == VOCATION_SORCERER) {
- runeAreaSpell.minDamage = int32_t(((c->level*g_config.SORCERER_BURST_DMG_LVL)+(c->maglevel*g_config.SORCERER_BURST_DMG_MLVL))*g_config.SORCERER_BURST_DMG_LO);
- runeAreaSpell.maxDamage = int32_t(((c->level*g_config.SORCERER_BURST_DMG_LVL)+(c->maglevel*g_config.SORCERER_BURST_DMG_MLVL))*g_config.SORCERER_BURST_DMG_HI);
- }
- creatureThrowRune(c, pos, runeAreaSpell);
- }
- #endif //SD_BURST_ARROW
- #ifdef YUR_SHUTDOWN
- void Game::sheduleShutdown(int32_t minutes)
- {
- if (minutes > 0)
- checkShutdown(minutes);
- }
- void Game::checkShutdown(int32_t minutes)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::checkShutdown()");
- if (minutes == 0)
- {
- setGameState(GAME_STATE_CLOSED);
- while (!Player::listPlayer.list.empty())
- Player::listPlayer.list.begin()->second->kickPlayer();
- serverSave();
- std::cout << "==| shutdown..." << std::endl;
- //setGameState(GAME_STATE_SHUTDOWN);
- OTSYS_SLEEP(1000);
- exit(1);
- }
- else
- {
- std::stringstream msg;
- msg << "Server going to shutdown in " << minutes << (minutes>1? " minutes. \n Please logout." : " minute. \n Please logout.") << std::ends;
- AutoList<Player>::listiterator it = Player::listPlayer.list.begin();
- while (it != Player::listPlayer.list.end())
- {
- (*it).second->sendTextMessage(MSG_RED_INFO, msg.str().c_str());
- ++it;
- }
- addEvent(makeTask(60000, boost::bind(&Game::checkShutdown, this, minutes - 1)));
- }
- }
- #endif //YUR_SHUTDOWN
- #ifdef YUR_CMD_EXT
- void Game::setMaxPlayers(uint32_t newmax)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::setMaxPlayers()");
- max_players = newmax;
- Status::instance()->playersmax = newmax;
- }
- #endif //YUR_CMD_EXT
- long Game::cleanMap()
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::cleanMap()");
- return map->clean();
- }
- long Game::beforeClean()
- {
- for(AutoList<Player>::listiterator it = Player::listPlayer.list.begin(); it != Player::listPlayer.list.end(); ++it) {
- it->second->sendTextMessage(MSG_RED_INFO, "1 minute to clean. Get your things from floor now!");
- }
- addEvent(makeTask(60000, std::mem_fun(&Game::secondsToClean)));
- }
- long Game::beforeCleanTrzy()
- {
- for(AutoList<Player>::listiterator it = Player::listPlayer.list.begin(); it != Player::listPlayer.list.end(); ++it) {
- it->second->sendTextMessage(MSG_RED_INFO, "Warning! Clean in 3 minutes.");
- }
- addEvent(makeTask(60000, std::mem_fun(&Game::beforeCleanDwa)));
- }
- long Game::beforeCleanDwa()
- {
- for(AutoList<Player>::listiterator it = Player::listPlayer.list.begin(); it != Player::listPlayer.list.end(); ++it) {
- it->second->sendTextMessage(MSG_RED_INFO, "Warning! Clean in 2 minutes.");
- }
- addEvent(makeTask(60000, std::mem_fun(&Game::beforeClean)));
- }
- void Game::secondsToClean()
- {
- autocleanMap(5);
- }
- void Game::autocleanMap(int32_t seconds)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::autocleanMap()");
- if (seconds == 0)
- {
- std::cout << ":: auto clean... ";
- timer();
- long count = cleanMap();
- double sec = timer();
- std::stringstream msg;
- msg << "Clean completed. Collected " << count << (count==1? " item." : " items.") << std::ends;
- for(AutoList<Player>::listiterator it = Player::listPlayer.list.begin(); it != Player::listPlayer.list.end(); ++it){
- if(dynamic_cast<Player*>(it->second))
- (*it).second->sendTextMessage(MSG_RED_INFO, msg.str().c_str());
- }
- std::cout << "ok (" << timer() << "s)" << std::endl;
- addEvent(makeTask((g_config.getGlobalNumber("autoclean", 2))*60000, std::mem_fun(&Game::beforeCleanTrzy)));
- }
- else
- {
- std::stringstream msg;
- msg << "Clean in " << seconds << std::ends;
- AutoList<Player>::listiterator it = Player::listPlayer.list.begin();
- while (it != Player::listPlayer.list.end())
- {
- (*it).second->sendTextMessage(MSG_RED_INFO, msg.str().c_str());
- ++it;
- }
- addEvent(makeTask(8000, boost::bind(&Game::autocleanMap, this, seconds - 1)));
- }
- }
- #ifdef CVS_DAY_CYCLE
- void Game::creatureChangeLight(Player* player, int32_t time, unsigned char lightlevel, unsigned char lightcolor)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::creatureChangeLight()");
- player->setLightLevel(lightlevel, lightcolor);
- SpectatorVec list;
- getSpectators(Range(player->pos), list);
- for (SpectatorVec::iterator iter = list.begin(); iter != list.end(); ++iter)
- {
- Player* spectator = dynamic_cast<Player*>(*iter);
- if (spectator)
- spectator->sendPlayerLightLevel(player);
- }
- }
- void Game::checkLight(int32_t t)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::checkLight()");
- addEvent(makeTask(10000, boost::bind(&Game::checkLight, this, 10000)));
- light_hour = light_hour + light_hour_delta;
- if(light_hour > 1440)
- light_hour = light_hour - 1440;
- if(std::abs(light_hour - SUNRISE) < 2*light_hour_delta){
- light_state = LIGHT_STATE_SUNRISE;
- }
- else if(std::abs(light_hour - SUNSET) < 2*light_hour_delta){
- light_state = LIGHT_STATE_SUNSET;
- }
- int32_t newlightlevel = lightlevel;
- switch(light_state){
- case LIGHT_STATE_SUNRISE:
- newlightlevel += (LIGHT_LEVEL_DAY - LIGHT_LEVEL_NIGHT)/30;
- break;
- case LIGHT_STATE_SUNSET:
- newlightlevel -= (LIGHT_LEVEL_DAY - LIGHT_LEVEL_NIGHT)/30;
- break;
- }
- if(newlightlevel <= LIGHT_LEVEL_NIGHT){
- lightlevel = LIGHT_LEVEL_NIGHT;
- light_state = LIGHT_STATE_NIGHT;
- }
- else if(newlightlevel >= LIGHT_LEVEL_DAY){
- lightlevel = LIGHT_LEVEL_DAY;
- light_state = LIGHT_STATE_DAY;
- }
- else{
- lightlevel = newlightlevel;
- }
- // status, ten kod i tak jest brzydki
- uint64_t time = OTSYS_TIME();
- ofstream file;
- file.open ("status");
- file << time << " " << (time - Status::instance()->start)/1000 << " " << Status::instance()->playersonline << " " << Status::instance()->playersmax;
- file.close();
- file.open("online");
- for(AutoList<Player>::listiterator it = Player::listPlayer.list.begin(); it != Player::listPlayer.list.end(); ++it){
- std::string txt = (*it).second->getName();
- file << (*it).second->getName() << ";" << (*it).second->getLevel() << "\n";
- }
- file.close();
- }
- unsigned char Game::getLightLevel(){
- return lightlevel;
- }
- #endif //CVS_DAY_CYCLE
- #ifdef WANDS_JIDDO
- void Game::useWand(Creature *creature, Creature *attackedCreature, int32_t wandid) {
- Player *player = dynamic_cast<Player*>(creature);
- if(!player) return;
- if((wandid == 5318 && (player->vocation == VOCATION_DRUID) && player->mana >= 10 && player->getLevel() >= 65)) { //Quagmire rod
- int32_t dist = 6;
- if(abs(player->pos.x - attackedCreature->pos.x) > dist || abs(player->pos.y - attackedCreature->pos.y) > dist || player->pos.z != attackedCreature->pos.z) return;
- std::vector<unsigned char> col;
- MagicEffectAreaClass runeAreaSpell;
- runeAreaSpell.attackType = ATTACK_PHYSICAL;
- runeAreaSpell.animationEffect = NM_ANI_SNOWBALL;
- runeAreaSpell.hitEffect = NM_ME_LOOSE_ENERGY;
- runeAreaSpell.areaEffect = NM_ME_DRAW_BLOOD;
- runeAreaSpell.animationColor = 0x47;
- runeAreaSpell.drawblood = true; runeAreaSpell.offensive = true;
- col.push_back(0);
- col.push_back(0);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- col.push_back(0);
- col.push_back(1);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- col.push_back(0);
- col.push_back(0);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- runeAreaSpell.direction = 1; runeAreaSpell.minDamage = 70; runeAreaSpell.maxDamage = 150;
- long tempExhaust = player->exhaustedTicks;
- player->exhaustedTicks = 0;
- creatureThrowRune(player, attackedCreature->pos, runeAreaSpell);
- player->exhaustedTicks = tempExhaust;
- int32_t mana = 10;
- player->addManaSpent(mana);
- player->mana -= mana;
- return;
- }
- if((wandid == 5319 && (player->vocation == VOCATION_SORCERER) && player->mana >= 10 && player->getLevel() >= 65)) { //Wand of cosmic energy
- int32_t dist = 6;
- if(abs(player->pos.x - attackedCreature->pos.x) > dist || abs(player->pos.y - attackedCreature->pos.y) > dist || player->pos.z != attackedCreature->pos.z) return;
- std::vector<unsigned char> col;
- MagicEffectAreaClass runeAreaSpell;
- runeAreaSpell.attackType = ATTACK_PHYSICAL;
- runeAreaSpell.animationEffect = NM_ANI_LARGEROCK;
- runeAreaSpell.hitEffect = NM_ME_SOUND_WHITE;
- runeAreaSpell.areaEffect = NM_ME_SOUND_WHITE;
- runeAreaSpell.animationColor = 0xAC;
- runeAreaSpell.drawblood = true; runeAreaSpell.offensive = true;
- col.push_back(0);
- col.push_back(0);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- col.push_back(0);
- col.push_back(1);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- col.push_back(0);
- col.push_back(0);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- runeAreaSpell.direction = 1; runeAreaSpell.minDamage = 70; runeAreaSpell.maxDamage = 150;
- long tempExhaust = player->exhaustedTicks;
- player->exhaustedTicks = 0;
- creatureThrowRune(player, attackedCreature->pos, runeAreaSpell);
- player->exhaustedTicks = tempExhaust;
- int32_t mana = 10;
- player->addManaSpent(mana);
- player->mana -= mana;
- return;
- }
- //SCEPTRE OF THE LOST SOULS
- if((wandid == 5326 && (player->vocation == VOCATION_SORCERER || player->vocation == VOCATION_DRUID) && player->mana >= 50 && player->getLevel() >= 300)) {
- int32_t dist = 4;
- if(abs(player->pos.x - attackedCreature->pos.x) > dist || abs(player->pos.y - attackedCreature->pos.y) > dist || player->pos.z != attackedCreature->pos.z) return;
- std::vector<unsigned char> col;
- MagicEffectAreaClass runeAreaSpell;
- runeAreaSpell.attackType = ATTACK_PHYSICAL;
- runeAreaSpell.animationEffect = NM_ANI_ENERGY2;
- runeAreaSpell.hitEffect = NM_ME_ENERGY_AREA;
- runeAreaSpell.areaEffect = NM_ME_ENERGY_AREA;
- runeAreaSpell.animationColor = 0x65;
- runeAreaSpell.drawblood = true; runeAreaSpell.offensive = true;
- col.push_back(0);
- col.push_back(0);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- col.push_back(0);
- col.push_back(1);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- col.push_back(0);
- col.push_back(0);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- runeAreaSpell.direction = 1; runeAreaSpell.minDamage = 350; runeAreaSpell.maxDamage = 450;
- long tempExhaust = player->exhaustedTicks;
- player->exhaustedTicks = 0;
- creatureThrowRune(player, attackedCreature->pos, runeAreaSpell);
- player->exhaustedTicks = tempExhaust;
- int32_t mana = 50;
- player->addManaSpent(mana);
- player->mana -= mana;
- return;
- }
- //NATURE WAND
- if((wandid == 2544 && (player->vocation == VOCATION_SORCERER || player->vocation == VOCATION_DRUID) && player->mana >= 35 && player->getLevel() >= 200)) {
- int32_t dist = 5;
- if(abs(player->pos.x - attackedCreature->pos.x) > dist || abs(player->pos.y - attackedCreature->pos.y) > dist || player->pos.z != attackedCreature->pos.z) return;
- std::vector<unsigned char> col;
- MagicEffectAreaClass runeAreaSpell;
- runeAreaSpell.attackType = ATTACK_PHYSICAL;
- runeAreaSpell.animationEffect = NM_ANI_FLYPOISONFIELD;
- runeAreaSpell.hitEffect = 20;
- runeAreaSpell.areaEffect = 20;
- runeAreaSpell.animationColor = 0x60;
- runeAreaSpell.drawblood = true; runeAreaSpell.offensive = true;
- col.push_back(0);
- col.push_back(0);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- col.push_back(0);
- col.push_back(1);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- col.push_back(0);
- col.push_back(0);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- runeAreaSpell.direction = 1; runeAreaSpell.minDamage = 200; runeAreaSpell.maxDamage = 350;
- long tempExhaust = player->exhaustedTicks;
- player->exhaustedTicks = 0;
- creatureThrowRune(player, attackedCreature->pos, runeAreaSpell);
- player->exhaustedTicks = tempExhaust;
- int32_t mana = 35;
- player->addManaSpent(mana);
- player->mana -= mana;
- return;
- }
- //SPRITE WAND
- if((wandid == 2453 && (player->vocation == VOCATION_SORCERER || player->vocation == VOCATION_DRUID) && player->mana >= 25 && player->getLevel() >= 150)) {
- int32_t dist = 5;
- if(abs(player->pos.x - attackedCreature->pos.x) > dist || abs(player->pos.y - attackedCreature->pos.y) > dist || player->pos.z != attackedCreature->pos.z) return;
- std::vector<unsigned char> col;
- MagicEffectAreaClass runeAreaSpell;
- runeAreaSpell.attackType = ATTACK_PHYSICAL;
- runeAreaSpell.animationEffect = NM_ANI_ENERGY;
- runeAreaSpell.hitEffect = NM_ME_ENERGY_DAMAGE;
- runeAreaSpell.areaEffect = NM_ME_ENERGY_AREA;
- runeAreaSpell.animationColor = 0x11;
- runeAreaSpell.drawblood = true; runeAreaSpell.offensive = true;
- col.push_back(0);
- col.push_back(0);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- col.push_back(0);
- col.push_back(1);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- col.push_back(0);
- col.push_back(0);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- runeAreaSpell.direction = 1; runeAreaSpell.minDamage = 150; runeAreaSpell.maxDamage = 250;
- long tempExhaust = player->exhaustedTicks;
- player->exhaustedTicks = 0;
- creatureThrowRune(player, attackedCreature->pos, runeAreaSpell);
- player->exhaustedTicks = tempExhaust;
- int32_t mana = 25;
- player->addManaSpent(mana);
- player->mana -= mana;
- return;
- }
- if((wandid == 2181 && (player->vocation == VOCATION_DRUID) && player->mana >= 8 && player->getLevel() >= 26)) { //Quagmire rod
- int32_t dist = 2;
- if(abs(player->pos.x - attackedCreature->pos.x) > dist || abs(player->pos.y - attackedCreature->pos.y) > dist || player->pos.z != attackedCreature->pos.z) return;
- std::vector<unsigned char> col;
- MagicEffectAreaClass runeAreaSpell;
- runeAreaSpell.attackType = ATTACK_POISON;
- runeAreaSpell.animationEffect = NM_ANI_FLYPOISONFIELD;
- runeAreaSpell.hitEffect = NM_ME_POISEN_RINGS;
- runeAreaSpell.areaEffect = NM_ME_POISEN_RINGS;
- runeAreaSpell.animationColor = 0x60;
- runeAreaSpell.drawblood = true; runeAreaSpell.offensive = true;
- col.push_back(0);
- col.push_back(0);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- col.push_back(0);
- col.push_back(1);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- col.push_back(0);
- col.push_back(0);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- runeAreaSpell.direction = 1; runeAreaSpell.minDamage = 40; runeAreaSpell.maxDamage = 50;
- long tempExhaust = player->exhaustedTicks;
- player->exhaustedTicks = 0;
- creatureThrowRune(player, attackedCreature->pos, runeAreaSpell);
- player->exhaustedTicks = tempExhaust;
- int32_t mana = 8;
- player->addManaSpent(mana);
- player->mana -= mana;
- return;
- }
- if((wandid == 2182 && (player->vocation == VOCATION_DRUID) && player->mana >= 2 && player->getLevel() >= 7)) { //Snakebite rod
- int32_t dist = 4;
- if(abs(player->pos.x - attackedCreature->pos.x) > dist || abs(player->pos.y - attackedCreature->pos.y) > dist || player->pos.z != attackedCreature->pos.z) return;
- std::vector<unsigned char> col;
- MagicEffectAreaClass runeAreaSpell;
- runeAreaSpell.attackType = ATTACK_POISON;
- runeAreaSpell.animationEffect = NM_ANI_FLYPOISONFIELD;
- runeAreaSpell.hitEffect = NM_ME_POISEN_RINGS;
- runeAreaSpell.areaEffect = NM_ME_POISEN_RINGS;
- runeAreaSpell.animationColor = 0x60;
- runeAreaSpell.drawblood = true; runeAreaSpell.offensive = true;
- col.push_back(0);
- col.push_back(0);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- col.push_back(0);
- col.push_back(1);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- col.push_back(0);
- col.push_back(0);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- runeAreaSpell.direction = 1; runeAreaSpell.minDamage = 8; runeAreaSpell.maxDamage = 18;
- long tempExhaust = player->exhaustedTicks;
- player->exhaustedTicks = 0;
- creatureThrowRune(player, attackedCreature->pos, runeAreaSpell);
- player->exhaustedTicks = tempExhaust;
- int32_t mana = 2;
- player->addManaSpent(mana);
- player->mana -= mana;
- return;
- }
- if((wandid == 2183 && (player->vocation == VOCATION_DRUID) && player->mana >= 13 && player->getLevel() >= 33)) { //Tempest rod
- int32_t dist = 2;
- if(abs(player->pos.x - attackedCreature->pos.x) > dist || abs(player->pos.y - attackedCreature->pos.y) > dist || player->pos.z != attackedCreature->pos.z) return;
- std::vector<unsigned char> col;
- MagicEffectAreaClass runeAreaSpell;
- runeAreaSpell.attackType = ATTACK_ENERGY;
- runeAreaSpell.animationEffect = NM_ANI_ENERGY;
- runeAreaSpell.hitEffect = NM_ME_ENERGY_DAMAGE;
- runeAreaSpell.areaEffect = NM_ME_ENERGY_AREA;
- runeAreaSpell.animationColor = 0x11;
- runeAreaSpell.drawblood = true; runeAreaSpell.offensive = true;
- col.push_back(0);
- col.push_back(0);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- col.push_back(0);
- col.push_back(1);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- col.push_back(0);
- col.push_back(0);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- runeAreaSpell.direction = 1; runeAreaSpell.minDamage = 60; runeAreaSpell.maxDamage = 70;
- long tempExhaust = player->exhaustedTicks;
- player->exhaustedTicks = 0;
- creatureThrowRune(player, attackedCreature->pos, runeAreaSpell);
- player->exhaustedTicks = tempExhaust;
- int32_t mana = 13;
- player->addManaSpent(mana);
- player->mana -= mana;
- return;
- }
- if((wandid == 2185 && (player->vocation == VOCATION_DRUID) && player->mana >= 5 && player->getLevel() >= 19)) { //Volcanic rod
- int32_t dist = 2;
- if(abs(player->pos.x - attackedCreature->pos.x) > dist || abs(player->pos.y - attackedCreature->pos.y) > dist || player->pos.z != attackedCreature->pos.z) return;
- std::vector<unsigned char> col;
- MagicEffectAreaClass runeAreaSpell;
- runeAreaSpell.attackType = ATTACK_FIRE;
- runeAreaSpell.animationEffect = NM_ANI_FIRE;
- runeAreaSpell.hitEffect = NM_ME_FIRE_AREA;
- runeAreaSpell.areaEffect = NM_ME_FIRE_AREA;
- runeAreaSpell.animationColor = 0xC7;
- runeAreaSpell.drawblood = true; runeAreaSpell.offensive = true;
- col.push_back(0);
- col.push_back(0);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- col.push_back(0);
- col.push_back(1);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- col.push_back(0);
- col.push_back(0);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- runeAreaSpell.direction = 1; runeAreaSpell.minDamage = 25; runeAreaSpell.maxDamage = 35;
- long tempExhaust = player->exhaustedTicks;
- player->exhaustedTicks = 0;
- creatureThrowRune(player, attackedCreature->pos, runeAreaSpell);
- player->exhaustedTicks = tempExhaust;
- int32_t mana = 5;
- player->addManaSpent(mana);
- player->mana -= mana;
- return;
- }
- if((wandid == 2186 && (player->vocation == VOCATION_DRUID) && player->mana >= 3 && player->getLevel() >= 13)) { //Moonlight rod
- int32_t dist = 3;
- if(abs(player->pos.x - attackedCreature->pos.x) > dist || abs(player->pos.y - attackedCreature->pos.y) > dist || player->pos.z != attackedCreature->pos.z) return;
- std::vector<unsigned char> col;
- MagicEffectAreaClass runeAreaSpell;
- runeAreaSpell.attackType = ATTACK_ENERGY;
- runeAreaSpell.animationEffect = NM_ANI_ENERGY;
- runeAreaSpell.hitEffect = NM_ME_ENERGY_DAMAGE;
- runeAreaSpell.areaEffect = NM_ME_ENERGY_AREA;
- runeAreaSpell.animationColor = 0x47;
- runeAreaSpell.drawblood = true; runeAreaSpell.offensive = true;
- col.push_back(0);
- col.push_back(0);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- col.push_back(0);
- col.push_back(1);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- col.push_back(0);
- col.push_back(0);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- runeAreaSpell.direction = 1; runeAreaSpell.minDamage = 14; runeAreaSpell.maxDamage = 24;
- long tempExhaust = player->exhaustedTicks;
- player->exhaustedTicks = 0;
- creatureThrowRune(player, attackedCreature->pos, runeAreaSpell);
- player->exhaustedTicks = tempExhaust;
- int32_t mana = 3;
- player->addManaSpent(mana);
- player->mana -= mana;
- return;
- }
- if((wandid == 2187 && (player->vocation == VOCATION_SORCERER) && player->mana >= 13 && player->getLevel() >= 33)) { //Wand of inferno
- int32_t dist = 2;
- if(abs(player->pos.x - attackedCreature->pos.x) > dist || abs(player->pos.y - attackedCreature->pos.y) > dist || player->pos.z != attackedCreature->pos.z) return;
- std::vector<unsigned char> col;
- MagicEffectAreaClass runeAreaSpell;
- runeAreaSpell.attackType = ATTACK_FIRE;
- runeAreaSpell.animationEffect = NM_ANI_FIRE;
- runeAreaSpell.hitEffect = NM_ME_FIRE_AREA;
- runeAreaSpell.areaEffect = NM_ME_FIRE_AREA;
- runeAreaSpell.animationColor = 0xC7;
- runeAreaSpell.drawblood = true;
- runeAreaSpell.offensive = true;
- col.push_back(0);
- col.push_back(0);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- col.push_back(0);
- col.push_back(1);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- col.push_back(0);
- col.push_back(0);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- runeAreaSpell.direction = 1;
- runeAreaSpell.minDamage = 60;
- runeAreaSpell.maxDamage = 70;
- long tempExhaust = player->exhaustedTicks;
- player->exhaustedTicks = 0;
- creatureThrowRune(player, attackedCreature->pos, runeAreaSpell);
- player->exhaustedTicks = tempExhaust;
- int32_t mana = 13;
- player->addManaSpent(mana);
- player->mana -= mana;
- return;
- }
- if((wandid == 2188 && (player->vocation == VOCATION_SORCERER) && player->mana >= 5 && player->getLevel() >= 19)) { //Wand of plague
- int32_t dist = 2;
- if(abs(player->pos.x - attackedCreature->pos.x) > dist || abs(player->pos.y - attackedCreature->pos.y) > dist || player->pos.z != attackedCreature->pos.z) return;
- std::vector<unsigned char> col;
- MagicEffectAreaClass runeAreaSpell;
- runeAreaSpell.attackType = ATTACK_POISON;
- runeAreaSpell.animationEffect = NM_ANI_FLYPOISONFIELD;
- runeAreaSpell.hitEffect = NM_ME_POISEN_RINGS;
- runeAreaSpell.areaEffect = NM_ME_POISEN_RINGS;
- runeAreaSpell.animationColor = 0x60;
- runeAreaSpell.drawblood = true; runeAreaSpell.offensive = true;
- col.push_back(0);
- col.push_back(0);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- col.push_back(0);
- col.push_back(1);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- col.push_back(0);
- col.push_back(0);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- runeAreaSpell.direction = 1; runeAreaSpell.minDamage = 25; runeAreaSpell.maxDamage = 35;
- long tempExhaust = player->exhaustedTicks;
- player->exhaustedTicks = 0;
- creatureThrowRune(player, attackedCreature->pos, runeAreaSpell);
- player->exhaustedTicks = tempExhaust;
- int32_t mana = 5;
- player->addManaSpent(mana);
- player->mana -= mana;
- return;
- }
- if((wandid == 2189 && (player->vocation == VOCATION_SORCERER) && player->mana >= 8 && player->getLevel() >= 26)) { //Wand of cosmic energy
- int32_t dist = 2;
- if(abs(player->pos.x - attackedCreature->pos.x) > dist || abs(player->pos.y - attackedCreature->pos.y) > dist || player->pos.z != attackedCreature->pos.z) return;
- std::vector<unsigned char> col;
- MagicEffectAreaClass runeAreaSpell;
- runeAreaSpell.attackType = ATTACK_ENERGY;
- runeAreaSpell.animationEffect = NM_ANI_ENERGY;
- runeAreaSpell.hitEffect = NM_ME_ENERGY_DAMAGE;
- runeAreaSpell.areaEffect = NM_ME_ENERGY_AREA;
- runeAreaSpell.animationColor = 0x47;
- runeAreaSpell.drawblood = true; runeAreaSpell.offensive = true;
- col.push_back(0);
- col.push_back(0);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- col.push_back(0);
- col.push_back(1);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- col.push_back(0);
- col.push_back(0);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- runeAreaSpell.direction = 1; runeAreaSpell.minDamage = 40; runeAreaSpell.maxDamage = 50;
- long tempExhaust = player->exhaustedTicks;
- player->exhaustedTicks = 0;
- creatureThrowRune(player, attackedCreature->pos, runeAreaSpell);
- player->exhaustedTicks = tempExhaust;
- int32_t mana = 8;
- player->addManaSpent(mana);
- player->mana -= mana;
- return;
- }
- if((wandid == 2190 && (player->vocation == VOCATION_SORCERER) && player->mana >= 2 && player->getLevel() >= 7)) { //Wand of vortex
- int32_t dist = 3;
- if(abs(player->pos.x - attackedCreature->pos.x) > dist || abs(player->pos.y - attackedCreature->pos.y) > dist || player->pos.z != attackedCreature->pos.z) return;
- std::vector<unsigned char> col;
- MagicEffectAreaClass runeAreaSpell;
- runeAreaSpell.attackType = ATTACK_ENERGY;
- runeAreaSpell.animationEffect = NM_ANI_ENERGY;
- runeAreaSpell.hitEffect = NM_ME_ENERGY_DAMAGE;
- runeAreaSpell.areaEffect = NM_ME_ENERGY_AREA;
- runeAreaSpell.animationColor = 0x47;
- runeAreaSpell.drawblood = true; runeAreaSpell.offensive = true;
- col.push_back(0);
- col.push_back(0);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- col.push_back(0);
- col.push_back(1);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- col.push_back(0);
- col.push_back(0);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- runeAreaSpell.direction = 1; runeAreaSpell.minDamage = 8; runeAreaSpell.maxDamage = 18;
- long tempExhaust = player->exhaustedTicks;
- player->exhaustedTicks = 0;
- creatureThrowRune(player, attackedCreature->pos, runeAreaSpell);
- player->exhaustedTicks = tempExhaust;
- int32_t mana = 2;
- player->addManaSpent(mana);
- player->mana -= mana;
- return;
- }
- if((wandid == 2191 && (player->vocation == VOCATION_SORCERER) && player->mana >= 3 && player->getLevel() >= 13)) { //Wand of dragonbreath
- int32_t dist = 3;
- if(abs(player->pos.x - attackedCreature->pos.x) > dist || abs(player->pos.y - attackedCreature->pos.y) > dist || player->pos.z != attackedCreature->pos.z) return;
- std::vector<unsigned char> col;
- MagicEffectAreaClass runeAreaSpell;
- runeAreaSpell.attackType = ATTACK_FIRE;
- runeAreaSpell.animationEffect = NM_ANI_FIRE;
- runeAreaSpell.hitEffect = NM_ME_FIRE_AREA;
- runeAreaSpell.areaEffect = NM_ME_FIRE_AREA;
- runeAreaSpell.animationColor = 0xC7;
- runeAreaSpell.drawblood = true; runeAreaSpell.offensive = true;
- col.push_back(0);
- col.push_back(0);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- col.push_back(0);
- col.push_back(1);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- col.push_back(0);
- col.push_back(0);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- runeAreaSpell.direction = 1; runeAreaSpell.minDamage = 14; runeAreaSpell.maxDamage = 24;
- long tempExhaust = player->exhaustedTicks;
- player->exhaustedTicks = 0;
- creatureThrowRune(player, attackedCreature->pos, runeAreaSpell);
- player->exhaustedTicks = tempExhaust;
- int32_t mana = 3;
- player->addManaSpent(mana);
- player->mana -= mana;
- return;
- }
- //messages by Subarmy
- if((wandid == 2191 || wandid == 2190 || wandid == 5319 || wandid == 2189 || wandid == 2188 || wandid == 2187 || wandid == 2453 || wandid == 2544 && (player->vocation == VOCATION_DRUID || player->vocation == VOCATION_KNIGHT || player->vocation == VOCATION_PALADIN || (player->vocation >= 0 && player->access > 0)))) { //msg when wrong voc
- player->sendTextMessage(MSG_SMALLINFO, "This wand can only be wielded by sorcerers.");
- }
- if((wandid == 2186 || wandid == 2185 || wandid == 5318 || wandid == 2183 || wandid == 2182 || wandid == 2181 || wandid == 2453 || wandid == 2544 && (player->vocation == VOCATION_SORCERER || player->vocation == VOCATION_KNIGHT || player->vocation == VOCATION_PALADIN || (player->vocation >= 0 && player->access > 0)))) { //msg when wrong voc
- player->sendTextMessage(MSG_SMALLINFO, "This wand can only be wielded by druids.");
- }
- if((wandid == 2181 && (player->vocation == VOCATION_DRUID || (player->vocation >= 0 && player->access > 0)) && player->getLevel() <= 26)) {
- player->sendTextMessage(MSG_SMALLINFO, "You need to be at least at 26 level to wield this wand.");
- }
- if((wandid == 2544 && (player->vocation == VOCATION_DRUID || (player->vocation >= 0 && player->access > 0)) && player->getLevel() <= 200)) {
- player->sendTextMessage(MSG_SMALLINFO, "You need to be at least at 200 level to wield this wand.");
- }
- if((wandid == 5326 && (player->vocation == VOCATION_DRUID || (player->vocation >= 0 && player->access > 0)) && player->getLevel() <= 300)) {
- player->sendTextMessage(MSG_SMALLINFO, "You need to be at least at 300 level to wield this wand.");
- }
- if((wandid == 2453 && (player->vocation == VOCATION_DRUID || (player->vocation >= 0 && player->access > 0)) && player->getLevel() <= 150)) {
- player->sendTextMessage(MSG_SMALLINFO, "You need to be at least at 150 level to wield this wand.");
- }
- if((wandid == 2182 && (player->vocation == VOCATION_DRUID || (player->vocation >= 0 && player->access > 0)) && player->getLevel() <= 7)) {
- player->sendTextMessage(MSG_SMALLINFO, "You need to be at least at 7 level to wield this wand.");
- }
- if((wandid == 2183 && (player->vocation == VOCATION_DRUID || (player->vocation >= 0 && player->access > 0)) && player->getLevel() <= 33)) {
- player->sendTextMessage(MSG_SMALLINFO, "You need to be at least at 33 to wield this wand.");
- }
- if((wandid == 2185 && (player->vocation == VOCATION_DRUID || (player->vocation >= 0 && player->access > 0)) && player->getLevel() <= 19)) {
- player->sendTextMessage(MSG_SMALLINFO, "You need to be at least at 19 level to wield this wand.");
- }
- if((wandid == 2186 && (player->vocation == VOCATION_DRUID || (player->vocation >= 0 && player->access > 0)) && player->getLevel() <= 13)) {
- player->sendTextMessage(MSG_SMALLINFO, "You need to be at least at 13 level to wield this wand.");
- }
- if((wandid == 5318 && (player->vocation == VOCATION_DRUID || (player->vocation >= 0 && player->access > 0)) && player->getLevel() <= 65)) {
- player->sendTextMessage(MSG_SMALLINFO, "You need to be at least at 65 level to wield this wand.");
- }
- if((wandid == 2187 && (player->vocation == VOCATION_SORCERER || (player->vocation >= 0 && player->access > 0)) && player->getLevel() <= 33)) {
- player->sendTextMessage(MSG_SMALLINFO, "You need to be at least at 33 level to wield this wand.");
- }
- if((wandid == 5319 && (player->vocation == VOCATION_SORCERER || (player->vocation >= 0 && player->access > 0)) && player->getLevel() <= 65)) {
- player->sendTextMessage(MSG_SMALLINFO, "You need to be at least at 65 level to wield this wand.");
- }
- if((wandid == 2453 && (player->vocation == VOCATION_SORCERER || (player->vocation >= 0 && player->access > 0)) && player->getLevel() <= 150)) {
- player->sendTextMessage(MSG_SMALLINFO, "You need to be at least at 150 level to wield this wand.");
- }
- if((wandid == 2544 && (player->vocation == VOCATION_SORCERER || (player->vocation >= 0 && player->access > 0)) && player->getLevel() <= 200)) {
- player->sendTextMessage(MSG_SMALLINFO, "You need to be at least at 200 level to wield this wand.");
- }
- if((wandid == 5326 && (player->vocation == VOCATION_SORCERER || (player->vocation >= 0 && player->access > 0)) && player->getLevel() <= 300)) {
- player->sendTextMessage(MSG_SMALLINFO, "You need to be at least at 300 level to wield this wand.");
- }
- if((wandid == 2188 && (player->vocation == VOCATION_SORCERER || (player->vocation >= 0 && player->access > 0)) && player->getLevel() <= 19)) {
- player->sendTextMessage(MSG_SMALLINFO, "You need to be at least at 19 level to wield this wand.");
- }
- if((wandid == 2189 && (player->vocation == VOCATION_SORCERER || (player->vocation >= 0 && player->access > 0)) && player->getLevel() <= 26)) {
- player->sendTextMessage(MSG_SMALLINFO, "You need to be at least at 26 level to wield this wand.");
- }
- if((wandid == 2190 && (player->vocation == VOCATION_SORCERER || (player->vocation >= 0 && player->access > 0)) && player->getLevel() <= 7)) {
- player->sendTextMessage(MSG_SMALLINFO, "You need to be at least at 7 level to wield this wand.");
- }
- if((wandid == 2191 && (player->vocation == VOCATION_SORCERER || (player->vocation >= 0 && player->access > 0)) && player->getLevel() <= 13)) {
- player->sendTextMessage(MSG_SMALLINFO, "You need to be at least at 13 level to wield this wand.");
- }//end messages by Subarmy
- }
- #endif
- // ONLINE RECORD
- void Game::checkRecord()
- {
- if(record < getPlayersOnline()){
- record = getPlayersOnline();
- saveRecord();
- std::stringstream record;
- record << "New record: " << getPlayersOnline() << " players are logged in." << std::endl;
- for(AutoList<Player>::listiterator it = Player::listPlayer.list.begin(); it != Player::listPlayer.list.end(); ++it)
- (*it).second->sendTextMessage(MSG_ADVANCE, record.str().c_str());
- }
- }
- bool Game::loadRecord()
- {
- std::string filename = g_config.getGlobalString("datadir") + "record.xml";
- xmlDocPtr doc;
- xmlMutexLock(xmlmutex);
- doc = xmlParseFile(filename.c_str());
- if (doc)
- {
- xmlNodePtr root, tmp;
- root = xmlDocGetRootElement(doc);
- if (xmlStrcmp(root->name, (const xmlChar*)"record"))
- {
- xmlFreeDoc(doc);
- xmlMutexUnlock(xmlmutex);
- return false;
- }
- record = atoi((const char*)xmlGetProp(root, (const xmlChar *)"record"));
- xmlFreeDoc(doc);
- xmlMutexUnlock(xmlmutex);
- return true;
- }
- xmlMutexUnlock(xmlmutex);
- return false;
- }
- bool Game::saveRecord()
- {
- std::string filename = g_config.getGlobalString("datadir") + "record.xml";
- xmlDocPtr doc;
- xmlNodePtr root, tmp;
- xmlMutexLock(xmlmutex);
- time_t time = std::time(NULL);
- doc = xmlNewDoc((const xmlChar*)"1.0");
- doc->children = xmlNewDocNode(doc, NULL, (const xmlChar*)"record", NULL);
- root = doc->children;
- std::stringstream sb;
- sb << record; xmlSetProp(root, (const xmlChar*) "record", (const xmlChar*)sb.str().c_str()); sb.str("");
- sb << time; xmlSetProp(root, (const xmlChar*) "time", (const xmlChar*)sb.str().c_str()); sb.str("");
- xmlSaveFile(filename.c_str(), doc);
- xmlFreeDoc(doc);
- xmlMutexUnlock(xmlmutex);
- return true;
- }
- // ANIMATED TEXT WHEN ADVANCE
- void Game::sendAnimatedTextExt(const Position pos,int32_t aniColor,const std::string &text)
- {
- SpectatorVec list;
- SpectatorVec::iterator it;
- getSpectators(Range(pos), list);
- for(it = list.begin(); it != list.end(); ++it){
- Player* spec = dynamic_cast<Player*>(*it);
- if(spec)
- spec->sendAnimatedText(pos, aniColor, text);
- }
- }
- // CREATUREBYPOSITION
- Creature* Game::getCreatureByPosition(int32_t x, int32_t y, int32_t z)
- {
- for(AutoList<Creature>::listiterator it = listCreature.list.begin(); it != listCreature.list.end(); ++it){
- if(it->second->pos.x == x && it->second->pos.y == y && it->second->pos.z == z)
- return it->second;
- }
- return NULL;
- }
- // CREATE CONDITION
- void Game::CreateCondition(Creature* creature, Creature* target, unsigned char animationColor, unsigned char damageEffect, unsigned char hitEffect, attacktype_t attackType, bool offensive, int32_t maxDamage, int32_t minDamage, long ticks, long count)
- {
- uint32_t targetID;
- if(target)
- targetID = target->getID();
- else
- targetID = 0;
- MagicEffectTargetCreatureCondition magicCondition = MagicEffectTargetCreatureCondition(targetID);
- magicCondition.animationColor = animationColor;
- magicCondition.damageEffect = damageEffect;
- magicCondition.hitEffect = hitEffect;
- magicCondition.attackType = attackType;
- magicCondition.maxDamage = maxDamage;
- magicCondition.minDamage = minDamage;
- magicCondition.offensive = offensive;
- CreatureCondition condition = CreatureCondition(ticks, count, magicCondition);
- creature->addCondition(condition, true);
- Player *player = dynamic_cast<Player*>(creature);
- if(player)
- player->sendIcons();
- }
- // Fields loaded from map - The Chaos
- void Game::doFieldDamage(Creature* creature, unsigned char animationColor, unsigned char damageEffect,
- unsigned char hitEffect, attacktype_t attackType, bool offensive, int32_t damage)
- {
- MagicEffectClass cd;
- cd.animationColor = animationColor;
- cd.damageEffect = damageEffect;
- cd.hitEffect = hitEffect;
- cd.attackType = attackType;
- cd.offensive = offensive;
- Player* itsHim = dynamic_cast<Player*>(getCreatureByID(creature->getID()));
- if(itsHim){ //Since that was causing damage/2 against player, here its my solution =)
- cd.maxDamage = damage*2;
- cd.minDamage = damage*2;
- }
- else{
- cd.maxDamage = damage;
- cd.minDamage = damage;
- }
- creatureMakeMagic(NULL, creature->pos, &cd);
- }
- void Game::updateTile(const Position& pos)
- {
- SpectatorVec list;
- SpectatorVec::iterator i;
- getSpectators(Range(pos), list);
- for(i = list.begin(); i != list.end(); ++i)
- (*i)->onTileUpdated(pos);
- }
- void Game::banPlayer(Player *player, std::string reason, std::string action, std::string comment, bool IPban)
- {
- int32_t bantime = 0;
- if(player){
- if(comment=="deletion")
- player->deleted = 1; // make player deleted
- else
- bantime = atoi(comment.c_str()) * 86400; // else make players banned for "comment" days (86400 = 1 day)
- if(player->finalwarning == 1 || player->times == 4)
- player->deleted = 1; // if player was already warned let delete thy char
- if(action=="AccountBan+FinalWarning" || player->times == 3)
- player->finalwarning = 1; // if player has warned set variable
- if(reason=="Excessive unjustifed player killing")
- bantime = g_config.getGlobalNumber("pkbandays",3) * 86400; // baannnnn pekaayssss (from config.lua)
- player->banned = 1;
- player->times++;
- player->comment = comment;
- player->reason = reason;
- player->action = action;
- player->banstart = std::time(NULL);
- player->banend = player->banstart + bantime;
- time_t endBan = player->banend;
- player->banrealtime = ctime(&endBan); // this variable stores REAL ban date in string, so you wont see 11105220952 in accmaker ;)
- if(IPban){
- std::pair<uint32_t, uint32_t> IpNetMask;
- IpNetMask.first = player->lastip;
- IpNetMask.second = 0xFFFFFFFF;
- if(IpNetMask.first > 0)
- bannedIPs.push_back(IpNetMask);
- }
- std::stringstream ban;
- ban << "You just have been banned for " << reason << "!";
- player->sendTextMessage(MSG_INFO, ban.str().c_str());
- player->kickPlayer();
- }
- }
- #ifdef REX_MUTED
- #endif //REX_MUTED
- #ifdef HUCZU_FIX
- bool Game::loadCities(Player* player, std::string name)
- {
- xmlDocPtr doc;
- std::string file = "data/miasta.xml";
- doc = xmlParseFile(file.c_str());
- if(doc){
- xmlNodePtr root, miasto;
- root = xmlDocGetRootElement(doc);
- if(xmlStrcmp(root->name, (const xmlChar*)"miasta")) {
- xmlFreeDoc(doc);
- return -1;
- }
- miasto = root->children;
- while(miasto){
- if(strcmp((char*) miasto->name, "miasto")==0){
- std::string nameIN = (const char*)xmlGetProp(miasto, (const xmlChar *) "nazwa");
- int32_t x = atoi((const char*)xmlGetProp(miasto, (const xmlChar *) "x"));
- int32_t y = atoi((const char*)xmlGetProp(miasto, (const xmlChar *) "y"));
- int32_t z = atoi((const char*)xmlGetProp(miasto, (const xmlChar *) "z"));
- Position pos(x,y,z);
- if(nameIN == name)
- teleport(player,pos);
- }
- miasto = miasto->next;
- }
- xmlFreeDoc(doc);
- return 0;
- }
- return -1;
- }
- #endif //HUCZU_FIX
- // RAID SYSTEM
- bool Game::loadRaid(std::string name)
- {
- xmlDocPtr doc;
- std::cout << "Executing raid named " << name << "." << std::endl;
- std::string file = "data/world/raids.xml";
- doc = xmlParseFile(file.c_str());
- if(doc){
- xmlNodePtr root, raid, command;
- root = xmlDocGetRootElement(doc);
- if(xmlStrcmp(root->name, (const xmlChar*)"raids")) {
- xmlFreeDoc(doc);
- return -1;
- }
- raid = root->children;
- while(raid){
- if(strcmp((char*) raid->name, "raid")==0){
- std::string nameIN = (const char*)xmlGetProp(raid, (const xmlChar *) "name");
- if(nameIN == name) {
- std::string messageIN = (const char*)xmlGetProp(raid, (const xmlChar *) "message");
- std::string brodcasterIN = (const char*)xmlGetProp(raid, (const xmlChar *) "brodcaster");
- Creature *c = getCreatureByName(brodcasterIN);
- if(c) {
- creatureBroadcastMessage(c,messageIN);
- } else {
- std::cout << "Could not send news msg! Brodcaster does not exist" << std::endl;
- }
- if(nameIN == name) {
- command = raid->children;
- while(command) {
- if(strcmp((char*) command->name, "monster")==0){
- std::string monstername = (const char*)xmlGetProp(command, (const xmlChar *) "name");
- int32_t x = atoi((const char*)xmlGetProp(command, (const xmlChar *) "x"));
- int32_t y = atoi((const char*)xmlGetProp(command, (const xmlChar *) "y"));
- int32_t z = atoi((const char*)xmlGetProp(command, (const xmlChar *) "z"));
- int32_t loot = atoi((const char*)xmlGetProp(command, (const xmlChar *) "lootid")); //Not yet implemented!
- int32_t chance = atoi((const char*)xmlGetProp(command, (const xmlChar *) "chance")); //Not yet implemented!
- placeRaidMonster(monstername, x, y, z);
- }
- if(strcmp((char*) command->name, "area")==0){
- std::string monstername = (const char*)xmlGetProp(command, (const xmlChar *) "monster");
- int32_t count = atoi((const char*)xmlGetProp(command, (const xmlChar *) "count"));
- int32_t xf = atoi((const char*)xmlGetProp(command, (const xmlChar *) "posxfrom"));
- int32_t yf = atoi((const char*)xmlGetProp(command, (const xmlChar *) "posyfrom"));
- int32_t zf = atoi((const char*)xmlGetProp(command, (const xmlChar *) "poszfrom"));
- int32_t xt = atoi((const char*)xmlGetProp(command, (const xmlChar *) "posxto"));
- int32_t yt = atoi((const char*)xmlGetProp(command, (const xmlChar *) "posyto"));
- int32_t zt = atoi((const char*)xmlGetProp(command, (const xmlChar *) "poszto"));
- int32_t i = 0;
- int32_t tries = 0;
- while (i<=count && tries<=(count*10)) {
- int32_t x = (int32_t)((xt-xf) * (rand()/(RAND_MAX+1.0)) + xf);
- int32_t y = (int32_t)((yt-yf) * (rand()/(RAND_MAX+1.0)) + yf);
- int32_t z = (int32_t)((zt-zf) * (rand()/(RAND_MAX+1.0)) + zf);
- Tile* t = map->getTile(x,y,z);
- if(t && t->isPz() == false) {
- placeRaidMonster(monstername, x, y, z);
- i++;
- }
- tries++;
- }
- }
- if(strcmp((char*) command->name, "message")==0){
- std::string msg = (const char*)xmlGetProp(command, (const xmlChar *) "text");
- std::string brodcaster = (const char*)xmlGetProp(command, (const xmlChar *) "brodcaster");
- Creature *c = getCreatureByName(brodcaster);
- if(c) {
- creatureBroadcastMessage(c,msg);
- } else {
- std::cout << "Could not send news msg! Brodcaster does not exist." << std::endl;
- }
- }
- command = command->next;
- }
- }
- }
- }
- raid = raid->next;
- }
- xmlFreeDoc(doc);
- return 0;
- }
- return -1;
- }
- bool Game::placeRaidMonster(std::string name, int32_t x, int32_t y, int32_t z)
- {
- Monster* monster = Monster::createMonster(name, this);
- //For new CVS use the following line:
- //Monster* monster = Monster::createMonster(name, this);
- if(!monster){
- delete monster;
- return false;
- }
- Position pos;
- pos.x = x;
- pos.y = y;
- pos.z = z;
- // Place the monster
- if(!placeCreature(pos, monster)) {
- delete monster;
- return false;
- }
- return true;
- }
- void Game::spectatorText(Position pos, unsigned char color, std::string text)
- {
- SpectatorVec list;
- SpectatorVec::iterator it;
- getSpectators(Range(pos, true), list);
- for(it = list.begin(); it != list.end(); ++it) {
- if(Player* p = dynamic_cast<Player*>(*it)) {
- p->sendAnimatedText(pos, color, text);
- }
- }
- }
- #ifdef DT_PREMMY
- bool Game::countPremmy(Player *player)
- {
- Account acc = IOAccount::instance()->loadAccount(player->accountNumber);
- int32_t cont;
- if(acc.lastsaveday == 0)
- cont = 0;
- else
- cont = acc.lastsaveday2 - acc.lastsaveday;
- //std::cout << "Last Login in Acc: " << acc.lastsaveday << " - Today: " << acc.lastsaveday2 << " - Days removed from acc: " << cont << std::endl;
- if(cont < 0){
- cont =+ 365; //dodajemy caly rok
- }
- if((acc.premDays - cont) <= 0)
- {
- acc.premDays = 0;
- player->premmium = false;
- }
- else
- {
- acc.premDays = acc.premDays - cont;
- player->premmium = true;
- }
- if(g_config.FREE_PREMMY)
- player->premmium = true;
- IOAccount::instance()->saveAccount(acc);
- }
- #endif //DT_PREMMY
- #ifdef ZS_SWORDS
- void Game::useSword(Creature *creature, Creature *attackedCreature, int32_t swordid)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::useSword()");
- Player *player = dynamic_cast<Player*>(creature);
- if(!player || !attackedCreature || player->pos.z != attackedCreature->pos.z)
- return;
- int32_t dist, mana = 0;
- MagicEffectAreaNoExhaustionClass runeAreaSpell;
- runeAreaSpell.drawblood = true;
- runeAreaSpell.offensive = true;
- runeAreaSpell.direction = 1;
- // P O I S O N //
- if (swordid == ITEM_P_MB && player->vocation == VOCATION_KNIGHT &&
- player->mana >= g_config.MANA_P_MB && player->getLevel() >= 220)
- {
- dist = g_config.RANGE_P_MB;
- if (abs(player->pos.x - attackedCreature->pos.x) > dist ||
- abs(player->pos.y - attackedCreature->pos.y) > dist)
- return;
- runeAreaSpell.attackType = ATTACK_SWORD;
- runeAreaSpell.animationEffect = NM_ANI_FLYPOISONFIELD;
- runeAreaSpell.hitEffect = NM_ME_POISEN_RINGS;
- runeAreaSpell.areaEffect = NM_ME_POISEN_RINGS;
- runeAreaSpell.animationColor = 0x60;
- runeAreaSpell.minDamage = 10;
- runeAreaSpell.maxDamage = 60;
- mana = g_config.MANA_P_MB;
- }
- else if (swordid == ITEM_P_MAUL && player->vocation == VOCATION_KNIGHT &&
- player->mana >= g_config.MANA_P_MAUL && player->getLevel() >= 220)
- {
- dist = g_config.RANGE_P_MAUL;
- if (abs(player->pos.x - attackedCreature->pos.x) > dist ||
- abs(player->pos.y - attackedCreature->pos.y) > dist)
- return;
- runeAreaSpell.attackType = ATTACK_SWORD;
- runeAreaSpell.animationEffect = NM_ANI_FLYPOISONFIELD;
- runeAreaSpell.hitEffect = NM_ME_POISEN_RINGS;
- runeAreaSpell.areaEffect = NM_ME_POISEN_RINGS;
- runeAreaSpell.animationColor = 0x60;
- runeAreaSpell.minDamage = 10;
- runeAreaSpell.maxDamage = 60;
- mana = g_config.MANA_P_MAUL;
- }
- else if (swordid == ITEM_P_HEAD && player->vocation == VOCATION_KNIGHT &&
- player->mana >= g_config.MANA_P_HEAD && player->getLevel() >= 220)
- {
- dist = g_config.RANGE_P_HEAD;
- if (abs(player->pos.x - attackedCreature->pos.x) > dist ||
- abs(player->pos.y - attackedCreature->pos.y) > dist)
- return;
- runeAreaSpell.attackType = ATTACK_SWORD;
- runeAreaSpell.animationEffect = NM_ANI_FLYPOISONFIELD;
- runeAreaSpell.hitEffect = NM_ME_POISEN_RINGS;
- runeAreaSpell.areaEffect = NM_ME_POISEN_RINGS;
- runeAreaSpell.animationColor = 0x60;
- runeAreaSpell.minDamage = 10;
- runeAreaSpell.maxDamage = 60;
- mana = g_config.MANA_P_HEAD;
- }
- // F I R E //
- else if (swordid == ITEM_F_MB && player->vocation == VOCATION_KNIGHT &&
- player->mana >= g_config.MANA_F_MB && player->getLevel() >= 320)
- {
- dist = g_config.RANGE_F_MB;
- if (abs(player->pos.x - attackedCreature->pos.x) > dist ||
- abs(player->pos.y - attackedCreature->pos.y) > dist)
- return;
- runeAreaSpell.attackType = ATTACK_SWORD;
- runeAreaSpell.animationEffect = NM_ANI_FIRE;
- runeAreaSpell.hitEffect = NM_ME_EXPLOSION_AREA;
- runeAreaSpell.areaEffect = NM_ME_EXPLOSION_AREA;
- runeAreaSpell.animationColor = 0xC6;
- runeAreaSpell.minDamage = 60;
- runeAreaSpell.maxDamage = 110;
- mana = g_config.MANA_F_MB;
- }
- else if (swordid == ITEM_F_MAUL && player->vocation == VOCATION_KNIGHT &&
- player->mana >= g_config.MANA_F_MAUL && player->getLevel() >= 320)
- {
- dist = g_config.RANGE_F_MAUL;
- if (abs(player->pos.x - attackedCreature->pos.x) > dist ||
- abs(player->pos.y - attackedCreature->pos.y) > dist)
- return;
- runeAreaSpell.attackType = ATTACK_SWORD;
- runeAreaSpell.animationEffect = NM_ANI_FIRE;
- runeAreaSpell.hitEffect = NM_ME_EXPLOSION_AREA;
- runeAreaSpell.areaEffect = NM_ME_EXPLOSION_AREA;
- runeAreaSpell.animationColor = 0xC6;
- runeAreaSpell.minDamage = 60;
- runeAreaSpell.maxDamage = 110;
- mana = g_config.MANA_F_MAUL;
- }
- else if (swordid == ITEM_F_HEAD && player->vocation == VOCATION_KNIGHT &&
- player->mana >= g_config.MANA_F_HEAD && player->getLevel() >= 320)
- {
- dist = g_config.RANGE_F_HEAD;
- if (abs(player->pos.x - attackedCreature->pos.x) > dist ||
- abs(player->pos.y - attackedCreature->pos.y) > dist)
- return;
- runeAreaSpell.attackType = ATTACK_SWORD;
- runeAreaSpell.animationEffect = NM_ANI_FIRE;
- runeAreaSpell.hitEffect = NM_ME_EXPLOSION_AREA;
- runeAreaSpell.areaEffect = NM_ME_EXPLOSION_AREA;
- runeAreaSpell.animationColor = 0xC6;
- runeAreaSpell.minDamage = 60;
- runeAreaSpell.maxDamage = 110;
- mana = g_config.MANA_F_HEAD;
- }
- // E N E R G Y //
- else if (swordid == ITEM_E_MB && player->vocation == VOCATION_KNIGHT &&
- player->mana >= g_config.MANA_E_MB && player->getLevel() >= 420)
- {
- dist = g_config.RANGE_E_MB;
- if (abs(player->pos.x - attackedCreature->pos.x) > dist ||
- abs(player->pos.y - attackedCreature->pos.y) > dist)
- return;
- runeAreaSpell.attackType = ATTACK_SWORD;
- runeAreaSpell.animationEffect = NM_ANI_SUDDENDEATH;
- runeAreaSpell.hitEffect = NM_ME_MORT_AREA;
- runeAreaSpell.areaEffect = NM_ME_MORT_AREA;
- runeAreaSpell.animationColor = 0xB9;
- runeAreaSpell.minDamage = 110;
- runeAreaSpell.maxDamage = 160;
- mana = g_config.MANA_E_MB;
- }
- else if (swordid == ITEM_E_MAUL && player->vocation == VOCATION_KNIGHT &&
- player->mana >= g_config.MANA_E_MAUL && player->getLevel() >= 420)
- {
- dist = g_config.RANGE_E_MAUL;
- if (abs(player->pos.x - attackedCreature->pos.x) > dist ||
- abs(player->pos.y - attackedCreature->pos.y) > dist)
- return;
- runeAreaSpell.attackType = ATTACK_SWORD;
- runeAreaSpell.animationEffect = NM_ANI_SUDDENDEATH;
- runeAreaSpell.hitEffect = NM_ME_MORT_AREA;
- runeAreaSpell.areaEffect = NM_ME_MORT_AREA;
- runeAreaSpell.animationColor = 0xB9;
- runeAreaSpell.minDamage = 110;
- runeAreaSpell.maxDamage = 160;
- mana = g_config.MANA_E_MAUL;
- }
- else if (swordid == ITEM_E_HEAD && player->vocation == VOCATION_KNIGHT &&
- player->mana >= g_config.MANA_E_HEAD && player->getLevel() >= 420)
- {
- dist = g_config.RANGE_E_HEAD;
- if (abs(player->pos.x - attackedCreature->pos.x) > dist ||
- abs(player->pos.y - attackedCreature->pos.y) > dist)
- return;
- runeAreaSpell.attackType = ATTACK_SWORD;
- runeAreaSpell.animationEffect = NM_ANI_SUDDENDEATH;
- runeAreaSpell.hitEffect = NM_ME_MORT_AREA;
- runeAreaSpell.areaEffect = NM_ME_MORT_AREA;
- runeAreaSpell.animationColor = 0xB9;
- runeAreaSpell.minDamage = 110;
- runeAreaSpell.maxDamage = 160;
- mana = g_config.MANA_E_HEAD;
- }
- // P L A Y E R W E A P O N S //
- else if (swordid == ITEM_HAIK_AXE && player->vocation == VOCATION_KNIGHT &&
- player->mana >= g_config.MANA_HAIK_AXE && player->getLevel() >= 500)
- {
- dist = g_config.RANGE_HAIK_AXE;
- if (abs(player->pos.x - attackedCreature->pos.x) > dist ||
- abs(player->pos.y - attackedCreature->pos.y) > dist)
- return;
- runeAreaSpell.attackType = ATTACK_SWORD;
- runeAreaSpell.animationEffect = NM_ANI_STAR;
- runeAreaSpell.hitEffect = NM_ME_STAR;
- runeAreaSpell.areaEffect = NM_ME_STAR;
- runeAreaSpell.animationColor = 0xD2;
- runeAreaSpell.minDamage = 300;
- runeAreaSpell.maxDamage = 350;
- mana = g_config.MANA_HAIK_AXE;
- }
- else if (swordid == ITEM_BLETKA_AXE && player->vocation == VOCATION_KNIGHT &&
- player->mana >= g_config.MANA_BLETKA_AXE)
- {
- dist = g_config.RANGE_BLETKA_AXE;
- if (abs(player->pos.x - attackedCreature->pos.x) > dist ||
- abs(player->pos.y - attackedCreature->pos.y) > dist)
- return;
- runeAreaSpell.attackType = ATTACK_SWORD;
- runeAreaSpell.animationEffect = NM_ANI_STAR;
- runeAreaSpell.hitEffect = NM_ME_STAR;
- runeAreaSpell.areaEffect = NM_ME_STAR;
- runeAreaSpell.animationColor = 0xD2;
- runeAreaSpell.minDamage = 150;
- runeAreaSpell.maxDamage = 200;
- mana = g_config.MANA_BLETKA_AXE;
- }
- // K U N I E C //
- if (mana > 0)
- {
- std::vector<unsigned char> col;
- col.push_back(0);
- col.push_back(0);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- col.push_back(0);
- col.push_back(1);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- col.push_back(0);
- col.push_back(0);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- creatureThrowRune(player, attackedCreature->pos, runeAreaSpell);
- player->addManaSpent(mana);
- player->mana -= mana;
- }
- }
- #endif //ZS_SWORDS
- #ifdef YUR_READABLES
- bool Game::LoadReadables()
- {
- std::string file = g_config.getGlobalString("datadir") + "readables.xml";
- xmlDocPtr doc;
- xmlMutexLock(xmlmutex);
- doc = xmlParseFile(file.c_str());
- if (!doc)
- return false;
- xmlNodePtr root, readableNode;
- root = xmlDocGetRootElement(doc);
- if (xmlStrcmp(root->name, (const xmlChar*)"readables"))
- {
- xmlFreeDoc(doc);
- xmlMutexUnlock(xmlmutex);
- return false;
- }
- readableNode = root->children;
- while (readableNode)
- {
- if (strcmp((char*) readableNode->name, "readable") == 0)
- {
- int32_t x = atoi((const char*)xmlGetProp(readableNode, (const xmlChar *) "x"));
- int32_t y = atoi((const char*)xmlGetProp(readableNode, (const xmlChar *) "y"));
- int32_t z = atoi((const char*)xmlGetProp(readableNode, (const xmlChar *) "z"));
- std::string text = (const char*)xmlGetProp(readableNode, (const xmlChar *) "text");
- for (size_t i = 0; i < text.length()-1; i++) // make real newlines
- if (text.at(i) == '\\' && text.at(i+1) == 'n')
- {
- text[i] = ' ';
- text[i+1] = '\n';
- }
- Tile* tile = getTile(x, y, z);
- if (tile)
- {
- Thing* thing = tile->getTopThing();
- Item* item = thing? dynamic_cast<Item*>(thing) : NULL;
- if (item)
- item->setReadable(text);
- else
- {
- std::cout << "\nTop thing at " << Position(x,y,z) << " is not an item!";
- return false;
- }
- }
- else
- {
- std::cout << "\nTile " << Position(x,y,z) << " is not valid!";
- return false;
- }
- }
- readableNode = readableNode->next;
- }
- xmlFreeDoc(doc);
- xmlMutexUnlock(xmlmutex);
- return true;
- }
- #endif //YUR_READABLES
- void Game::Blasting(Creature* c, Creature *attackedCreature, const Position& pos)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::Blasting()");
- Player* player = dynamic_cast<Player*>(c);
- unsigned short dist = 6;
- unsigned short REQ_MANA = 200;
- uint32_t poziom = player->level;
- uint32_t magpoziom = player->maglevel;
- if (abs(player->pos.x - attackedCreature->pos.x) > dist ||
- abs(player->pos.y - attackedCreature->pos.y) > dist)
- return;
- MagicEffectAreaNoExhaustionClass runeAreaSpell;
- runeAreaSpell.drawblood = true;
- runeAreaSpell.offensive = true;
- runeAreaSpell.direction = 1;
- runeAreaSpell.attackType = ATTACK_PHYSICAL;
- runeAreaSpell.animationEffect = NM_ANI_REMOTE;
- runeAreaSpell.hitEffect = NM_ME_EXPLO;
- runeAreaSpell.areaEffect = NM_ME_EXPLO;
- runeAreaSpell.animationColor = 0x60;
- if((poziom * 2 + magpoziom * 3) >= 100){
- runeAreaSpell.minDamage = int32_t((poziom * 2 + magpoziom * 3) * 1.6 );
- runeAreaSpell.maxDamage = int32_t((poziom * 2 + magpoziom * 3) * 1.9 );
- }else{
- runeAreaSpell.minDamage = int32_t(100 * 1.5 );
- runeAreaSpell.maxDamage = int32_t(100 * 1.8 );
- }
- std::vector<unsigned char> col;
- col.push_back(0);
- col.push_back(0);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- col.push_back(0);
- col.push_back(1);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- col.clear();
- col.push_back(0);
- col.push_back(0);
- col.push_back(0);
- runeAreaSpell.areaVec.push_back(col);
- creatureThrowRune(c, pos, runeAreaSpell);
- player->flamTicks = 2*1000;
- if (player->access < g_config.ACCESS_PROTECT)
- {
- player->mana -= REQ_MANA;
- player->addManaSpent(REQ_MANA);
- }
- }
- #ifdef KOSZ
- bool Game::canDelete(Player *player, unsigned short itemid, Position toPos, Position fromPos, int32_t from_stack, unsigned char count)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::canDelete()");
- if(itemid == 99 || (itemid >= 4329 && itemid <= 4555))
- return false;
- else if(fromPos.x != 0xFFFF && ((abs(player->pos.x - fromPos.x) > 1) || (abs(player->pos.y - fromPos.y) > 1) || (player->pos.z != fromPos.z)))
- return false;
- else if(map->canThrowObjectTo(player->pos, toPos, BLOCK_PROJECTILE) != RET_NOERROR)
- return false;
- else if(toPos.x == 0xFFFF)
- return false;
- else if((player->access < g_config.ACCESS_REMOTE) &&
- ((abs(player->pos.x - fromPos.x) > 1) || (abs(player->pos.y - fromPos.y) > 1) || (player->pos.z != fromPos.z)))
- return false;
- Item* trash = dynamic_cast<Item*>(getThing(fromPos, from_stack, player));
- if(trash){
- trash->pos = fromPos;
- if((abs(player->pos.x - toPos.x) > trash->throwRange) || (abs(player->pos.y - toPos.y) > trash->throwRange)) {
- return false;
- }
- Tile *toTile = map->getTile(toPos);
- if(toTile){
- if((toTile->ground->getID() >= GROUND_WATER1 && toTile->ground->getID() <= GROUND_WATER4) || (toTile->ground->getID() >= GROUND_WATER5 && toTile->ground->getID() <= GROUND_WATER16) || (toTile->ground->getID() == GROUND_WATER17) || (toTile->ground->getID() >= GROUND_WATER18 && toTile->ground->getID() <= GROUND_WATER35) || (toTile->ground->getID() >= GROUND_WATER36 && toTile->ground->getID() <= GROUND_WATER38) || (toTile->ground->getID() >= GROUND_WATER39 && toTile->ground->getID() <= GROUND_WATER44) || (toTile->ground->getID() >= GROUND_LAVA1 && toTile->ground->getID() <= GROUND_SWAMP4) || (toTile->ground->getID() >= GROUND_BLACK_SWAMP1 && toTile->ground->getID() <= GROUND_BLACK_SWAMP4)){
- if(!trash->isNotMoveable() && trash->isBlocking())
- return false;
- else if(trashObjects(player, toTile, trash, toPos, fromPos, from_stack, count))
- return true;
- }
- Item *toItem = dynamic_cast<Item*>(toTile->getTopTopItem());
- if(toItem && toItem->getID() == ITEM_DUSTBIN){
- if(!trash->isNotMoveable() && trash->isBlocking())
- return false;
- else if(trashObjects(player, toTile, trash, toPos, fromPos, from_stack, count))
- return true;
- }
- }
- }
- return false;
- }
- bool Game::trashObjects(Player *player, Tile *toTile, Item *trash, Position toPos, Position fromPos, int32_t from_stack, unsigned char count)
- {
- //OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::trashObjects()");
- if(!player || !toTile || !trash || !from_stack || !count){
- return false;}
- if(toTile){
- switch(toTile->ground->getID()){
- case GROUND_WATER1:
- case GROUND_WATER2:
- case GROUND_WATER3:
- case GROUND_WATER4:
- case GROUND_WATER5:
- case GROUND_WATER6:
- case GROUND_WATER7:
- case GROUND_WATER8:
- case GROUND_WATER9:
- case GROUND_WATER10:
- case GROUND_WATER11:
- case GROUND_WATER12:
- case GROUND_WATER13:
- case GROUND_WATER14:
- case GROUND_WATER15:
- case GROUND_WATER16:
- case GROUND_WATER17:
- case GROUND_WATER18:
- case GROUND_WATER19:
- case GROUND_WATER20:
- case GROUND_WATER21:
- case GROUND_WATER22:
- case GROUND_WATER23:
- case GROUND_WATER24:
- case GROUND_WATER25:
- case GROUND_WATER26:
- case GROUND_WATER27:
- case GROUND_WATER28:
- case GROUND_WATER29:
- case GROUND_WATER30:
- case GROUND_WATER31:
- case GROUND_WATER32:
- case GROUND_WATER33:
- case GROUND_WATER34:
- case GROUND_WATER35:
- case GROUND_WATER36:
- case GROUND_WATER37:
- case GROUND_WATER38:
- case GROUND_WATER39:
- case GROUND_WATER40:
- case GROUND_WATER41:
- case GROUND_WATER42:
- case GROUND_WATER43:
- case GROUND_WATER44:
- spectatorEffect(toPos, NM_ME_LOOSE_ENERGY);
- if(trashItems(player, trash, fromPos, from_stack, count))
- return true;
- break;
- case GROUND_LAVA1:
- case GROUND_LAVA2:
- case GROUND_LAVA3:
- case GROUND_LAVA4:
- spectatorEffect(toPos, NM_ME_HITBY_FIRE);
- if(trashItems(player, trash, fromPos, from_stack, count))
- return true;
- break;
- case GROUND_SWAMP1:
- case GROUND_SWAMP2:
- case GROUND_SWAMP3:
- case GROUND_SWAMP4:
- spectatorEffect(toPos, NM_ME_POISEN_RINGS);
- if(trashItems(player, trash, fromPos, from_stack, count))
- return true;
- break;
- case GROUND_BLACK_SWAMP1:
- case GROUND_BLACK_SWAMP2:
- case GROUND_BLACK_SWAMP3:
- case GROUND_BLACK_SWAMP4:
- spectatorEffect(toPos, NM_ME_MORT_AREA);
- if(trashItems(player, trash, fromPos, from_stack, count))
- return true;
- break;
- }
- }
- return false;
- }
- bool Game::trashItems(Player *player, Item *trash, Position fromPos, int32_t from_stack, unsigned char count)
- {
- //OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::trashItems()");
- if(!trash){return false;}
- if(trash->getID() == 99 || (trash->getID() >= 4329 && trash->getID() <= 4555))
- return false;
- else if(fromPos.x != 0xFFFF && ((abs(player->pos.x - fromPos.x) > 1) || (abs(player->pos.y - fromPos.y) > 1) || (player->pos.z != fromPos.z)))
- return false;
- else if((player->access < g_config.ACCESS_REMOTE) &&
- ((abs(player->pos.x - fromPos.x) > 1) || (abs(player->pos.y - fromPos.y) > 1) || (player->pos.z != fromPos.z)))
- return false;
- if(trash && player){
- if(trash->isStackable()){
- if(trash->getItemCountOrSubtype() > count){
- trash->setItemCountOrSubtype(trash->getItemCountOrSubtype() - count);
- sendUpdateThing(player,fromPos,trash,from_stack);
- player->updateInventoryWeigth();
- return true;
- }
- else{
- if(removeThing(player, fromPos, trash)){
- player->updateInventoryWeigth();
- return true;
- }
- }
- }
- else{
- if(removeThing(player, fromPos, trash)){
- player->updateInventoryWeigth();
- return true;
- }
- }
- }
- return false;
- }
- bool Game::canTeleportItem(Player *player, unsigned short itemid, Position toPos, Position fromPos, int32_t from_stack, unsigned char count)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::canTeleportItem()");
- if(itemid == 99 || (itemid >= 4329 && itemid <= 4555))
- return false;
- else if(fromPos.x != 0xFFFF && ((abs(player->pos.x - fromPos.x) > 1) || (abs(player->pos.y - fromPos.y) > 1) || (player->pos.z != fromPos.z)))
- return false;
- else if(map->canThrowObjectTo(player->pos, toPos, BLOCK_PROJECTILE) != RET_NOERROR)
- return false;
- else if(toPos.x == 0xFFFF)
- return false;
- else if(!checkChangeFloor(map->getTile(toPos), getTile(toPos.x,toPos.y,toPos.z+1)))
- return false;
- else if((player->access < g_config.ACCESS_REMOTE) &&
- ((abs(player->pos.x - fromPos.x) > 1) || (abs(player->pos.y - fromPos.y) > 1) || (player->pos.z != fromPos.z)))
- return false;
- Item* tpItem = dynamic_cast<Item*>(getThing(fromPos, from_stack, player));
- if(tpItem){
- tpItem->pos = fromPos;
- if((abs(player->pos.x - toPos.x) > tpItem->throwRange) || (abs(player->pos.y - toPos.y) > tpItem->throwRange)) {
- return false;
- }
- if(tpItem->isStackable()){
- if(tpItem->getItemCountOrSubtype() > count){
- tpItem->setItemCountOrSubtype(tpItem->getItemCountOrSubtype() - count);
- Item *newitem = Item::CreateItem(tpItem->getID(), count);
- addThing(player,getTeleportPos(toPos),newitem);
- sendUpdateThing(player,fromPos,tpItem,from_stack);
- player->updateInventoryWeigth();
- return true;
- }
- else{
- if(removeThing(player, fromPos, tpItem)){
- addThing(player,getTeleportPos(toPos),tpItem);
- player->updateInventoryWeigth();
- return true;
- }
- }
- }
- else{
- if(removeThing(player, fromPos, tpItem)){
- addThing(player,getTeleportPos(toPos),tpItem);
- player->updateInventoryWeigth();
- return true;
- }
- }
- }
- return false;
- }
- void Game::spectatorEffect(Position pos, unsigned char type)
- {
- SpectatorVec list;
- SpectatorVec::iterator it;
- getSpectators(Range(pos, true), list);
- for(it = list.begin(); it != list.end(); ++it) {
- if(Player* p = dynamic_cast<Player*>(*it)) {
- p->sendMagicEffect(pos, type);
- }
- }
- }
- bool Game::checkChangeFloor(Tile *toTile, Tile* downTile)
- {
- if(toTile->ground && toTile->ground->floorChangeDown())
- {
- if(downTile){
- if(downTile->floorChange(NORTH) && downTile->floorChange(EAST)){
- return true;
- }
- else if(downTile->floorChange(NORTH) && downTile->floorChange(WEST)){
- return true;
- }
- else if(downTile->floorChange(SOUTH) && downTile->floorChange(EAST)){
- return true;
- }
- else if(downTile->floorChange(SOUTH) && downTile->floorChange(WEST)){
- return true;
- }
- else if(downTile->floorChange(NORTH)){
- return true;
- }
- else if(downTile->floorChange(SOUTH)){
- return true;
- }
- else if(downTile->floorChange(EAST)){
- return true;
- }
- else if(downTile->floorChange(WEST)){
- return true;
- }
- else if(Item::items[toTile->ground->getID()].floorChangeDown){
- return true;
- }
- else {
- return true;
- }
- }
- }
- else if(toTile->floorChange(NORTH) && toTile->floorChange(EAST)){
- return true;
- }
- else if(toTile->floorChange(NORTH) && toTile->floorChange(WEST)){
- return true;
- }
- else if(toTile->floorChange(SOUTH) && toTile->floorChange(EAST)){
- return true;
- }
- else if(toTile->floorChange(SOUTH) && toTile->floorChange(WEST)){
- return true;
- }
- else if(toTile->floorChange(NORTH)){
- return true;
- }
- else if(toTile->floorChange(SOUTH)){
- return true;
- }
- else if(toTile->floorChange(EAST)){
- return true;
- }
- else if(toTile->floorChange(WEST)){
- return true;
- }
- if(!toTile){
- if(!downTile)
- {
- return false;
- }
- else if(downTile->floorChange(NORTH) && downTile->floorChange(EAST)){
- return true;
- }
- else if(downTile->floorChange(NORTH) && downTile->floorChange(WEST)){
- return true;
- }
- else if(downTile->floorChange(SOUTH) && downTile->floorChange(EAST)){
- return true;
- }
- else if(downTile->floorChange(SOUTH) && downTile->floorChange(WEST)){
- return true;
- }
- else if(downTile->floorChange(NORTH)){
- return true;
- }
- else if(downTile->floorChange(SOUTH)){
- return true;
- }
- else if(downTile->floorChange(EAST)){
- return true;
- }
- else if(downTile->floorChange(WEST)){
- return true;
- }
- }
- return false;
- }
- Position Game::getTeleportPos(Position to)
- {
- Tile *toTile = map->getTile(to);
- if(toTile->ground && toTile->ground->floorChangeDown())
- {
- Tile* downTile = getTile(to.x, to.y, to.z+1);
- if(downTile){
- //diagonal begin
- if(downTile->floorChange(NORTH) && downTile->floorChange(EAST)){
- return Position(to.x-1, to.y+1, to.z+1);
- }
- else if(downTile->floorChange(NORTH) && downTile->floorChange(WEST)){
- return Position(to.x+1, to.y+1, to.z+1);
- }
- else if(downTile->floorChange(SOUTH) && downTile->floorChange(EAST)){
- return Position(to.x-1, to.y-1, to.z+1);
- }
- else if(downTile->floorChange(SOUTH) && downTile->floorChange(WEST)){
- return Position(to.x+1, to.y-1, to.z+1);
- }
- //diagonal end
- else if(downTile->floorChange(NORTH)){
- return Position(to.x, to.y+1, to.z+1);
- }
- else if(downTile->floorChange(SOUTH)){
- return Position(to.x, to.y-1, to.z+1);
- }
- else if(downTile->floorChange(EAST)){
- return Position(to.x-1, to.y, to.z+1);
- }
- else if(downTile->floorChange(WEST)){
- return Position(to.x+1, to.y, to.z+1);
- }
- //floor change down
- else if(Item::items[toTile->ground->getID()].floorChangeDown){
- return Position(to.x, to.y, to.z+1);
- }
- else {
- return Position(to.x, to.y, to.z+1);
- }
- }
- }
- //diagonal begin
- else if(toTile->floorChange(NORTH) && toTile->floorChange(EAST)){
- return Position(to.x+1, to.y-1, to.z-1);
- }
- else if(toTile->floorChange(NORTH) && toTile->floorChange(WEST)){
- return Position(to.x-1, to.y-1, to.z-1);
- }
- else if(toTile->floorChange(SOUTH) && toTile->floorChange(EAST)){
- return Position(to.x+1, to.y+1, to.z-1);
- }
- else if(toTile->floorChange(SOUTH) && toTile->floorChange(WEST)){
- return Position(to.x-1, to.y+1, to.z-1);
- }
- else if(toTile->floorChange(NORTH)){
- return Position(to.x, to.y-1, to.z-1);
- }
- else if(toTile->floorChange(SOUTH)){
- return Position(to.x, to.y+1, to.z-1);
- }
- else if(toTile->floorChange(EAST)){
- return Position(to.x+1, to.y, to.z-1);
- }
- else if(toTile->floorChange(WEST)){
- return Position(to.x-1, to.y, to.z-1);
- }
- if(!toTile){
- Tile* downTile = getTile(to.x, to.y, to.z+1);
- if(!downTile)
- {
- return Position(0,0,0);
- }
- else if(downTile->floorChange(NORTH) && downTile->floorChange(EAST)){
- return Position(to.x-2, to.y+2, to.z+1);
- }
- else if(downTile->floorChange(NORTH) && downTile->floorChange(WEST)){
- return Position(to.x+2, to.y+2, to.z+1);
- }
- else if(downTile->floorChange(SOUTH) && downTile->floorChange(EAST)){
- return Position(to.x-2, to.y-2, to.z+1);
- }
- else if(downTile->floorChange(SOUTH) && downTile->floorChange(WEST)){
- return Position(to.x+2, to.y-2, to.z+1);
- }
- else if(downTile->floorChange(NORTH)){
- return Position(to.x, to.y + 1, to.z+1);
- }
- else if(downTile->floorChange(SOUTH)){
- return Position(to.x, to.y - 1, to.z+1);
- }
- else if(downTile->floorChange(EAST)){
- return Position(to.x - 1, to.y, to.z+1);
- }
- else if(downTile->floorChange(WEST)){
- return Position(to.x + 1, to.y, to.z+1);
- }
- }
- }
- #endif //KOSZ
- void Game::globalMagicEffect(const Position pos, unsigned char type)
- {
- SpectatorVec list;
- SpectatorVec::iterator it;
- getSpectators(Range(pos), list);
- for(it = list.begin(); it != list.end(); ++it){
- Player* p = dynamic_cast<Player*>(*it);
- if(p)
- p->sendMagicEffect(pos, type);
- }
- }
- void Game::checkCreatureFollow(uint32_t id)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::checkCreatureFollow");
- Player *player = getPlayerByID(id);
- if(!player)
- return;
- if(!player->pathList.empty()) {
- Creature *followCreature = getCreatureByID(player->followCreature);
- if(followCreature == 0)
- return;
- if((std::abs(player->pos.x - followCreature->pos.x) > 7) ||
- (std::abs(player->pos.y - followCreature->pos.y) > 5) || (player->pos.z != followCreature->pos.z)){
- player->sendTextMessage(MSG_SMALLINFO, "Target lost.");
- player->eventCheckFollow = 0;
- player->followCreature = 0;
- playerSetAttackedCreature(player, 0);
- return;
- }
- if(followCreature && abs(followCreature->pos.x - player->pos.x) <= 1 && abs(followCreature->pos.y - player->pos.y) <= 1) player->pathList.clear();
- else {
- Position toPos = player->pathList.front();
- player->pathList.pop_front();
- player->lastmove = OTSYS_TIME();
- this->thingMove(player, player, toPos.x, toPos.y, player->pos.z, 1);
- flushSendBuffers();
- }
- }
- if(!player->pathList.empty()) {
- long long delay = player->getSleepTicks();
- stopEvent(player->eventCheckFollow);
- player->eventCheckFollow = addEvent(makeTask(delay, std::bind2nd(std::mem_fun(&Game::checkCreatureFollow), id)));
- } else {
- player->eventCheckFollow = 0;
- }
- }
- void Game::checkCreatureFollowAttack(uint32_t id)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::checkCreatureFollowAttack");
- Player *player = getPlayerByID(id);
- if(!player)
- return;
- if(!player->pathList.empty()) {
- Creature *followCreature = getCreatureByID(player->followCreature);
- if(followCreature == 0)
- return;
- if(player->followMode == 0x00) {
- stopEvent(player->eventCheckFollow);
- player->eventCheckFollow = 0;
- player->followCreature = 0;
- return;
- }
- if((std::abs(player->pos.x - followCreature->pos.x) > 7) ||
- (std::abs(player->pos.y - followCreature->pos.y) > 5) || (player->pos.z != followCreature->pos.z)){
- player->sendTextMessage(MSG_SMALLINFO, "Target lost.");
- player->eventCheckFollow = 0;
- player->followCreature = 0;
- playerSetAttackedCreature(player, 0);
- return;
- }
- if(followCreature && abs(followCreature->pos.x - player->pos.x) <= 1 && abs(followCreature->pos.y - player->pos.y) <= 1) player->pathList.clear();
- else {
- Position toPos = player->pathList.front();
- player->pathList.pop_front();
- player->lastmove = OTSYS_TIME();
- this->thingMove(player, player, toPos.x, toPos.y, player->pos.z, 1);
- flushSendBuffers();
- }
- }
- if(!player->pathList.empty()) {
- long long delay = player->getSleepTicks();
- stopEvent(player->eventCheckFollow);
- player->eventCheckFollow = addEvent(makeTask(delay, std::bind2nd(std::mem_fun(&Game::checkCreatureFollowAttack), id)));
- } else {
- player->eventCheckFollow = 0;
- }
- }
- void Game::playerFollow(Player* player, Creature *followCreature)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::playerFollow()");
- if(followCreature->isRemoved || player->isRemoved || !player || !followCreature){
- player->eventCheckFollow = 0;
- player->followCreature = 0;
- return;
- }
- player->pathList = getPathToEx(player, player->pos, followCreature->pos, false);
- long long delay = player->getSleepTicks();
- player->eventCheckFollow = addEvent(makeTask(delay, std::bind2nd(std::mem_fun(&Game::checkCreatureFollow), player->getID())));
- }
- void Game::playerFollowAttacking(Player* player, Creature *followCreature)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::playerFollow()");
- if(followCreature->isRemoved || player->isRemoved || !player || !followCreature){
- player->eventCheckFollow = 0;
- player->followCreature = 0;
- return;
- }
- if(player->followMode == 0x00) {
- stopEvent(player->eventCheckFollow);
- player->eventCheckFollow = 0;
- player->followCreature = 0;
- return;
- }
- player->pathList = getPathToEx(player, player->pos, followCreature->pos, false);
- long long delay = player->getSleepTicks();
- player->eventCheckFollow = addEvent(makeTask(delay, std::bind2nd(std::mem_fun(&Game::checkCreatureFollowAttack), player->getID())));
- }
- void Game::playerSetFollowCreature(Player* player, uint32_t creatureid)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::playerSetFollowCreature()");
- if(player->isRemoved || !player)
- return;
- if(creatureid == 0) {
- stopEvent(player->eventCheckFollow);
- player->eventCheckFollow = 0;
- player->followCreature = 0;
- }
- Creature* followCreature = NULL;
- if(creatureid != 0) {
- followCreature = getCreatureByID(creatureid);
- }
- if(followCreature) {
- player->followCreature = followCreature->getID();
- stopEvent(player->eventCheckFollow);
- playerFollow(player, followCreature);
- }
- }
- void Game::playerAttackSetFollowCreature(Player* player, uint32_t creatureid)
- {
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::playerAttackSetFollowCreature()");
- if(player->isRemoved || !player)
- return;
- if(player->followMode == 0x00) {
- return;
- }
- if(creatureid == 0) {
- stopEvent(player->eventCheckFollow);
- player->eventCheckFollow = 0;
- player->followCreature = 0;
- }
- Creature* followCreature = NULL;
- if(creatureid != 0) {
- followCreature = getCreatureByID(creatureid);
- }
- if(followCreature) {
- player->followCreature = followCreature->getID();
- stopEvent(player->eventCheckFollow);
- playerFollowAttacking(player, followCreature);
- }
- }
- #ifdef HUCZU_AUTORESTART
- void Game::beforeRestart()
- {
- sheduleShutdown(5);
- }
- #endif
- void Game::creatureUseShop(Creature *creature, int id, int count, std::string way){
- OTSYS_THREAD_LOCK_CLASS lockClass(gameLock, "Game::creatureUseShop()");
- int stackpos = map->getTile(creature->pos)->getThingStackPos(creature);
- SpectatorVec list;
- SpectatorVec::iterator it;
- map->getSpectators(Range(creature->pos, true), list);
- for(it = list.begin(); it != list.end(); ++it) {
- if(dynamic_cast<Npc*>(*it)) {
- (*it)->onCreatureUseShop(creature, id, count, way);
- }
- }
- }
Add Comment
Please, Sign In to add comment