summaryrefslogtreecommitdiff
path: root/src/map/npc.h
blob: e1ec6e5e49dcff3c18973a12968e2a34f64393c5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
// Copyright (c) Hercules Dev Team, licensed under GNU GPL.
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams

#ifndef _NPC_H_
#define _NPC_H_

#include "map.h" // struct block_list
#include "status.h" // struct status_change
#include "unit.h" // struct unit_data
struct block_list;
struct npc_data;
struct view_data;

struct npc_timerevent_list {
	int timer,pos;
};
struct npc_label_list {
	char name[NAME_LENGTH];
	int pos;
};
struct npc_item_list {
	unsigned int nameid,value;
};

struct npc_data {
	struct block_list bl;
	struct unit_data *ud;
	struct view_data *vd;
	unsigned int option;
	struct npc_data *master_nd;
	short class_;
	short speed;
	char name[NAME_LENGTH+1];// display name
	char exname[NAME_LENGTH+1];// unique npc name
	int chat_id;
	int touching_id;
	int64 next_walktime;
	uint8 dir;
	
	unsigned size : 2;

	struct status_data status;
	unsigned short level;
	unsigned short stat_point;

	void* chatdb; // pointer to a npc_parse struct (see npc_chat.c)
	char* path;/* path dir */
	enum npc_subtype subtype;
	int src_id;
	union {
		struct {
			struct script_code *script;
			short xs,ys; // OnTouch area radius
			int guild_id;
			int timer,timerid,timeramount,rid;
			int64 timertick;
			struct npc_timerevent_list *timer_event;
			int label_list_num;
			struct npc_label_list *label_list;
		} scr;
		struct {
			struct npc_item_list* shop_item;
			int count;
		} shop;
		struct {
			short xs,ys; // OnTouch area radius
			short x,y; // destination coords
			unsigned short mapindex; // destination map
		} warp;
		struct {
			struct mob_data *md;
			time_t kill_time;
			char killer_name[NAME_LENGTH];
		} tomb;
	} u;
};



#define START_NPC_NUM 110000000

enum actor_classes {
	WARP_CLASS = 45,
	HIDDEN_WARP_CLASS = 139,
	WARP_DEBUG_CLASS = 722,
	FLAG_CLASS = 722,
	INVISIBLE_CLASS = 32767,
};

// Old NPC range
#define MAX_NPC_CLASS 1000
// New NPC range
#define MAX_NPC_CLASS2_START 10000
#define MAX_NPC_CLASS2_END 10049

//Checks if a given id is a valid npc id. [Skotlex]
//Since new npcs are added all the time, the max valid value is the one before the first mob (Scorpion = 1001)
#define npcdb_checkid(id) ( ( (id) >= 46 && (id) <= 125) || (id) == HIDDEN_WARP_CLASS || ( (id) > 400 && (id) < MAX_NPC_CLASS ) || (id) == INVISIBLE_CLASS || ( (id) > MAX_NPC_CLASS2_START && (id) < MAX_NPC_CLASS2_END ) )

//Script NPC events.
enum npce_event {
	NPCE_LOGIN,
	NPCE_LOGOUT,
	NPCE_LOADMAP,
	NPCE_BASELVUP,
	NPCE_JOBLVUP,
	NPCE_DIE,
	NPCE_KILLPC,
	NPCE_KILLNPC,
	NPCE_MAX
};

// linked list of npc source files
struct npc_src_list {
	struct npc_src_list* next;
	char name[4]; // dynamic array, the structure is allocated with extra bytes (string length)
};

struct event_data {
	struct npc_data *nd;
	int pos;
};

struct npc_path_data {
	char* path;
	unsigned short references;
};

