diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common/mmo.h | 8 | ||||
-rw-r--r-- | src/config/const.h | 8 | ||||
-rw-r--r-- | src/config/renewal.h | 12 | ||||
-rw-r--r-- | src/map/atcommand.c | 4 | ||||
-rw-r--r-- | src/map/clif.c | 21 | ||||
-rw-r--r-- | src/map/clif.h | 18 | ||||
-rw-r--r-- | src/map/map.c | 4 | ||||
-rw-r--r-- | src/map/map.h | 1 | ||||
-rw-r--r-- | src/map/npc.c | 184 | ||||
-rw-r--r-- | src/map/npc.h | 2 | ||||
-rw-r--r-- | src/map/pc.c | 6 | ||||
-rw-r--r-- | src/map/pc.h | 2 | ||||
-rw-r--r-- | src/map/script.c | 11 | ||||
-rw-r--r-- | src/map/status.h | 4 | ||||
-rw-r--r-- | src/plugins/HPMHooking/HPMHooking.Hooks.inc | 24 |
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; |