diff options
Diffstat (limited to 'src/npc.cpp')
-rw-r--r-- | src/npc.cpp | 193 |
1 files changed, 148 insertions, 45 deletions
diff --git a/src/npc.cpp b/src/npc.cpp index 5665ad95..bc25fa5d 100644 --- a/src/npc.cpp +++ b/src/npc.cpp @@ -1,43 +1,59 @@ /* * The Mana World - * Copyright 2004 The Mana World Development Team + * Copyright (C) 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 + * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * - * The Mana World is distributed in the hope that it will be useful, + * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with The Mana World; if not, write to the Free Software + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "npc.h" - #include "animatedsprite.h" -#include "graphics.h" +#include "npc.h" #include "particle.h" +#include "text.h" -#include "gui/gui.h" -#include "net/messageout.h" +#include "gui/npc_text.h" + +#ifdef TMWSERV_SUPPORT #include "net/gameserver/player.h" +#else +#include "net/messageout.h" +#include "net/ea/protocol.h" +#endif + #include "resources/npcdb.h" +extern NpcTextDialog *npcTextDialog; + NPC *current_npc = 0; -NPC::NPC(Uint16 id, int sprite, Map *map): - Being(id, sprite, map) +static const int NAME_X_OFFSET = 15; +static const int NAME_Y_OFFSET = 30; + +#ifdef TMWSERV_SUPPORT +NPC::NPC(Uint16 id, int job, Map *map): + Player(id, job, map) +#else +NPC::NPC(Uint32 id, Uint16 job, Map *map, Network *network): + Player(id, job, map), + mNetwork(network) +#endif { - NPCInfo info = NPCDB::get(sprite); + NPCInfo info = NPCDB::get(job); - //setup NPC sprites + // Setup NPC sprites int c = BASE_SPRITE; for (std::list<NPCsprite*>::const_iterator i = info.sprites.begin(); i != info.sprites.end(); @@ -51,74 +67,161 @@ NPC::NPC(Uint16 id, int sprite, Map *map): c++; } - //setup particle effects - for (std::list<std::string>::const_iterator i = info.particles.begin(); - i != info.particles.end(); - i++) + if (mParticleEffects) { - Particle *p = particleEngine->addEffect(*i, 0, 0, 0); - this->controlParticle(p); + //setup particle effects + for (std::list<std::string>::const_iterator i = info.particles.begin(); + i != info.particles.end(); + i++) + { + Particle *p = particleEngine->addEffect(*i, 0, 0); + this->controlParticle(p); + } } + mName = 0; + + mNameColor = 0x21bbbb; } -Being::Type -NPC::getType() const +NPC::~NPC() { - return Being::NPC; + delete mName; + + if (current_npc == this) handleDeath(); +} + +void NPC::setName(const std::string &name) +{ + const std::string displayName = name.substr(0, name.find('#', 0)); + + delete mName; + mName = new Text(displayName, mPx + NAME_X_OFFSET, mPy + NAME_Y_OFFSET, + gcn::Graphics::CENTER, gcn::Color(200, 200, 255)); + Being::setName(displayName + " (NPC)"); } -void NPC::drawName(Graphics *graphics, Sint32 offsetX, Sint32 offsetY) +void NPC::setGender(Gender gender) { - const Vector &pos = getPosition(); - const int px = (int) pos.x + offsetX; - const int py = (int) pos.y + offsetY; + Being::setGender(gender); +} - graphics->setFont(speechFont); - graphics->setColor(gcn::Color(200, 200, 255)); - graphics->drawText(mName, px, py, gcn::Graphics::CENTER); +void NPC::setSprite(int slot, int id, std::string color) +{ + // Fix this later should it not be adequate enough. + Being::setSprite(slot, id, color); +} + +Being::Type NPC::getType() const +{ + return Being::NPC; } -void -NPC::talk() +void NPC::talk() { +#ifdef TMWSERV_SUPPORT Net::GameServer::Player::talkToNPC(mId, true); +#else + MessageOut outMsg(mNetwork); + outMsg.writeInt16(CMSG_NPC_TALK); + outMsg.writeInt32(mId); + outMsg.writeInt8(0); +#endif current_npc = this; } -void -NPC::nextDialog() +void NPC::nextDialog() { +#ifdef TMWSERV_SUPPORT Net::GameServer::Player::talkToNPC(mId, false); +#else + MessageOut outMsg(mNetwork); + outMsg.writeInt16(CMSG_NPC_NEXT_REQUEST); + outMsg.writeInt32(mId); +#endif } -void -NPC::dialogChoice(int choice) +void NPC::dialogChoice(char choice) { +#ifdef TMWSERV_SUPPORT Net::GameServer::Player::selectFromNPC(mId, choice); +#else + MessageOut outMsg(mNetwork); + outMsg.writeInt16(CMSG_NPC_LIST_CHOICE); + outMsg.writeInt32(mId); + outMsg.writeInt8(choice); +#endif +} + +void NPC::integerInput(int value) +{ +#ifdef EATHENA_SUPPORT + MessageOut outMsg(mNetwork); + outMsg.writeInt16(CMSG_NPC_INT_RESPONSE); + outMsg.writeInt32(mId); + outMsg.writeInt32(value); +#endif +} + +void NPC::stringInput(const std::string &value) +{ +#ifdef EATHENA_SUPPORT + MessageOut outMsg(mNetwork); + outMsg.writeInt16(CMSG_NPC_STR_RESPONSE); + outMsg.writeInt16(value.length() + 9); + outMsg.writeInt32(mId); + outMsg.writeString(value, value.length()); + outMsg.writeInt8(0); +#endif } /* * TODO Unify the buy() and sell() methods, without sacrificing readability of * the code calling the method. buy(bool buySell) would be bad... */ -void -NPC::buy() +void NPC::buy() { // XXX Convert for new server - /* - MessageOut outMsg(CMSG_NPC_BUY_SELL_REQUEST); +#ifdef EATHENA_SUPPORT + MessageOut outMsg(mNetwork); + outMsg.writeInt16(CMSG_NPC_BUY_SELL_REQUEST); outMsg.writeInt32(mId); outMsg.writeInt8(0); - */ +#endif } -void -NPC::sell() +void NPC::sell() { // XXX Convert for new server - /* - MessageOut outMsg(CMSG_NPC_BUY_SELL_REQUEST); +#ifdef EATHENA_SUPPORT + MessageOut outMsg(mNetwork); + outMsg.writeInt16(CMSG_NPC_BUY_SELL_REQUEST); outMsg.writeInt32(mId); outMsg.writeInt8(1); - */ +#endif +} + +void NPC::updateCoords() +{ + if (mName) + { +#ifdef TMWSERV_SUPPORT + const Vector &pos = getPosition(); + const int px = (int) pos.x + NAME_X_OFFSET; + const int py = (int) pos.y + NAME_Y_OFFSET; +#else + const int px = mPx + NAME_X_OFFSET; + const int py = mPy + NAME_Y_OFFSET; +#endif + mName->adviseXY(px, py); + } +} + +void NPC::handleDeath() +{ + printf("NPC::handleDeath\n"); + if (this != current_npc) return; + + if (npcTextDialog->isVisible()) + npcTextDialog->showCloseButton(); + else current_npc = NULL; } |