summaryrefslogtreecommitdiff
path: root/src/npc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/npc.cpp')
-rw-r--r--src/npc.cpp193
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;
}