/* npc.c interface */
struct npc_interface {
	/* */
	struct npc_data *motd;
	DBMap *ev_db; // const char* event_name -> struct event_data*
	DBMap *ev_label_db; // const char* label_name (without leading "::") -> struct linkdb_node**   (key: struct npc_data*; data: struct event_data*)
	DBMap *name_db; // const char* npc_name -> struct npc_data*
	DBMap *path_db;
	struct eri *timer_event_ers; //For the npc timer data. [Skotlex]
	struct npc_data *fake_nd;
	struct npc_src_list *src_files;
	struct unit_data base_ud;
	/* */
	int (*init) (void);
	int (*final) (void);
	/* */
	int (*get_new_npc_id) (void);
	struct view_data* (*get_viewdata) (int class_);
	int (*isnear_sub) (struct block_list *bl, va_list args);
	bool (*isnear) (struct block_list *bl);
	int (*ontouch_event) (struct map_session_data *sd, struct npc_data *nd);
	int (*ontouch2_event) (struct map_session_data *sd, struct npc_data *nd);
	int (*enable_sub) (struct block_list *bl, va_list ap);
	int (*enable) (const char *name, int flag);
	struct npc_data* (*name2id) (const char *name);
	int (*event_dequeue) (struct map_session_data *sd);
	DBData (*event_export_create) (DBKey key, va_list args);
	int (*event_export) (struct npc_data *nd, int i);
	int (*event_sub) (struct map_session_data *sd, struct event_data *ev, const char *eventname);
	void (*event_doall_sub) (void *key, void *data, va_list ap);
	int (*event_do) (const char *name);
	int (*event_doall_id) (const char *name, int rid);
	int (*event_doall) (const char *name);
	int (*event_do_clock) (int tid, int64 tick, int id, intptr_t data);
	void (*event_do_oninit) (void);
	int (*timerevent_export) (struct npc_data *nd, int i);
	int (*timerevent) (int tid, int64 tick, int id, intptr_t data);
	int (*timerevent_start) (struct npc_data *nd, int rid);
	int (*timerevent_stop) (struct npc_data *nd);
	void (*timerevent_quit) (struct map_session_data *sd);
	int64 (*gettimerevent_tick) (struct npc_data *nd);
	int (*settimerevent_tick) (struct npc_data *nd, int newtimer);
	int (*event) (struct map_session_data *sd, const char *eventname, int ontouch);
	int (*touch_areanpc_sub) (struct block_list *bl, va_list ap);
	int (*touchnext_areanpc) (struct map_session_data *sd, bool leavemap);
	int (*touch_areanpc) (struct map_session_data *sd, int16 m, int16 x, int16 y);
	int (*touch_areanpc2) (struct mob_data *md);
	int (*check_areanpc) (int flag, int16 m, int16 x, int16 y, int16 range);
	struct npc_data* (*checknear) (struct map_session_data *sd, struct block_list *bl);
	int (*globalmessage) (const char *name, const char *mes);
	void (*run_tomb) (struct map_session_data *sd, struct npc_data *nd);
	int (*click) (struct map_session_data *sd, struct npc_data *nd);
	int (*scriptcont) (struct map_session_data *sd, int id, bool closing);
	int (*buysellsel) (struct map_session_data *sd, int id, int type);
	int (*cashshop_buylist) (struct map_session_data *sd, int points, int count, unsigned short *item_list);
	int (*buylist_sub) (struct map_session_data *sd, int n, unsigned short *item_list, struct npc_data *nd);
	int (*cashshop_buy) (struct map_session_data *sd, int nameid, int amount, int points);
	int (*buylist) (struct map_session_data *sd, int n, unsigned short *item_list);
	int (*selllist_sub) (struct map_session_data *sd, int n, unsigned short *item_list, struct npc_data *nd);
	int (*selllist) (struct map_session_data *sd, int n, unsigned short *item_list);
	int (*remove_map) (struct npc_data *nd);
	int (*unload_ev) (DBKey key, DBData *data, va_list ap);
	int (*unload_ev_label) (DBKey key, DBData *data, va_list ap);
	int (*unload_dup_sub) (struct npc_data *nd, va_list args);
	void (*unload_duplicates) (struct npc_data *nd);
	int (*unload) (struct npc_data *nd, bool single);
	void (*clearsrcfile) (void);
	void (*addsrcfile) (const char *name);
	void (*delsrcfile) (const char *name);
	void (*parsename) (struct npc_data *nd, const char *name, const char *start, const char *buffer, const char *filepath);
	struct npc_data* (*add_warp) (char *name, short from_mapid, short from_x, short from_y, short xs, short ys, unsigned short to_mapindex, short to_x, short to_y);
	const char* (*parse_warp) (char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath);
	const char* (*parse_shop) (char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath);
	void (*convertlabel_db) (struct npc_label_list *label_list, const char *filepath);
	const char* (*skip_script) (const char *start, const char *buffer, const char *filepath);
	const char* (*parse_script) (char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath, bool runOnInit);
	const char* (*parse_duplicate) (char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath);
	int (*duplicate4instance) (struct npc_data *snd, int16 m);
	void (*setcells) (struct npc_data *nd);
	int (*unsetcells_sub) (struct block_list *bl, va_list ap);
	void (*unsetcells) (struct npc_data *nd);
	void (*movenpc) (struct npc_data *nd, int16 x, int16 y);
	void (*setdisplayname) (struct npc_data *nd, const char *newname);
	void (*setclass) (struct npc_data *nd, short class_);
	int (*do_atcmd_event) (struct map_session_data *sd, const char *command, const char *message, const char *eventname);
	const char* (*parse_function) (char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath);
	void (*parse_mob2) (struct spawn_data *mobspawn);
	const char* (*parse_mob) (char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath);
	const char* (*parse_mapflag) (char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath);
	void (*parsesrcfile) (const char *filepath, bool runOnInit);
	int (*script_event) (struct map_session_data *sd, enum npce_event type);
	void (*read_event_script) (void);
	int (*path_db_clear_sub) (DBKey key, DBData *data, va_list args);
	int (*ev_label_db_clear_sub) (DBKey key, DBData *data, va_list args);
	int (*reload) (void);
	bool (*unloadfile) (const char *filepath);
	void (*do_clear_npc) (void);
	void (*debug_warps_sub) (struct npc_data *nd);
	void (*debug_warps) (void);
	/**
	 * For the Secure NPC Timeout option (check config/Secure.h) [RR]
	 **/
	int (*secure_timeout_timer) (int tid, int64 tick, int id, intptr_t data);
};

