npc.h

main 256 lines · 6.5 KB Raw
Alex Alex Commit Server upload 18/10/2026 23:38
1/**
2 * The Forgotten Server - a free and open-source MMORPG server emulator
3 * Copyright (C) 2019 Mark Samman <mark.samman@gmail.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20#ifndef FS_NPC_H_B090D0CB549D4435AFA03647195D156F
21#define FS_NPC_H_B090D0CB549D4435AFA03647195D156F
22
23#include "creature.h"
24#include "luascript.h"
25
26#include <set>
27
28class Npc;
29class Player;
30
31class Npcs
32{
33 public:
34 static void reload();
35};
36
37class NpcScriptInterface final : public LuaScriptInterface
38{
39 public:
40 NpcScriptInterface();
41
42 bool loadNpcLib(const std::string& file);
43
44 private:
45 void registerFunctions();
46
47 static int luaActionSay(lua_State* L);
48 static int luaActionMove(lua_State* L);
49 static int luaActionMoveTo(lua_State* L);
50 static int luaActionTurn(lua_State* L);
51 static int luaActionFollow(lua_State* L);
52 static int luagetDistanceTo(lua_State* L);
53 static int luaSetNpcFocus(lua_State* L);
54 static int luaGetNpcCid(lua_State* L);
55 static int luaGetNpcParameter(lua_State* L);
56 static int luaOpenShopWindow(lua_State* L);
57 static int luaCloseShopWindow(lua_State* L);
58 static int luaDoSellItem(lua_State* L);
59
60 // metatable
61 static int luaNpcGetParameter(lua_State* L);
62 static int luaNpcSetFocus(lua_State* L);
63
64 static int luaNpcOpenShopWindow(lua_State* L);
65 static int luaNpcCloseShopWindow(lua_State* L);
66
67 private:
68 bool initState() override;
69 bool closeState() override;
70
71 bool libLoaded;
72};
73
74class NpcEventsHandler
75{
76 public:
77 NpcEventsHandler(const std::string& file, Npc* npc);
78
79 void onCreatureAppear(Creature* creature);
80 void onCreatureDisappear(Creature* creature);
81 void onCreatureMove(Creature* creature, const Position& oldPos, const Position& newPos);
82 void onCreatureSay(Creature* creature, SpeakClasses, const std::string& text);
83 void onPlayerTrade(Player* player, int32_t callback, uint16_t itemId, uint8_t count, uint8_t amount, bool ignore = false, bool inBackpacks = false);
84 void onPlayerCloseChannel(Player* player);
85 void onPlayerEndTrade(Player* player);
86 void onThink();
87
88 bool isLoaded() const;
89
90 private:
91 Npc* npc;
92 NpcScriptInterface* scriptInterface;
93
94 int32_t creatureAppearEvent = -1;
95 int32_t creatureDisappearEvent = -1;
96 int32_t creatureMoveEvent = -1;
97 int32_t creatureSayEvent = -1;
98 int32_t playerCloseChannelEvent = -1;
99 int32_t playerEndTradeEvent = -1;
100 int32_t thinkEvent = -1;
101 bool loaded = false;
102};
103
104class Npc final : public Creature
105{
106 public:
107 ~Npc();
108
109 // non-copyable
110 Npc(const Npc&) = delete;
111 Npc& operator=(const Npc&) = delete;
112
113 Npc* getNpc() override {
114 return this;
115 }
116 const Npc* getNpc() const override {
117 return this;
118 }
119
120 bool isPushable() const override {
121 return pushable && walkTicks != 0;
122 }
123
124 void setID() override {
125 if (id == 0) {
126 id = npcAutoID++;
127 }
128 }
129
130 void removeList() override;
131 void addList() override;
132
133 static Npc* createNpc(const std::string& name);
134
135 bool canSee(const Position& pos) const override;
136
137 bool load();
138 void reload();
139
140 const std::string& getName() const override {
141 return name;
142 }
143 const std::string& getNameDescription() const override {
144 return name;
145 }
146
147 CreatureType_t getType() const override {
148 return CREATURETYPE_NPC;
149 }
150
151 uint8_t getSpeechBubble() const override {
152 return speechBubble;
153 }
154 void setSpeechBubble(const uint8_t bubble) {
155 speechBubble = bubble;
156 }
157
158 void doSay(const std::string& text);
159 void doSayToPlayer(Player* player, const std::string& text);
160
161 void doMoveTo(const Position& pos);
162
163 int32_t getMasterRadius() const {
164 return masterRadius;
165 }
166 const Position& getMasterPos() const {
167 return masterPos;
168 }
169 void setMasterPos(Position pos, int32_t radius = 1) {
170 masterPos = pos;
171 if (masterRadius == -1) {
172 masterRadius = radius;
173 }
174 }
175
176 void onPlayerCloseChannel(Player* player);
177 void onPlayerTrade(Player* player, int32_t callback, uint16_t itemId, uint8_t count,
178 uint8_t amount, bool ignore = false, bool inBackpacks = false);
179 void onPlayerEndTrade(Player* player, int32_t buyCallback, int32_t sellCallback);
180
181 void turnToCreature(Creature* creature);
182 void setCreatureFocus(Creature* creature);
183
184 NpcScriptInterface* getScriptInterface();
185
186 static uint32_t npcAutoID;
187
188 private:
189 explicit Npc(const std::string& name);
190
191 void onCreatureAppear(Creature* creature, bool isLogin) override;
192 void onRemoveCreature(Creature* creature, bool isLogout) override;
193 void onCreatureMove(Creature* creature, const Tile* newTile, const Position& newPos,
194 const Tile* oldTile, const Position& oldPos, bool teleport) override;
195
196 void onCreatureSay(Creature* creature, SpeakClasses type, const std::string& text) override;
197 void onThink(uint32_t interval) override;
198 std::string getDescription(int32_t lookDistance) const override;
199
200 bool isImmune(CombatType_t) const override {
201 return !attackable;
202 }
203 bool isImmune(ConditionType_t) const override {
204 return !attackable;
205 }
206 bool isAttackable() const override {
207 return attackable;
208 }
209 bool getNextStep(Direction& dir, uint32_t& flags) override;
210
211 void setIdle(bool idle);
212 void updateIdleStatus();
213
214 bool canWalkTo(const Position& fromPos, Direction dir) const;
215 bool getRandomStep(Direction& dir) const;
216
217 void reset();
218 bool loadFromXml();
219
220 void addShopPlayer(Player* player);
221 void removeShopPlayer(Player* player);
222 void closeAllShopWindows();
223
224 std::map<std::string, std::string> parameters;
225
226 std::set<Player*> shopPlayerSet;
227 std::set<Player*> spectators;
228
229 std::string name;
230 std::string filename;
231
232 NpcEventsHandler* npcEventHandler;
233
234 Position masterPos;
235
236 uint32_t walkTicks;
237 int32_t focusCreature;
238 int32_t masterRadius;
239
240 uint8_t speechBubble;
241
242 bool floorChange;
243 bool attackable;
244 bool ignoreHeight;
245 bool loaded;
246 bool isIdle;
247 bool pushable;
248
249 static NpcScriptInterface* scriptInterface;
250
251 friend class Npcs;
252 friend class NpcScriptInterface;
253};
254
255#endif
256
Top