summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/mmo.h8
-rw-r--r--src/config/const.h8
-rw-r--r--src/config/renewal.h12
-rw-r--r--src/map/atcommand.c4
-rw-r--r--src/map/clif.c21
-rw-r--r--src/map/clif.h18
-rw-r--r--src/map/map.c4
-rw-r--r--src/map/map.h1
-rw-r--r--src/map/npc.c184
-rw-r--r--src/map/npc.h2
-rw-r--r--src/map/pc.c6
-rw-r--r--src/map/pc.h2
-rw-r--r--src/map/script.c11
-rw-r--r--src/map/status.h4
-rw-r--r--src/plugins/HPMHooking/HPMHooking.Hooks.inc24
15 files changed, 170 insertions, 139 deletions
diff --git a/src/common/mmo.h b/src/common/mmo.h
index 1d826463e..0003aa917 100644
--- a/src/common/mmo.h
+++ b/src/common/mmo.h
@@ -84,6 +84,14 @@
#endif // 20090603
#endif // 20070227
+/* Feb 1st 2012 */
+#if PACKETVER >= 20120201
+# define NEW_CARTS
+# define MAX_CARTS 9
+#else
+# define MAX_CARTS 5
+#endif
+
#define MAX_INVENTORY 100
//Max number of characters per account. Note that changing this setting alone is not enough if the client is not hexed to support more characters as well.
#define MAX_CHARS 9
diff --git a/src/config/const.h b/src/config/const.h
index f9baa4d7d..ba06d70cb 100644
--- a/src/config/const.h
+++ b/src/config/const.h
@@ -87,14 +87,6 @@
#define RE_LVL_TMDMOD()
#endif
-/* Feb 1st 2012 */
-#if PACKETVER >= 20120201
- #define NEW_CARTS
- #define MAX_CARTS 9
-#else
- #define MAX_CARTS 5
-#endif
-
// Renewal variable cast time reduction
#ifdef RENEWAL_CAST
#define VARCAST_REDUCTION(val) do { \
diff --git a/src/config/renewal.h b/src/config/renewal.h
index 36bdd3958..1c48b9f8a 100644
--- a/src/config/renewal.h
+++ b/src/config/renewal.h
@@ -13,8 +13,18 @@
* @INFO: This file holds general-purpose renewal settings, for class-specific ones check /src/config/classes folder
**/
+/**
+ * Renewal full toggle switch.
+ *
+ * Uncomment this line to disable all of the below settings at once.
+ * Note: in UNIX builds, this can be easily done without touching this
+ * line, by passing --disable-renewal to the configure script:
+ * ./configure --disable-renewal
+ */
//#define DISABLE_RENEWAL
-#ifndef DISABLE_RENEWAL
+
+
+#ifndef DISABLE_RENEWAL // Do not change this line
/// game renewal server mode
/// (disable by commenting the line)
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index df3be40a5..7a6ad84e4 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -4,7 +4,7 @@
#define HERCULES_CORE
-#include "../config/core.h" // AUTOLOOTITEM_SIZE, AUTOTRADE_PERSISTENCY, MAX_CARTS, MAX_SUGGESTIONS, MOB_FLEE(), MOB_HIT(), RENEWAL, RENEWAL_DROP, RENEWAL_EXP
+#include "../config/core.h" // AUTOLOOTITEM_SIZE, AUTOTRADE_PERSISTENCY, MAX_SUGGESTIONS, MOB_FLEE(), MOB_HIT(), RENEWAL, RENEWAL_DROP, RENEWAL_EXP
#include "atcommand.h"
#include <math.h>
@@ -45,7 +45,7 @@
#include "../common/conf.h"
#include "../common/core.h"
#include "../common/malloc.h"
-#include "../common/mmo.h"
+#include "../common/mmo.h" // MAX_CARTS
#include "../common/nullpo.h"
#include "../common/random.h"
#include "../common/showmsg.h"
diff --git a/src/map/clif.c b/src/map/clif.c
index 1da6070e8..068cb1e07 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -4,7 +4,7 @@
#define HERCULES_CORE
-#include "../config/core.h" // ANTI_MAYAP_CHEAT, NEW_CARTS, RENEWAL, SECURE_NPCTIMEOUT
+#include "../config/core.h" // ANTI_MAYAP_CHEAT, RENEWAL, SECURE_NPCTIMEOUT
#include "clif.h"
#include <stdio.h>
@@ -48,6 +48,7 @@
#include "../common/ers.h"
#include "../common/grfio.h"
#include "../common/malloc.h"
+#include "../common/mmo.h" // NEW_CARTS
#include "../common/nullpo.h"
#include "../common/random.h"
#include "../common/showmsg.h"
@@ -8136,7 +8137,7 @@ void clif_disp_message(struct block_list* src, const char* mes, size_t len, enum
/// result:
/// 0 = failure
/// 1 = success
-void clif_GM_kickack(struct map_session_data *sd, int id)
+void clif_GM_kickack(struct map_session_data *sd, int result)
{
int fd;
@@ -8145,7 +8146,7 @@ void clif_GM_kickack(struct map_session_data *sd, int id)
fd = sd->fd;
WFIFOHEAD(fd,packet_len(0xcd));
WFIFOW(fd,0) = 0xcd;
- WFIFOB(fd,2) = id; // FIXME: this is not account id
+ WFIFOB(fd,2) = result;
WFIFOSET(fd, packet_len(0xcd));
}
@@ -8159,7 +8160,7 @@ void clif_GM_kick(struct map_session_data *sd,struct map_session_data *tsd) {
map->quit(tsd);
if( sd )
- clif->GM_kickack(sd,tsd->status.account_id);
+ clif->GM_kickack(sd, 1);
}
@@ -15561,20 +15562,10 @@ void clif_cashshop_show(struct map_session_data *sd, struct npc_data *nd) {
WFIFOSET(fd,WFIFOW(fd,2));
}
-
/// Cashshop Buy Ack (ZC_PC_CASH_POINT_UPDATE).
/// 0289 <cash point>.L <error>.W
/// 0289 <cash point>.L <kafra point>.L <error>.W (PACKETVER >= 20070711)
-/// error:
-/// 0 = The deal has successfully completed. (ERROR_TYPE_NONE)
-/// 1 = The Purchase has failed because the NPC does not exist. (ERROR_TYPE_NPC)
-/// 2 = The Purchase has failed because the Kafra Shop System is not working correctly. (ERROR_TYPE_SYSTEM)
-/// 3 = You are over your Weight Limit. (ERROR_TYPE_INVENTORY_WEIGHT)
-/// 4 = You cannot purchase items while you are in a trade. (ERROR_TYPE_EXCHANGE)
-/// 5 = The Purchase has failed because the Item Information was incorrect. (ERROR_TYPE_ITEM_ID)
-/// 6 = You do not have enough Kafra Credit Points. (ERROR_TYPE_MONEY)
-/// 7 = You can purchase up to 10 items.
-/// 8 = Some items could not be purchased.
+/// For error return codes see enum cashshop_error@clif.h
void clif_cashshop_ack(struct map_session_data* sd, int error) {
struct npc_data *nd;
int fd = sd->fd;
diff --git a/src/map/clif.h b/src/map/clif.h
index f54c4afce..7b27e1fe6 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -349,6 +349,22 @@ enum clif_messages {
};
/**
+ * Used to answer CZ_PC_BUY_CASH_POINT_ITEM (clif_parse_cashshop_buy)
+ **/
+enum cashshop_error {
+ ERROR_TYPE_NONE = 0, // The deal has successfully completed. (ERROR_TYPE_NONE)
+ ERROR_TYPE_NPC, // The Purchase has failed because the NPC does not exist. (ERROR_TYPE_NPC)
+ ERROR_TYPE_SYSTEM, // The Purchase has failed because the Kafra Shop System is not working correctly. (ERROR_TYPE_SYSTEM)
+ ERROR_TYPE_INVENTORY_WEIGHT, // You are over your Weight Limit. (ERROR_TYPE_INVENTORY_WEIGHT)
+ ERROR_TYPE_EXCHANGE, // You cannot purchase items while you are in a trade. (ERROR_TYPE_EXCHANGE)
+ ERROR_TYPE_ITEM_ID, // The Purchase has failed because the Item Information was incorrect. (ERROR_TYPE_ITEM_ID)
+ ERROR_TYPE_MONEY, // You do not have enough Kafra Credit Points. (ERROR_TYPE_MONEY)
+ // Unofficial type names
+ ERROR_TYPE_QUANTITY, // You can purchase up to 10 items. (ERROR_TYPE_QUANTITY)
+ ERROR_TYPE_NOT_ALL, // Some items could not be purchased. (ERROR_TYPE_NOT_ALL)
+};
+
+/**
* Color Table
**/
enum clif_colors {
@@ -910,7 +926,7 @@ struct clif_interface {
void (*friendslist_toggle) (struct map_session_data *sd,int account_id, int char_id, int online);
void (*friendlist_req) (struct map_session_data* sd, int account_id, int char_id, const char* name);
/* gm-related */
- void (*GM_kickack) (struct map_session_data *sd, int id);
+ void (*GM_kickack) (struct map_session_data *sd, int result);
void (*GM_kick) (struct map_session_data *sd,struct map_session_data *tsd);
void (*manner_message) (struct map_session_data* sd, uint32 type);
void (*GM_silence) (struct map_session_data* sd, struct map_session_data* tsd, uint8 type);
diff --git a/src/map/map.c b/src/map/map.c
index bccb51d7e..01d3dbb9f 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -3656,6 +3656,8 @@ int inter_config_read(char *cfgName) {
strcpy(map->autotrade_merchants_db, w2);
else if(strcmpi(w1,"autotrade_data_db")==0)
strcpy(map->autotrade_data_db, w2);
+ else if(strcmpi(w1,"npc_market_data_db")==0)
+ strcpy(map->npc_market_data_db, w2);
/* sql log db */
else if(strcmpi(w1,"log_db_ip")==0)
strcpy(logs->db_ip, w2);
@@ -5832,7 +5834,7 @@ int do_init(int argc, char *argv[])
exit(EXIT_SUCCESS);
}
- npc->event_do_oninit(); // Init npcs (OnInit)
+ npc->event_do_oninit( false ); // Init npcs (OnInit)
npc->market_fromsql(); /* after OnInit */
if (battle_config.pk_mode)
diff --git a/src/map/map.h b/src/map/map.h
index 8277c7a62..539b02ed8 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -845,6 +845,7 @@ struct map_interface {
char interreg_db[32];
char autotrade_merchants_db[32];
char autotrade_data_db[32];
+ char npc_market_data_db[32];
char default_codepage[32];
diff --git a/src/map/npc.c b/src/map/npc.c
index 289c42d44..cf509e11f 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -450,14 +450,17 @@ int npc_event_do_clock(int tid, int64 tick, int id, intptr_t data) {
return c;
}
-/*==========================================
- * OnInit Event execution (the start of the event and watch)
- *------------------------------------------*/
-void npc_event_do_oninit(void)
+/**
+ * OnInit event execution (the start of the event and watch)
+ * @param reload Is the server reloading?
+ **/
+void npc_event_do_oninit( bool reload )
{
ShowStatus("Event '"CL_WHITE"OnInit"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs."CL_CLL"\n", npc->event_doall("OnInit"));
- timer->add_interval(timer->gettick()+100,npc->event_do_clock,0,0,1000);
+ // This interval has already been added on startup
+ if( !reload )
+ timer->add_interval(timer->gettick()+100,npc->event_do_clock,0,0,1000);
}
/*==========================================
@@ -1298,23 +1301,23 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns
unsigned short shop_size = 0;
if( sd->state.trading )
- return 4;
+ return ERROR_TYPE_EXCHANGE;
if( count <= 0 )
- return 5;
+ return ERROR_TYPE_ITEM_ID;
if( points < 0 )
- return 6;
+ return ERROR_TYPE_MONEY;
if( !(nd = (struct npc_data *)map->id2bl(sd->npc_shopid)) )
- return 1;
+ return ERROR_TYPE_NPC;
if( nd->subtype != CASHSHOP ) {
if( nd->subtype == SCRIPT && nd->u.scr.shop && nd->u.scr.shop->type != NST_ZENY && nd->u.scr.shop->type != NST_MARKET ) {
shop = nd->u.scr.shop->item;
shop_size = nd->u.scr.shop->items;
} else
- return 1;
+ return ERROR_TYPE_NPC;
} else {
shop = nd->u.shop.shop_item;
shop_size = nd->u.shop.count;
@@ -1330,11 +1333,11 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns
amount = item_list[i*2+0];
if( !itemdb->exists(nameid) || amount <= 0 )
- return 5;
+ return ERROR_TYPE_ITEM_ID;
ARR_FIND(0,shop_size,j,shop[j].nameid == nameid);
if( j == shop_size || shop[j].value <= 0 )
- return 5;
+ return ERROR_TYPE_ITEM_ID;
if( !itemdb->isstackable(nameid) && amount > 1 ) {
ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %d!\n",
@@ -1347,7 +1350,7 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns
new_++;
break;
case ADDITEM_OVERAMOUNT:
- return 3;
+ return ERROR_TYPE_INVENTORY_WEIGHT;
}
vt += shop[j].value * amount;
@@ -1355,20 +1358,20 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns
}
if( w + sd->weight > sd->max_weight )
- return 3;
+ return ERROR_TYPE_INVENTORY_WEIGHT;
if( pc->inventoryblank(sd) < new_ )
- return 3;
+ return ERROR_TYPE_INVENTORY_WEIGHT;
if( points > vt ) points = vt;
// Payment Process ----------------------------------------------------
if( nd->subtype == SCRIPT && nd->u.scr.shop->type == NST_CUSTOM ) {
if( !npc->trader_pay(nd,sd,vt,points) )
- return 6;
+ return ERROR_TYPE_MONEY;
} else {
if( sd->kafraPoints < points || sd->cashPoints < (vt - points) )
- return 6;
+ return ERROR_TYPE_MONEY;
pc->paycash(sd,vt,points);
}
// Delivery Process ----------------------------------------------------
@@ -1387,7 +1390,7 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns
}
}
- return 0;
+ return ERROR_TYPE_NONE;
}
//npc_buylist for script-controlled shops.
@@ -1423,8 +1426,7 @@ void npc_market_fromsql(void) {
int itemid;
int amount;
- /* TODO inter-server.conf npc_market_data */
- if ( SQL_ERROR == SQL->StmtPrepare(stmt, "SELECT `name`, `itemid`, `amount` FROM `npc_market_data`")
+ if ( SQL_ERROR == SQL->StmtPrepare(stmt, "SELECT `name`, `itemid`, `amount` FROM `%s`", map->npc_market_data_db)
|| SQL_ERROR == SQL->StmtExecute(stmt)
) {
SqlStmt_ShowDebug(stmt);
@@ -1471,20 +1473,20 @@ void npc_market_fromsql(void) {
* Saves persistent NPC Market Data into SQL
**/
void npc_market_tosql(struct npc_data *nd, unsigned short index) {
- /* TODO inter-server.conf npc_market_data */
- if( SQL_ERROR == SQL->Query(map->mysql_handle, "REPLACE INTO `npc_market_data` VALUES ('%s','%d','%d')", nd->exname, nd->u.scr.shop->item[index].nameid, nd->u.scr.shop->item[index].qty) )
+ if( SQL_ERROR == SQL->Query(map->mysql_handle, "REPLACE INTO `%s` VALUES ('%s','%d','%d')",
+ map->npc_market_data_db, nd->exname, nd->u.scr.shop->item[index].nameid, nd->u.scr.shop->item[index].qty) )
Sql_ShowDebug(map->mysql_handle);
}
/**
* Removes persistent NPC Market Data from SQL
*/
void npc_market_delfromsql_sub(const char *npcname, unsigned short index) {
- /* TODO inter-server.conf npc_market_data */
if( index == USHRT_MAX ) {
- if( SQL_ERROR == SQL->Query(map->mysql_handle, "DELETE FROM `npc_market_data` WHERE `name`='%s'", npcname) )
+ if( SQL_ERROR == SQL->Query(map->mysql_handle, "DELETE FROM `%s` WHERE `name`='%s'", map->npc_market_data_db, npcname) )
Sql_ShowDebug(map->mysql_handle);
} else {
- if( SQL_ERROR == SQL->Query(map->mysql_handle, "DELETE FROM `npc_market_data` WHERE `name`='%s' AND `itemid`='%d' LIMIT 1", npcname, index) )
+ if( SQL_ERROR == SQL->Query(map->mysql_handle, "DELETE FROM `%s` WHERE `name`='%s' AND `itemid`='%d' LIMIT 1",
+ map->npc_market_data_db, npcname, index) )
Sql_ShowDebug(map->mysql_handle);
}
}
@@ -1517,7 +1519,7 @@ bool npc_trader_open(struct map_session_data *sd, struct npc_data *nd) {
/* nothing to display, no items available */
if( i == nd->u.scr.shop->items ) {
- clif->colormes(sd->fd,COLOR_RED,"Shop is out of stock! Come again later!");/* TODO messages.conf-it */
+ clif->colormes(sd->fd,COLOR_RED, msg_txt(881));
return false;
}
@@ -1631,26 +1633,26 @@ int npc_cashshop_buy(struct map_session_data *sd, int nameid, int amount, int po
unsigned short shop_size = 0;
if( amount <= 0 )
- return 5;
+ return ERROR_TYPE_ITEM_ID;
if( points < 0 )
- return 6;
+ return ERROR_TYPE_MONEY;
if( sd->state.trading )
- return 4;
+ return ERROR_TYPE_EXCHANGE;
if( !(nd = (struct npc_data *)map->id2bl(sd->npc_shopid)) )
- return 1;
+ return ERROR_TYPE_NPC;
if( (item = itemdb->exists(nameid)) == NULL )
- return 5; // Invalid Item
+ return ERROR_TYPE_ITEM_ID; // Invalid Item
if( nd->subtype != CASHSHOP ) {
if( nd->subtype == SCRIPT && nd->u.scr.shop && nd->u.scr.shop->type != NST_ZENY && nd->u.scr.shop->type != NST_MARKET ) {
shop = nd->u.scr.shop->item;
shop_size = nd->u.scr.shop->items;
} else
- return 1;
+ return ERROR_TYPE_NPC;
} else {
shop = nd->u.shop.shop_item;
shop_size = nd->u.shop.count;
@@ -1659,10 +1661,10 @@ int npc_cashshop_buy(struct map_session_data *sd, int nameid, int amount, int po
ARR_FIND(0, shop_size, i, shop[i].nameid == nameid);
if( i == shop_size )
- return 5;
+ return ERROR_TYPE_ITEM_ID;
if( shop[i].value <= 0 )
- return 5;
+ return ERROR_TYPE_ITEM_ID;
if(!itemdb->isstackable(nameid) && amount > 1) {
ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %d!\n",
@@ -1673,15 +1675,15 @@ int npc_cashshop_buy(struct map_session_data *sd, int nameid, int amount, int po
switch( pc->checkadditem(sd, nameid, amount) ) {
case ADDITEM_NEW:
if( pc->inventoryblank(sd) == 0 )
- return 3;
+ return ERROR_TYPE_INVENTORY_WEIGHT;
break;
case ADDITEM_OVERAMOUNT:
- return 3;
+ return ERROR_TYPE_INVENTORY_WEIGHT;
}
w = item->weight * amount;
if( w + sd->weight > sd->max_weight )
- return 3;
+ return ERROR_TYPE_INVENTORY_WEIGHT;
if( (double)shop[i].value * amount > INT_MAX ) {
ShowWarning("npc_cashshop_buy: Item '%s' (%d) price overflow attempt!\n", item->name, nameid);
@@ -1689,7 +1691,7 @@ int npc_cashshop_buy(struct map_session_data *sd, int nameid, int amount, int po
nd->exname, map->list[nd->bl.m].name, nd->bl.x, nd->bl.y,
sd->status.name, sd->status.account_id, sd->status.char_id,
shop[i].value, amount);
- return 5;
+ return ERROR_TYPE_ITEM_ID;
}
price = shop[i].value * amount;
@@ -1699,10 +1701,10 @@ int npc_cashshop_buy(struct map_session_data *sd, int nameid, int amount, int po
if( nd->subtype == SCRIPT && nd->u.scr.shop->type == NST_CUSTOM ) {
if( !npc->trader_pay(nd,sd,price,points) )
- return 6;
+ return ERROR_TYPE_MONEY;
} else {
if( (sd->kafraPoints < points) || (sd->cashPoints < price - points) )
- return 6;
+ return ERROR_TYPE_MONEY;
pc->paycash(sd, price, points);
}
@@ -1716,7 +1718,7 @@ int npc_cashshop_buy(struct map_session_data *sd, int nameid, int amount, int po
pc->additem(sd,&item_tmp, amount, LOG_TYPE_NPC);
}
- return 0;
+ return ERROR_TYPE_NONE;
}
/// Player item purchase from npc shop.
@@ -2612,7 +2614,7 @@ const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const char* s
enum npc_subtype type;
if( strcmp(w1,"-") == 0 ) {
- // 'floating' shop?
+ // 'floating' shop
x = y = dir = 0;
m = -1;
} else {// w1=<map name>,<x>,<y>,<facing>
@@ -2711,7 +2713,7 @@ const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const char* s
nd->dir = dir;
if( map->list[nd->bl.m].users )
clif->spawn(&nd->bl);
- } else {// 'floating' shop?
+ } else {// 'floating' shop
map->addiddb(&nd->bl);
}
strdb_put(npc->name_db, nd->exname, nd);
@@ -4294,14 +4296,39 @@ int npc_ev_label_db_clear_sub(DBKey key, DBData *data, va_list args)
return 0;
}
+/**
+ * Main npc file processing
+ * @param npc_min Minimum npc id - used to know how many NPCs were loaded
+ **/
+void npc_process_files( int npc_min ) {
+ struct npc_src_list *file; // Current file
+
+ ShowStatus("Loading NPCs...\r");
+ for( file = npc->src_files; file != NULL; file = file->next ) {
+ ShowStatus("Loading NPC file: %s"CL_CLL"\r", file->name);
+ if (npc->parsesrcfile(file->name, false) != EXIT_SUCCESS)
+ map->retval = EXIT_FAILURE;
+ }
+ ShowInfo ("Done loading '"CL_WHITE"%d"CL_RESET"' NPCs:"CL_CLL"\n"
+ "\t-'"CL_WHITE"%d"CL_RESET"' Warps\n"
+ "\t-'"CL_WHITE"%d"CL_RESET"' Shops\n"
+ "\t-'"CL_WHITE"%d"CL_RESET"' Scripts\n"
+ "\t-'"CL_WHITE"%d"CL_RESET"' Spawn sets\n"
+ "\t-'"CL_WHITE"%d"CL_RESET"' Mobs Cached\n"
+ "\t-'"CL_WHITE"%d"CL_RESET"' Mobs Not Cached\n",
+ npc_id - npc_min, npc_warp, npc_shop, npc_script, npc_mob, npc_cache_mob, npc_delay_mob);
+}
+
//Clear then reload npcs files
int npc_reload(void) {
- struct npc_src_list *nsl;
int16 m, i;
int npc_new_min = npc_id;
struct s_mapiterator* iter;
struct block_list* bl;
+ if (map->retval == EXIT_FAILURE)
+ map->retval = EXIT_SUCCESS; // Clear return status in case something failed before.
+
/* clear guild flag cache */
guild->flags_clear();
@@ -4358,46 +4385,35 @@ int npc_reload(void) {
// reset mapflags
map->flags_init();
- //TODO: the following code is copy-pasted from do_init_npc(); clean it up
- // Reloading npcs now
- for (nsl = npc->src_files; nsl; nsl = nsl->next) {
- ShowStatus("Loading NPC file: %s"CL_CLL"\r", nsl->name);
- npc->parsesrcfile(nsl->name,false);
- }
- ShowInfo ("Done loading '"CL_WHITE"%d"CL_RESET"' NPCs:"CL_CLL"\n"
- "\t-'"CL_WHITE"%d"CL_RESET"' Warps\n"
- "\t-'"CL_WHITE"%d"CL_RESET"' Shops\n"
- "\t-'"CL_WHITE"%d"CL_RESET"' Scripts\n"
- "\t-'"CL_WHITE"%d"CL_RESET"' Spawn sets\n"
- "\t-'"CL_WHITE"%d"CL_RESET"' Mobs Cached\n"
- "\t-'"CL_WHITE"%d"CL_RESET"' Mobs Not Cached\n",
- npc_id - npc_new_min, npc_warp, npc_shop, npc_script, npc_mob, npc_cache_mob, npc_delay_mob);
-
+ // Reprocess npc files and reload constants
itemdb->name_constants();
-
+ npc_process_files( npc_new_min );
+
instance->reload();
map->zone_init();
-
+
npc->motd = npc->name2id("HerculesMOTD"); /* [Ind/Hercules] */
-
+
//Re-read the NPC Script Events cache.
npc->read_event_script();
- /* refresh guild castle flags on both woe setups */
- npc->event_doall("OnAgitInit");
- npc->event_doall("OnAgitInit2");
-
- //Execute the OnInit event for freshly loaded npcs. [Skotlex]
- ShowStatus("Event '"CL_WHITE"OnInit"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n",npc->event_doall("OnInit"));
-
- npc->market_fromsql();/* after OnInit */
-
+ // Execute main initialisation events
+ // The correct initialisation order is:
+ // OnInit -> OnInterIfInit -> OnInterIfInitOnce -> OnAgitInit -> OnAgitInit2
+ npc->event_do_oninit( true );
+ npc->market_fromsql();
// Execute rest of the startup events if connected to char-server. [Lance]
- if(!intif->CheckForCharServer()){
+ // Executed when connection is established with char-server in chrif_connectack
+ if( !intif->CheckForCharServer() ) {
ShowStatus("Event '"CL_WHITE"OnInterIfInit"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n", npc->event_doall("OnInterIfInit"));
ShowStatus("Event '"CL_WHITE"OnInterIfInitOnce"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n", npc->event_doall("OnInterIfInitOnce"));
}
+ // Refresh guild castle flags on both woe setups
+ // These events are only executed after receiving castle information from char-server
+ npc->event_doall("OnAgitInit");
+ npc->event_doall("OnAgitInit2");
+
return 0;
}
@@ -4479,7 +4495,6 @@ static void npc_debug_warps(void) {
* npc initialization
*------------------------------------------*/
int do_init_npc(bool minimal) {
- struct npc_src_list *file;
int i;
memset(&npc->base_ud, 0, sizeof( struct unit_data) );
@@ -4508,28 +4523,17 @@ int do_init_npc(bool minimal) {
npc_last_npd = NULL;
npc_last_path = NULL;
npc_last_ref = NULL;
-
+
+ // Should be loaded before npc processing, otherwise labels could overwrite constant values
+ // and lead to undefined behavior [Panikon]
+ itemdb->name_constants();
+
if (!minimal) {
npc->timer_event_ers = ers_new(sizeof(struct timer_event_data),"clif.c::timer_event_ers",ERS_OPT_NONE);
- // process all npc files
- ShowStatus("Loading NPCs...\r");
- for( file = npc->src_files; file != NULL; file = file->next ) {
- ShowStatus("Loading NPC file: %s"CL_CLL"\r", file->name);
- npc->parsesrcfile(file->name,false);
- }
- ShowInfo ("Done loading '"CL_WHITE"%d"CL_RESET"' NPCs:"CL_CLL"\n"
- "\t-'"CL_WHITE"%d"CL_RESET"' Warps\n"
- "\t-'"CL_WHITE"%d"CL_RESET"' Shops\n"
- "\t-'"CL_WHITE"%d"CL_RESET"' Scripts\n"
- "\t-'"CL_WHITE"%d"CL_RESET"' Spawn sets\n"
- "\t-'"CL_WHITE"%d"CL_RESET"' Mobs Cached\n"
- "\t-'"CL_WHITE"%d"CL_RESET"' Mobs Not Cached\n",
- npc_id - START_NPC_NUM, npc_warp, npc_shop, npc_script, npc_mob, npc_cache_mob, npc_delay_mob);
+ npc_process_files(START_NPC_NUM);
}
- itemdb->name_constants();
-
if (!minimal) {
map->zone_init();
diff --git a/src/map/npc.h b/src/map/npc.h
index a277d4968..6e9686d33 100644
--- a/src/map/npc.h
+++ b/src/map/npc.h
@@ -193,7 +193,7 @@ struct npc_interface {
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);
+ void (*event_do_oninit) ( bool reload );
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);
diff --git a/src/map/pc.c b/src/map/pc.c
index 45adfe22a..08ff8baf9 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -4,7 +4,7 @@
#define HERCULES_CORE
-#include "../config/core.h" // DBPATH, GP_BOUND_ITEMS, MAX_CARTS, MAX_SPIRITBALL, NEW_CARTS, RENEWAL, RENEWAL_ASPD, RENEWAL_CAST, RENEWAL_DROP, RENEWAL_EXP, SECURE_NPCTIMEOUT
+#include "../config/core.h" // DBPATH, GP_BOUND_ITEMS, MAX_SPIRITBALL, RENEWAL, RENEWAL_ASPD, RENEWAL_CAST, RENEWAL_DROP, RENEWAL_EXP, SECURE_NPCTIMEOUT
#include "pc.h"
#include <stdio.h>
@@ -45,7 +45,7 @@
#include "../common/conf.h"
#include "../common/core.h" // get_svn_revision()
#include "../common/malloc.h"
-#include "../common/mmo.h" //NAME_LENGTH
+#include "../common/mmo.h" // NAME_LENGTH, MAX_CARTS, NEW_CARTS
#include "../common/nullpo.h"
#include "../common/random.h"
#include "../common/showmsg.h"
@@ -8039,7 +8039,7 @@ int pc_setoption(struct map_session_data *sd,int type)
*------------------------------------------*/
int pc_setcart(struct map_session_data *sd,int type) {
#ifndef NEW_CARTS
- int cart[6] = {0x0000,OPTION_CART1,OPTION_CART2,OPTION_CART3,OPTION_CART4,OPTION_CART5};
+ int cart[6] = {OPTION_NOTHING,OPTION_CART1,OPTION_CART2,OPTION_CART3,OPTION_CART4,OPTION_CART5};
int option;
#endif
nullpo_ret(sd);
diff --git a/src/map/pc.h b/src/map/pc.h
index c4026a48d..5d723fcf8 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -21,7 +21,7 @@
#include "vending.h" // struct s_vending
#include "../common/cbasetypes.h"
#include "../common/ers.h" // struct eri
-#include "../common/mmo.h" // JOB_*, MAX_FAME_LIST, struct fame_list, struct mmo_charstatus
+#include "../common/mmo.h" // JOB_*, MAX_FAME_LIST, struct fame_list, struct mmo_charstatus, NEW_CARTS
/**
* Defines
diff --git a/src/map/script.c b/src/map/script.c
index e4cf7f227..b432e6720 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -4,7 +4,7 @@
#define HERCULES_CORE
-#include "../config/core.h" // NEW_CARTS, RENEWAL, RENEWAL_ASPD, RENEWAL_CAST, RENEWAL_DROP, RENEWAL_EDP, RENEWAL_EXP, RENEWAL_LVDMG, SCRIPT_CALLFUNC_CHECK, SECURE_NPCTIMEOUT, SECURE_NPCTIMEOUT_INTERVAL
+#include "../config/core.h" // RENEWAL, RENEWAL_ASPD, RENEWAL_CAST, RENEWAL_DROP, RENEWAL_EDP, RENEWAL_EXP, RENEWAL_LVDMG, SCRIPT_CALLFUNC_CHECK, SECURE_NPCTIMEOUT, SECURE_NPCTIMEOUT_INTERVAL
#include "script.h"
#include <math.h>
@@ -45,6 +45,7 @@
#include "../common/cbasetypes.h"
#include "../common/malloc.h"
#include "../common/md5calc.h"
+#include "../common/mmo.h" // NEW_CARTS
#include "../common/nullpo.h"
#include "../common/random.h"
#include "../common/showmsg.h"
@@ -2914,6 +2915,8 @@ int set_reg(struct script_state* st, TBL_PC* sd, int64 num, const char* name, co
return pc_setglobalreg_str(sd, num, str);
}
} else {// integer variable
+ // FIXME: This isn't safe, in 32bits systems we're converting a 64bit pointer
+ // to a 32bit int, this will lead to overflows! [Panikon]
int val = (int)__64BPTRSIZE(value);
if(script->str_data[script_getvarid(num)].type == C_PARAM) {
@@ -2921,7 +2924,11 @@ int set_reg(struct script_state* st, TBL_PC* sd, int64 num, const char* name, co
if( st != NULL ) {
ShowError("script:set_reg: failed to set param '%s' to %d.\n", name, val);
script->reportsrc(st);
- st->state = END;
+ // Instead of just stop the script execution we let the character close
+ // the window if it was open.
+ st->state = (sd->state.dialog) ? CLOSE : END;
+ if( st->state == CLOSE )
+ clif->scriptclose(sd, st->oid);
}
return 0;
}
diff --git a/src/map/status.h b/src/map/status.h
index baa586297..6bb563b0b 100644
--- a/src/map/status.h
+++ b/src/map/status.h
@@ -5,10 +5,10 @@
#ifndef _MAP_STATUS_H_
#define _MAP_STATUS_H_
-#include "../config/core.h" // defType, NEW_CARTS, RENEWAL, RENEWAL_ASPD
+#include "../config/core.h" // defType, RENEWAL, RENEWAL_ASPD
#include "../common/cbasetypes.h"
-#include "../common/mmo.h"
+#include "../common/mmo.h" // NEW_CARTS
struct block_list;
struct elemental_data;
diff --git a/src/plugins/HPMHooking/HPMHooking.Hooks.inc b/src/plugins/HPMHooking/HPMHooking.Hooks.inc
index e4f627c81..83af64c07 100644
--- a/src/plugins/HPMHooking/HPMHooking.Hooks.inc
+++ b/src/plugins/HPMHooking/HPMHooking.Hooks.inc
@@ -14350,14 +14350,14 @@ void HP_clif_friendlist_req(struct map_session_data *sd, int account_id, int cha
}
return;
}
-void HP_clif_GM_kickack(struct map_session_data *sd, int id) {
+void HP_clif_GM_kickack(struct map_session_data *sd, int result) {
int hIndex = 0;
if( HPMHooks.count.HP_clif_GM_kickack_pre ) {
- void (*preHookFunc) (struct map_session_data *sd, int *id);
+ void (*preHookFunc) (struct map_session_data *sd, int *result);
*HPMforce_return = false;
for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_GM_kickack_pre; hIndex++ ) {
preHookFunc = HPMHooks.list.HP_clif_GM_kickack_pre[hIndex].func;
- preHookFunc(sd, &id);
+ preHookFunc(sd, &result);
}
if( *HPMforce_return ) {
*HPMforce_return = false;
@@ -14365,13 +14365,13 @@ void HP_clif_GM_kickack(struct map_session_data *sd, int id) {
}
}
{
- HPMHooks.source.clif.GM_kickack(sd, id);
+ HPMHooks.source.clif.GM_kickack(sd, result);
}
if( HPMHooks.count.HP_clif_GM_kickack_post ) {
- void (*postHookFunc) (struct map_session_data *sd, int *id);
+ void (*postHookFunc) (struct map_session_data *sd, int *result);
for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_GM_kickack_post; hIndex++ ) {
postHookFunc = HPMHooks.list.HP_clif_GM_kickack_post[hIndex].func;
- postHookFunc(sd, &id);
+ postHookFunc(sd, &result);
}
}
return;
@@ -43052,14 +43052,14 @@ int HP_npc_event_do_clock(int tid, int64 tick, int id, intptr_t data) {
}
return retVal___;
}
-void HP_npc_event_do_oninit(void) {
+void HP_npc_event_do_oninit(bool reload) {
int hIndex = 0;
if( HPMHooks.count.HP_npc_event_do_oninit_pre ) {
- void (*preHookFunc) (void);
+ void (*preHookFunc) (bool *reload);
*HPMforce_return = false;
for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_event_do_oninit_pre; hIndex++ ) {
preHookFunc = HPMHooks.list.HP_npc_event_do_oninit_pre[hIndex].func;
- preHookFunc();
+ preHookFunc(&reload);
}
if( *HPMforce_return ) {
*HPMforce_return = false;
@@ -43067,13 +43067,13 @@ void HP_npc_event_do_oninit(void) {
}
}
{
- HPMHooks.source.npc.event_do_oninit();
+ HPMHooks.source.npc.event_do_oninit(reload);
}
if( HPMHooks.count.HP_npc_event_do_oninit_post ) {
- void (*postHookFunc) (void);
+ void (*postHookFunc) (bool *reload);
for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_event_do_oninit_post; hIndex++ ) {
postHookFunc = HPMHooks.list.HP_npc_event_do_oninit_post[hIndex].func;
- postHookFunc();
+ postHookFunc(&reload);
}
}
return;