From 1673de8b5553f6dcd4898c84b8d44ba8b30740f1 Mon Sep 17 00:00:00 2001 From: Guillaume Melquiond Date: Wed, 3 Jan 2007 17:10:43 +0000 Subject: Split persistent player data from game server data. Enabled inventory code back. --- ChangeLog | 24 ++ src/Makefile.am | 32 +-- src/account-server/account.hpp | 3 +- src/account-server/accounthandler.cpp | 26 +-- src/account-server/dalstorage.cpp | 22 +- src/account-server/serverhandler.cpp | 12 +- src/account-server/serverhandler.hpp | 2 +- src/being.cpp | 87 ------- src/being.h | 230 ------------------- src/chat-server/chatchannel.hpp | 2 - src/chat-server/chathandler.cpp | 1 + src/controller.h | 2 +- src/debug.cpp | 60 ----- src/debug.h | 49 ---- src/defines.h | 21 +- src/game-server/accountconnection.cpp | 10 +- src/game-server/accountconnection.hpp | 4 +- src/game-server/being.cpp | 87 +++++++ src/game-server/being.hpp | 214 +++++++++++++++++ src/game-server/gamehandler.cpp | 6 +- src/game-server/gamehandler.hpp | 2 +- src/game-server/inventory.cpp | 419 ++++++++++++++++++++++++++++++++++ src/game-server/inventory.hpp | 233 +++++++++++++++++++ src/game-server/itemmanager.cpp | 4 +- src/game-server/map.cpp | 302 ++++++++++++++++++++++++ src/game-server/map.hpp | 174 ++++++++++++++ src/game-server/mapcomposite.cpp | 6 +- src/game-server/mapcomposite.hpp | 11 +- src/game-server/mapmanager.cpp | 2 +- src/game-server/mapreader.cpp | 2 +- src/game-server/object.cpp | 79 +++++++ src/game-server/object.hpp | 258 +++++++++++++++++++++ src/game-server/player.cpp | 87 +++++++ src/game-server/player.hpp | 124 ++++++++++ src/game-server/state.cpp | 3 +- src/game-server/trigger.cpp | 2 +- src/game-server/trigger.hpp | 2 +- src/inventory.cpp | 419 ---------------------------------- src/inventory.h | 230 ------------------- src/item.h | 5 +- src/map.cpp | 305 ------------------------- src/map.h | 174 -------------- src/object.cpp | 79 ------- src/object.h | 257 --------------------- src/player.cpp | 85 ------- src/player.h | 267 ---------------------- src/playerdata.hpp | 250 ++++++++++++++++++++ 47 files changed, 2333 insertions(+), 2342 deletions(-) delete mode 100644 src/being.cpp delete mode 100644 src/being.h delete mode 100644 src/debug.cpp delete mode 100644 src/debug.h create mode 100644 src/game-server/being.cpp create mode 100644 src/game-server/being.hpp create mode 100644 src/game-server/inventory.cpp create mode 100644 src/game-server/inventory.hpp create mode 100644 src/game-server/map.cpp create mode 100644 src/game-server/map.hpp create mode 100644 src/game-server/object.cpp create mode 100644 src/game-server/object.hpp create mode 100644 src/game-server/player.cpp create mode 100644 src/game-server/player.hpp delete mode 100644 src/inventory.cpp delete mode 100644 src/inventory.h delete mode 100644 src/map.cpp delete mode 100644 src/map.h delete mode 100644 src/object.cpp delete mode 100644 src/object.h delete mode 100644 src/player.cpp delete mode 100644 src/player.h create mode 100644 src/playerdata.hpp diff --git a/ChangeLog b/ChangeLog index 6bcda2aa..1d5fbe6b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +2007-01-03 Guillaume Melquiond + + * src/debug.h, src/debug.cpp, src/Makefile.am: Removed obsolete debug + helpers. + * src/playerdata.hpp: Taken persistent data out of Player. + * src/being.h, src/being.cpp, src/object.h, src/object.cpp, src/map.h, + src/player.h, src/player.cpp, src/inventory.h, src/inventory.cpp, + src/map.cpp: Moved to src/game-server directory and changed header + extension to hpp. + * src/controller.h, src/item.h, src/game-server/mapcomposite.cpp, + src/game-server/mapreader.cpp, src/game-server/mapcomposite.hpp, + src/game-server/trigger.cpp, src/game-server/trigger.hpp, + src/game-server/accountconnection.cpp, src/game-server/gamehandler.hpp, + src/game-server/state.cpp, src/game-server/accountconnection.hpp, + src/game-server/itemmanager.cpp: Updated accordingly. + * src/account-server/account.hpp, src/account-server/serverhandler.cpp, + src/account-server/dalstorage.cpp, src/chat-server/chatchannel.hpp, + src/account-server/serverhandler.hpp, src/chat-server/chathandler.cpp, + src/account-server/accounthandler.cpp: Relied on PlayerData to remove + dependencies on Thing, Object, MovingObject, etc. + * src/defines.h: Fixed enumerations. + * src/games-server/gamehandler.cpp, src/game-server/player.cpp: + Commented in inventory code back. + 2007-01-02 Guillaume Melquiond * tmwserv.cbp, tmwserv.dev, runserv.sh: Removed obsolete project files diff --git a/src/Makefile.am b/src/Makefile.am index 759927e5..255b25e7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -6,17 +6,10 @@ bin_PROGRAMS = tmwserv-account tmwserv-game tmwserv_account_SOURCES = \ account-server/main-account.cpp \ - being.h \ configuration.h \ configuration.cpp \ - debug.h \ - debug.cpp \ defines.h \ - inventory.h \ - item.h \ - object.h \ - player.h \ - player.cpp \ + playerdata.hpp \ point.h \ resourcemanager.h \ resourcemanager.cpp \ @@ -70,25 +63,14 @@ tmwserv_account_SOURCES = \ tmwserv_game_SOURCES = \ game-server/main-game.cpp \ - being.h \ - being.cpp \ configuration.h \ configuration.cpp \ controller.h \ controller.cpp \ - debug.h \ - debug.cpp \ defines.h \ - inventory.h \ - inventory.cpp \ item.h \ item.cpp \ - map.h \ - map.cpp \ - object.h \ - object.cpp \ - player.h \ - player.cpp \ + playerdata.hpp \ point.h \ resourcemanager.h \ resourcemanager.cpp \ @@ -96,16 +78,26 @@ tmwserv_game_SOURCES = \ skill.cpp \ game-server/accountconnection.hpp \ game-server/accountconnection.cpp \ + game-server/being.hpp \ + game-server/being.cpp \ game-server/gamehandler.hpp \ game-server/gamehandler.cpp \ + game-server/inventory.hpp \ + game-server/inventory.cpp \ game-server/itemmanager.hpp \ game-server/itemmanager.cpp \ + game-server/map.hpp \ + game-server/map.cpp \ game-server/mapcomposite.hpp \ game-server/mapcomposite.cpp \ game-server/mapmanager.hpp \ game-server/mapmanager.cpp \ game-server/mapreader.hpp \ game-server/mapreader.cpp \ + game-server/object.hpp \ + game-server/object.cpp \ + game-server/player.hpp \ + game-server/player.cpp \ game-server/state.hpp \ game-server/state.cpp \ game-server/testing.cpp \ diff --git a/src/account-server/account.hpp b/src/account-server/account.hpp index e9d9e408..a97158a7 100644 --- a/src/account-server/account.hpp +++ b/src/account-server/account.hpp @@ -25,7 +25,8 @@ #include -#include "player.h" +#include "defines.h" +#include "playerdata.hpp" /** * Notes: diff --git a/src/account-server/accounthandler.cpp b/src/account-server/accounthandler.cpp index 72a23818..004e1b8b 100644 --- a/src/account-server/accounthandler.cpp +++ b/src/account-server/accounthandler.cpp @@ -22,7 +22,6 @@ */ #include "configuration.h" -#include "debug.h" #include "point.h" #include "account-server/accounthandler.hpp" #include "account-server/account.hpp" @@ -182,7 +181,7 @@ AccountHandler::processMessage(NetComputer *comp, MessageIn &message) std::string address; short port; - if (!serverHandler->getGameServerFromMap(chars[charNum]->getMapId(), address, port)) + if (!serverHandler->getGameServerFromMap(chars[charNum]->getMap(), address, port)) { result.writeByte(ERRMSG_FAILURE); LOG_ERROR("Character Selection: No game server for the map.", 0); @@ -194,11 +193,8 @@ AccountHandler::processMessage(NetComputer *comp, MessageIn &message) PlayerPtr selectedChar = computer.getCharacter(); result.writeByte(ERRMSG_OK); - selectedChar->setDestination(selectedChar->getPosition()); - selectedChar->setSpeed(150); // TODO - LOG_INFO(selectedChar->getName() - << " is trying to enter the servers.", 1); + << " is trying to enter the servers.", 1); std::string magic_token(32, ' '); for (int i = 0; i < 32; ++i) { @@ -552,9 +548,9 @@ AccountHandler::handleCharacterCreateMessage(AccountClient &computer, MessageIn &msg) { std::string name = msg.readString(); - char hairStyle = msg.readByte(); - char hairColor = msg.readByte(); - Gender gender = (Gender) msg.readByte(); + int hairStyle = msg.readByte(); + int hairColor = msg.readByte(); + int gender = msg.readByte(); MessageOut reply(APMSG_CHAR_CREATE_RESPONSE); @@ -572,17 +568,17 @@ AccountHandler::handleCharacterCreateMessage(AccountClient &computer, LOG_INFO(name << ": has got double quotes in it.", 1); reply.writeByte(ERRMSG_INVALID_ARGUMENT); } - else if ((hairStyle < 0) || (hairStyle > (signed) MAX_HAIRSTYLE_VALUE)) + else if (hairStyle < 0 || hairStyle > MAX_HAIRSTYLE_VALUE) { LOG_INFO(name << ": Character's hair Style is invalid.", 1); reply.writeByte(CREATE_INVALID_HAIRSTYLE); } - else if ((hairColor < 0) || (hairColor > (signed) MAX_HAIRCOLOR_VALUE)) + else if (hairColor < 0 || hairColor > MAX_HAIRCOLOR_VALUE) { LOG_INFO(name << ": Character's hair Color is invalid.", 1); reply.writeByte(CREATE_INVALID_HAIRCOLOR); } - else if ((gender < 0) || (gender > (signed) MAX_GENDER_VALUE)) + else if (gender < 0 || gender > MAX_GENDER_VALUE) { LOG_INFO(name << ": Character's gender is invalid.", 1); reply.writeByte(CREATE_INVALID_GENDER); @@ -665,7 +661,7 @@ AccountHandler::handleCharacterCreateMessage(AccountClient &computer, } else { - PlayerPtr newCharacter(new Player(name)); + PlayerPtr newCharacter(new PlayerData(name)); for (int i = 0; i < NB_RSTAT; ++i) newCharacter->setRawStat(i, rawStats.stats[i]); newCharacter->setMoney(0); @@ -673,10 +669,10 @@ AccountHandler::handleCharacterCreateMessage(AccountClient &computer, newCharacter->setGender(gender); newCharacter->setHairStyle(hairStyle); newCharacter->setHairColor(hairColor); - newCharacter->setMapId((int) config.getValue("defaultMap", 1)); + newCharacter->setMap((int) config.getValue("defaultMap", 1)); Point startingPos = { (int) config.getValue("startX", 0), (int) config.getValue("startY", 0) }; - newCharacter->setPosition(startingPos); + newCharacter->setPos(startingPos); computer.getAccount()->addCharacter(newCharacter); LOG_INFO("Character " << name << " was created for " diff --git a/src/account-server/dalstorage.cpp b/src/account-server/dalstorage.cpp index 2208a91e..ee9901fa 100644 --- a/src/account-server/dalstorage.cpp +++ b/src/account-server/dalstorage.cpp @@ -309,14 +309,14 @@ PlayerPtr DALStorage::getCharacter(int id) // a string to an unsigned short. string_to< unsigned short > toUshort; - Player *player = new Player(charInfo(0, 2), toUint(charInfo(0, 0))); - player->setGender((Gender)toUshort(charInfo(0, 3))); + PlayerData *player = new PlayerData(charInfo(0, 2), toUint(charInfo(0, 0))); + player->setGender(toUshort(charInfo(0, 3))); player->setHairStyle(toUshort(charInfo(0, 4))); player->setHairColor(toUshort(charInfo(0, 5))); player->setLevel(toUshort(charInfo(0, 6))); player->setMoney(toUint(charInfo(0, 7))); Point pos = { toUshort(charInfo(0, 8)), toUshort(charInfo(0, 9)) }; - player->setPosition(pos); + player->setPos(pos); for (int i = 0; i < NB_RSTAT; ++i) { player->setRawStat(i, toUshort(charInfo(0, 11 + i))); @@ -325,13 +325,13 @@ PlayerPtr DALStorage::getCharacter(int id) int mapId = toUint(charInfo(0, 10)); if (mapId > 0) { - player->setMapId(mapId); + player->setMap(mapId); } else { // Set player to default map and one of the default location // Default map is to be 1, as not found return value will be 0. - player->setMapId((int)config.getValue("defaultMap", 1)); + player->setMap((int)config.getValue("defaultMap", 1)); } PlayerPtr ptr(player); @@ -659,9 +659,9 @@ void DALStorage::flush(AccountPtr const &account) << (int)(*it)->getHairColor() << ", " << (int)(*it)->getLevel() << ", " << (*it)->getMoney() << ", " - << (*it)->getPosition().x << ", " - << (*it)->getPosition().y << ", " - << (*it)->getMapId() << ", " + << (*it)->getPos().x << ", " + << (*it)->getPos().y << ", " + << (*it)->getMap() << ", " << (*it)->getRawStat(STAT_STRENGTH) << ", " << (*it)->getRawStat(STAT_AGILITY) << ", " << (*it)->getRawStat(STAT_VITALITY) << ", " @@ -691,9 +691,9 @@ void DALStorage::flush(AccountPtr const &account) << " hair_color = " << (int)(*it)->getHairColor() << ", " << " level = " << (int)(*it)->getLevel() << ", " << " money = " << (*it)->getMoney() << ", " - << " x = " << (*it)->getPosition().x << ", " - << " y = " << (*it)->getPosition().y << ", " - << " map_id = " << (*it)->getMapId() << ", " + << " x = " << (*it)->getPos().x << ", " + << " y = " << (*it)->getPos().y << ", " + << " map_id = " << (*it)->getMap() << ", " << " str = " << (*it)->getRawStat(STAT_STRENGTH) << ", " << " agi = " << (*it)->getRawStat(STAT_AGILITY) << ", " << " vit = " << (*it)->getRawStat(STAT_VITALITY) << ", " diff --git a/src/account-server/serverhandler.cpp b/src/account-server/serverhandler.cpp index 3d3846a7..2a1af5ee 100644 --- a/src/account-server/serverhandler.cpp +++ b/src/account-server/serverhandler.cpp @@ -71,7 +71,7 @@ bool ServerHandler::getGameServerFromMap(unsigned mapId, std::string &address, s void ServerHandler::registerGameClient(std::string const &token, PlayerPtr ptr) { - unsigned mapId = ptr->getMapId(); + unsigned mapId = ptr->getMap(); MessageOut msg(AGMSG_PLAYER_ENTER); msg.writeLong(ptr->getDatabaseID()); msg.writeString(ptr->getName()); @@ -82,7 +82,7 @@ void ServerHandler::registerGameClient(std::string const &token, PlayerPtr ptr) msg.writeShort(ptr->getMoney()); for (int j = 0; j < NB_RSTAT; ++j) msg.writeShort(ptr->getRawStat(j)); - Point pos = ptr->getPosition(); + Point pos = ptr->getPos(); msg.writeShort(pos.x); msg.writeShort(pos.y); msg.writeShort(mapId); @@ -130,7 +130,7 @@ void ServerHandler::processMessage(NetComputer *comp, MessageIn &msg) int id = msg.readLong(); Storage &store = Storage::instance("tmw"); PlayerPtr ptr = store.getCharacter(id); - ptr->setGender((Gender)msg.readByte()); + ptr->setGender(msg.readByte()); ptr->setHairStyle(msg.readByte()); ptr->setHairColor(msg.readByte()); ptr->setLevel(msg.readByte()); @@ -140,8 +140,8 @@ void ServerHandler::processMessage(NetComputer *comp, MessageIn &msg) int x = msg.readShort(); int y = msg.readShort(); Point pos = { x, y }; - ptr->setPosition(pos); - ptr->setMapId(msg.readShort()); + ptr->setPos(pos); + ptr->setMap(msg.readShort()); } break; case GAMSG_REDIRECT: @@ -156,7 +156,7 @@ void ServerHandler::processMessage(NetComputer *comp, MessageIn &msg) PlayerPtr ptr = store.getCharacter(id); std::string address; short port; - if (serverHandler->getGameServerFromMap(ptr->getMapId(), address, port)) + if (serverHandler->getGameServerFromMap(ptr->getMap(), address, port)) { registerGameClient(magic_token, ptr); result.writeShort(AGMSG_REDIRECT_RESPONSE); diff --git a/src/account-server/serverhandler.hpp b/src/account-server/serverhandler.hpp index 797e0a48..1325b065 100644 --- a/src/account-server/serverhandler.hpp +++ b/src/account-server/serverhandler.hpp @@ -26,7 +26,7 @@ #include -#include "player.h" +#include "playerdata.hpp" #include "net/connectionhandler.hpp" /** diff --git a/src/being.cpp b/src/being.cpp deleted file mode 100644 index cece203a..00000000 --- a/src/being.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - * The Mana World Server - * Copyright 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World 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 any later version. - * - * The Mana World 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 The Mana World; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id$ - */ - -#include "being.h" -#include "game-server/mapcomposite.hpp" -#include "utils/logger.h" - -void Being::damage(Damage damage) -{ - int HPloss; - - HPloss = damage; // TODO: Implement complex damage calculation here - - mHitpoints -= HPloss; - mHitsTaken.push_back(HPloss); - LOG_DEBUG("Being " << getPublicID() << " got hit", 0); -} - -void Being::performAttack(MapComposite *map) -{ - int SHORT_RANGE = 32; - Point ppos = getPosition(); - int dir = getDirection(); - - /* TODO: calculate real attack power and damage properties based on - character equipment and stats. */ - Damage damage = 1; - - for (MovingObjectIterator i(map->getAroundObjectIterator(this, SHORT_RANGE)); i; ++i) - { - MovingObject *o = *i; - if (o == this) - { - continue; - } - - int type = o->getType(); - Point opos = o->getPosition(); - int dx = opos.x - ppos.x, dy = opos.y - ppos.y; - - if ((type != OBJECT_PLAYER && type != OBJECT_MONSTER) || - (std::abs(dx) > SHORT_RANGE || std::abs(dy) > SHORT_RANGE)) - { - continue; - } - - // basic triangle-shaped damage zone - switch (dir) - { - case DIRECTION_UP: - if (!(dy <= dx && dx <= -dy)) continue; - break; - case DIRECTION_DOWN: - if (!(-dy <= dx && dx <= dy)) continue; - break; - case DIRECTION_LEFT: - if (!(dx <= dy && dy <= -dx)) continue; - break; - case DIRECTION_RIGHT: - if (!(-dx <= dy && dy <= dx)) continue; - break; - default: - break; - } - - static_cast< Being * >(o)->damage(damage); - } -} diff --git a/src/being.h b/src/being.h deleted file mode 100644 index 760bea73..00000000 --- a/src/being.h +++ /dev/null @@ -1,230 +0,0 @@ -/* - * The Mana World Server - * Copyright 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World 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 any later version. - * - * The Mana World 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 The Mana World; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id$ - */ - -#ifndef _TMWSERV_BEING_H_ -#define _TMWSERV_BEING_H_ - -#include -#include -#include - -#include "defines.h" -#include "object.h" -#include "utils/countedptr.h" - -class MapComposite; - -/** - * Element attribute for beings, actors and items. - */ -typedef enum { - ELEMENT_NEUTRAL = 0, - ELEMENT_FIRE, - ELEMENT_WATER, - ELEMENT_EARTH, - ELEMENT_AIR, - ELEMENT_SACRED, - ELEMENT_DEATH -} Element; - -/** - * States attribute for beings, and actors. - * States can be multiple for the same being. - */ -struct BeingState { - bool STATE_NORMAL; - bool STATE_POISONED; - bool STATE_STONED; - bool STATE_STUNNED; - bool STATE_SLOWED; - bool STATE_TIRED; - bool STATE_MAD; - bool STATE_BERSERK; - bool STATE_HASTED; - bool STATE_FLOATING; -}; - -/** - * Moves enum for beings and actors for others players vision. - */ -typedef enum { - ACTION_DEFAULT = 0, - ACTION_STAND, - ACTION_WALK, - ACTION_RUN, - ACTION_JUMP, - ACTION_CRAWL, - ACTION_ATTACK, - ACTION_ATTACK_SWING, - ACTION_ATTACK_STAB, - ACTION_ATTACK_BOW, - ACTION_ATTACK_THROW, - ACTION_CAST_MAGIC, - ACTION_USE_ITEM, - ACTION_SIT, - ACTION_SLEEP, - ACTION_HURT, - ACTION_DEAD, - ACTION_INVALID -} SpriteAction; - -/** - * Beings and actors directions - */ -enum { - DIRECTION_DOWN = 1, - DIRECTION_UP, - DIRECTION_LEFT, - DIRECTION_RIGHT -}; - -/** - * Raw statistics of a Player. - */ -enum { - STAT_STRENGTH = 0, - STAT_AGILITY, - STAT_VITALITY, - STAT_INTELLIGENCE, - STAT_DEXTERITY, - STAT_LUCK, - NB_RSTAT -}; - -/** - * Structure types for the raw statistics of a Player. - */ -struct RawStatistics -{ - unsigned short stats[NB_RSTAT]; -}; - - -/** - * Computed statistics of a Being. - */ -enum { - STAT_HEAT = 0, - STAT_ATTACK, - STAT_DEFENCE, - STAT_MAGIC, - STAT_ACCURACY, - STAT_SPEED, - NB_CSTAT -}; - -/** - * Structure type for the computed statistics of a Being. - */ -struct Statistics -{ - unsigned short stats[NB_CSTAT]; -}; - -/** - * Placeholder for a more complex damage structure - */ -typedef unsigned short Damage; - -/** - * Type definition for a list of hits - */ -typedef std::list Hits; - -/** - * Generic Being (living object). - * Used for players & monsters (all animated objects). - */ -class Being : public MovingObject -{ - public: - /** - * Proxy constructor. - */ - Being(int type, int id) - : MovingObject(type, id) - {} - - /** - * Sets a computed statistic. - * - * @param numStat the statistic number. - * @param value the new value. - */ - void setStat(int numStat, unsigned short value) - { mStats.stats[numStat] = value; } - - /** - * Gets a computed statistic. - * - * @param numStat the statistic number. - * @return the statistic value. - */ - unsigned short getStat(int numStat) - { return mStats.stats[numStat]; } - - /** - * Takes a damage structure, computes the real damage based on the - * stats, deducts the result from the hitpoints and adds the result to - * the HitsTaken list. - */ - void damage(Damage); - - /** - * Gets the damage list. - */ - Hits const &getHitsTaken() const - { return mHitsTaken; } - - /** - * Clears the damage list. - */ - void clearHitsTaken() - { mHitsTaken.clear(); } - - /** - * Performs an attack. - */ - void performAttack(MapComposite *); - - private: - Being(Being const &rhs); - Being &operator=(Being const &rhs); - - Statistics mStats; /**< stats modifiers or computed stats */ - - int mHitpoints; /**< Hitpoints of the being */ - - Hits mHitsTaken; /**< List of punches taken since last update */ -}; - -/** - * Type definition for a smart pointer to Being. - */ -typedef utils::CountedPtr BeingPtr; - -/** - * Type definition for a list of Beings. - */ -typedef std::vector Beings; - -#endif // _TMWSERV_BEING_H_ diff --git a/src/chat-server/chatchannel.hpp b/src/chat-server/chatchannel.hpp index 29a0734e..0fd6d4be 100644 --- a/src/chat-server/chatchannel.hpp +++ b/src/chat-server/chatchannel.hpp @@ -27,8 +27,6 @@ #include #include -#include "being.h" - class ChatChannel { public: typedef std::vector< std::string > ChannelUsers; diff --git a/src/chat-server/chathandler.cpp b/src/chat-server/chathandler.cpp index bb56c160..323abe76 100644 --- a/src/chat-server/chathandler.cpp +++ b/src/chat-server/chathandler.cpp @@ -21,6 +21,7 @@ * $Id$ */ +#include "defines.h" #include "chat-server/chatchannelmanager.hpp" #include "chat-server/chathandler.hpp" #include "net/connectionhandler.hpp" diff --git a/src/controller.h b/src/controller.h index 7a76d33d..adbc54a7 100644 --- a/src/controller.h +++ b/src/controller.h @@ -23,7 +23,7 @@ #ifndef _TMWSERV_CONTROLLER_H_ #define _TMWSERV_CONTROLLER_H_ -#include "being.h" +#include "game-server/being.hpp" /** * A controller can take control of a being. diff --git a/src/debug.cpp b/src/debug.cpp deleted file mode 100644 index 671528a2..00000000 --- a/src/debug.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/* - * The Mana World Server - * Copyright 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World 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 - * any later version. - * - * The Mana World 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 The Mana World; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id$ - */ - -// This file contains debugging global functions - -#include "debug.h" - -// global debugging flag (set to false in release version) -int debugflag = false; - - -void debugCatch(int result) -{ - if (!debugflag) { - return; // break out if we are not debugging - } - - - switch (result) - { - case TMW_SUCCESS: // function successful - return; - break; - case TMW_ACCOUNTERROR_NOEXIST: // account does not exist - // show the programmer a message - break; - case TMW_ACCOUNTERROR_BANNED: // account is banned - // show the programmer a message - break; - case TMW_ACCOUNTERROR_ALREADYASSIGNED: // account is in use - // show the programmer a message (this may signal a logout bug - break; - case TMW_ACCOUNTERROR_CHARNOTFOUND: // the character is not found - // show a message - break; - case TMW_ACCOUNTERROR_ASSIGNFAILED: // failed to assign the handle to the user - // show a message - break; - } -} diff --git a/src/debug.h b/src/debug.h deleted file mode 100644 index 65a95e36..00000000 --- a/src/debug.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * The Mana World Server - * Copyright 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World 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 - * any later version. - * - * The Mana World 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 The Mana World; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id$ - */ - -#ifndef _TMWSERV_DEBUG_H_ -#define _TMWSERV_DEBUG_H_ - -// This file defines the return types for debugging - -/** - * Returns a message on function failure if the debug flag is set to true. - */ -extern void debugCatch(int result); - - -// message handler definitions -// add your definitions to this list, sorted by type. Each group starts with a -// different multiple of 100 - - // GENERAL -#define TMW_SUCCESS 1 // the function completed successfully - - // ACCOUNT -#define TMW_ACCOUNTERROR_NOEXIST 100 -#define TMW_ACCOUNTERROR_BANNED 101 -#define TMW_ACCOUNTERROR_ALREADYASSIGNED 102 -#define TMW_ACCOUNTERROR_CHARNOTFOUND 103 -#define TMW_ACCOUNTERROR_ASSIGNFAILED 104 - -#endif diff --git a/src/defines.h b/src/defines.h index fc8c8705..ba2ba4af 100644 --- a/src/defines.h +++ b/src/defines.h @@ -44,17 +44,10 @@ typedef enum { AL_RESTRICTED // User rights have been restricted } AccountLevel; - -/** - * Enumeration type for the player genders. - */ -typedef enum { - GENDER_MALE, - GENDER_FEMALE -} Gender; - +enum +{ // Network related -const unsigned int MAX_CLIENTS = 1024, + MAX_CLIENTS = 1024, // Chat related /** @@ -97,8 +90,8 @@ const unsigned int MAX_CLIENTS = 1024, /** * Determine the area in which a character is aware of other beings */ - AROUND_AREA = 320; - + AROUND_AREA = 320 +}; /** * Enumerated type for communicated messages @@ -201,7 +194,7 @@ enum { ERRMSG_NO_LOGIN, // the user is not yet logged ERRMSG_NO_CHARACTER_SELECTED, // the user needs a character ERRMSG_INSUFFICIENT_RIGHTS, // the user is not privileged - ERRMSG_INVALID_ARGUMENT, // part of the received message was invalid + ERRMSG_INVALID_ARGUMENT // part of the received message was invalid }; // Login specific return values @@ -238,7 +231,7 @@ enum { // Chat errors return values enum { CHAT_USING_BAD_WORDS = 0x40, - CHAT_UNHANDLED_COMMAND, + CHAT_UNHANDLED_COMMAND }; // Chat channels event values diff --git a/src/game-server/accountconnection.cpp b/src/game-server/accountconnection.cpp index ceb0b5dd..d536abfc 100644 --- a/src/game-server/accountconnection.cpp +++ b/src/game-server/accountconnection.cpp @@ -23,10 +23,10 @@ #include "configuration.h" #include "defines.h" -#include "player.h" #include "game-server/accountconnection.hpp" #include "game-server/gamehandler.hpp" #include "game-server/mapmanager.hpp" +#include "game-server/player.hpp" #include "net/messagein.hpp" #include "net/messageout.hpp" #include "utils/logger.h" @@ -53,7 +53,7 @@ bool AccountConnection::start() return true; } -void AccountConnection::sendPlayerData(Player *p) +void AccountConnection::sendPlayerData(PlayerData *p) { MessageOut msg(GAMSG_PLAYER_DATA); msg.writeLong(p->getDatabaseID()); @@ -64,10 +64,10 @@ void AccountConnection::sendPlayerData(Player *p) msg.writeShort(p->getMoney()); for (int j = 0; j < NB_RSTAT; ++j) msg.writeShort(p->getRawStat(j)); - Point pos = p->getPosition(); + Point pos = p->getPos(); msg.writeShort(pos.x); msg.writeShort(pos.y); - msg.writeShort(p->getMapId()); + msg.writeShort(p->getMap()); send(msg); } @@ -80,7 +80,7 @@ void AccountConnection::processMessage(MessageIn &msg) int id = msg.readLong(); std::string name = msg.readString(); Player *ptr = new Player(name, id); - ptr->setGender((Gender)msg.readByte()); + ptr->setGender(msg.readByte()); ptr->setHairStyle(msg.readByte()); ptr->setHairColor(msg.readByte()); ptr->setLevel(msg.readByte()); diff --git a/src/game-server/accountconnection.hpp b/src/game-server/accountconnection.hpp index 9722fe69..e418a111 100644 --- a/src/game-server/accountconnection.hpp +++ b/src/game-server/accountconnection.hpp @@ -26,7 +26,7 @@ #include "net/connection.hpp" -class Player; +class PlayerData; /** * A connection to the account server. @@ -43,7 +43,7 @@ class AccountConnection: public Connection /** * Sends data of given player. */ - void sendPlayerData(Player *); + void sendPlayerData(PlayerData *); protected: /** diff --git a/src/game-server/being.cpp b/src/game-server/being.cpp new file mode 100644 index 00000000..64986c26 --- /dev/null +++ b/src/game-server/being.cpp @@ -0,0 +1,87 @@ +/* + * The Mana World Server + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World 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 any later version. + * + * The Mana World 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 The Mana World; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#include "game-server/being.hpp" +#include "game-server/mapcomposite.hpp" +#include "utils/logger.h" + +void Being::damage(Damage damage) +{ + int HPloss; + + HPloss = damage; // TODO: Implement complex damage calculation here + + mHitpoints -= HPloss; + mHitsTaken.push_back(HPloss); + LOG_DEBUG("Being " << getPublicID() << " got hit", 0); +} + +void Being::performAttack(MapComposite *map) +{ + int SHORT_RANGE = 32; + Point ppos = getPosition(); + int dir = getDirection(); + + /* TODO: calculate real attack power and damage properties based on + character equipment and stats. */ + Damage damage = 1; + + for (MovingObjectIterator i(map->getAroundObjectIterator(this, SHORT_RANGE)); i; ++i) + { + MovingObject *o = *i; + if (o == this) + { + continue; + } + + int type = o->getType(); + Point opos = o->getPosition(); + int dx = opos.x - ppos.x, dy = opos.y - ppos.y; + + if ((type != OBJECT_PLAYER && type != OBJECT_MONSTER) || + (std::abs(dx) > SHORT_RANGE || std::abs(dy) > SHORT_RANGE)) + { + continue; + } + + // basic triangle-shaped damage zone + switch (dir) + { + case DIRECTION_UP: + if (!(dy <= dx && dx <= -dy)) continue; + break; + case DIRECTION_DOWN: + if (!(-dy <= dx && dx <= dy)) continue; + break; + case DIRECTION_LEFT: + if (!(dx <= dy && dy <= -dx)) continue; + break; + case DIRECTION_RIGHT: + if (!(-dx <= dy && dy <= dx)) continue; + break; + default: + break; + } + + static_cast< Being * >(o)->damage(damage); + } +} diff --git a/src/game-server/being.hpp b/src/game-server/being.hpp new file mode 100644 index 00000000..32b30b1e --- /dev/null +++ b/src/game-server/being.hpp @@ -0,0 +1,214 @@ +/* + * The Mana World Server + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World 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 any later version. + * + * The Mana World 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 The Mana World; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#ifndef _TMWSERV_BEING_H_ +#define _TMWSERV_BEING_H_ + +#include +#include +#include + +#include "defines.h" +#include "game-server/object.hpp" +#include "utils/countedptr.h" + +class MapComposite; + +/** + * Element attribute for beings, actors and items. + */ +enum +{ + ELEMENT_NEUTRAL = 0, + ELEMENT_FIRE, + ELEMENT_WATER, + ELEMENT_EARTH, + ELEMENT_AIR, + ELEMENT_SACRED, + ELEMENT_DEATH +}; + +/** + * States attribute for beings, and actors. + * States can be multiple for the same being. + */ +struct BeingState +{ + bool STATE_NORMAL; + bool STATE_POISONED; + bool STATE_STONED; + bool STATE_STUNNED; + bool STATE_SLOWED; + bool STATE_TIRED; + bool STATE_MAD; + bool STATE_BERSERK; + bool STATE_HASTED; + bool STATE_FLOATING; +}; + +/** + * Moves enum for beings and actors for others players vision. + */ +enum +{ + ACTION_DEFAULT = 0, + ACTION_STAND, + ACTION_WALK, + ACTION_RUN, + ACTION_JUMP, + ACTION_CRAWL, + ACTION_ATTACK, + ACTION_ATTACK_SWING, + ACTION_ATTACK_STAB, + ACTION_ATTACK_BOW, + ACTION_ATTACK_THROW, + ACTION_CAST_MAGIC, + ACTION_USE_ITEM, + ACTION_SIT, + ACTION_SLEEP, + ACTION_HURT, + ACTION_DEAD, + ACTION_INVALID +}; + +/** + * Beings and actors directions + */ +enum +{ + DIRECTION_DOWN = 1, + DIRECTION_UP, + DIRECTION_LEFT, + DIRECTION_RIGHT +}; + + +/** + * Computed statistics of a Being. + */ +enum +{ + STAT_HEAT = 0, + STAT_ATTACK, + STAT_DEFENCE, + STAT_MAGIC, + STAT_ACCURACY, + STAT_SPEED, + NB_CSTAT +}; + +/** + * Structure type for the computed statistics of a Being. + */ +struct Statistics +{ + unsigned short stats[NB_CSTAT]; +}; + +/** + * Placeholder for a more complex damage structure + */ +typedef unsigned short Damage; + +/** + * Type definition for a list of hits + */ +typedef std::list Hits; + +/** + * Generic Being (living object). + * Used for players & monsters (all animated objects). + */ +class Being : public MovingObject +{ + public: + /** + * Proxy constructor. + */ + Being(int type, int id) + : MovingObject(type, id) + {} + + /** + * Sets a computed statistic. + * + * @param numStat the statistic number. + * @param value the new value. + */ + void setStat(int numStat, unsigned short value) + { mStats.stats[numStat] = value; } + + /** + * Gets a computed statistic. + * + * @param numStat the statistic number. + * @return the statistic value. + */ + unsigned short getStat(int numStat) + { return mStats.stats[numStat]; } + + /** + * Takes a damage structure, computes the real damage based on the + * stats, deducts the result from the hitpoints and adds the result to + * the HitsTaken list. + */ + void damage(Damage); + + /** + * Gets the damage list. + */ + Hits const &getHitsTaken() const + { return mHitsTaken; } + + /** + * Clears the damage list. + */ + void clearHitsTaken() + { mHitsTaken.clear(); } + + /** + * Performs an attack. + */ + void performAttack(MapComposite *); + + private: + Being(Being const &rhs); + Being &operator=(Being const &rhs); + + Statistics mStats; /**< stats modifiers or computed stats */ + + int mHitpoints; /**< Hitpoints of the being */ + + Hits mHitsTaken; /**< List of punches taken since last update */ +}; + +/** + * Type definition for a smart pointer to Being. + */ +typedef utils::CountedPtr BeingPtr; + +/** + * Type definition for a list of Beings. + */ +typedef std::vector Beings; + +#endif // _TMWSERV_BEING_H_ diff --git a/src/game-server/gamehandler.cpp b/src/game-server/gamehandler.cpp index 56b9533c..f7a3905a 100644 --- a/src/game-server/gamehandler.cpp +++ b/src/game-server/gamehandler.cpp @@ -24,8 +24,8 @@ #include #include -#include "map.h" #include "game-server/gamehandler.hpp" +#include "game-server/map.hpp" #include "game-server/state.hpp" #include "net/messagein.hpp" #include "net/messageout.hpp" @@ -231,7 +231,6 @@ void GameHandler::processMessage(NetComputer *comp, MessageIn &message) gameState->sayAround(computer.character, say); } break; - /* case PGMSG_PICKUP: { // add item to inventory (this is too simplistic atm) @@ -260,7 +259,6 @@ void GameHandler::processMessage(NetComputer *comp, MessageIn &message) result.writeByte(ERRMSG_FAILURE); } } break; - */ case PGMSG_WALK: { @@ -272,7 +270,6 @@ void GameHandler::processMessage(NetComputer *comp, MessageIn &message) // no response should be required } break; - /* case PGMSG_EQUIP: { message.readLong(); // ItemId: Not useful, the inventory knows it @@ -282,7 +279,6 @@ void GameHandler::processMessage(NetComputer *comp, MessageIn &message) result.writeByte(computer.character->equip(slot) ? ERRMSG_OK : ERRMSG_FAILURE); } break; - */ case PGMSG_ATTACK: { diff --git a/src/game-server/gamehandler.hpp b/src/game-server/gamehandler.hpp index f574d9ec..faeff656 100644 --- a/src/game-server/gamehandler.hpp +++ b/src/game-server/gamehandler.hpp @@ -24,7 +24,7 @@ #ifndef _TMW_SERVER_GAMEHANDLER_ #define _TMW_SERVER_GAMEHANDLER_ -#include "player.h" +#include "game-server/player.hpp" #include "net/connectionhandler.hpp" /** diff --git a/src/game-server/inventory.cpp b/src/game-server/inventory.cpp new file mode 100644 index 00000000..b3b8a254 --- /dev/null +++ b/src/game-server/inventory.cpp @@ -0,0 +1,419 @@ +/* + * The Mana World Server + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World 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 + * any later version. + * + * The Mana World 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 The Mana World; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#include "game-server/inventory.hpp" +#include "game-server/itemmanager.hpp" + +// --------- +// Items +// --------- +unsigned char +Inventory::getInventoryFreeSlot() +{ + for (int a = 0; a < MAX_ITEMS_IN_INVENTORY; a++) + { + if (itemList.at(a).amount == 0) + return a; + } + return INVENTORY_FULL; +} + +unsigned char +Inventory::getSlotFromId(const unsigned int itemId) +{ + for (int a = 0; a < MAX_ITEMS_IN_INVENTORY; a++) + { + if (itemList.at(a).itemId == itemId) + return a; + } + return INVENTORY_FULL; +} + +bool +Inventory::hasItem(unsigned int itemId, + bool searchInInventory, + bool searchInEquipment) +{ + bool hasItem = false; + // Search in inventory + if (searchInInventory) + { + std::vector::iterator iter = itemList.begin(); + for (iter = itemList.begin(); iter != itemList.end(); ++iter) + { + if (iter->itemId == itemId) + hasItem = true; + } + } + // Search in equipment + if (searchInEquipment) + { + std::vector::iterator equipIter = equippedItemList.begin(); + for (equipIter = equippedItemList.begin(); + equipIter != equippedItemList.end(); + ++equipIter) + { + if (equipIter->itemId == itemId) + hasItem = true; + } + if (equippedProjectiles.itemId == itemId) + hasItem = true; + } + return hasItem; +} + +short +Inventory::addItem(unsigned int itemId, unsigned char amount) +{ + // We get the max number of item we can have in the same slot + // for the given item. + unsigned char maxPerSlot = itemManager->getMaxPerSlot(itemId); + // We'll add items in slots with the item type and in free slots + // until it's all done or until the inventory will be all parsed. + // Searching for items with the same Id in the inventory, before + // seeking a free slot. + unsigned char amountToAdd = amount; + + // Parsing inventory + unsigned char currentAmountInSlot = 0; + std::vector::iterator iter = itemList.begin(); + for (iter = itemList.begin(); iter != itemList.end(); ++iter) + { + currentAmountInSlot = iter->amount; + // If a slot has got place for some more of such an item. + if (iter->itemId == itemId && currentAmountInSlot < maxPerSlot) + { + // If there isn't enough space to put every item in the slot. + // We add the difference. + if ((maxPerSlot - currentAmountInSlot) < amountToAdd) + { + iter->amount += (maxPerSlot - currentAmountInSlot); + amountToAdd -= (maxPerSlot - currentAmountInSlot); + } + else // there is enough to add everything. + { + iter->amount += amountToAdd; + amountToAdd = 0; // Ok! + } + } + // Or if there is an empty slot. + else if (iter->amount == 0) + { + // We add the item in the new slot (setting also the Id.) + if (maxPerSlot < amountToAdd) + { + iter->amount = maxPerSlot; + amountToAdd -= maxPerSlot; + } + else + { + iter->amount += amountToAdd; + amountToAdd = 0; // Ok! + } + iter->itemId = itemId; + } + } + + return (short)(amount - amountToAdd); +} + +short +Inventory::removeItem(unsigned int itemId, unsigned char amount) +{ + // We'll remove items in slots with the item type + // until it's all done or until the inventory will be all parsed. + // Searching for items with the same Id in the inventory + unsigned char amountToRemove = amount; + + // Parsing inventory + unsigned char currentAmountInSlot = 0; + std::vector::iterator iter = itemList.begin(); + for (iter = itemList.begin(); iter != itemList.end(); ++iter) + { + currentAmountInSlot = iter->amount; + // If a slot has got such an item, remove it + if (iter->itemId == itemId && currentAmountInSlot > 0) + { + // If there isn't enough to finish, we remove the difference + // Emptying the slot, so we clean also the itemId. + if (currentAmountInSlot <= amountToRemove) + { + amountToRemove -= currentAmountInSlot; + iter->amount = 0; + iter->itemId = 0; + } + else // there is enough to remove everything. + { + iter->amount -= amountToRemove; + amountToRemove = 0; // Ok! + } + } + } + return (short)(amount - amountToRemove); +} + +short +Inventory::removeItem(unsigned char slot, unsigned char amount) +{ + if (itemList.at(slot).amount < amount) + { + unsigned char value = itemList.at(slot).amount; + itemList.at(slot).amount = 0; + return (short)value; + } + else + { + itemList.at(slot).amount -= amount; + return amount; + } +} + +bool +Inventory::use(unsigned char slot, BeingPtr itemUser) +{ + return false; // TODO +} + +bool +Inventory::use(unsigned int itemId, BeingPtr itemUser) +{ + return false; // TODO +} + +// --------- +// Equipment +// --------- +unsigned char +Inventory::equipItem(unsigned int itemId) +{ + // First, we look for the item in the player's inventory. + if (!hasItem(itemId, true, false)) + return false; + + unsigned char availableSlots = 0, firstSlot = 0, secondSlot = 0; + + unsigned short itemType = itemManager->getItemType(itemId); + switch (itemType) + { + case ITEM_EQUIPMENT_TWO_HANDS_WEAPON: + // Special case 1, the two one-handed weapons are to be placed back + // in the inventory, if there are any. + if (equippedItemList.at(EQUIP_FIGHT1_SLOT).itemId > 0) + { // Slot 1 full + // old two-handed weapon case: + if (equippedItemList.at(EQUIP_FIGHT1_SLOT).itemType + == ITEM_EQUIPMENT_TWO_HANDS_WEAPON) + { + equippedItemList.at(EQUIP_FIGHT2_SLOT).itemId = 0; + equippedItemList.at(EQUIP_FIGHT2_SLOT).itemType = 0; + } + + if (unequipItem_(equippedItemList.at(EQUIP_FIGHT1_SLOT).itemId, + EQUIP_FIGHT1_SLOT) == INVENTORY_FULL) + return INVENTORY_FULL; + } + if (equippedItemList.at(EQUIP_FIGHT2_SLOT).itemId > 0) + { // Slot 2 full + if (unequipItem_(equippedItemList.at(EQUIP_FIGHT2_SLOT).itemId, + EQUIP_FIGHT2_SLOT) == INVENTORY_FULL) + return INVENTORY_FULL; + } + // Only the slot 1 needs to be updated. + return equipItem_(itemId, itemType, EQUIP_FIGHT1_SLOT); + break; + + case ITEM_EQUIPMENT_PROJECTILE: + // Special case 2: the projectile is a Stored Item structure, + // but is still considered as part of the equipment. + // Case 1: Reloading + if (equippedProjectiles.itemId == itemId) + { + equippedProjectiles.amount += removeItem(itemId, + (255 - equippedProjectiles.amount)); + return EQUIP_PROJECTILES_SLOT; + } + else // Case 2: Changing projectiles. + { + short added; + added = addItem(equippedProjectiles.itemId, + equippedProjectiles.amount); + if (added == equippedProjectiles.amount) + { // Ok, we can equip + equippedProjectiles.itemId = itemId; + equippedProjectiles.amount = removeItem(itemId, 255); + return EQUIP_PROJECTILES_SLOT; + } + else // Some were unequipped. + { + equippedProjectiles.amount -= added; + return INVENTORY_FULL; + } + } + break; + + case ITEM_EQUIPMENT_ONE_HAND_WEAPON: + case ITEM_EQUIPMENT_SHIELD: + availableSlots = 2; + firstSlot = EQUIP_FIGHT1_SLOT; + secondSlot = EQUIP_FIGHT2_SLOT; + break; + case ITEM_EQUIPMENT_RING: + availableSlots = 2; + firstSlot = EQUIP_RING1_SLOT; + secondSlot = EQUIP_RING2_SLOT; + break; + case ITEM_EQUIPMENT_BREST: + availableSlots = 1; + firstSlot = EQUIP_BREST_SLOT; + break; + case ITEM_EQUIPMENT_ARMS: + availableSlots = 1; + firstSlot = EQUIP_ARMS_SLOT; + break; + case ITEM_EQUIPMENT_HEAD: + availableSlots = 1; + firstSlot = EQUIP_HEAD_SLOT; + break; + case ITEM_EQUIPMENT_LEGS: + availableSlots = 1; + firstSlot = EQUIP_LEGS_SLOT; + break; + case ITEM_EQUIPMENT_NECKLACE: + availableSlots = 1; + firstSlot = EQUIP_NECKLACE_SLOT; + break; + case ITEM_EQUIPMENT_FEET: + availableSlots = 1; + firstSlot = EQUIP_FEET_SLOT; + break; + + case ITEM_UNUSABLE: + case ITEM_USABLE: + default: + return NOT_EQUIPPABLE; + } + + switch (availableSlots) + { + case 1: + if (equippedItemList.at(firstSlot).itemId > 0) + { + if (unequipItem_(equippedItemList.at(firstSlot).itemId, + firstSlot) != INVENTORY_FULL) + return equipItem_(itemId, itemType, firstSlot); + else + return INVENTORY_FULL; + } + else // slot empty, we can equip. + { + return equipItem_(itemId, itemType, firstSlot); + } + break; + + case 2: + if (equippedItemList.at(firstSlot).itemId > 0) + { + // If old weapon is two-handed one, we can unequip + // the first slot only, and clean the second. + if (equippedItemList.at(firstSlot).itemId == + ITEM_EQUIPMENT_TWO_HANDS_WEAPON) + { + if (unequipItem_(equippedItemList.at(firstSlot).itemId, + firstSlot) != INVENTORY_FULL) + return equipItem_(itemId, itemType, firstSlot); + else + return INVENTORY_FULL; + } + + if (equippedItemList.at(secondSlot).itemId > 0) + { // Both slots are full, + // we remove the first one to equip + if (unequipItem_(equippedItemList.at(firstSlot).itemId, + firstSlot) != INVENTORY_FULL) + return equipItem_(itemId, itemType, firstSlot); + else + return INVENTORY_FULL; + } + else // Second slot empty, we can equip. + { + return equipItem_(itemId, itemType, secondSlot); + } + } + else // first slot empty, we can equip. + { + return equipItem_(itemId, itemType, firstSlot); + } + break; + + default: + return NOT_EQUIPPABLE; + } +} + +bool +Inventory::equipItem(unsigned char inventorySlot, unsigned char equipmentSlot) +{ + return false; // TODO +} + +bool +Inventory::unequipItem(unsigned int itemId) +{ + return false; // TODO +} + +bool +Inventory::unequipItem(unsigned char inventorySlot, + unsigned char equipmentSlot) +{ + return false; // TODO +} + +unsigned char +Inventory::equipItem_(unsigned int itemId, + unsigned int itemType, + unsigned char equipmentSlot) +{ + if (removeItem(itemId, 1) == 1) + { + equippedItemList.at(equipmentSlot).itemId = itemId; + equippedItemList.at(equipmentSlot).itemType = itemType; + return equipmentSlot; + } + else + return NO_ITEM_TO_EQUIP; +} + +unsigned char +Inventory::unequipItem_(unsigned int itemId, + unsigned char equipmentSlot) +{ + if (addItem(itemId, 1) == 1) + { + equippedItemList.at(equipmentSlot).itemId = 0; + equippedItemList.at(equipmentSlot).itemType = 0; + return equipmentSlot; + } + else + return INVENTORY_FULL; +} diff --git a/src/game-server/inventory.hpp b/src/game-server/inventory.hpp new file mode 100644 index 00000000..61bc5818 --- /dev/null +++ b/src/game-server/inventory.hpp @@ -0,0 +1,233 @@ +/* + * The Mana World Server + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World 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 + * any later version. + * + * The Mana World 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 The Mana World; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#ifndef INVENTORY_H +#define INVENTORY_H + +#include "game-server/being.hpp" + +enum +{ +// items in inventory : + MAX_ITEMS_IN_INVENTORY = 50, // Max 252. +// Equipment rules: +// 1 Brest equipment + EQUIP_BREST_SLOT = 0, +// 1 arms equipment + EQUIP_ARMS_SLOT = 1, +// 1 head equipment + EQUIP_HEAD_SLOT = 2, +// 1 legs equipment + EQUIP_LEGS_SLOT = 3, +// 1 feet equipment + EQUIP_FEET_SLOT = 4, +// 2 rings + EQUIP_RING1_SLOT = 5, + EQUIP_RING2_SLOT = 6, +// 1 necklace + EQUIP_NECKLACE_SLOT = 7, +// Fight: +// 2 one-handed weapons + EQUIP_FIGHT1_SLOT = 8, + EQUIP_FIGHT2_SLOT = 9, +// or 1 two-handed weapon +// or 1 one-handed weapon + 1 shield. +// Projectiles + EQUIP_PROJECTILES_SLOT = 10, +// = 10 total slots for equipment. + TOTAL_EQUIPMENT_SLOTS = 11, +// Error codes + NOT_EQUIPPABLE = 253, + NO_ITEM_TO_EQUIP = 254, + INVENTORY_FULL = 255 +}; + +/** + * Stored Item only contains id reference to items + * in the order not to carry every item info for each carried items + * in the inventory. + * Also contains amount. + */ +struct StoredItem +{ + unsigned int itemId; + unsigned char amount; +}; + +/** + * Equipped items that keeps which kind of item is in equipment. + */ +struct EquippedItem +{ + unsigned int itemId; + short itemType; +}; + +/** + * Class used to store minimal info on player's inventories + * to keep it fast. + * See Item and ItemManager to get more info on an item. + */ +class Inventory +{ + public: + /** + * Convenience function to get slot from ItemId. + * If more than one occurence is found, the first is given. + */ + unsigned char + getSlotFromId(unsigned int itemId); + + /** + * Return StoredItem + */ + StoredItem + getStoredItemAt(unsigned char slot) const { return itemList[slot]; }; + + /** + * Search in inventory and equipment if an item is present. + */ + bool + hasItem(unsigned int itemId, + bool searchInInventory = true, + bool searchInEquipment = true); + + /** + * Tells an item's amount + */ + unsigned short + getItemAmount(unsigned char slot) const { return itemList[slot].amount; }; + + /** + * Return Item reference Id + */ + unsigned int + getItemId(unsigned char slot) const { return itemList[slot].itemId; }; + + /** + * add an item with amount + * (don't create it if amount was 0) + * @return short value: Indicates the number of items added. + */ + short + addItem(unsigned int itemId, unsigned char amount = 1); + + /** + * Remove an item searched by ItemId. + * Delete if amount = 0. + * @return short value: Indicates the number of items removed. + * This function removes the given amount using every slots + * if necessary. + */ + short + removeItem(unsigned int itemId, unsigned char amount = 0); + + /** + * Remove an item searched by slot index. + * Delete if amount = 0. + * @return short value: Indicates the number of items removed. + * Removes only in the given slot. + */ + short + removeItem(unsigned char slot, unsigned char amount = 0); + + /** + * Equip an item searched by its id. + * Can equip more than one item at a time. + * @return unsigned char value: Returns the slot if successful + * or the error code if not. + */ + unsigned char + equipItem(unsigned int itemId); + + /** + * Unequip an item searched by its id. + * Can unequip more than one item at a time. + */ + bool + unequipItem(unsigned int itemId); + + /** + * Equip an item searched by its slot index. + */ + bool + equipItem(unsigned char inventorySlot, unsigned char equipmentSlot); + + /** + * Unequip an equipped item searched by its slot index. + */ + bool + unequipItem(unsigned char inventorySlot, unsigned char equipmentSlot); + + /** + * The function called to use an item applying + * only the modifiers + */ + bool + use(unsigned char slot, BeingPtr itemUser); + + /** + * The function called to use an item applying + * only the modifiers + */ + bool + use(unsigned int itemId, BeingPtr itemUser); + + private: + + /** + * Give the first free slot number in itemList. + */ + unsigned char getInventoryFreeSlot(); + + /** + * Quick equip an equipment with a given equipSlot, + * an itemId and an itemType. + * @return the equipment slot if successful, + * the error code, if not. + */ + unsigned char equipItem_(unsigned int itemId, + unsigned int itemType, + unsigned char equipmentSlot); + + /** + * Quick unequip an equipment with a given equipSlot, + * and an itemId. + * @return the Equipment slot if successful, + * the error code, if not. + */ + unsigned char unequipItem_(unsigned int itemId, + unsigned char equipmentSlot); + + + // Stored items in inventory and equipment + std::vector itemList; /**< Items in inventory */ + std::vector equippedItemList; /**< Equipped Items */ + /** + * Used to know which type of arrow is used with a bow, + * for instance + */ + StoredItem equippedProjectiles; +}; + +#endif diff --git a/src/game-server/itemmanager.cpp b/src/game-server/itemmanager.cpp index 3ce8350c..01b957a6 100644 --- a/src/game-server/itemmanager.cpp +++ b/src/game-server/itemmanager.cpp @@ -18,7 +18,7 @@ * along with The Mana World; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id:$ + * $Id$ */ #include "resourcemanager.h" @@ -81,7 +81,7 @@ ItemManager::ItemManager(std::string const &itemReferenceFile) std::string scriptName = XML::getProperty(node, "script_name", std::string()); Modifiers modifiers; - modifiers.element = (Element)XML::getProperty(node, "element", 0); + modifiers.element = XML::getProperty(node, "element", 0); modifiers.lifetime = XML::getProperty(node, "lifetime", 0); modifiers.rawStats[STAT_STRENGTH] = XML::getProperty(node, "strength", 0); modifiers.rawStats[STAT_AGILITY] = XML::getProperty(node, "agility", 0); diff --git a/src/game-server/map.cpp b/src/game-server/map.cpp new file mode 100644 index 00000000..876ba674 --- /dev/null +++ b/src/game-server/map.cpp @@ -0,0 +1,302 @@ +/* + * The Mana World + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World 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 + * any later version. + * + * The Mana World 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 The Mana World; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#include + +#include "game-server/map.hpp" + +MetaTile::MetaTile(): + whichList(0) +{ +} + + +Location::Location(int x, int y, MetaTile *tile): + x(x), y(y), tile(tile) +{ +} + +bool Location::operator< (const Location &loc) const +{ + return tile->Fcost > loc.tile->Fcost; +} + + +Map::Map(): + width(0), height(0), + tileWidth(32), tileHeight(32), + onClosedList(1), onOpenList(2) +{ + metaTiles = new MetaTile[width * height]; +} + +Map::Map(int width, int height): + width(width), height(height), + tileWidth(32), tileHeight(32), + onClosedList(1), onOpenList(2) +{ + metaTiles = new MetaTile[width * height]; +} + +Map::~Map() +{ + delete[] metaTiles; +} + +void +Map::setSize(int width, int height) +{ + this->width = width; + this->height = height; + delete[] metaTiles; + metaTiles = new MetaTile[width * height]; +} + +void +Map::setWalk(int x, int y, bool walkable) +{ + metaTiles[x + y * width].walkable = walkable; +} + +bool +Map::getWalk(int x, int y) +{ + // If walkable, check for colliding into a being + if (!tileCollides(x, y)) + { + /* + std::list::iterator i = beings.begin(); + while (i != beings.end()) { + Being *being = (*i); + // Collision when non-portal being is found at this location + if (being->x == x && being->y == y && being->job != 45) { + return false; + } + i++; + } + */ + return true; + } + else { + return false; + } +} + +bool +Map::tileCollides(int x, int y) +{ + // You can't walk outside of the map + if (x < 0 || y < 0 || x >= width || y >= height) { + return true; + } + + // Check if the tile is walkable + return !metaTiles[x + y * width].walkable; +} + +MetaTile* +Map::getMetaTile(int x, int y) +{ + return &metaTiles[x + y * width]; +} + +static int const basicCost = 100; + +std::list +Map::findPath(int startX, int startY, int destX, int destY) +{ + // Path to be built up (empty by default) + std::list path; + + // Declare open list, a list with open tiles sorted on F cost + std::priority_queue openList; + + // Return when destination not walkable + if (!getWalk(destX, destY)) return path; + + // Reset starting tile's G cost to 0 + MetaTile *startTile = getMetaTile(startX, startY); + startTile->Gcost = 0; + + // Add the start point to the open list + openList.push(Location(startX, startY, startTile)); + + bool foundPath = false; + + // Keep trying new open tiles until no more tiles to try or target found + while (!openList.empty() && !foundPath) + { + // Take the location with the lowest F cost from the open list, and + // add it to the closed list. + Location curr = openList.top(); + openList.pop(); + + // If the tile is already on the closed list, this means it has already + // been processed with a shorter path to the start point (lower G cost) + if (curr.tile->whichList == onClosedList) + { + continue; + } + + // Put the current tile on the closed list + curr.tile->whichList = onClosedList; + + // Check the adjacent tiles + for (int dy = -1; dy <= 1; dy++) + { + for (int dx = -1; dx <= 1; dx++) + { + // Calculate location of tile to check + int x = curr.x + dx; + int y = curr.y + dy; + + // Skip if if we're checking the same tile we're leaving from, + // or if the new location falls outside of the map boundaries + if ((dx == 0 && dy == 0) || + (x < 0 || y < 0 || x >= width || y >= height)) + { + continue; + } + + MetaTile *newTile = getMetaTile(x, y); + + // Skip if the tile is on the closed list or is not walkable + if (newTile->whichList == onClosedList || !getWalk(x, y)) + { + continue; + } + + // When taking a diagonal step, verify that we can skip the + // corner. We allow skipping past beings but not past non- + // walkable tiles. + if (dx != 0 && dy != 0) + { + MetaTile *t1 = getMetaTile(curr.x, curr.y + dy); + MetaTile *t2 = getMetaTile(curr.x + dx, curr.y); + + if (!(t1->walkable && t2->walkable)) + { + continue; + } + } + + // Calculate G cost for this route, ~sqrt(2) for moving diagonal + int Gcost = curr.tile->Gcost + + (dx == 0 || dy == 0 ? basicCost : basicCost * 362 / 256); + + /* Demote an arbitrary direction to speed pathfinding by + adding a defect (TODO: change depending on the desired + visual effect, e.g. a cross-product defect toward + destination). + Important: as long as the total defect along any path is + less than the basicCost, the pathfinder will still find one + of the shortest paths! */ + if (dx == 0 || dy == 0) + { + // Demote horizontal and vertical directions, so that two + // consecutive directions cannot have the same Fcost. + ++Gcost; + } + + // Skip if Gcost becomes too much + // Warning: probably not entirely accurate + if (Gcost > 20 * basicCost) + { + continue; + } + + if (newTile->whichList != onOpenList) + { + // Found a new tile (not on open nor on closed list) + + /* Update Hcost of the new tile. The pathfinder does not + work reliably if the heuristic cost is higher than the + real cost. In particular, using Manhattan distance is + forbidden here. */ + int dx = std::abs(x - destX), dy = std::abs(y - destY); + newTile->Hcost = std::abs(dx - dy) * basicCost + + std::min(dx, dy) * (basicCost * 362 / 256); + + // Set the current tile as the parent of the new tile + newTile->parentX = curr.x; + newTile->parentY = curr.y; + + // Update Gcost and Fcost of new tile + newTile->Gcost = Gcost; + newTile->Fcost = newTile->Gcost + newTile->Hcost; + + if (x != destX || y != destY) { + // Add this tile to the open list + newTile->whichList = onOpenList; + openList.push(Location(x, y, newTile)); + } + else { + // Target location was found + foundPath = true; + } + } + else if (Gcost < newTile->Gcost) + { + // Found a shorter route. + // Update Gcost and Fcost of the new tile + newTile->Gcost = Gcost; + newTile->Fcost = newTile->Gcost + newTile->Hcost; + + // Set the current tile as the parent of the new tile + newTile->parentX = curr.x; + newTile->parentY = curr.y; + + // Add this tile to the open list (it's already + // there, but this instance has a lower F score) + openList.push(Location(x, y, newTile)); + } + } + } + } + + // Two new values to indicate whether a tile is on the open or closed list, + // this way we don't have to clear all the values between each pathfinding. + onClosedList += 2; + onOpenList += 2; + + // If a path has been found, iterate backwards using the parent locations + // to extract it. + if (foundPath) + { + int pathX = destX; + int pathY = destY; + + while (pathX != startX || pathY != startY) + { + // Add the new path node to the start of the path list + path.push_front(PATH_NODE(pathX, pathY)); + + // Find out the next parent + MetaTile *tile = getMetaTile(pathX, pathY); + pathX = tile->parentX; + pathY = tile->parentY; + } + } + + return path; +} diff --git a/src/game-server/map.hpp b/src/game-server/map.hpp new file mode 100644 index 00000000..a7c1fe2a --- /dev/null +++ b/src/game-server/map.hpp @@ -0,0 +1,174 @@ +/* + * The Mana World + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World 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 + * any later version. + * + * The Mana World 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 The Mana World; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#ifndef _TMW_MAP_H +#define _TMW_MAP_H + +#include +#include +#include + + +struct PATH_NODE { + PATH_NODE(unsigned short u, unsigned short v) + : x(u), y(v) + {} + + unsigned short x, y; +}; + +/** + * A meta tile stores additional information about a location on a tile map. + * This is information that doesn't need to be repeated for each tile in each + * layer of the map. + */ +class MetaTile +{ + public: + /** + * Constructor. + */ + MetaTile(); + + // Pathfinding members + int Fcost; /**< Estimation of total path cost */ + int Gcost; /**< Cost from start to this location */ + int Hcost; /**< Estimated cost to goal */ + int whichList; /**< No list, open list or closed list */ + int parentX; /**< X coordinate of parent tile */ + int parentY; /**< Y coordinate of parent tile */ + bool walkable; /**< Can beings walk on this tile */ +}; + +/** + * A location on a tile map. Used for pathfinding, open list. + */ +class Location +{ + public: + /** + * Constructor. + */ + Location(int x, int y, MetaTile *tile); + + /** + * Comparison operator. + */ + bool operator< (const Location &loc) const; + + int x, y; + MetaTile *tile; +}; + +/** + * A tile map. + */ +class Map +{ + public: + /** + * Constructor. + */ + Map(); + + /** + * Constructor that takes initial map size as parameters. + */ + Map(int width, int height); + + /** + * Destructor. + */ + ~Map(); + + /** + * Sets the size of the map. This will destroy any existing map data. + */ + void + setSize(int width, int height); + + /** + * Get tile reference. + */ + MetaTile* + getMetaTile(int x, int y); + + /** + * Set walkability flag for a tile + */ + void + setWalk(int x, int y, bool walkable); + + /** + * Tell if a tile is walkable or not, includes checking beings. + */ + bool + getWalk(int x, int y); + + /** + * Tell if a tile collides, not including a check on beings. + */ + bool + tileCollides(int x, int y); + + /** + * Returns the width of this map. + */ + int getWidth() const + { return width; } + + /** + * Returns the height of this map. + */ + int getHeight() const + { return height; } + + /** + * Returns the tile width of this map. + */ + int getTileWidth() const + { return tileWidth; } + + /** + * Returns the tile height used by this map. + */ + int getTileHeight() const + { return tileHeight; } + + /** + * Find a path from one location to the next. + */ + std::list + findPath(int startX, int startY, + int destX, int destY); + + private: + int width, height; + int tileWidth, tileHeight; + MetaTile *metaTiles; + + // Pathfinding members + int onClosedList, onOpenList; +}; + +#endif diff --git a/src/game-server/mapcomposite.cpp b/src/game-server/mapcomposite.cpp index 8b7ef9d7..1b824447 100644 --- a/src/game-server/mapcomposite.cpp +++ b/src/game-server/mapcomposite.cpp @@ -24,8 +24,10 @@ #include #include -#include "map.h" +#include "point.h" +#include "game-server/map.hpp" #include "game-server/mapcomposite.hpp" +#include "game-server/player.hpp" /* TODO: Implement overlapping map zones instead of strict partitioning. Purpose: to decrease the number of zone changes, as overlapping allows for @@ -393,7 +395,7 @@ ZoneIterator MapComposite::getInsideRectangleIterator(Rectangle const &p) const return ZoneIterator(r, this); } -ZoneIterator MapComposite::getAroundPlayerIterator(Player *obj, int radius) const +ZoneIterator MapComposite::getAroundPlayerIterator(MovingObject *obj, int radius) const { MapRegion r1; fillRegion(r1, obj->getOldPosition(), radius); diff --git a/src/game-server/mapcomposite.hpp b/src/game-server/mapcomposite.hpp index 0623f602..526b36e2 100644 --- a/src/game-server/mapcomposite.hpp +++ b/src/game-server/mapcomposite.hpp @@ -26,11 +26,14 @@ #include -#include "object.h" -#include "player.h" - class Map; class MapComposite; +class MovingObject; +class Object; +class Player; +class Point; +class Rectangle; +class Thing; /** * Ordered sets of zones of a map. @@ -191,7 +194,7 @@ class MapComposite { * Gets an iterator on the objects around the old and new positions of * a player (including the ones that were but are now elsewhere). */ - ZoneIterator getAroundPlayerIterator(Player *, int radius) const; + ZoneIterator getAroundPlayerIterator(MovingObject *, int radius) const; /** * Gets everything related to the map. diff --git a/src/game-server/mapmanager.cpp b/src/game-server/mapmanager.cpp index d3f431b2..accf7ca0 100644 --- a/src/game-server/mapmanager.cpp +++ b/src/game-server/mapmanager.cpp @@ -23,8 +23,8 @@ #include -#include "map.h" #include "resourcemanager.h" +#include "game-server/map.hpp" #include "game-server/mapmanager.hpp" #include "game-server/mapreader.hpp" #include "utils/logger.h" diff --git a/src/game-server/mapreader.cpp b/src/game-server/mapreader.cpp index d3a49a3c..63d81a64 100644 --- a/src/game-server/mapreader.cpp +++ b/src/game-server/mapreader.cpp @@ -21,8 +21,8 @@ * $Id$ */ -#include "map.h" #include "resourcemanager.h" +#include "game-server/map.hpp" #include "game-server/mapreader.hpp" #include "utils/base64.h" #include "utils/logger.h" diff --git a/src/game-server/object.cpp b/src/game-server/object.cpp new file mode 100644 index 00000000..9921182d --- /dev/null +++ b/src/game-server/object.cpp @@ -0,0 +1,79 @@ +/* + * The Mana World Server + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World 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 any later version. + * + * The Mana World 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 The Mana World; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#include "game-server/map.hpp" +#include "game-server/mapmanager.hpp" +#include "game-server/object.hpp" + +void MovingObject::move() +{ + mOld = getPosition(); + if (mActionTime > 100) + { + // current move has not yet ended + mActionTime -= 100; + return; + } + + int tileSX = mOld.x / 32, tileSY = mOld.y / 32; + int tileDX = mDst.x / 32, tileDY = mDst.y / 32; + if (tileSX == tileDX && tileSY == tileDY) + { + // moving while staying on the same tile is free + setPosition(mDst); + mActionTime = 0; + return; + } + + Map *map = mapManager->getMap(getMapId()); + // TODO: cache pathfinding results + std::list path = map->findPath(tileSX, tileSY, tileDX, tileDY); + if (path.empty()) + { + // no path was found + mDst = mOld; + mActionTime = 0; + return; + } + + PATH_NODE prev(tileSX, tileSY); + Point pos; + do + { + PATH_NODE next = path.front(); + path.pop_front(); + mActionTime += (prev.x != next.x && prev.y != next.y) + ? mSpeed * 362 / 256 : mSpeed; + if (path.empty()) + { + // skip last tile center + pos = mDst; + break; + } + pos.x = next.x * 32 + 16; + pos.y = next.y * 32 + 16; + } + while (mActionTime < 100); + setPosition(pos); + + mActionTime = mActionTime > 100 ? mActionTime - 100 : 0; +} diff --git a/src/game-server/object.hpp b/src/game-server/object.hpp new file mode 100644 index 00000000..498680e4 --- /dev/null +++ b/src/game-server/object.hpp @@ -0,0 +1,258 @@ +/* + * The Mana World Server + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World 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 any later version. + * + * The Mana World 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 The Mana World; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + + +#ifndef _TMWSERV_OBJECT_H_ +#define _TMWSERV_OBJECT_H_ + +#include + +#include "point.h" + +// Object type enumeration +enum +{ + OBJECT_ITEM = 0, // A simple item + OBJECT_ACTOR, // An item that toggle map/quest actions (doors, switchs, ...) and can speak (map panels). + OBJECT_NPC, // Non-Playable-Character is an actor capable of movement and maybe actions + OBJECT_MONSTER, // A monster (moving actor with AI. Should be able to toggle map/quest actions, too) + OBJECT_PLAYER, // A normal being + OBJECT_OTHER // Server-only object +}; + +class MapComposite; + +enum +{ + NEW_ON_MAP = 1, + NEW_DESTINATION = 2, + ATTACK = 4 +}; + +/** + * Base class for in-game objects. + */ +class Thing +{ + public: + /** + * Constructor. + */ + Thing(int type) + : mType(type) + {} + + /** + * Empty virtual destructor. + */ + virtual ~Thing() {} + + /** + * Gets type. + * + * @return the type. + */ + int getType() const + { return mType; } + + /** + * Returns whether this thing is visible on the map or not. (Object) + */ + bool isVisible() const + { return mType != OBJECT_OTHER; } + + /** + * Returns whether this thing can move on the map or not. (MovingObject) + */ + bool canMove() const + { return mType == OBJECT_PLAYER || mType == OBJECT_MONSTER || + mType == OBJECT_NPC; } + + /** + * Returns whether this thing can fight or not. (Being) + */ + bool canFight() const + { return mType == OBJECT_PLAYER || mType == OBJECT_MONSTER; } + + /** + * Updates the internal status. + */ + virtual void + update() = 0; + + /** + * Gets the map this thing is located on. + * + * @return ID of map. + */ + int getMapId() const + { return mMapId; } + + /** + * Sets the map this thing is located on. + */ + void setMapId(int mapId) + { mMapId = mapId; } + + private: + unsigned short mMapId; /**< id of the map being is on */ + char mType; /**< Object type */ +}; + +/** + * Generic client-visible object definition. + */ +class Object: public Thing +{ + public: + /** + * Constructor. + */ + Object(int type) + : Thing(type), + mUpdateFlags(0) + {} + + /** + * Sets the coordinates. + * + * @param p the coordinates. + */ + void setPosition(const Point &p) + { mPos = p; } + + /** + * Gets the coordinates. + * + * @return the coordinates. + */ + Point const &getPosition() const + { return mPos; } + + /** + * Gets what changed in the object. + */ + int getUpdateFlags() const + { return mUpdateFlags; } + + /** + * Sets some changes in the object. + */ + void raiseUpdateFlags(int n) + { mUpdateFlags |= n; } + + /** + * Clears changes in the object. + */ + void clearUpdateFlags() + { mUpdateFlags = 0; } + + private: + char mUpdateFlags; /**< changes in object status */ + Point mPos; /**< coordinates */ +}; + +/** + * Base class for in-game moving objects. + */ +class MovingObject: public Object +{ + public: + /** + * Proxy constructor. + */ + MovingObject(int type, int id) + : Object(type), + mPublicID(id), + mDirection(0), + mActionTime(0) + {} + + /** + * Gets the destination coordinates of the object. + */ + Point const &getDestination() const + { return mDst; } + + /** + * Sets the destination coordinates of the object. + */ + void setDestination(Point dst) + { mDst = dst; raiseUpdateFlags(NEW_DESTINATION); } + + /** + * Gets the old coordinates of the object. + */ + Point getOldPosition() const + { return mOld; } + + /** + * Sete object direction + */ + void setDirection(int direction) + { mDirection = direction; } + + /** + * Gets object direction + */ + + unsigned char getDirection() const + { return mDirection; } + + /** + * Sets object speed. + */ + void setSpeed(unsigned s) + { mSpeed = s; } + + /** + * Moves the object toward its destination. + */ + void move(); + + /** + * Get public ID. + * + * @return the public ID, 65535 if none yet. + */ + int getPublicID() const + { return mPublicID; } + + /** + * Set public ID. + * The object shall not have any public ID yet. + */ + void setPublicID(int id) + { mPublicID = id; } + + private: + unsigned short mPublicID; /**< Object ID sent to clients (unique with respect to the map) */ + Point mDst; /**< target coordinates */ + Point mOld; /**< old coordinates */ + unsigned short mSpeed; /**< speed */ + + protected: + unsigned char mDirection; /**< Facing direction */ + unsigned short mActionTime; /**< delay until next action */ +}; + +#endif // _TMWSERV_OBJECT_H_ diff --git a/src/game-server/player.cpp b/src/game-server/player.cpp new file mode 100644 index 00000000..294239f9 --- /dev/null +++ b/src/game-server/player.cpp @@ -0,0 +1,87 @@ +/* + * The Mana World Server + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World 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 any later version. + * + * The Mana World 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 The Mana World; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#include + +#include "defines.h" +#include "game-server/player.hpp" + +/** + * Update the internal status. + */ +void Player::update() +{ + // computed stats. + setStat(STAT_HEAT, 20 + (20 * getRawStat(STAT_VITALITY))); + setStat(STAT_ATTACK, 10 + getRawStat(STAT_STRENGTH)); + setStat(STAT_DEFENCE, 10 + getRawStat(STAT_STRENGTH)); + setStat(STAT_MAGIC, 10 + getRawStat(STAT_INTELLIGENCE)); + setStat(STAT_ACCURACY, 50 + getRawStat(STAT_DEXTERITY)); + setStat(STAT_SPEED, getRawStat(STAT_DEXTERITY)); + + // Update persistent data. + setPos(getPosition()); + setMap(getMapId()); + + // attacking + if (mIsAttacking) + { + // plausibility check of attack command + if (mActionTime <= 0) + { + // request perform attack + mActionTime = 1000; + mIsAttacking = false; + raiseUpdateFlags(ATTACK); + } + } +} + +void Player::setInventory(const Inventory &inven) +{ + inventory = inven; +} + +bool Player::addItem(unsigned int itemId, unsigned char amount) +{ + return inventory.addItem(itemId, amount); +} + +bool Player::removeItem(unsigned int itemId, unsigned char amount) +{ + return inventory.removeItem(itemId, amount); +} + +bool Player::hasItem(unsigned int itemId) +{ + return inventory.hasItem(itemId); +} + +bool Player::equip(unsigned char slot) +{ + return false; // TODO +} + +bool Player::unequip(unsigned char slot) +{ + return false; // TODO +} diff --git a/src/game-server/player.hpp b/src/game-server/player.hpp new file mode 100644 index 00000000..4ecef616 --- /dev/null +++ b/src/game-server/player.hpp @@ -0,0 +1,124 @@ +/* + * The Mana World Server + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World 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 any later version. + * + * The Mana World 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 The Mana World; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#ifndef _TMWSERV_PLAYER_H_ +#define _TMWSERV_PLAYER_H_ + +#include +#include + +#include "playerdata.hpp" +#include "game-server/being.hpp" +#include "game-server/inventory.hpp" + +class GameClient; + +class Player : public Being, public PlayerData +{ + public: + + Player(std::string const &name, int id = -1) + : Being(OBJECT_PLAYER, 65535), + PlayerData(name, id), + mClient(NULL), + mIsAttacking(false) + {} + + /** + * Updates the internal status. + */ + void update(); + + /** + * Sets inventory. + */ + void + setInventory(const Inventory &inven); + + /** + * Adds item with ID to inventory. + * + * @return Item add success/failure + */ + bool + addItem(unsigned int itemId, unsigned char amount = 1); + + /** + * Removes item with ID from inventory. + * + * @return Item delete success/failure + */ + bool + removeItem(unsigned int itemId, unsigned char amount = 0); + + /** + * Checks if character has an item. + * + * @return true if being has item, false otherwise + */ + bool + hasItem(unsigned int itemId); + + /** + * Equips item with ID in equipment slot. + * + * @return Equip success/failure + */ + bool + equip(unsigned char slot); + + /** + * Un-equips item. + * + * @return Un-equip success/failure + */ + bool + unequip(unsigned char slot); + + /** + * Set attacking state + **/ + void setAttacking(bool isAttacking) + { mIsAttacking = isAttacking; } + + /** + * Gets client computer. + */ + GameClient *getClient() const + { return mClient; } + + /** + * Sets client computer. + */ + void setClient(GameClient *c) + { mClient = c; } + + private: + Player(Player const &); + Player &operator=(Player const &); + + GameClient *mClient; /**< Client computer. */ + Inventory inventory; /**< Player inventory and equipment. */ + bool mIsAttacking; /**< Attacking state. */ +}; + +#endif // _TMWSERV_PLAYER_H_ diff --git a/src/game-server/state.cpp b/src/game-server/state.cpp index 7e78857e..9763d459 100644 --- a/src/game-server/state.cpp +++ b/src/game-server/state.cpp @@ -23,12 +23,11 @@ #include -#include "controller.h" #include "defines.h" -#include "map.h" #include "point.h" #include "game-server/accountconnection.hpp" #include "game-server/gamehandler.hpp" +#include "game-server/map.hpp" #include "game-server/mapcomposite.hpp" #include "game-server/mapmanager.hpp" #include "game-server/state.hpp" diff --git a/src/game-server/trigger.cpp b/src/game-server/trigger.cpp index 22a25697..469fb544 100644 --- a/src/game-server/trigger.cpp +++ b/src/game-server/trigger.cpp @@ -21,8 +21,8 @@ * $Id$ */ -#include "player.h" #include "game-server/mapcomposite.hpp" +#include "game-server/object.hpp" #include "game-server/state.hpp" #include "game-server/trigger.hpp" diff --git a/src/game-server/trigger.hpp b/src/game-server/trigger.hpp index a3149812..bb4f776d 100644 --- a/src/game-server/trigger.hpp +++ b/src/game-server/trigger.hpp @@ -24,7 +24,7 @@ #ifndef _TMWSERV_TRIGGER #define _TMWSERV_TRIGGER -#include "object.h" +class Object; class TriggerAction { diff --git a/src/inventory.cpp b/src/inventory.cpp deleted file mode 100644 index 97f29737..00000000 --- a/src/inventory.cpp +++ /dev/null @@ -1,419 +0,0 @@ -/* - * The Mana World Server - * Copyright 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World 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 - * any later version. - * - * The Mana World 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 The Mana World; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id$ - */ - -#include "inventory.h" -#include "game-server/itemmanager.hpp" - -// --------- -// Items -// --------- -unsigned char -Inventory::getInventoryFreeSlot() -{ - for (int a = 0; a < MAX_ITEMS_IN_INVENTORY; a++) - { - if (itemList.at(a).amount == 0) - return a; - } - return INVENTORY_FULL; -} - -unsigned char -Inventory::getSlotFromId(const unsigned int itemId) -{ - for (int a = 0; a < MAX_ITEMS_IN_INVENTORY; a++) - { - if (itemList.at(a).itemId == itemId) - return a; - } - return INVENTORY_FULL; -} - -bool -Inventory::hasItem(unsigned int itemId, - bool searchInInventory, - bool searchInEquipment) -{ - bool hasItem = false; - // Search in inventory - if (searchInInventory) - { - std::vector::iterator iter = itemList.begin(); - for (iter = itemList.begin(); iter != itemList.end(); ++iter) - { - if (iter->itemId == itemId) - hasItem = true; - } - } - // Search in equipment - if (searchInEquipment) - { - std::vector::iterator equipIter = equippedItemList.begin(); - for (equipIter = equippedItemList.begin(); - equipIter != equippedItemList.end(); - ++equipIter) - { - if (equipIter->itemId == itemId) - hasItem = true; - } - if (equippedProjectiles.itemId == itemId) - hasItem = true; - } - return hasItem; -} - -short -Inventory::addItem(unsigned int itemId, unsigned char amount) -{ - // We get the max number of item we can have in the same slot - // for the given item. - unsigned char maxPerSlot = itemManager->getMaxPerSlot(itemId); - // We'll add items in slots with the item type and in free slots - // until it's all done or until the inventory will be all parsed. - // Searching for items with the same Id in the inventory, before - // seeking a free slot. - unsigned char amountToAdd = amount; - - // Parsing inventory - unsigned char currentAmountInSlot = 0; - std::vector::iterator iter = itemList.begin(); - for (iter = itemList.begin(); iter != itemList.end(); ++iter) - { - currentAmountInSlot = iter->amount; - // If a slot has got place for some more of such an item. - if (iter->itemId == itemId && currentAmountInSlot < maxPerSlot) - { - // If there isn't enough space to put every item in the slot. - // We add the difference. - if ((maxPerSlot - currentAmountInSlot) < amountToAdd) - { - iter->amount += (maxPerSlot - currentAmountInSlot); - amountToAdd -= (maxPerSlot - currentAmountInSlot); - } - else // there is enough to add everything. - { - iter->amount += amountToAdd; - amountToAdd = 0; // Ok! - } - } - // Or if there is an empty slot. - else if (iter->amount == 0) - { - // We add the item in the new slot (setting also the Id.) - if (maxPerSlot < amountToAdd) - { - iter->amount = maxPerSlot; - amountToAdd -= maxPerSlot; - } - else - { - iter->amount += amountToAdd; - amountToAdd = 0; // Ok! - } - iter->itemId = itemId; - } - } - - return (short)(amount - amountToAdd); -} - -short -Inventory::removeItem(unsigned int itemId, unsigned char amount) -{ - // We'll remove items in slots with the item type - // until it's all done or until the inventory will be all parsed. - // Searching for items with the same Id in the inventory - unsigned char amountToRemove = amount; - - // Parsing inventory - unsigned char currentAmountInSlot = 0; - std::vector::iterator iter = itemList.begin(); - for (iter = itemList.begin(); iter != itemList.end(); ++iter) - { - currentAmountInSlot = iter->amount; - // If a slot has got such an item, remove it - if (iter->itemId == itemId && currentAmountInSlot > 0) - { - // If there isn't enough to finish, we remove the difference - // Emptying the slot, so we clean also the itemId. - if (currentAmountInSlot <= amountToRemove) - { - amountToRemove -= currentAmountInSlot; - iter->amount = 0; - iter->itemId = 0; - } - else // there is enough to remove everything. - { - iter->amount -= amountToRemove; - amountToRemove = 0; // Ok! - } - } - } - return (short)(amount - amountToRemove); -} - -short -Inventory::removeItem(unsigned char slot, unsigned char amount) -{ - if (itemList.at(slot).amount < amount) - { - unsigned char value = itemList.at(slot).amount; - itemList.at(slot).amount = 0; - return (short)value; - } - else - { - itemList.at(slot).amount -= amount; - return amount; - } -} - -bool -Inventory::use(unsigned char slot, BeingPtr itemUser) -{ - return false; // TODO -} - -bool -Inventory::use(unsigned int itemId, BeingPtr itemUser) -{ - return false; // TODO -} - -// --------- -// Equipment -// --------- -unsigned char -Inventory::equipItem(unsigned int itemId) -{ - // First, we look for the item in the player's inventory. - if (!hasItem(itemId, true, false)) - return false; - - unsigned char availableSlots = 0, firstSlot = 0, secondSlot = 0; - - unsigned short itemType = itemManager->getItemType(itemId); - switch (itemType) - { - case ITEM_EQUIPMENT_TWO_HANDS_WEAPON: - // Special case 1, the two one-handed weapons are to be placed back - // in the inventory, if there are any. - if (equippedItemList.at(EQUIP_FIGHT1_SLOT).itemId > 0) - { // Slot 1 full - // old two-handed weapon case: - if (equippedItemList.at(EQUIP_FIGHT1_SLOT).itemType - == ITEM_EQUIPMENT_TWO_HANDS_WEAPON) - { - equippedItemList.at(EQUIP_FIGHT2_SLOT).itemId = 0; - equippedItemList.at(EQUIP_FIGHT2_SLOT).itemType = 0; - } - - if (unequipItem_(equippedItemList.at(EQUIP_FIGHT1_SLOT).itemId, - EQUIP_FIGHT1_SLOT) == INVENTORY_FULL) - return INVENTORY_FULL; - } - if (equippedItemList.at(EQUIP_FIGHT2_SLOT).itemId > 0) - { // Slot 2 full - if (unequipItem_(equippedItemList.at(EQUIP_FIGHT2_SLOT).itemId, - EQUIP_FIGHT2_SLOT) == INVENTORY_FULL) - return INVENTORY_FULL; - } - // Only the slot 1 needs to be updated. - return equipItem_(itemId, itemType, EQUIP_FIGHT1_SLOT); - break; - - case ITEM_EQUIPMENT_PROJECTILE: - // Special case 2: the projectile is a Stored Item structure, - // but is still considered as part of the equipment. - // Case 1: Reloading - if (equippedProjectiles.itemId == itemId) - { - equippedProjectiles.amount += removeItem(itemId, - (255 - equippedProjectiles.amount)); - return EQUIP_PROJECTILES_SLOT; - } - else // Case 2: Changing projectiles. - { - short added; - added = addItem(equippedProjectiles.itemId, - equippedProjectiles.amount); - if (added == equippedProjectiles.amount) - { // Ok, we can equip - equippedProjectiles.itemId = itemId; - equippedProjectiles.amount = removeItem(itemId, 255); - return EQUIP_PROJECTILES_SLOT; - } - else // Some were unequipped. - { - equippedProjectiles.amount -= added; - return INVENTORY_FULL; - } - } - break; - - case ITEM_EQUIPMENT_ONE_HAND_WEAPON: - case ITEM_EQUIPMENT_SHIELD: - availableSlots = 2; - firstSlot = EQUIP_FIGHT1_SLOT; - secondSlot = EQUIP_FIGHT2_SLOT; - break; - case ITEM_EQUIPMENT_RING: - availableSlots = 2; - firstSlot = EQUIP_RING1_SLOT; - secondSlot = EQUIP_RING2_SLOT; - break; - case ITEM_EQUIPMENT_BREST: - availableSlots = 1; - firstSlot = EQUIP_BREST_SLOT; - break; - case ITEM_EQUIPMENT_ARMS: - availableSlots = 1; - firstSlot = EQUIP_ARMS_SLOT; - break; - case ITEM_EQUIPMENT_HEAD: - availableSlots = 1; - firstSlot = EQUIP_HEAD_SLOT; - break; - case ITEM_EQUIPMENT_LEGS: - availableSlots = 1; - firstSlot = EQUIP_LEGS_SLOT; - break; - case ITEM_EQUIPMENT_NECKLACE: - availableSlots = 1; - firstSlot = EQUIP_NECKLACE_SLOT; - break; - case ITEM_EQUIPMENT_FEET: - availableSlots = 1; - firstSlot = EQUIP_FEET_SLOT; - break; - - case ITEM_UNUSABLE: - case ITEM_USABLE: - default: - return NOT_EQUIPPABLE; - } - - switch (availableSlots) - { - case 1: - if (equippedItemList.at(firstSlot).itemId > 0) - { - if (unequipItem_(equippedItemList.at(firstSlot).itemId, - firstSlot) != INVENTORY_FULL) - return equipItem_(itemId, itemType, firstSlot); - else - return INVENTORY_FULL; - } - else // slot empty, we can equip. - { - return equipItem_(itemId, itemType, firstSlot); - } - break; - - case 2: - if (equippedItemList.at(firstSlot).itemId > 0) - { - // If old weapon is two-handed one, we can unequip - // the first slot only, and clean the second. - if (equippedItemList.at(firstSlot).itemId == - ITEM_EQUIPMENT_TWO_HANDS_WEAPON) - { - if (unequipItem_(equippedItemList.at(firstSlot).itemId, - firstSlot) != INVENTORY_FULL) - return equipItem_(itemId, itemType, firstSlot); - else - return INVENTORY_FULL; - } - - if (equippedItemList.at(secondSlot).itemId > 0) - { // Both slots are full, - // we remove the first one to equip - if (unequipItem_(equippedItemList.at(firstSlot).itemId, - firstSlot) != INVENTORY_FULL) - return equipItem_(itemId, itemType, firstSlot); - else - return INVENTORY_FULL; - } - else // Second slot empty, we can equip. - { - return equipItem_(itemId, itemType, secondSlot); - } - } - else // first slot empty, we can equip. - { - return equipItem_(itemId, itemType, firstSlot); - } - break; - - default: - return NOT_EQUIPPABLE; - } -} - -bool -Inventory::equipItem(unsigned char inventorySlot, unsigned char equipmentSlot) -{ - return false; // TODO -} - -bool -Inventory::unequipItem(unsigned int itemId) -{ - return false; // TODO -} - -bool -Inventory::unequipItem(unsigned char inventorySlot, - unsigned char equipmentSlot) -{ - return false; // TODO -} - -unsigned char -Inventory::equipItem_(unsigned int itemId, - unsigned int itemType, - unsigned char equipmentSlot) -{ - if (removeItem(itemId, 1) == 1) - { - equippedItemList.at(equipmentSlot).itemId = itemId; - equippedItemList.at(equipmentSlot).itemType = itemType; - return equipmentSlot; - } - else - return NO_ITEM_TO_EQUIP; -} - -unsigned char -Inventory::unequipItem_(unsigned int itemId, - unsigned char equipmentSlot) -{ - if (addItem(itemId, 1) == 1) - { - equippedItemList.at(equipmentSlot).itemId = 0; - equippedItemList.at(equipmentSlot).itemType = 0; - return equipmentSlot; - } - else - return INVENTORY_FULL; -} diff --git a/src/inventory.h b/src/inventory.h deleted file mode 100644 index d2e7961c..00000000 --- a/src/inventory.h +++ /dev/null @@ -1,230 +0,0 @@ -/* - * The Mana World Server - * Copyright 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World 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 - * any later version. - * - * The Mana World 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 The Mana World; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id$ - */ - -#ifndef INVENTORY_H -#define INVENTORY_H - -#include "being.h" - -// items in inventory : -const unsigned char MAX_ITEMS_IN_INVENTORY = 50, // Max 252. -// Equipment rules: -// 1 Brest equipment - EQUIP_BREST_SLOT = 0, -// 1 arms equipment - EQUIP_ARMS_SLOT = 1, -// 1 head equipment - EQUIP_HEAD_SLOT = 2, -// 1 legs equipment - EQUIP_LEGS_SLOT = 3, -// 1 feet equipment - EQUIP_FEET_SLOT = 4, -// 2 rings - EQUIP_RING1_SLOT = 5, - EQUIP_RING2_SLOT = 6, -// 1 necklace - EQUIP_NECKLACE_SLOT = 7, -// Fight: -// 2 one-handed weapons - EQUIP_FIGHT1_SLOT = 8, - EQUIP_FIGHT2_SLOT = 9, -// or 1 two-handed weapon -// or 1 one-handed weapon + 1 shield. -// Projectiles - EQUIP_PROJECTILES_SLOT = 10, -// = 10 total slots for equipment. - TOTAL_EQUIPMENT_SLOTS = 11, -// Error codes - NOT_EQUIPPABLE = 253, - NO_ITEM_TO_EQUIP = 254, - INVENTORY_FULL = 255; - -/** - * Stored Item only contains id reference to items - * in the order not to carry every item info for each carried items - * in the inventory. - * Also contains amount. - */ -struct StoredItem -{ - unsigned int itemId; - unsigned char amount; -}; - -/** - * Equipped items that keeps which kind of item is in equipment. - */ -struct EquippedItem -{ - unsigned int itemId; - short itemType; -}; - -/** - * Class used to store minimal info on player's inventories - * to keep it fast. - * See Item and ItemManager to get more info on an item. - */ -class Inventory -{ - public: - /** - * Convenience function to get slot from ItemId. - * If more than one occurence is found, the first is given. - */ - unsigned char - getSlotFromId(unsigned int itemId); - - /** - * Return StoredItem - */ - StoredItem - getStoredItemAt(unsigned char slot) const { return itemList[slot]; }; - - /** - * Search in inventory and equipment if an item is present. - */ - bool - hasItem(unsigned int itemId, - bool searchInInventory = true, - bool searchInEquipment = true); - - /** - * Tells an item's amount - */ - unsigned short - getItemAmount(unsigned char slot) const { return itemList[slot].amount; }; - - /** - * Return Item reference Id - */ - unsigned int - getItemId(unsigned char slot) const { return itemList[slot].itemId; }; - - /** - * add an item with amount - * (don't create it if amount was 0) - * @return short value: Indicates the number of items added. - */ - short - addItem(unsigned int itemId, unsigned char amount = 1); - - /** - * Remove an item searched by ItemId. - * Delete if amount = 0. - * @return short value: Indicates the number of items removed. - * This function removes the given amount using every slots - * if necessary. - */ - short - removeItem(unsigned int itemId, unsigned char amount = 0); - - /** - * Remove an item searched by slot index. - * Delete if amount = 0. - * @return short value: Indicates the number of items removed. - * Removes only in the given slot. - */ - short - removeItem(unsigned char slot, unsigned char amount = 0); - - /** - * Equip an item searched by its id. - * Can equip more than one item at a time. - * @return unsigned char value: Returns the slot if successful - * or the error code if not. - */ - unsigned char - equipItem(unsigned int itemId); - - /** - * Unequip an item searched by its id. - * Can unequip more than one item at a time. - */ - bool - unequipItem(unsigned int itemId); - - /** - * Equip an item searched by its slot index. - */ - bool - equipItem(unsigned char inventorySlot, unsigned char equipmentSlot); - - /** - * Unequip an equipped item searched by its slot index. - */ - bool - unequipItem(unsigned char inventorySlot, unsigned char equipmentSlot); - - /** - * The function called to use an item applying - * only the modifiers - */ - bool - use(unsigned char slot, BeingPtr itemUser); - - /** - * The function called to use an item applying - * only the modifiers - */ - bool - use(unsigned int itemId, BeingPtr itemUser); - - private: - - /** - * Give the first free slot number in itemList. - */ - unsigned char getInventoryFreeSlot(); - - /** - * Quick equip an equipment with a given equipSlot, - * an itemId and an itemType. - * @return the equipment slot if successful, - * the error code, if not. - */ - unsigned char equipItem_(unsigned int itemId, - unsigned int itemType, - unsigned char equipmentSlot); - - /** - * Quick unequip an equipment with a given equipSlot, - * and an itemId. - * @return the Equipment slot if successful, - * the error code, if not. - */ - unsigned char unequipItem_(unsigned int itemId, - unsigned char equipmentSlot); - - - // Stored items in inventory and equipment - std::vector itemList; /**< Items in inventory */ - std::vector equippedItemList; /**< Equipped Items */ - /** - * Used to know which type of arrow is used with a bow, - * for instance - */ - StoredItem equippedProjectiles; -}; - -#endif diff --git a/src/item.h b/src/item.h index ea9dd2d5..3ac9c68d 100644 --- a/src/item.h +++ b/src/item.h @@ -24,7 +24,8 @@ #ifndef ITEM_H #define ITEM_H -#include "being.h" +#include "playerdata.hpp" +#include "game-server/being.hpp" /** * Enumeration of available Item types. @@ -103,7 +104,7 @@ typedef enum BeingStateEffect { struct Modifiers { // General - Element element; /**< Item Element */ + unsigned char element; /**< Item Element */ BeingStateEffect beingStateEffect; /**< Being State (dis)alteration */ unsigned short lifetime; /**< Modifiers lifetime in seconds. */ diff --git a/src/map.cpp b/src/map.cpp deleted file mode 100644 index ec6767af..00000000 --- a/src/map.cpp +++ /dev/null @@ -1,305 +0,0 @@ -/* - * The Mana World - * Copyright 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World 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 - * any later version. - * - * The Mana World 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 The Mana World; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id$ - */ - -#include "map.h" - -#include - -#include "being.h" - - -MetaTile::MetaTile(): - whichList(0) -{ -} - - -Location::Location(int x, int y, MetaTile *tile): - x(x), y(y), tile(tile) -{ -} - -bool Location::operator< (const Location &loc) const -{ - return tile->Fcost > loc.tile->Fcost; -} - - -Map::Map(): - width(0), height(0), - tileWidth(32), tileHeight(32), - onClosedList(1), onOpenList(2) -{ - metaTiles = new MetaTile[width * height]; -} - -Map::Map(int width, int height): - width(width), height(height), - tileWidth(32), tileHeight(32), - onClosedList(1), onOpenList(2) -{ - metaTiles = new MetaTile[width * height]; -} - -Map::~Map() -{ - delete[] metaTiles; -} - -void -Map::setSize(int width, int height) -{ - this->width = width; - this->height = height; - delete[] metaTiles; - metaTiles = new MetaTile[width * height]; -} - -void -Map::setWalk(int x, int y, bool walkable) -{ - metaTiles[x + y * width].walkable = walkable; -} - -bool -Map::getWalk(int x, int y) -{ - // If walkable, check for colliding into a being - if (!tileCollides(x, y)) - { - /* - std::list::iterator i = beings.begin(); - while (i != beings.end()) { - Being *being = (*i); - // Collision when non-portal being is found at this location - if (being->x == x && being->y == y && being->job != 45) { - return false; - } - i++; - } - */ - return true; - } - else { - return false; - } -} - -bool -Map::tileCollides(int x, int y) -{ - // You can't walk outside of the map - if (x < 0 || y < 0 || x >= width || y >= height) { - return true; - } - - // Check if the tile is walkable - return !metaTiles[x + y * width].walkable; -} - -MetaTile* -Map::getMetaTile(int x, int y) -{ - return &metaTiles[x + y * width]; -} - -static int const basicCost = 100; - -std::list -Map::findPath(int startX, int startY, int destX, int destY) -{ - // Path to be built up (empty by default) - std::list path; - - // Declare open list, a list with open tiles sorted on F cost - std::priority_queue openList; - - // Return when destination not walkable - if (!getWalk(destX, destY)) return path; - - // Reset starting tile's G cost to 0 - MetaTile *startTile = getMetaTile(startX, startY); - startTile->Gcost = 0; - - // Add the start point to the open list - openList.push(Location(startX, startY, startTile)); - - bool foundPath = false; - - // Keep trying new open tiles until no more tiles to try or target found - while (!openList.empty() && !foundPath) - { - // Take the location with the lowest F cost from the open list, and - // add it to the closed list. - Location curr = openList.top(); - openList.pop(); - - // If the tile is already on the closed list, this means it has already - // been processed with a shorter path to the start point (lower G cost) - if (curr.tile->whichList == onClosedList) - { - continue; - } - - // Put the current tile on the closed list - curr.tile->whichList = onClosedList; - - // Check the adjacent tiles - for (int dy = -1; dy <= 1; dy++) - { - for (int dx = -1; dx <= 1; dx++) - { - // Calculate location of tile to check - int x = curr.x + dx; - int y = curr.y + dy; - - // Skip if if we're checking the same tile we're leaving from, - // or if the new location falls outside of the map boundaries - if ((dx == 0 && dy == 0) || - (x < 0 || y < 0 || x >= width || y >= height)) - { - continue; - } - - MetaTile *newTile = getMetaTile(x, y); - - // Skip if the tile is on the closed list or is not walkable - if (newTile->whichList == onClosedList || !getWalk(x, y)) - { - continue; - } - - // When taking a diagonal step, verify that we can skip the - // corner. We allow skipping past beings but not past non- - // walkable tiles. - if (dx != 0 && dy != 0) - { - MetaTile *t1 = getMetaTile(curr.x, curr.y + dy); - MetaTile *t2 = getMetaTile(curr.x + dx, curr.y); - - if (!(t1->walkable && t2->walkable)) - { - continue; - } - } - - // Calculate G cost for this route, ~sqrt(2) for moving diagonal - int Gcost = curr.tile->Gcost + - (dx == 0 || dy == 0 ? basicCost : basicCost * 362 / 256); - - /* Demote an arbitrary direction to speed pathfinding by - adding a defect (TODO: change depending on the desired - visual effect, e.g. a cross-product defect toward - destination). - Important: as long as the total defect along any path is - less than the basicCost, the pathfinder will still find one - of the shortest paths! */ - if (dx == 0 || dy == 0) - { - // Demote horizontal and vertical directions, so that two - // consecutive directions cannot have the same Fcost. - ++Gcost; - } - - // Skip if Gcost becomes too much - // Warning: probably not entirely accurate - if (Gcost > 20 * basicCost) - { - continue; - } - - if (newTile->whichList != onOpenList) - { - // Found a new tile (not on open nor on closed list) - - /* Update Hcost of the new tile. The pathfinder does not - work reliably if the heuristic cost is higher than the - real cost. In particular, using Manhattan distance is - forbidden here. */ - int dx = std::abs(x - destX), dy = std::abs(y - destY); - newTile->Hcost = std::abs(dx - dy) * basicCost + - std::min(dx, dy) * (basicCost * 362 / 256); - - // Set the current tile as the parent of the new tile - newTile->parentX = curr.x; - newTile->parentY = curr.y; - - // Update Gcost and Fcost of new tile - newTile->Gcost = Gcost; - newTile->Fcost = newTile->Gcost + newTile->Hcost; - - if (x != destX || y != destY) { - // Add this tile to the open list - newTile->whichList = onOpenList; - openList.push(Location(x, y, newTile)); - } - else { - // Target location was found - foundPath = true; - } - } - else if (Gcost < newTile->Gcost) - { - // Found a shorter route. - // Update Gcost and Fcost of the new tile - newTile->Gcost = Gcost; - newTile->Fcost = newTile->Gcost + newTile->Hcost; - - // Set the current tile as the parent of the new tile - newTile->parentX = curr.x; - newTile->parentY = curr.y; - - // Add this tile to the open list (it's already - // there, but this instance has a lower F score) - openList.push(Location(x, y, newTile)); - } - } - } - } - - // Two new values to indicate whether a tile is on the open or closed list, - // this way we don't have to clear all the values between each pathfinding. - onClosedList += 2; - onOpenList += 2; - - // If a path has been found, iterate backwards using the parent locations - // to extract it. - if (foundPath) - { - int pathX = destX; - int pathY = destY; - - while (pathX != startX || pathY != startY) - { - // Add the new path node to the start of the path list - path.push_front(PATH_NODE(pathX, pathY)); - - // Find out the next parent - MetaTile *tile = getMetaTile(pathX, pathY); - pathX = tile->parentX; - pathY = tile->parentY; - } - } - - return path; -} diff --git a/src/map.h b/src/map.h deleted file mode 100644 index a7c1fe2a..00000000 --- a/src/map.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - * The Mana World - * Copyright 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World 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 - * any later version. - * - * The Mana World 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 The Mana World; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id$ - */ - -#ifndef _TMW_MAP_H -#define _TMW_MAP_H - -#include -#include -#include - - -struct PATH_NODE { - PATH_NODE(unsigned short u, unsigned short v) - : x(u), y(v) - {} - - unsigned short x, y; -}; - -/** - * A meta tile stores additional information about a location on a tile map. - * This is information that doesn't need to be repeated for each tile in each - * layer of the map. - */ -class MetaTile -{ - public: - /** - * Constructor. - */ - MetaTile(); - - // Pathfinding members - int Fcost; /**< Estimation of total path cost */ - int Gcost; /**< Cost from start to this location */ - int Hcost; /**< Estimated cost to goal */ - int whichList; /**< No list, open list or closed list */ - int parentX; /**< X coordinate of parent tile */ - int parentY; /**< Y coordinate of parent tile */ - bool walkable; /**< Can beings walk on this tile */ -}; - -/** - * A location on a tile map. Used for pathfinding, open list. - */ -class Location -{ - public: - /** - * Constructor. - */ - Location(int x, int y, MetaTile *tile); - - /** - * Comparison operator. - */ - bool operator< (const Location &loc) const; - - int x, y; - MetaTile *tile; -}; - -/** - * A tile map. - */ -class Map -{ - public: - /** - * Constructor. - */ - Map(); - - /** - * Constructor that takes initial map size as parameters. - */ - Map(int width, int height); - - /** - * Destructor. - */ - ~Map(); - - /** - * Sets the size of the map. This will destroy any existing map data. - */ - void - setSize(int width, int height); - - /** - * Get tile reference. - */ - MetaTile* - getMetaTile(int x, int y); - - /** - * Set walkability flag for a tile - */ - void - setWalk(int x, int y, bool walkable); - - /** - * Tell if a tile is walkable or not, includes checking beings. - */ - bool - getWalk(int x, int y); - - /** - * Tell if a tile collides, not including a check on beings. - */ - bool - tileCollides(int x, int y); - - /** - * Returns the width of this map. - */ - int getWidth() const - { return width; } - - /** - * Returns the height of this map. - */ - int getHeight() const - { return height; } - - /** - * Returns the tile width of this map. - */ - int getTileWidth() const - { return tileWidth; } - - /** - * Returns the tile height used by this map. - */ - int getTileHeight() const - { return tileHeight; } - - /** - * Find a path from one location to the next. - */ - std::list - findPath(int startX, int startY, - int destX, int destY); - - private: - int width, height; - int tileWidth, tileHeight; - MetaTile *metaTiles; - - // Pathfinding members - int onClosedList, onOpenList; -}; - -#endif diff --git a/src/object.cpp b/src/object.cpp deleted file mode 100644 index c2e11a7f..00000000 --- a/src/object.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* - * The Mana World Server - * Copyright 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World 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 any later version. - * - * The Mana World 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 The Mana World; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id$ - */ - -#include "map.h" -#include "object.h" -#include "game-server/mapmanager.hpp" - -void MovingObject::move() -{ - mOld = getPosition(); - if (mActionTime > 100) - { - // current move has not yet ended - mActionTime -= 100; - return; - } - - int tileSX = mOld.x / 32, tileSY = mOld.y / 32; - int tileDX = mDst.x / 32, tileDY = mDst.y / 32; - if (tileSX == tileDX && tileSY == tileDY) - { - // moving while staying on the same tile is free - setPosition(mDst); - mActionTime = 0; - return; - } - - Map *map = mapManager->getMap(getMapId()); - // TODO: cache pathfinding results - std::list path = map->findPath(tileSX, tileSY, tileDX, tileDY); - if (path.empty()) - { - // no path was found - mDst = mOld; - mActionTime = 0; - return; - } - - PATH_NODE prev(tileSX, tileSY); - Point pos; - do - { - PATH_NODE next = path.front(); - path.pop_front(); - mActionTime += (prev.x != next.x && prev.y != next.y) - ? mSpeed * 362 / 256 : mSpeed; - if (path.empty()) - { - // skip last tile center - pos = mDst; - break; - } - pos.x = next.x * 32 + 16; - pos.y = next.y * 32 + 16; - } - while (mActionTime < 100); - setPosition(pos); - - mActionTime = mActionTime > 100 ? mActionTime - 100 : 0; -} diff --git a/src/object.h b/src/object.h deleted file mode 100644 index 4ad8c0be..00000000 --- a/src/object.h +++ /dev/null @@ -1,257 +0,0 @@ -/* - * The Mana World Server - * Copyright 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World 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 any later version. - * - * The Mana World 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 The Mana World; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id$ - */ - - -#ifndef _TMWSERV_OBJECT_H_ -#define _TMWSERV_OBJECT_H_ - -#include - -#include "point.h" - -// Object type enumeration -enum { - OBJECT_ITEM = 0, // A simple item - OBJECT_ACTOR, // An item that toggle map/quest actions (doors, switchs, ...) and can speak (map panels). - OBJECT_NPC, // Non-Playable-Character is an actor capable of movement and maybe actions - OBJECT_MONSTER, // A monster (moving actor with AI. Should be able to toggle map/quest actions, too) - OBJECT_PLAYER, // A normal being - OBJECT_OTHER // Server-only object -}; - -class MapComposite; - -enum -{ - NEW_ON_MAP = 1, - NEW_DESTINATION = 2, - ATTACK = 4 -}; - -/** - * Base class for in-game objects. - */ -class Thing -{ - public: - /** - * Constructor. - */ - Thing(int type) - : mType(type) - {} - - /** - * Empty virtual destructor. - */ - virtual ~Thing() {} - - /** - * Gets type. - * - * @return the type. - */ - int getType() const - { return mType; } - - /** - * Returns whether this thing is visible on the map or not. (Object) - */ - bool isVisible() const - { return mType != OBJECT_OTHER; } - - /** - * Returns whether this thing can move on the map or not. (MovingObject) - */ - bool canMove() const - { return mType == OBJECT_PLAYER || mType == OBJECT_MONSTER || - mType == OBJECT_NPC; } - - /** - * Returns whether this thing can fight or not. (Being) - */ - bool canFight() const - { return mType == OBJECT_PLAYER || mType == OBJECT_MONSTER; } - - /** - * Updates the internal status. - */ - virtual void - update() = 0; - - /** - * Gets the map this thing is located on. - * - * @return ID of map. - */ - int getMapId() const - { return mMapId; } - - /** - * Sets the map this thing is located on. - */ - void setMapId(int mapId) - { mMapId = mapId; } - - private: - unsigned short mMapId; /**< id of the map being is on */ - char mType; /**< Object type */ -}; - -/** - * Generic client-visible object definition. - */ -class Object: public Thing -{ - public: - /** - * Constructor. - */ - Object(int type) - : Thing(type), - mUpdateFlags(0) - {} - - /** - * Sets the coordinates. - * - * @param p the coordinates. - */ - void setPosition(const Point &p) - { mPos = p; } - - /** - * Gets the coordinates. - * - * @return the coordinates. - */ - Point const &getPosition() const - { return mPos; } - - /** - * Gets what changed in the object. - */ - int getUpdateFlags() const - { return mUpdateFlags; } - - /** - * Sets some changes in the object. - */ - void raiseUpdateFlags(int n) - { mUpdateFlags |= n; } - - /** - * Clears changes in the object. - */ - void clearUpdateFlags() - { mUpdateFlags = 0; } - - private: - char mUpdateFlags; /**< changes in object status */ - Point mPos; /**< coordinates */ -}; - -/** - * Base class for in-game moving objects. - */ -class MovingObject: public Object -{ - public: - /** - * Proxy constructor. - */ - MovingObject(int type, int id) - : Object(type), - mPublicID(id), - mDirection(0), - mActionTime(0) - {} - - /** - * Gets the destination coordinates of the object. - */ - Point const &getDestination() const - { return mDst; } - - /** - * Sets the destination coordinates of the object. - */ - void setDestination(Point dst) - { mDst = dst; raiseUpdateFlags(NEW_DESTINATION); } - - /** - * Gets the old coordinates of the object. - */ - Point getOldPosition() const - { return mOld; } - - /** - * Sete object direction - */ - void setDirection(int direction) - { mDirection = direction; } - - /** - * Gets object direction - */ - - unsigned char getDirection() const - { return mDirection; } - - /** - * Sets object speed. - */ - void setSpeed(unsigned s) - { mSpeed = s; } - - /** - * Moves the object toward its destination. - */ - void move(); - - /** - * Get public ID. - * - * @return the public ID, 65535 if none yet. - */ - int getPublicID() const - { return mPublicID; } - - /** - * Set public ID. - * The object shall not have any public ID yet. - */ - void setPublicID(int id) - { mPublicID = id; } - - private: - unsigned short mPublicID; /**< Object ID sent to clients (unique with respect to the map) */ - Point mDst; /**< target coordinates */ - Point mOld; /**< old coordinates */ - unsigned short mSpeed; /**< speed */ - - protected: - unsigned char mDirection; /**< Facing direction */ - unsigned short mActionTime; /**< delay until next action */ -}; - -#endif // _TMWSERV_OBJECT_H_ diff --git a/src/player.cpp b/src/player.cpp deleted file mode 100644 index e7d84d3e..00000000 --- a/src/player.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* - * The Mana World Server - * Copyright 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World 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 any later version. - * - * The Mana World 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 The Mana World; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id$ - */ - -#include - -#include "defines.h" -#include "player.h" - -/** - * Update the internal status. - */ -void Player::update() -{ - // computed stats. - setStat(STAT_HEAT, 20 + (20 * mRawStats.stats[STAT_VITALITY])); - setStat(STAT_ATTACK, 10 + mRawStats.stats[STAT_STRENGTH]); - setStat(STAT_DEFENCE, 10 + mRawStats.stats[STAT_STRENGTH]); - setStat(STAT_MAGIC, 10 + mRawStats.stats[STAT_INTELLIGENCE]); - setStat(STAT_ACCURACY, 50 + mRawStats.stats[STAT_DEXTERITY]); - setStat(STAT_SPEED, mRawStats.stats[STAT_DEXTERITY]); - - // attacking - if (mIsAttacking) - { - // plausibility check of attack command - if (mActionTime <= 0) - { - // request perform attack - mActionTime = 1000; - mIsAttacking = false; - raiseUpdateFlags(ATTACK); - } - } -} - -/* -void Player::setInventory(const Inventory &inven) -{ - inventory = inven; -} - -bool Player::addItem(unsigned int itemId, unsigned char amount) -{ - return inventory.addItem(itemId, amount); -} - -bool Player::removeItem(unsigned int itemId, unsigned char amount) -{ - return inventory.removeItem(itemId, amount); -} - -bool Player::hasItem(unsigned int itemId) -{ - return inventory.hasItem(itemId); -} - -bool Player::equip(unsigned char slot) -{ - return false; // TODO -} - -bool Player::unequip(unsigned char slot) -{ - return false; // TODO -} -*/ diff --git a/src/player.h b/src/player.h deleted file mode 100644 index deffb752..00000000 --- a/src/player.h +++ /dev/null @@ -1,267 +0,0 @@ -/* - * The Mana World Server - * Copyright 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World 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 any later version. - * - * The Mana World 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 The Mana World; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id$ - */ - -#ifndef _TMWSERV_PLAYER_H_ -#define _TMWSERV_PLAYER_H_ - -#include -#include - -#include "being.h" -#include "defines.h" -#include "inventory.h" -#include "utils/countedptr.h" - -class GameClient; - -class Player : public Being -{ - public: - - Player(std::string const &name, int id = -1) - : Being(OBJECT_PLAYER, 65535), - mDatabaseID(id), - mName(name), - mClient(NULL), - mIsAttacking(false) - {} - - /** - * Gets the name. - * - * @return the name. - */ - std::string const &getName() const - { return mName; } - - /** - * Sets the hair style. - * - * @param style the new hair style. - */ - void setHairStyle(unsigned char style) - { mHairStyle = style; } - - /** - * Gets the hair style. - * - * @return the hair style value. - */ - unsigned char getHairStyle() const - { return mHairStyle; } - - /** - * Sets the hair color. - * - * @param color the new hair color. - */ - void setHairColor(unsigned char color) - { mHairColor = color; } - - /** - * Gets the hair color. - * - * @return the hair color value. - */ - unsigned char getHairColor() const - { return mHairColor; } - - /** - * Sets the gender. - * - * @param gender the new gender. - */ - void setGender(Gender gender) - { mGender = gender; } - - /** - * Gets the gender. - * - * @return the gender. - */ - Gender getGender() const - { return mGender; } - - /** - * Sets the level. - * - * @param level the new level. - */ - void setLevel(unsigned char level) - { mLevel = level; } - - /** - * Gets the level. - * - * @return the level. - */ - unsigned char getLevel() const - { return mLevel; } - - /** - * Sets the money. - * - * @param amount the new amount. - */ - void setMoney(unsigned int amount) - { mMoney = amount; } - - /** - * Gets the amount of money. - * - * @return the amount of money. - */ - unsigned int getMoney() const - { return mMoney; } - - /** - * Sets a raw statistic. - * - * @param numStat the statistic number. - * @param value the new value. - */ - void setRawStat(int numStat, unsigned short value) - { mRawStats.stats[numStat] = value; } - - /** - * Gets a raw statistic. - * - * @param numStat the statistic number. - * @return the statistic value. - */ - unsigned short getRawStat(int numStat) - { return mRawStats.stats[numStat]; } - - /** - * Updates the internal status. - */ - void update(); - - /** - * Sets inventory. - */ - void - setInventory(const Inventory &inven); - - /** - * Adds item with ID to inventory. - * - * @return Item add success/failure - */ - bool - addItem(unsigned int itemId, unsigned char amount = 1); - - /** - * Removes item with ID from inventory. - * - * @return Item delete success/failure - */ - bool - removeItem(unsigned int itemId, unsigned char amount = 0); - - /** - * Checks if character has an item. - * - * @return true if being has item, false otherwise - */ - bool - hasItem(unsigned int itemId); - - /** - * Equips item with ID in equipment slot. - * - * @return Equip success/failure - */ - bool - equip(unsigned char slot); - - /** - * Un-equips item. - * - * @return Un-equip success/failure - */ - bool - unequip(unsigned char slot); - - /** - * Set attacking state - **/ - void setAttacking(bool isAttacking) - { mIsAttacking = isAttacking; } - - /** - * Gets database ID. - * - * @return the database ID, a negative number if none yet. - */ - int getDatabaseID() const - { return mDatabaseID; } - - /** - * Sets database ID. - * The object shall not have any ID yet. - */ - void setDatabaseID(int id) - { mDatabaseID = id; } - - /** - * Gets client computer. - */ - GameClient *getClient() const - { return mClient; } - - /** - * Sets client computer. - */ - void setClient(GameClient *c) - { mClient = c; } - - private: - Player(Player const &); - Player &operator=(Player const &); - - int mDatabaseID; /**< Player database ID (unique with respect to its type) */ - std::string mName; /**< name of the being */ - GameClient *mClient; /**< client computer, directly set by GameClient */ - Gender mGender; /**< gender of the being */ - unsigned char mHairStyle; /**< Hair Style of the being */ - unsigned char mHairColor; /**< Hair Color of the being */ - unsigned char mLevel; /**< level of the being */ - unsigned int mMoney; /**< wealth of the being */ - RawStatistics mRawStats; /**< raw stats of the being */ - - Inventory inventory; /**< Player inventory and Equipment */ - - bool mIsAttacking; /**< attacking state */ -}; - -/** - * Type definition for a smart pointer to Player. - */ -typedef utils::CountedPtr PlayerPtr; - -/** - * Type definition for a list of Players. - */ -typedef std::vector Players; - -#endif // _TMWSERV_PLAYER_H_ diff --git a/src/playerdata.hpp b/src/playerdata.hpp new file mode 100644 index 00000000..cc4a4b46 --- /dev/null +++ b/src/playerdata.hpp @@ -0,0 +1,250 @@ +/* + * The Mana World Server + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World 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 any later version. + * + * The Mana World 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 The Mana World; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#ifndef _TMWSERV_PLAYERDATA +#define _TMWSERV_PLAYERDATA + +#include +#include + +#include "point.h" +#include "utils/countedptr.h" + +/** + * Gender of a Player. + */ +enum +{ + GENDER_MALE = 0, + GENDER_FEMALE +}; + +/** + * Raw statistics of a Player. + */ +enum +{ + STAT_STRENGTH = 0, + STAT_AGILITY, + STAT_VITALITY, + STAT_INTELLIGENCE, + STAT_DEXTERITY, + STAT_LUCK, + NB_RSTAT +}; + +/** + * Structure types for the raw statistics of a Player. + */ +struct RawStatistics +{ + unsigned short stats[NB_RSTAT]; +}; + + +class PlayerData +{ + public: + + PlayerData(std::string const &name, int id = -1) + : mDatabaseID(id), + mName(name) + {} + + /** + * Gets the name. + * + * @return the name. + */ + std::string const &getName() const + { return mName; } + + /** + * Sets the hair style. + * + * @param style the new hair style. + */ + void setHairStyle(int style) + { mHairStyle = style; } + + /** + * Gets the hair style. + * + * @return the hair style value. + */ + int getHairStyle() const + { return mHairStyle; } + + /** + * Sets the hair color. + * + * @param color the new hair color. + */ + void setHairColor(int color) + { mHairColor = color; } + + /** + * Gets the hair color. + * + * @return the hair color value. + */ + int getHairColor() const + { return mHairColor; } + + /** + * Sets the gender. + * + * @param gender the new gender. + */ + void setGender(int gender) + { mGender = gender; } + + /** + * Gets the gender. + * + * @return the gender. + */ + int getGender() const + { return mGender; } + + /** + * Sets the level. + * + * @param level the new level. + */ + void setLevel(int level) + { mLevel = level; } + + /** + * Gets the level. + * + * @return the level. + */ + int getLevel() const + { return mLevel; } + + /** + * Sets the money. + * + * @param amount the new amount. + */ + void setMoney(int amount) + { mMoney = amount; } + + /** + * Gets the amount of money. + * + * @return the amount of money. + */ + int getMoney() const + { return mMoney; } + + /** + * Sets a raw statistic. + * + * @param numStat the statistic number. + * @param value the new value. + */ + void setRawStat(int numStat, int value) + { mRawStats.stats[numStat] = value; } + + /** + * Gets a raw statistic. + * + * @param numStat the statistic number. + * @return the statistic value. + */ + int getRawStat(int numStat) + { return mRawStats.stats[numStat]; } + + /** + * Gets database ID. + * + * @return the database ID, a negative number if none yet. + */ + int getDatabaseID() const + { return mDatabaseID; } + + /** + * Sets database ID. + * The object shall not have any ID yet. + */ + void setDatabaseID(int id) + { mDatabaseID = id; } + + /** + * Gets the map this thing is located on. + * + * @return ID of map. + */ + int getMap() const + { return mMapId; } + + /** + * Sets the map this thing is located on. + */ + void setMap(int mapId) + { mMapId = mapId; } + + /** + * Sets the coordinates. + * + * @param p the coordinates. + */ + void setPos(const Point &p) + { mPos = p; } + + /** + * Gets the coordinates. + * + * @return the coordinates. + */ + Point const &getPos() const + { return mPos; } + + private: + PlayerData(PlayerData const &); + PlayerData &operator=(PlayerData const &); + + int mDatabaseID; /**< Player database ID. */ + std::string mName; /**< Name of the being. */ + unsigned char mGender; /**< Gender of the being. */ + unsigned char mHairStyle; /**< Hair Style of the being. */ + unsigned char mHairColor; /**< Hair Color of the being. */ + unsigned char mLevel; /**< Level of the being. */ + unsigned short mMapId; /**< Map the being is on. */ + Point mPos; /**< Position the being is at. */ + unsigned int mMoney; /**< Wealth of the being. */ + RawStatistics mRawStats; /**< Raw statistics of the being. */ +}; + +/** + * Type definition for a smart pointer to PlayerData. + */ +typedef utils::CountedPtr< PlayerData > PlayerPtr; + +/** + * Type definition for a list of Players. + */ +typedef std::vector< PlayerPtr > Players; + +#endif -- cgit v1.2.3-70-g09d2