struct npc_interface *npc;

void npc_defaults(void);


/* comes from npc_chat.c */
#ifdef PCRE_SUPPORT
#include "../../3rdparty/pcre/include/pcre.h"
/* Structure containing all info associated with a single pattern block */
struct pcrematch_entry {
	struct pcrematch_entry* next;
	char* pattern;
	pcre* pcre_;
	pcre_extra* pcre_extra_;
	char* label;
};

/* A set of patterns that can be activated and deactived with a single command */
struct pcrematch_set {
	struct pcrematch_set* prev;
	struct pcrematch_set* next;
	struct pcrematch_entry* head;
	int setid;
};

/*
 * Entire data structure hung off a NPC
 *
 * The reason I have done it this way (a void * in npc_data and then
 * this) was to reduce the number of patches that needed to be applied
 * to a ragnarok distribution to bring this code online.  I
 * also wanted people to be able to grab this one file to get updates
 * without having to do a large number of changes.
 */
struct npc_parse {
	struct pcrematch_set* active;
	struct pcrematch_set* inactive;
};

struct npc_chat_interface {
	int (*sub) (struct block_list* bl, va_list ap);
	void (*finalize) (struct npc_data* nd);
	void (*def_pattern) (struct npc_data* nd, int setid, const char* pattern, const char* label);
	struct pcrematch_entry* (*create_pcrematch_entry) (struct pcrematch_set* set);
	void (*delete_pcreset) (struct npc_data* nd, int setid);
	void (*deactivate_pcreset) (struct npc_data* nd, int setid);
	void (*activate_pcreset) (struct npc_data* nd, int setid);
	struct pcrematch_set* (*lookup_pcreset) (struct npc_data* nd, int setid);
	void (*finalize_pcrematch_entry) (struct pcrematch_entry* e);
};

struct npc_chat_interface *npc_chat;

void npc_chat_defaults(void);
#endif

#endif /* _NPC_H_ */