diff options
Diffstat (limited to 'src')
175 files changed, 32635 insertions, 21781 deletions
diff --git a/src/char/Makefile.in b/src/char/Makefile.in index 4bb7f3fb8..ab1e7c234 100644 --- a/src/char/Makefile.in +++ b/src/char/Makefile.in @@ -1,29 +1,33 @@ -COMMON_H = $(shell ls ../common/*.h) -CONFIG_H = $(shell ls ../config/*.h ../config/*/*.h) +CONFIG_D = ../config +CONFIG_H = $(wildcard $(CONFIG_D)/*.h) $(wildcard $(CONFIG_D)/*/*.h) -MT19937AR_D = ../../3rdparty/mt19937ar -MT19937AR_OBJ = $(MT19937AR_D)/mt19937ar.o -MT19937AR_H = $(MT19937AR_D)/mt19937ar.h -MT19937AR_INCLUDE = -I$(MT19937AR_D) +COMMON_D = ../common +COMMON_H = $(wildcard $(COMMON_D)/*.h) LIBCONFIG_D = ../../3rdparty/libconfig LIBCONFIG_OBJ = $(addprefix $(LIBCONFIG_D)/, libconfig.o grammar.o scanctx.o \ - scanner.o strbuf.o) + scanner.o strbuf.o) LIBCONFIG_H = $(addprefix $(LIBCONFIG_D)/, libconfig.h grammar.h parsectx.h \ - scanctx.h scanner.h strbuf.h wincompat.h) + scanctx.h scanner.h strbuf.h wincompat.h) LIBCONFIG_INCLUDE = -I$(LIBCONFIG_D) -CHAR_OBJ = $(addprefix obj_sql/, char.o inter.o int_auction.o int_elemental.o \ - int_guild.o int_homun.o int_mail.o int_mercenary.o int_party.o \ - int_pet.o int_quest.o int_storage.o pincode.o) +MT19937AR_D = ../../3rdparty/mt19937ar +MT19937AR_OBJ = $(MT19937AR_D)/mt19937ar.o +MT19937AR_H = $(MT19937AR_D)/mt19937ar.h +MT19937AR_INCLUDE = -I$(MT19937AR_D) + +CHAR_C = char.c inter.c int_auction.c int_elemental.c int_guild.c int_homun.c \ + int_mail.c int_mercenary.c int_party.c int_pet.c int_quest.c \ + int_storage.c pincode.c +CHAR_OBJ = $(addprefix obj_sql/, $(patsubst %.c,%.o,$(CHAR_C))) CHAR_H = char.h inter.h int_auction.h int_elemental.h int_guild.h int_homun.h \ - int_mail.h int_mercenary.h int_party.h int_pet.h int_quest.h \ - int_storage.h pincode.h + int_mail.h int_mercenary.h int_party.h int_pet.h int_quest.h \ + int_storage.h pincode.h HAVE_MYSQL=@HAVE_MYSQL@ ifeq ($(HAVE_MYSQL),yes) - CHAR_SERVER_SQL_DEPENDS=$(CHAR_OBJ) ../common/obj_sql/common_sql.a ../common/obj_all/common.a $(MT19937AR_OBJ) $(LIBCONFIG_OBJ) + CHAR_SERVER_SQL_DEPENDS=$(CHAR_OBJ) $(COMMON_D)/obj_sql/common_sql.a $(COMMON_D)/obj_all/common.a $(MT19937AR_OBJ) $(LIBCONFIG_OBJ) else CHAR_SERVER_SQL_DEPENDS=needs_mysql endif @@ -50,22 +54,22 @@ clean: buildclean help: @echo "possible targets are 'char-server' 'all' 'clean' 'help'" - @echo "'char-server' - char server" - @echo "'all' - builds all above targets" - @echo "'clean' - cleans builds and objects" - @echo "'buildclean' - cleans build temporary (object) files, without deleting the" - @echo " executables" - @echo "'help' - outputs this message" + @echo "'char-server' - char server" + @echo "'all' - builds all above targets" + @echo "'clean' - cleans builds and objects" + @echo "'buildclean' - cleans build temporary (object) files, without deleting the" + @echo " executables" + @echo "'help' - outputs this message" ##################################################################### +Makefile: Makefile.in + @$(MAKE) -C ../.. src/char/Makefile + needs_mysql: @echo "MySQL not found or disabled by the configure script" @exit 1 -Makefile: Makefile.in - @$(MAKE) -C ../.. src/char/Makefile - # object directories obj_sql: @@ -78,7 +82,8 @@ char-server: ../../char-server@EXEEXT@ ../../char-server@EXEEXT@: $(CHAR_SERVER_SQL_DEPENDS) Makefile @echo " LD $(notdir $@)" - @$(CC) @LDFLAGS@ -o ../../char-server@EXEEXT@ $(CHAR_OBJ) ../common/obj_sql/common_sql.a ../common/obj_all/common.a $(MT19937AR_OBJ) $(LIBCONFIG_OBJ) @LIBS@ @MYSQL_LIBS@ + @$(CC) @LDFLAGS@ -o ../../char-server@EXEEXT@ $(CHAR_OBJ) $(COMMON_D)/obj_sql/common_sql.a \ + $(COMMON_D)/obj_all/common.a $(MT19937AR_OBJ) $(LIBCONFIG_OBJ) @LIBS@ @MYSQL_LIBS@ # char object files @@ -87,13 +92,13 @@ obj_sql/%.o: %.c $(CHAR_H) $(COMMON_H) $(CONFIG_H) $(MT19937AR_H) $(LIBCONFIG_H) @$(CC) @CFLAGS@ $(MT19937AR_INCLUDE) $(LIBCONFIG_INCLUDE) @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $< # missing object files -../common/obj_all/common.a: +$(COMMON_D)/obj_all/common.a: @echo " MAKE $@" - @$(MAKE) -C ../common sql + @$(MAKE) -C $(COMMON_D) sql -../common/obj_sql/common_sql.a: +$(COMMON_D)/obj_sql/common_sql.a: @echo " MAKE $@" - @$(MAKE) -C ../common sql + @$(MAKE) -C $(COMMON_D) sql $(MT19937AR_OBJ): @echo " MAKE $@" diff --git a/src/char/char.c b/src/char/char.c index 7a948398c..5b497bd0c 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -45,7 +45,6 @@ char inventory_db[256] = "inventory"; char charlog_db[256] = "charlog"; char storage_db[256] = "storage"; char interlog_db[256] = "interlog"; -char reg_db[256] = "global_reg_value"; char skill_db[256] = "skill"; char memo_db[256] = "memo"; char guild_db[256] = "guild"; @@ -70,6 +69,11 @@ char mercenary_owner_db[256] = "mercenary_owner"; char ragsrvinfo_db[256] = "ragsrvinfo"; char elemental_db[256] = "elemental"; char interreg_db[32] = "interreg"; +char account_data_db[256] = "account_data"; +char acc_reg_num_db[32] = "acc_reg_num_db"; +char acc_reg_str_db[32] = "acc_reg_str_db"; +char char_reg_str_db[32] = "char_reg_str_db"; +char char_reg_num_db[32] = "char_reg_num_db"; // show loading/saving messages int save_log = 1; @@ -104,7 +108,8 @@ uint32 char_ip = 0; char bind_ip_str[128]; uint32 bind_ip = INADDR_ANY; uint16 char_port = 6121; -int char_maintenance = 0; +int char_server_type = 0; +int char_maintenance_min_group_id = 0; bool char_new = true; int char_new_display = 0; @@ -132,7 +137,7 @@ int max_connect_user = -1; int gm_allow_group = -1; int autosave_interval = DEFAULT_AUTOSAVE_INTERVAL; int start_zeny = 0; -int start_items[MAX_START_ITEMS*2]; +int start_items[MAX_START_ITEMS*3]; int guild_exp_rate = 100; //Custom limits for the fame lists. [Skotlex] @@ -178,7 +183,7 @@ static DBMap* auth_db; // int account_id -> struct auth_node* // Online User Database //----------------------------------------------------- -static int chardb_waiting_disconnect(int tid, unsigned int tick, int id, intptr_t data); +static int chardb_waiting_disconnect(int tid, int64 tick, int id, intptr_t data); int delete_char_sql(int char_id); /** @@ -329,15 +334,15 @@ void set_char_offline(int char_id, int account_id) static int char_db_setoffline(DBKey key, DBData *data, va_list ap) { struct online_char_data* character = (struct online_char_data*)DB->data2ptr(data); - int server = va_arg(ap, int); - if (server == -1) { + int server_id = va_arg(ap, int); + if (server_id == -1) { character->char_id = -1; character->server = -1; if(character->waiting_disconnect != INVALID_TIMER){ timer->delete(character->waiting_disconnect, chardb_waiting_disconnect); character->waiting_disconnect = INVALID_TIMER; } - } else if (character->server == server) + } else if (character->server == server_id) character->server = -2; //In some map server that we aren't connected to. return 0; } @@ -462,7 +467,7 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p) (p->ele_id != cp->ele_id) || (p->shield != cp->shield) || (p->head_top != cp->head_top) || (p->head_mid != cp->head_mid) || (p->head_bottom != cp->head_bottom) || (p->delete_date != cp->delete_date) || (p->rename != cp->rename) || (p->slotchange != cp->slotchange) || (p->robe != cp->robe) || - (p->show_equip != cp->show_equip) || (p->allow_party != cp->allow_party) + (p->show_equip != cp->show_equip) || (p->allow_party != cp->allow_party) || (p->font != cp->font) ) { //Save status unsigned int opt = 0; @@ -478,7 +483,7 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p) "`option`='%d',`party_id`='%d',`guild_id`='%d',`pet_id`='%d',`homun_id`='%d',`elemental_id`='%d'," "`weapon`='%d',`shield`='%d',`head_top`='%d',`head_mid`='%d',`head_bottom`='%d'," "`last_map`='%s',`last_x`='%d',`last_y`='%d',`save_map`='%s',`save_x`='%d',`save_y`='%d', `rename`='%d'," - "`delete_date`='%lu',`robe`='%d',`slotchange`='%d', `char_opt`='%u'" + "`delete_date`='%lu',`robe`='%d',`slotchange`='%d', `char_opt`='%u', `font`='%u'" " WHERE `account_id`='%d' AND `char_id` = '%d'", char_db, p->base_level, p->job_level, p->base_exp, p->job_exp, p->zeny, @@ -489,7 +494,7 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p) mapindex_id2name(p->last_point.map), p->last_point.x, p->last_point.y, mapindex_id2name(p->save_point.map), p->save_point.x, p->save_point.y, p->rename, (unsigned long)p->delete_date, // FIXME: platform-dependent size - p->robe,p->slotchange,opt, + p->robe,p->slotchange,opt,p->font, p->account_id, p->char_id) ) { Sql_ShowDebug(sql_handle); @@ -497,6 +502,14 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p) } else strcat(save_status, " status"); } + + if( p->bank_vault != cp->bank_vault || p->mod_exp != cp->mod_exp || p->mod_drop != cp->mod_drop || p->mod_death != cp->mod_death ) { + if( SQL_ERROR == SQL->Query(sql_handle, "REPLACE INTO `%s` (`account_id`,`bank_vault`,`base_exp`,`base_drop`,`base_death`) VALUES ('%d','%d','%d','%d','%d')",account_data_db,p->account_id,p->bank_vault,p->mod_exp,p->mod_drop,p->mod_death) ) { + Sql_ShowDebug(sql_handle); + errors++; + } else + strcat(save_status, " accdata"); + } //Values that will seldom change (to speed up saving) if ( @@ -675,6 +688,7 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p) strcat(save_status, " hotkeys"); } #endif + StrBuf->Destroy(&buf); if (save_status[0]!='\0' && save_log) ShowInfo("Saved char %d - %s:%s.\n", char_id, p->name, save_status); @@ -714,8 +728,8 @@ int memitemdata_to_sql(const struct item items[], int max, int id, int tableswit // it significantly reduces cpu load on the database server. StrBuf->Init(&buf); - StrBuf->AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`"); - for( j = 0; j < MAX_SLOTS; ++j ) + StrBuf->AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `bound`"); + for( j = 0; j < MAX_SLOTS; ++j ) StrBuf->Printf(&buf, ", `card%d`", j); StrBuf->Printf(&buf, " FROM `%s` WHERE `%s`='%d'", tablename, selectoption, id); @@ -732,13 +746,14 @@ int memitemdata_to_sql(const struct item items[], int max, int id, int tableswit SQL->StmtBindColumn(stmt, 0, SQLDT_INT, &item.id, 0, NULL, NULL); SQL->StmtBindColumn(stmt, 1, SQLDT_SHORT, &item.nameid, 0, NULL, NULL); SQL->StmtBindColumn(stmt, 2, SQLDT_SHORT, &item.amount, 0, NULL, NULL); - SQL->StmtBindColumn(stmt, 3, SQLDT_USHORT, &item.equip, 0, NULL, NULL); + SQL->StmtBindColumn(stmt, 3, SQLDT_UINT, &item.equip, 0, NULL, NULL); SQL->StmtBindColumn(stmt, 4, SQLDT_CHAR, &item.identify, 0, NULL, NULL); SQL->StmtBindColumn(stmt, 5, SQLDT_CHAR, &item.refine, 0, NULL, NULL); SQL->StmtBindColumn(stmt, 6, SQLDT_CHAR, &item.attribute, 0, NULL, NULL); SQL->StmtBindColumn(stmt, 7, SQLDT_UINT, &item.expire_time, 0, NULL, NULL); - for( j = 0; j < MAX_SLOTS; ++j ) - SQL->StmtBindColumn(stmt, 8+j, SQLDT_SHORT, &item.card[j], 0, NULL, NULL); + SQL->StmtBindColumn(stmt, 8, SQLDT_UCHAR, &item.bound, 0, NULL, NULL); + for( j = 0; j < MAX_SLOTS; ++j ) + SQL->StmtBindColumn(stmt, 9+j, SQLDT_SHORT, &item.card[j], 0, NULL, NULL); // bit array indicating which inventory items have already been matched flag = (bool*) aCalloc(max, sizeof(bool)); @@ -765,17 +780,18 @@ int memitemdata_to_sql(const struct item items[], int max, int id, int tableswit items[i].identify == item.identify && items[i].refine == item.refine && items[i].attribute == item.attribute && - items[i].expire_time == item.expire_time ) + items[i].expire_time == item.expire_time && + items[i].bound == item.bound ) ; //Do nothing. else { // update all fields. StrBuf->Clear(&buf); - StrBuf->Printf(&buf, "UPDATE `%s` SET `amount`='%d', `equip`='%d', `identify`='%d', `refine`='%d',`attribute`='%d', `expire_time`='%u'", - tablename, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute, items[i].expire_time); - for( j = 0; j < MAX_SLOTS; ++j ) - StrBuf->Printf(&buf, ", `card%d`=%d", j, items[i].card[j]); - StrBuf->Printf(&buf, " WHERE `id`='%d' LIMIT 1", item.id); + StrBuf->Printf(&buf, "UPDATE `%s` SET `amount`='%d', `equip`='%d', `identify`='%d', `refine`='%d',`attribute`='%d', `expire_time`='%u', `bound`='%d'", + tablename, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute, items[i].expire_time, items[i].bound); + for( j = 0; j < MAX_SLOTS; ++j )for( j = 0; j < MAX_SLOTS; ++j ) + StrBuf->Printf(&buf, ", `card%d`=%d", j, items[i].card[j]); + StrBuf->Printf(&buf, " WHERE `id`='%d' LIMIT 1", item.id); if( SQL_ERROR == SQL->QueryStr(sql_handle, StrBuf->Value(&buf)) ) { @@ -800,8 +816,8 @@ int memitemdata_to_sql(const struct item items[], int max, int id, int tableswit SQL->StmtFree(stmt); StrBuf->Clear(&buf); - StrBuf->Printf(&buf, "INSERT INTO `%s`(`%s`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `unique_id`", tablename, selectoption); - for( j = 0; j < MAX_SLOTS; ++j ) + StrBuf->Printf(&buf, "INSERT INTO `%s`(`%s`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `bound`, `unique_id`", tablename, selectoption); + for( j = 0; j < MAX_SLOTS; ++j ) StrBuf->Printf(&buf, ", `card%d`", j); StrBuf->AppendStr(&buf, ") VALUES "); @@ -818,9 +834,9 @@ int memitemdata_to_sql(const struct item items[], int max, int id, int tableswit else found = true; - StrBuf->Printf(&buf, "('%d', '%d', '%d', '%d', '%d', '%d', '%d', '%u', '%"PRIu64"'", - id, items[i].nameid, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute, items[i].expire_time, items[i].unique_id); - for( j = 0; j < MAX_SLOTS; ++j ) + StrBuf->Printf(&buf, "('%d', '%d', '%d', '%d', '%d', '%d', '%d', '%u', '%d', '%"PRIu64"'", + id, items[i].nameid, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute, items[i].expire_time, items[i].bound, items[i].unique_id); + for( j = 0; j < MAX_SLOTS; ++j ) StrBuf->Printf(&buf, ", '%d'", items[i].card[j]); StrBuf->AppendStr(&buf, ")"); @@ -858,8 +874,8 @@ int inventory_to_sql(const struct item items[], int max, int id) { // it significantly reduces cpu load on the database server. StrBuf->Init(&buf); - StrBuf->AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `favorite`"); - for( j = 0; j < MAX_SLOTS; ++j ) + StrBuf->AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `favorite`, `bound`"); + for( j = 0; j < MAX_SLOTS; ++j ) StrBuf->Printf(&buf, ", `card%d`", j); StrBuf->Printf(&buf, " FROM `%s` WHERE `char_id`='%d'", inventory_db, id); @@ -876,14 +892,15 @@ int inventory_to_sql(const struct item items[], int max, int id) { SQL->StmtBindColumn(stmt, 0, SQLDT_INT, &item.id, 0, NULL, NULL); SQL->StmtBindColumn(stmt, 1, SQLDT_SHORT, &item.nameid, 0, NULL, NULL); SQL->StmtBindColumn(stmt, 2, SQLDT_SHORT, &item.amount, 0, NULL, NULL); - SQL->StmtBindColumn(stmt, 3, SQLDT_USHORT, &item.equip, 0, NULL, NULL); + SQL->StmtBindColumn(stmt, 3, SQLDT_UINT, &item.equip, 0, NULL, NULL); SQL->StmtBindColumn(stmt, 4, SQLDT_CHAR, &item.identify, 0, NULL, NULL); SQL->StmtBindColumn(stmt, 5, SQLDT_CHAR, &item.refine, 0, NULL, NULL); SQL->StmtBindColumn(stmt, 6, SQLDT_CHAR, &item.attribute, 0, NULL, NULL); SQL->StmtBindColumn(stmt, 7, SQLDT_UINT, &item.expire_time, 0, NULL, NULL); SQL->StmtBindColumn(stmt, 8, SQLDT_CHAR, &item.favorite, 0, NULL, NULL); - for( j = 0; j < MAX_SLOTS; ++j ) - SQL->StmtBindColumn(stmt, 9+j, SQLDT_SHORT, &item.card[j], 0, NULL, NULL); + SQL->StmtBindColumn(stmt, 9, SQLDT_UCHAR, &item.bound, 0, NULL, NULL); + for( j = 0; j < MAX_SLOTS; ++j ) + SQL->StmtBindColumn(stmt, 10+j, SQLDT_SHORT, &item.card[j], 0, NULL, NULL); // bit array indicating which inventory items have already been matched flag = (bool*) aCalloc(max, sizeof(bool)); @@ -909,15 +926,16 @@ int inventory_to_sql(const struct item items[], int max, int id) { items[i].refine == item.refine && items[i].attribute == item.attribute && items[i].expire_time == item.expire_time && - items[i].favorite == item.favorite ) + items[i].favorite == item.favorite && + items[i].bound == item.bound ) ; //Do nothing. else { // update all fields. StrBuf->Clear(&buf); - StrBuf->Printf(&buf, "UPDATE `%s` SET `amount`='%d', `equip`='%d', `identify`='%d', `refine`='%d',`attribute`='%d', `expire_time`='%u', `favorite`='%d'", - inventory_db, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute, items[i].expire_time, items[i].favorite); - for( j = 0; j < MAX_SLOTS; ++j ) - StrBuf->Printf(&buf, ", `card%d`=%d", j, items[i].card[j]); + StrBuf->Printf(&buf, "UPDATE `%s` SET `amount`='%d', `equip`='%d', `identify`='%d', `refine`='%d',`attribute`='%d', `expire_time`='%u', `favorite`='%d', `bound`='%d'", + inventory_db, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute, items[i].expire_time, items[i].favorite, items[i].bound); + for( j = 0; j < MAX_SLOTS; ++j ) + StrBuf->Printf(&buf, ", `card%d`=%d", j, items[i].card[j]); StrBuf->Printf(&buf, " WHERE `id`='%d' LIMIT 1", item.id); if( SQL_ERROR == SQL->QueryStr(sql_handle, StrBuf->Value(&buf)) ) { @@ -940,8 +958,8 @@ int inventory_to_sql(const struct item items[], int max, int id) { SQL->StmtFree(stmt); StrBuf->Clear(&buf); - StrBuf->Printf(&buf, "INSERT INTO `%s` (`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `favorite`, `unique_id`", inventory_db); - for( j = 0; j < MAX_SLOTS; ++j ) + StrBuf->Printf(&buf, "INSERT INTO `%s` (`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `favorite`, `bound`, `unique_id`", inventory_db); + for( j = 0; j < MAX_SLOTS; ++j ) StrBuf->Printf(&buf, ", `card%d`", j); StrBuf->AppendStr(&buf, ") VALUES "); @@ -957,9 +975,9 @@ int inventory_to_sql(const struct item items[], int max, int id) { else found = true; - StrBuf->Printf(&buf, "('%d', '%d', '%d', '%d', '%d', '%d', '%d', '%u', '%d', '%"PRIu64"'", - id, items[i].nameid, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute, items[i].expire_time, items[i].favorite, items[i].unique_id); - for( j = 0; j < MAX_SLOTS; ++j ) + StrBuf->Printf(&buf, "('%d', '%d', '%d', '%d', '%d', '%d', '%d', '%u', '%d', '%d', '%"PRIu64"'", + id, items[i].nameid, items[i].amount, items[i].equip, items[i].identify, items[i].refine, items[i].attribute, items[i].expire_time, items[i].favorite, items[i].bound, items[i].unique_id); + for( j = 0; j < MAX_SLOTS; ++j ) StrBuf->Printf(&buf, ", '%d'", items[i].card[j]); StrBuf->AppendStr(&buf, ")"); @@ -989,6 +1007,7 @@ int mmo_chars_fromsql(struct char_session_data* sd, uint8* buf) struct mmo_charstatus p; int j = 0, i; char last_map[MAP_NAME_LENGTH_EXT]; + time_t unban_time = 0; stmt = SQL->StmtMalloc(sql_handle); if( stmt == NULL ) { @@ -997,8 +1016,10 @@ int mmo_chars_fromsql(struct char_session_data* sd, uint8* buf) } memset(&p, 0, sizeof(p)); - for(i = 0 ; i < MAX_CHARS; i++ ) + for(i = 0 ; i < MAX_CHARS; i++ ) { sd->found_char[i] = -1; + sd->unban_time[i] = 0; + } // read char data if( SQL_ERROR == SQL->StmtPrepare(stmt, "SELECT " @@ -1006,7 +1027,7 @@ int mmo_chars_fromsql(struct char_session_data* sd, uint8* buf) "`str`,`agi`,`vit`,`int`,`dex`,`luk`,`max_hp`,`hp`,`max_sp`,`sp`," "`status_point`,`skill_point`,`option`,`karma`,`manner`,`hair`,`hair_color`," "`clothes_color`,`weapon`,`shield`,`head_top`,`head_mid`,`head_bottom`,`last_map`,`rename`,`delete_date`," - "`robe`,`slotchange`" + "`robe`,`slotchange`,`unban_time`" " FROM `%s` WHERE `account_id`='%d' AND `char_num` < '%d'", char_db, sd->account_id, MAX_CHARS) || SQL_ERROR == SQL->StmtExecute(stmt) || SQL_ERROR == SQL->StmtBindColumn(stmt, 0, SQLDT_INT, &p.char_id, 0, NULL, NULL) @@ -1042,10 +1063,11 @@ int mmo_chars_fromsql(struct char_session_data* sd, uint8* buf) || SQL_ERROR == SQL->StmtBindColumn(stmt, 30, SQLDT_SHORT, &p.head_mid, 0, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 31, SQLDT_SHORT, &p.head_bottom, 0, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 32, SQLDT_STRING, &last_map, sizeof(last_map), NULL, NULL) - || SQL_ERROR == SQL->StmtBindColumn(stmt, 33, SQLDT_USHORT, &p.rename, 0, NULL, NULL) + || SQL_ERROR == SQL->StmtBindColumn(stmt, 33, SQLDT_USHORT, &p.rename, 0, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 34, SQLDT_UINT32, &p.delete_date, 0, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 35, SQLDT_SHORT, &p.robe, 0, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 36, SQLDT_USHORT, &p.slotchange, 0, NULL, NULL) + || SQL_ERROR == SQL->StmtBindColumn(stmt, 37, SQLDT_LONG, &unban_time, 0, NULL, NULL) ) { SqlStmt_ShowDebug(stmt); @@ -1054,8 +1076,9 @@ int mmo_chars_fromsql(struct char_session_data* sd, uint8* buf) } for( i = 0; i < MAX_CHARS && SQL_SUCCESS == SQL->StmtNextRow(stmt); i++ ) { - p.last_point.map = mapindex_name2id(last_map); + p.last_point.map = mapindex->name2id(last_map); sd->found_char[p.slot] = p.char_id; + sd->unban_time[p.slot] = unban_time; j += mmo_char_tobuf(WBUFP(buf, j), &p); } @@ -1085,6 +1108,7 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything int hotkey_num; #endif unsigned int opt; + int account_id; memset(p, 0, sizeof(struct mmo_charstatus)); @@ -1104,7 +1128,7 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything "`status_point`,`skill_point`,`option`,`karma`,`manner`,`party_id`,`guild_id`,`pet_id`,`homun_id`,`elemental_id`,`hair`," "`hair_color`,`clothes_color`,`weapon`,`shield`,`head_top`,`head_mid`,`head_bottom`,`last_map`,`last_x`,`last_y`," "`save_map`,`save_x`,`save_y`,`partner_id`,`father`,`mother`,`child`,`fame`,`rename`,`delete_date`,`robe`,`slotchange`," - "`char_opt`" + "`char_opt`,`font`" " FROM `%s` WHERE `char_id`=? LIMIT 1", char_db) || SQL_ERROR == SQL->StmtBindParam(stmt, 0, SQLDT_INT, &char_id, 0) || SQL_ERROR == SQL->StmtExecute(stmt) @@ -1137,7 +1161,7 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything || SQL_ERROR == SQL->StmtBindColumn(stmt, 26, SQLDT_INT, &p->guild_id, 0, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 27, SQLDT_INT, &p->pet_id, 0, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 28, SQLDT_INT, &p->hom_id, 0, NULL, NULL) - || SQL_ERROR == SQL->StmtBindColumn(stmt, 29, SQLDT_INT, &p->ele_id, 0, NULL, NULL) + || SQL_ERROR == SQL->StmtBindColumn(stmt, 29, SQLDT_INT, &p->ele_id, 0, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 30, SQLDT_SHORT, &p->hair, 0, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 31, SQLDT_SHORT, &p->hair_color, 0, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 32, SQLDT_SHORT, &p->clothes_color, 0, NULL, NULL) @@ -1157,11 +1181,12 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything || SQL_ERROR == SQL->StmtBindColumn(stmt, 46, SQLDT_INT, &p->mother, 0, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 47, SQLDT_INT, &p->child, 0, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 48, SQLDT_INT, &p->fame, 0, NULL, NULL) - || SQL_ERROR == SQL->StmtBindColumn(stmt, 49, SQLDT_USHORT, &p->rename, 0, NULL, NULL) + || SQL_ERROR == SQL->StmtBindColumn(stmt, 49, SQLDT_USHORT, &p->rename, 0, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 50, SQLDT_UINT32, &p->delete_date, 0, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 51, SQLDT_SHORT, &p->robe, 0, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 52, SQLDT_USHORT, &p->slotchange, 0, NULL, NULL) - || SQL_ERROR == SQL->StmtBindColumn(stmt, 53, SQLDT_UINT, &opt, 0, NULL, NULL) + || SQL_ERROR == SQL->StmtBindColumn(stmt, 53, SQLDT_UINT, &opt, 0, NULL, NULL) + || SQL_ERROR == SQL->StmtBindColumn(stmt, 54, SQLDT_UCHAR, &p->font, 0, NULL, NULL) ) { SqlStmt_ShowDebug(stmt); @@ -1174,17 +1199,20 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything SQL->StmtFree(stmt); return 0; } - p->last_point.map = mapindex_name2id(last_map); - p->save_point.map = mapindex_name2id(save_map); + + account_id = p->account_id; + + p->last_point.map = mapindex->name2id(last_map); + p->save_point.map = mapindex->name2id(save_map); if( p->last_point.map == 0 ) { - p->last_point.map = (unsigned short)strdb_iget(mapindex_db, MAP_DEFAULT); + p->last_point.map = (unsigned short)strdb_iget(mapindex->db, MAP_DEFAULT); p->last_point.x = MAP_DEFAULT_X; p->last_point.y = MAP_DEFAULT_Y; } if( p->save_point.map == 0 ) { - p->save_point.map = (unsigned short)strdb_iget(mapindex_db, MAP_DEFAULT); + p->save_point.map = (unsigned short)strdb_iget(mapindex->db, MAP_DEFAULT); p->save_point.x = MAP_DEFAULT_X; p->save_point.y = MAP_DEFAULT_Y; } @@ -1208,35 +1236,36 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything SqlStmt_ShowDebug(stmt); for( i = 0; i < MAX_MEMOPOINTS && SQL_SUCCESS == SQL->StmtNextRow(stmt); ++i ) { - tmp_point.map = mapindex_name2id(point_map); + tmp_point.map = mapindex->name2id(point_map); memcpy(&p->memo_point[i], &tmp_point, sizeof(tmp_point)); } strcat(t_msg, " memo"); //read inventory - //`inventory` (`id`,`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `card0`, `card1`, `card2`, `card3`, `expire_time`, `favorite`, `unique_id`) - StrBuf->Init(&buf); - StrBuf->AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `favorite`, `unique_id`"); - for( i = 0; i < MAX_SLOTS; ++i ) + //`inventory` (`id`,`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `card0`, `card1`, `card2`, `card3`, `expire_time`, `favorite`, `bound`, `unique_id`) + StrBuf->Init(&buf); + StrBuf->AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `favorite`, `bound`, `unique_id`"); + for( i = 0; i < MAX_SLOTS; ++i ) StrBuf->Printf(&buf, ", `card%d`", i); StrBuf->Printf(&buf, " FROM `%s` WHERE `char_id`=? LIMIT %d", inventory_db, MAX_INVENTORY); if( SQL_ERROR == SQL->StmtPrepareStr(stmt, StrBuf->Value(&buf)) || SQL_ERROR == SQL->StmtBindParam(stmt, 0, SQLDT_INT, &char_id, 0) || SQL_ERROR == SQL->StmtExecute(stmt) - || SQL_ERROR == SQL->StmtBindColumn(stmt, 0, SQLDT_INT, &tmp_item.id, 0, NULL, NULL) - || SQL_ERROR == SQL->StmtBindColumn(stmt, 1, SQLDT_SHORT, &tmp_item.nameid, 0, NULL, NULL) - || SQL_ERROR == SQL->StmtBindColumn(stmt, 2, SQLDT_SHORT, &tmp_item.amount, 0, NULL, NULL) - || SQL_ERROR == SQL->StmtBindColumn(stmt, 3, SQLDT_USHORT, &tmp_item.equip, 0, NULL, NULL) - || SQL_ERROR == SQL->StmtBindColumn(stmt, 4, SQLDT_CHAR, &tmp_item.identify, 0, NULL, NULL) - || SQL_ERROR == SQL->StmtBindColumn(stmt, 5, SQLDT_CHAR, &tmp_item.refine, 0, NULL, NULL) - || SQL_ERROR == SQL->StmtBindColumn(stmt, 6, SQLDT_CHAR, &tmp_item.attribute, 0, NULL, NULL) - || SQL_ERROR == SQL->StmtBindColumn(stmt, 7, SQLDT_UINT, &tmp_item.expire_time, 0, NULL, NULL) - || SQL_ERROR == SQL->StmtBindColumn(stmt, 8, SQLDT_CHAR, &tmp_item.favorite, 0, NULL, NULL) - || SQL_ERROR == SQL->StmtBindColumn(stmt, 9, SQLDT_ULONGLONG, &tmp_item.unique_id, 0, NULL, NULL) ) - SqlStmt_ShowDebug(stmt); + || SQL_ERROR == SQL->StmtBindColumn(stmt, 0, SQLDT_INT, &tmp_item.id, 0, NULL, NULL) + || SQL_ERROR == SQL->StmtBindColumn(stmt, 1, SQLDT_SHORT, &tmp_item.nameid, 0, NULL, NULL) + || SQL_ERROR == SQL->StmtBindColumn(stmt, 2, SQLDT_SHORT, &tmp_item.amount, 0, NULL, NULL) + || SQL_ERROR == SQL->StmtBindColumn(stmt, 3, SQLDT_UINT, &tmp_item.equip, 0, NULL, NULL) + || SQL_ERROR == SQL->StmtBindColumn(stmt, 4, SQLDT_CHAR, &tmp_item.identify, 0, NULL, NULL) + || SQL_ERROR == SQL->StmtBindColumn(stmt, 5, SQLDT_CHAR, &tmp_item.refine, 0, NULL, NULL) + || SQL_ERROR == SQL->StmtBindColumn(stmt, 6, SQLDT_CHAR, &tmp_item.attribute, 0, NULL, NULL) + || SQL_ERROR == SQL->StmtBindColumn(stmt, 7, SQLDT_UINT, &tmp_item.expire_time, 0, NULL, NULL) + || SQL_ERROR == SQL->StmtBindColumn(stmt, 8, SQLDT_CHAR, &tmp_item.favorite, 0, NULL, NULL) + || SQL_ERROR == SQL->StmtBindColumn(stmt, 9, SQLDT_UCHAR, &tmp_item.bound, 0, NULL, NULL) + || SQL_ERROR == SQL->StmtBindColumn(stmt, 10, SQLDT_UINT64, &tmp_item.unique_id, 0, NULL, NULL) ) + SqlStmt_ShowDebug(stmt); for( i = 0; i < MAX_SLOTS; ++i ) - if( SQL_ERROR == SQL->StmtBindColumn(stmt, 10+i, SQLDT_SHORT, &tmp_item.card[i], 0, NULL, NULL) ) + if( SQL_ERROR == SQL->StmtBindColumn(stmt, 11+i, SQLDT_SHORT, &tmp_item.card[i], 0, NULL, NULL) ) SqlStmt_ShowDebug(stmt); for( i = 0; i < MAX_INVENTORY && SQL_SUCCESS == SQL->StmtNextRow(stmt); ++i ) @@ -1245,28 +1274,30 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything strcat(t_msg, " inventory"); //read cart - //`cart_inventory` (`id`,`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `card0`, `card1`, `card2`, `card3`, expire_time`, `unique_id`) - StrBuf->Clear(&buf); - StrBuf->AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `unique_id`"); - for( j = 0; j < MAX_SLOTS; ++j ) + //`cart_inventory` (`id`,`char_id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `card0`, `card1`, `card2`, `card3`, expire_time`, `bound`, `unique_id`) + StrBuf->Clear(&buf); + StrBuf->AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `bound`, `unique_id`"); + for( j = 0; j < MAX_SLOTS; ++j ) StrBuf->Printf(&buf, ", `card%d`", j); StrBuf->Printf(&buf, " FROM `%s` WHERE `char_id`=? LIMIT %d", cart_db, MAX_CART); + memset(&tmp_item, 0, sizeof(tmp_item)); if( SQL_ERROR == SQL->StmtPrepareStr(stmt, StrBuf->Value(&buf)) || SQL_ERROR == SQL->StmtBindParam(stmt, 0, SQLDT_INT, &char_id, 0) || SQL_ERROR == SQL->StmtExecute(stmt) || SQL_ERROR == SQL->StmtBindColumn(stmt, 0, SQLDT_INT, &tmp_item.id, 0, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 1, SQLDT_SHORT, &tmp_item.nameid, 0, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 2, SQLDT_SHORT, &tmp_item.amount, 0, NULL, NULL) - || SQL_ERROR == SQL->StmtBindColumn(stmt, 3, SQLDT_USHORT, &tmp_item.equip, 0, NULL, NULL) + || SQL_ERROR == SQL->StmtBindColumn(stmt, 3, SQLDT_UINT, &tmp_item.equip, 0, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 4, SQLDT_CHAR, &tmp_item.identify, 0, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 5, SQLDT_CHAR, &tmp_item.refine, 0, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 6, SQLDT_CHAR, &tmp_item.attribute, 0, NULL, NULL) || SQL_ERROR == SQL->StmtBindColumn(stmt, 7, SQLDT_UINT, &tmp_item.expire_time, 0, NULL, NULL) - || SQL_ERROR == SQL->StmtBindColumn(stmt, 8, SQLDT_ULONGLONG, &tmp_item.unique_id, 0, NULL, NULL) ) - SqlStmt_ShowDebug(stmt); + || SQL_ERROR == SQL->StmtBindColumn(stmt, 8, SQLDT_UCHAR, &tmp_item.bound, 0, NULL, NULL) + || SQL_ERROR == SQL->StmtBindColumn(stmt, 9, SQLDT_UINT64, &tmp_item.unique_id, 0, NULL, NULL) ) + SqlStmt_ShowDebug(stmt); for( i = 0; i < MAX_SLOTS; ++i ) - if( SQL_ERROR == SQL->StmtBindColumn(stmt, 9+i, SQLDT_SHORT, &tmp_item.card[i], 0, NULL, NULL) ) + if( SQL_ERROR == SQL->StmtBindColumn(stmt, 10+i, SQLDT_SHORT, &tmp_item.card[i], 0, NULL, NULL) ) SqlStmt_ShowDebug(stmt); for( i = 0; i < MAX_CART && SQL_SUCCESS == SQL->StmtNextRow(stmt); ++i ) @@ -1338,6 +1369,21 @@ int mmo_char_fromsql(int char_id, struct mmo_charstatus* p, bool load_everything mercenary_owner_fromsql(char_id, p); strcat(t_msg, " mercenary"); + /* default */ + p->mod_exp = p->mod_drop = p->mod_death = 100; + + //`account_data` (`account_id`,`bank_vault`,`base_exp`,`base_drop`,`base_death`) + if( SQL_ERROR == SQL->StmtPrepare(stmt, "SELECT `bank_vault`,`base_exp`,`base_drop`,`base_death` FROM `%s` WHERE `account_id`=? LIMIT 1", account_data_db) + || SQL_ERROR == SQL->StmtBindParam(stmt, 0, SQLDT_INT, &account_id, 0) + || SQL_ERROR == SQL->StmtExecute(stmt) + || SQL_ERROR == SQL->StmtBindColumn(stmt, 0, SQLDT_INT, &p->bank_vault, 0, NULL, NULL) + || SQL_ERROR == SQL->StmtBindColumn(stmt, 1, SQLDT_USHORT, &p->mod_exp, 0, NULL, NULL) + || SQL_ERROR == SQL->StmtBindColumn(stmt, 2, SQLDT_USHORT, &p->mod_drop, 0, NULL, NULL) + || SQL_ERROR == SQL->StmtBindColumn(stmt, 3, SQLDT_USHORT, &p->mod_death, 0, NULL, NULL) ) + SqlStmt_ShowDebug(stmt); + + if( SQL_SUCCESS == SQL->StmtNextRow(stmt) ) + strcat(t_msg, " accdata"); if (save_log) ShowInfo("Loaded char (%d - %s): %s\n", char_id, p->name, t_msg); //ok. all data load successfuly! SQL->StmtFree(stmt); @@ -1533,7 +1579,7 @@ int make_new_char_sql(struct char_session_data* sd, char* name_, int str, int ag char name[NAME_LENGTH]; char esc_name[NAME_LENGTH*2+1]; - int char_id, flag, k; + int char_id, flag, k, l; safestrncpy(name, name_, NAME_LENGTH); normalize_name(name,TRIM_CHARS); @@ -1596,11 +1642,29 @@ int make_new_char_sql(struct char_session_data* sd, char* name_, int str, int ag #endif //Retrieve the newly auto-generated char id char_id = (int)SQL->LastInsertId(sql_handle); + //Give the char the default items - - for (k = 0; k < ARRAYLENGTH(start_items) && start_items[k] != 0; k += 2) { - if( SQL_ERROR == SQL->Query(sql_handle, "INSERT INTO `%s` (`char_id`,`nameid`, `amount`, `identify`) VALUES ('%d', '%d', '%d', '%d')", inventory_db, char_id, start_items[k], start_items[k + 1], 1) ) - Sql_ShowDebug(sql_handle); + for (k = 0; k < ARRAYLENGTH(start_items) && start_items[k] != 0; k += 3) { + // FIXME: How to define if an item is stackable without having to lookup itemdb? [panikon] + if( start_items[k+2] == 1 ) + { + if( SQL_ERROR == SQL->Query(sql_handle, + "INSERT INTO `%s` (`char_id`,`nameid`, `amount`, `identify`) VALUES ('%d', '%d', '%d', '%d')", + inventory_db, char_id, start_items[k], start_items[k + 1], 1) ) + Sql_ShowDebug(sql_handle); + } + else if( start_items[k+2] == 0 ) + { + // Non-stackable items should have their own entries (issue: 7279) + for( l = 0; l < start_items[k+1]; l++ ) + { + if( SQL_ERROR == SQL->Query(sql_handle, + "INSERT INTO `%s` (`char_id`,`nameid`, `amount`, `identify`) VALUES ('%d', '%d', '%d', '%d')", + inventory_db, char_id, start_items[k], 1, 1) + ) + Sql_ShowDebug(sql_handle); + } + } } ShowInfo("Created char: account: %d, char: %d, slot: %d, name: %s\n", sd->account_id, char_id, slot, name); @@ -1750,7 +1814,9 @@ int delete_char_sql(int char_id) Sql_ShowDebug(sql_handle); /* delete character registry */ - if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `type`=3 AND `char_id`='%d'", reg_db, char_id) ) + if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", char_reg_str_db, char_id) ) + Sql_ShowDebug(sql_handle); + if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `char_id`='%d'", char_reg_num_db, char_id) ) Sql_ShowDebug(sql_handle); /* delete skills */ @@ -1870,11 +1936,11 @@ int mmo_char_tobuf(uint8* buffer, struct mmo_charstatus* p) { offset += 2; #endif #if (PACKETVER >= 20100720 && PACKETVER <= 20100727) || PACKETVER >= 20100803 - mapindex_getmapname_ext(mapindex_id2name(p->last_point.map), (char*)WBUFP(buf,108)); + mapindex->getmapname_ext(mapindex_id2name(p->last_point.map), (char*)WBUFP(buf,108)); offset += MAP_NAME_LENGTH_EXT; #endif #if PACKETVER >= 20100803 - WBUFL(buf,124) = TOL(p->delete_date); + WBUFL(buf,124) = (int)p->delete_date; offset += 4; #endif #if PACKETVER >= 20110111 @@ -1894,6 +1960,7 @@ int mmo_char_tobuf(uint8* buffer, struct mmo_charstatus* p) { return 106+offset; } + /* Made Possible by Yommy~! <3 */ void mmo_char_send099d(int fd, struct char_session_data *sd) { WFIFOHEAD(fd,4 + (MAX_CHARS*MAX_CHAR_BUF)); @@ -1901,6 +1968,44 @@ void mmo_char_send099d(int fd, struct char_session_data *sd) { WFIFOW(fd,2) = mmo_chars_fromsql(sd, WFIFOP(fd,4)) + 4; WFIFOSET(fd,WFIFOW(fd,2)); } +/* Sends character ban list */ +/* Made Possible by Yommy~! <3 */ +void mmo_char_send020d(int fd, struct char_session_data *sd) { + int i; + time_t now = time(NULL); + + ARR_FIND(0, MAX_CHARS, i, sd->unban_time[i]); + + if( i != MAX_CHARS ) { + int c; + + WFIFOHEAD(fd, 4 + (MAX_CHARS*24)); + + WFIFOW(fd, 0) = 0x20d; + + for(i = 0, c = 0; i < MAX_CHARS; i++) { + if( sd->unban_time[i] ) { + timestamp2string((char*)WFIFOP(fd,8 + (28*c)), 20, sd->unban_time[i], "%Y-%m-%d %H:%M:%S"); + + if( sd->unban_time[i] > now ) + WFIFOL(fd, 4 + (24*c)) = sd->found_char[i]; + else { + /* reset -- client keeps this information even if you logout so we need to clear */ + WFIFOL(fd, 4 + (24*c)) = 0; + /* also update on mysql */ + sd->unban_time[i] = 0; + if( SQL_ERROR == SQL->Query(sql_handle, "UPDATE `%s` SET `unban_time`='0' WHERE `char_id`='%d' LIMIT 1", char_db, sd->found_char[i]) ) + Sql_ShowDebug(sql_handle); + } + c++; + } + } + + WFIFOW(fd, 2) = 4 + (24*c); + + WFIFOSET(fd, WFIFOW(fd, 2)); + } +} int mmo_char_send006b(int fd, struct char_session_data* sd); //---------------------------------------- // [Ind/Hercules] notify client about charselect window data @@ -2022,8 +2127,8 @@ void disconnect_player(int account_id) struct char_session_data* sd; // disconnect player if online on char-server - ARR_FIND( 0, fd_max, i, session[i] && (sd = (struct char_session_data*)session[i]->session_data) && sd->account_id == account_id ); - if( i < fd_max ) + ARR_FIND( 0, sockt->fd_max, i, session[i] && (sd = (struct char_session_data*)session[i]->session_data) && sd->account_id == account_id ); + if( i < sockt->fd_max ) set_eof(i); } @@ -2074,7 +2179,7 @@ static void char_auth_ok(int fd, struct char_session_data *sd) // continues when account data is received... } -int send_accounts_tologin(int tid, unsigned int tick, int id, intptr_t data); +int send_accounts_tologin(int tid, int64 tick, int id, intptr_t data); void mapif_server_reset(int id); @@ -2127,7 +2232,6 @@ void loginif_on_ready(void) int parse_fromlogin(int fd) { struct char_session_data* sd = NULL; - int i; // only process data from the login-server if( fd != login_fd ) { @@ -2142,7 +2246,7 @@ int parse_fromlogin(int fd) { loginif_on_disconnect(); return 0; } else if ( session[fd]->flag.ping ) {/* we've reached stall time */ - if( DIFF_TICK(last_tick, session[fd]->rdata_tick) > (stall_time * 2) ) {/* we can't wait any longer */ + if( DIFF_TICK(sockt->last_tick, session[fd]->rdata_tick) > (sockt->stall_time * 2) ) {/* we can't wait any longer */ set_eof(fd); return 0; } else if( session[fd]->flag.ping != 2 ) { /* we haven't sent ping out yet */ @@ -2160,10 +2264,9 @@ int parse_fromlogin(int fd) { uint16 command = RFIFOW(fd,0); if( HPM->packetsc[hpParse_FromLogin] ) { - if( (i = HPM->parse_packets(fd,hpParse_FromLogin)) ) { - if( i == 1 ) continue; - if( i == 2 ) return 0; - } + int success = HPM->parse_packets(fd,hpParse_FromLogin); + if( success == 1 ) continue; + else if( success == 2 ) return 0; } switch( command ) { @@ -2190,7 +2293,7 @@ int parse_fromlogin(int fd) { // acknowledgement of account authentication request case 0x2713: - if (RFIFOREST(fd) < 25) + if (RFIFOREST(fd) < 33) return 0; { int account_id = RFIFOL(fd,2); @@ -2201,7 +2304,9 @@ int parse_fromlogin(int fd) { int request_id = RFIFOL(fd,16); uint32 version = RFIFOL(fd,20); uint8 clienttype = RFIFOB(fd,24); - RFIFOSKIP(fd,25); + int group_id = RFIFOL(fd,25); + unsigned int expiration_time = RFIFOL(fd, 29); + RFIFOSKIP(fd,33); if( session_isActive(request_id) && (sd=(struct char_session_data*)session[request_id]->session_data) && !sd->auth && sd->account_id == account_id && sd->login_id1 == login_id1 && sd->login_id2 == login_id2 && sd->sex == sex ) @@ -2209,30 +2314,46 @@ int parse_fromlogin(int fd) { int client_fd = request_id; sd->version = version; sd->clienttype = clienttype; - switch( result ) - { - case 0:// ok - char_auth_ok(client_fd, sd); - break; - case 1:// auth failed - WFIFOHEAD(client_fd,3); - WFIFOW(client_fd,0) = 0x6c; - WFIFOB(client_fd,2) = 0;// rejected from server - WFIFOSET(client_fd,3); - break; + switch( result ) { + case 0:// ok + /* restrictions apply */ + if( char_server_type == CST_MAINTENANCE && group_id < char_maintenance_min_group_id ) { + WFIFOHEAD(client_fd,3); + WFIFOW(client_fd,0) = 0x6c; + WFIFOB(client_fd,2) = 0;// rejected from server + WFIFOSET(client_fd,3); + break; + } + /* the client will already deny this request, this check is to avoid someone bypassing. */ + if( char_server_type == CST_PAYING && (time_t)expiration_time < time(NULL) ) { + WFIFOHEAD(client_fd,3); + WFIFOW(client_fd,0) = 0x6c; + WFIFOB(client_fd,2) = 0;// rejected from server + WFIFOSET(client_fd,3); + break; + } + char_auth_ok(client_fd, sd); + break; + case 1:// auth failed + WFIFOHEAD(client_fd,3); + WFIFOW(client_fd,0) = 0x6c; + WFIFOB(client_fd,2) = 0;// rejected from server + WFIFOSET(client_fd,3); + break; } } } break; case 0x2717: // account data + { + int i; if (RFIFOREST(fd) < 72) return 0; // find the authenticated session with this account id - ARR_FIND( 0, fd_max, i, session[i] && (sd = (struct char_session_data*)session[i]->session_data) && sd->auth && sd->account_id == RFIFOL(fd,2) ); - if( i < fd_max ) { - int server_id; + ARR_FIND( 0, sockt->fd_max, i, session[i] && (sd = (struct char_session_data*)session[i]->session_data) && sd->auth && sd->account_id == RFIFOL(fd,2) ); + if( i < sockt->fd_max ) { memcpy(sd->email, RFIFOP(fd,6), 40); sd->expiration_time = (time_t)RFIFOL(fd,46); sd->group_id = RFIFOB(fd,50); @@ -2245,10 +2366,8 @@ int parse_fromlogin(int fd) { safestrncpy(sd->birthdate, (const char*)RFIFOP(fd,52), sizeof(sd->birthdate)); safestrncpy(sd->pincode, (const char*)RFIFOP(fd,63), sizeof(sd->pincode)); sd->pincode_change = RFIFOL(fd,68); - ARR_FIND( 0, ARRAYLENGTH(server), server_id, server[server_id].fd > 0 && server[server_id].map[0] ); // continued from char_auth_ok... - if( server_id == ARRAYLENGTH(server) || //server not online, bugreport:2359 - (max_connect_user == 0 && sd->group_id != gm_allow_group) || + if( (max_connect_user == 0 && sd->group_id != gm_allow_group) || ( max_connect_user > 0 && count_users() >= max_connect_user && sd->group_id != gm_allow_group ) ) { // refuse connection (over populated) WFIFOHEAD(i,3); @@ -2262,12 +2381,16 @@ int parse_fromlogin(int fd) { #else mmo_char_send006b(i, sd); #endif + #if PACKETVER >= 20060819 + mmo_char_send020d(i, sd); + #endif #if PACKETVER >= 20110309 pincode->handle(i, sd); #endif } } RFIFOSKIP(fd,72); + } break; // login-server alive packet @@ -2295,6 +2418,7 @@ int parse_fromlogin(int fd) { int class_[MAX_CHARS]; int guild_id[MAX_CHARS]; int num; + int i; char* data; struct auth_node* node = (struct auth_node*)idb_get(auth_db, acc); @@ -2359,17 +2483,12 @@ int parse_fromlogin(int fd) { break; // reply to an account_reg2 registry request - case 0x2729: + case 0x3804: if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2)) return 0; - - { //Receive account_reg2 registry, forward to map servers. - unsigned char buf[13+ACCOUNT_REG2_NUM*sizeof(struct global_reg)]; - memcpy(buf,RFIFOP(fd,0), RFIFOW(fd,2)); - WBUFW(buf,0) = 0x3804; //Map server can now receive all kinds of reg values with the same packet. [Skotlex] - mapif_sendall(buf, WBUFW(buf,2)); + //Receive account_reg2 registry, forward to map servers. + mapif_sendall(RFIFOP(fd, 0), RFIFOW(fd,2)); RFIFOSKIP(fd, RFIFOW(fd,2)); - } break; // State change of account/ban notification (from login-server) @@ -2411,8 +2530,8 @@ int parse_fromlogin(int fd) { {// Manual kick from char server. struct char_session_data *tsd; int i; - ARR_FIND( 0, fd_max, i, session[i] && (tsd = (struct char_session_data*)session[i]->session_data) && tsd->account_id == aid ); - if( i < fd_max ) + ARR_FIND( 0, sockt->fd_max, i, session[i] && (tsd = (struct char_session_data*)session[i]->session_data) && tsd->account_id == aid ); + if( i < sockt->fd_max ) { WFIFOHEAD(i,3); WFIFOW(i,0) = 0x81; @@ -2457,6 +2576,26 @@ int parse_fromlogin(int fd) { } break; + case 0x2736: // Failed accinfo lookup to forward to mapserver + if (RFIFOREST(fd) < 18) + return 0; + + mapif_parse_accinfo2(false, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOL(fd,14), + NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1, 0, 0); + RFIFOSKIP(fd,18); + break; + + case 0x2737: // Successful accinfo lookup to forward to mapserver + if (RFIFOREST(fd) < 183) + return 0; + + mapif_parse_accinfo2(true, RFIFOL(fd,167), RFIFOL(fd,171), RFIFOL(fd,175), RFIFOL(fd,179), + (char*)RFIFOP(fd,2), (char*)RFIFOP(fd,26), (char*)RFIFOP(fd,59), + (char*)RFIFOP(fd,99), (char*)RFIFOP(fd,119), (char*)RFIFOP(fd,151), + (char*)RFIFOP(fd,156), RFIFOL(fd,115), RFIFOL(fd,143), RFIFOL(fd,147)); + RFIFOSKIP(fd,183); + break; + default: ShowError("Unknown packet 0x%04x received from login-server, disconnecting.\n", command); set_eof(fd); @@ -2468,8 +2607,7 @@ int parse_fromlogin(int fd) { return 0; } -int check_connect_login_server(int tid, unsigned int tick, int id, intptr_t data); -int send_accounts_tologin(int tid, unsigned int tick, int id, intptr_t data); +int check_connect_login_server(int tid, int64 tick, int id, intptr_t data); void do_init_loginif(void) { @@ -2503,21 +2641,76 @@ int request_accreg2(int account_id, int char_id) } return 0; } - -//Send packet forward to login-server for account saving -int save_accreg2(unsigned char* buf, int len) -{ - if (login_fd > 0) { - WFIFOHEAD(login_fd,len+4); - memcpy(WFIFOP(login_fd,4), buf, len); - WFIFOW(login_fd,0) = 0x2728; - WFIFOW(login_fd,2) = len+4; - WFIFOSET(login_fd,len+4); - return 1; +/** + * Handles global account reg saving that continues with global_accreg_to_login_add and global_accreg_to_send + **/ +void global_accreg_to_login_start (int account_id, int char_id) { + WFIFOHEAD(login_fd, 60000 + 300); + WFIFOW(login_fd,0) = 0x2728; + WFIFOW(login_fd,2) = 14; + WFIFOL(login_fd,4) = account_id; + WFIFOL(login_fd,8) = char_id; + WFIFOW(login_fd,12) = 0;/* count */ +} +/** + * Completes global account reg saving that starts global_accreg_to_login_start and continues with global_accreg_to_login_add + **/ +void global_accreg_to_login_send (void) { + WFIFOSET(login_fd, WFIFOW(login_fd,2)); +} +/** + * Handles global account reg saving that starts global_accreg_to_login_start and ends with global_accreg_to_send + **/ +void global_accreg_to_login_add (const char *key, unsigned int index, intptr_t val, bool is_string) { + int nlen = WFIFOW(login_fd, 2); + size_t len; + + len = strlen(key)+1; + + WFIFOB(login_fd, nlen) = (unsigned char)len;/* won't be higher; the column size is 32 */ + nlen += 1; + + safestrncpy((char*)WFIFOP(login_fd,nlen), key, len); + nlen += len; + + WFIFOL(login_fd, nlen) = index; + nlen += 4; + + if( is_string ) { + WFIFOB(login_fd, nlen) = val ? 2 : 3; + nlen += 1; + + if( val ) { + char *sval = (char*)val; + len = strlen(sval)+1; + + WFIFOB(login_fd, nlen) = (unsigned char)len;/* won't be higher; the column size is 254 */ + nlen += 1; + + safestrncpy((char*)WFIFOP(login_fd,nlen), sval, len); + nlen += len; + } + + } else { + WFIFOB(login_fd, nlen) = val ? 0 : 1; + nlen += 1; + + if( val ) { + WFIFOL(login_fd, nlen) = (int)val; + nlen += 4; + } + + } + + WFIFOW(login_fd,12) += 1; + + WFIFOW(login_fd, 2) = nlen; + if( WFIFOW(login_fd, 2) > 60000 ) { + int account_id = WFIFOL(login_fd,4), char_id = WFIFOL(login_fd,8); + global_accreg_to_login_send(); + global_accreg_to_login_start(account_id,char_id);/* prepare next */ } - return 0; } - void char_read_fame_list(void) { int i; char* data; @@ -2697,6 +2890,16 @@ void mapif_on_disconnect(int id) mapif_server_reset(id); } +void mapif_on_parse_accinfo(int account_id, int u_fd, int u_aid, int u_group, int map_fd) { + WFIFOHEAD(login_fd,22); + WFIFOW(login_fd,0) = 0x2740; + WFIFOL(login_fd,2) = account_id; + WFIFOL(login_fd,6) = u_fd; + WFIFOL(login_fd,10) = u_aid; + WFIFOL(login_fd,14) = u_group; + WFIFOL(login_fd,18) = map_fd; + WFIFOSET(login_fd,22); +} int parse_frommap(int fd) { @@ -2730,7 +2933,7 @@ int parse_frommap(int fd) case 0x2b0a: if( RFIFOREST(fd) < RFIFOW(fd, 2) ) return 0; - socket_datasync(fd, false); + sockt->datasync(fd, false); RFIFOSKIP(fd,RFIFOW(fd,2)); break; @@ -2827,8 +3030,7 @@ int parse_frommap(int fd) Sql_ShowDebug(sql_handle); break; } - if( SQL->NumRows(sql_handle) > 0 ) - { + if( SQL->NumRows(sql_handle) > 0 ) { struct status_change_data scdata; int count; char* data; @@ -2849,8 +3051,7 @@ int parse_frommap(int fd) } if (count >= 50) ShowWarning("Too many status changes for %d:%d, some of them were not loaded.\n", aid, cid); - if (count > 0) - { + if (count > 0) { WFIFOW(fd,2) = 14 + count*sizeof(struct status_change_data); WFIFOW(fd,12) = count; WFIFOSET(fd,WFIFOW(fd,2)); @@ -2859,6 +3060,14 @@ int parse_frommap(int fd) if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '%d' AND `char_id`='%d'", scdata_db, aid, cid) ) Sql_ShowDebug(sql_handle); } + } else { //no sc (needs a response) + WFIFOHEAD(fd,14); + WFIFOW(fd,0) = 0x2b1d; + WFIFOW(fd,2) = 14; + WFIFOL(fd,4) = aid; + WFIFOL(fd,8) = cid; + WFIFOW(fd,12) = 0; + WFIFOSET(fd,WFIFOW(fd,2)); } SQL->FreeResult(sql_handle); #endif @@ -2973,6 +3182,7 @@ int parse_frommap(int fd) node->login_id2 = login_id2; //node->sex = 0; node->ip = ntohl(ip); + /* sounds troublesome. */ //node->expiration_time = 0; // unlimited/unknown time by default (not display in map-server) //node->gmlevel = 0; idb_put(auth_db, account_id, node); @@ -3094,7 +3304,7 @@ int parse_frommap(int fd) RFIFOSKIP(fd, 86); break; - case 0x2b0e: // Request from map-server to change an account's status (will just be forwarded to login server) + case 0x2b0e: // Request from map-server to change an account's or character's status (accounts will just be forwarded to login server) if (RFIFOREST(fd) < 44) return 0; { @@ -3103,7 +3313,7 @@ int parse_frommap(int fd) int acc = RFIFOL(fd,2); // account_id of who ask (-1 if server itself made this request) const char* name = (char*)RFIFOP(fd,6); // name of the target character - int type = RFIFOW(fd,30); // type of operation: 1-block, 2-ban, 3-unblock, 4-unban + int type = RFIFOW(fd,30); // type of operation: 1-block, 2-ban, 3-unblock, 4-unban, 5 changesex, 6 charban, 7 charunban short year = RFIFOW(fd,32); short month = RFIFOW(fd,34); short day = RFIFOW(fd,36); @@ -3113,25 +3323,22 @@ int parse_frommap(int fd) RFIFOSKIP(fd,44); SQL->EscapeStringLen(sql_handle, esc_name, name, strnlen(name, NAME_LENGTH)); - if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `account_id`,`name` FROM `%s` WHERE `name` = '%s'", char_db, esc_name) ) + + if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `account_id`,`char_id`,`unban_time` FROM `%s` WHERE `name` = '%s'", char_db, esc_name) ) Sql_ShowDebug(sql_handle); - else - if( SQL->NumRows(sql_handle) == 0 ) - { + else if( SQL->NumRows(sql_handle) == 0 ) { result = 1; // 1-player not found - } - else - if( SQL_SUCCESS != SQL->NextRow(sql_handle) ) + } else if( SQL_SUCCESS != SQL->NextRow(sql_handle) ) { Sql_ShowDebug(sql_handle); - //FIXME: set proper result value? - else - { - char name[NAME_LENGTH]; - int account_id; + result = 1; // 1-player not found + } else { + int account_id, char_id; char* data; + time_t unban_time; SQL->GetData(sql_handle, 0, &data, NULL); account_id = atoi(data); - SQL->GetData(sql_handle, 1, &data, NULL); safestrncpy(name, data, sizeof(name)); + SQL->GetData(sql_handle, 1, &data, NULL); char_id = atoi(data); + SQL->GetData(sql_handle, 2, &data, NULL); unban_time = atol(data); if( login_fd <= 0 ) result = 3; // 3-login-server offline @@ -3139,53 +3346,111 @@ int parse_frommap(int fd) // else // if( acc != -1 && isGM(acc) < isGM(account_id) ) // result = 2; // 2-gm level too low - else - switch( type ) { - case 1: // block - WFIFOHEAD(login_fd,10); - WFIFOW(login_fd,0) = 0x2724; - WFIFOL(login_fd,2) = account_id; - WFIFOL(login_fd,6) = 5; // new account status - WFIFOSET(login_fd,10); - break; - case 2: // ban - WFIFOHEAD(login_fd,18); - WFIFOW(login_fd, 0) = 0x2725; - WFIFOL(login_fd, 2) = account_id; - WFIFOW(login_fd, 6) = year; - WFIFOW(login_fd, 8) = month; - WFIFOW(login_fd,10) = day; - WFIFOW(login_fd,12) = hour; - WFIFOW(login_fd,14) = minute; - WFIFOW(login_fd,16) = second; - WFIFOSET(login_fd,18); - break; - case 3: // unblock - WFIFOHEAD(login_fd,10); - WFIFOW(login_fd,0) = 0x2724; - WFIFOL(login_fd,2) = account_id; - WFIFOL(login_fd,6) = 0; // new account status - WFIFOSET(login_fd,10); - break; - case 4: // unban - WFIFOHEAD(login_fd,6); - WFIFOW(login_fd,0) = 0x272a; - WFIFOL(login_fd,2) = account_id; - WFIFOSET(login_fd,6); - break; - case 5: // changesex - WFIFOHEAD(login_fd,6); - WFIFOW(login_fd,0) = 0x2727; - WFIFOL(login_fd,2) = account_id; - WFIFOSET(login_fd,6); - break; + else { + switch( type ) { + case 1: // block + WFIFOHEAD(login_fd,10); + WFIFOW(login_fd,0) = 0x2724; + WFIFOL(login_fd,2) = account_id; + WFIFOL(login_fd,6) = 5; // new account status + WFIFOSET(login_fd,10); + break; + case 2: // ban + WFIFOHEAD(login_fd,18); + WFIFOW(login_fd, 0) = 0x2725; + WFIFOL(login_fd, 2) = account_id; + WFIFOW(login_fd, 6) = year; + WFIFOW(login_fd, 8) = month; + WFIFOW(login_fd,10) = day; + WFIFOW(login_fd,12) = hour; + WFIFOW(login_fd,14) = minute; + WFIFOW(login_fd,16) = second; + WFIFOSET(login_fd,18); + break; + case 3: // unblock + WFIFOHEAD(login_fd,10); + WFIFOW(login_fd,0) = 0x2724; + WFIFOL(login_fd,2) = account_id; + WFIFOL(login_fd,6) = 0; // new account status + WFIFOSET(login_fd,10); + break; + case 4: // unban + WFIFOHEAD(login_fd,6); + WFIFOW(login_fd,0) = 0x272a; + WFIFOL(login_fd,2) = account_id; + WFIFOSET(login_fd,6); + break; + case 5: // changesex + WFIFOHEAD(login_fd,6); + WFIFOW(login_fd,0) = 0x2727; + WFIFOL(login_fd,2) = account_id; + WFIFOSET(login_fd,6); + break; + case 6: //char ban + /* handled by char server, so no redirection */ + { + time_t timestamp; + struct tm *tmtime; + SqlStmt* stmt = SQL->StmtMalloc(sql_handle); + + if (unban_time == 0 || unban_time < time(NULL)) + timestamp = time(NULL); // new ban + else + timestamp = unban_time; // add to existing ban + + tmtime = localtime(×tamp); + tmtime->tm_year = tmtime->tm_year + year; + tmtime->tm_mon = tmtime->tm_mon + month; + tmtime->tm_mday = tmtime->tm_mday + day; + tmtime->tm_hour = tmtime->tm_hour + hour; + tmtime->tm_min = tmtime->tm_min + minute; + tmtime->tm_sec = tmtime->tm_sec + second; + timestamp = mktime(tmtime); + + if( SQL_SUCCESS != SQL->StmtPrepare(stmt, + "UPDATE `%s` SET `unban_time` = ? WHERE `char_id` = ? LIMIT 1", + char_db) + || SQL_SUCCESS != SQL->StmtBindParam(stmt, 0, SQLDT_LONG, (void*)×tamp, sizeof(timestamp)) + || SQL_SUCCESS != SQL->StmtBindParam(stmt, 1, SQLDT_INT, (void*)&char_id, sizeof(char_id)) + || SQL_SUCCESS != SQL->StmtExecute(stmt) + + ) { + SqlStmt_ShowDebug(stmt); + } + + SQL->StmtFree(stmt); + + // condition applies; send to all map-servers to disconnect the player + if( timestamp > time(NULL) ) { + unsigned char buf[11]; + + WBUFW(buf,0) = 0x2b14; + WBUFL(buf,2) = char_id; + WBUFB(buf,6) = 2; + WBUFL(buf,7) = (unsigned int)timestamp; + mapif_sendall(buf, 11); + + // disconnect player if online on char-server + disconnect_player(account_id); + } + } + break; + case 7: //char unban + /* handled by char server, so no redirection */ + if( SQL_ERROR == SQL->Query(sql_handle, "UPDATE `%s` SET `unban_time` = '0' WHERE `char_id` = '%d' LIMIT 1", char_db, char_id) ) { + Sql_ShowDebug(sql_handle); + result = 1; + } + break; + + } } } SQL->FreeResult(sql_handle); // send answer if a player ask, not if the server ask - if( acc != -1 && type != 5) { // Don't send answer for changesex + if( acc != -1 && type != 5 ) { // Don't send answer for changesex WFIFOHEAD(fd,34); WFIFOW(fd, 0) = 0x2b0f; WFIFOL(fd, 2) = acc; @@ -3309,11 +3574,14 @@ int parse_frommap(int fd) cid = RFIFOL(fd, 8); count = RFIFOW(fd, 12); + /* clear; ensure no left overs e.g. permanent */ + if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '%d' AND `char_id`='%d'", scdata_db, aid, cid) ) + Sql_ShowDebug(sql_handle); + if( count > 0 ) { struct status_change_data data; StringBuf buf; - int i; StrBuf->Init(&buf); StrBuf->Printf(&buf, "INSERT INTO `%s` (`account_id`, `char_id`, `type`, `tick`, `val1`, `val2`, `val3`, `val4`) VALUES ", scdata_db); @@ -3342,14 +3610,14 @@ int parse_frommap(int fd) break; case 0x2b26: // auth request from map-server - if (RFIFOREST(fd) < 19) + if (RFIFOREST(fd) < 20) return 0; { int account_id; int char_id; int login_id1; - char sex; + char sex, standalone; uint32 ip; struct auth_node* node; struct mmo_charstatus* cd; @@ -3360,15 +3628,36 @@ int parse_frommap(int fd) login_id1 = RFIFOL(fd,10); sex = RFIFOB(fd,14); ip = ntohl(RFIFOL(fd,15)); - RFIFOSKIP(fd,19); + standalone = RFIFOB(fd, 19); + RFIFOSKIP(fd,20); node = (struct auth_node*)idb_get(auth_db, account_id); cd = (struct mmo_charstatus*)uidb_get(char_db_,char_id); - if( cd == NULL ) - { //Really shouldn't happen. + + if( cd == NULL ) { //Really shouldn't happen. mmo_char_fromsql(char_id, &char_dat, true); cd = (struct mmo_charstatus*)uidb_get(char_db_,char_id); } + + if( runflag == CHARSERVER_ST_RUNNING && cd && standalone ) { + cd->sex = sex; + + WFIFOHEAD(fd,25 + sizeof(struct mmo_charstatus)); + WFIFOW(fd,0) = 0x2afd; + WFIFOW(fd,2) = 25 + sizeof(struct mmo_charstatus); + WFIFOL(fd,4) = account_id; + WFIFOL(fd,8) = 0; + WFIFOL(fd,12) = 0; + WFIFOL(fd,16) = 0; + WFIFOL(fd,20) = 0; + WFIFOB(fd,24) = 0; + memcpy(WFIFOP(fd,25), cd, sizeof(struct mmo_charstatus)); + WFIFOSET(fd, WFIFOW(fd,2)); + + set_char_online(id, char_id, account_id); + break; + } + if( runflag == CHARSERVER_ST_RUNNING && cd != NULL && node != NULL && @@ -3451,6 +3740,40 @@ int parse_frommap(int fd) RFIFOFLUSH(fd); } break; + + /* individual sc data insertion/update */ + case 0x2740: + if( RFIFOREST(fd) < 28 ) + return 0; + else { + int account_id = RFIFOL(fd, 2), char_id = RFIFOL(fd, 6), + val1 = RFIFOL(fd, 12), val2 = RFIFOL(fd, 16), + val3 = RFIFOL(fd, 20), val4 = RFIFOL(fd, 24); + short type = RFIFOW(fd, 10); + + if( SQL_ERROR == SQL->Query(sql_handle, "REPLACE INTO `%s` (`account_id`,`char_id`,`type`,`tick`,`val1`,`val2`,`val3`,`val4`) VALUES ('%d','%d','%d',-1,'%d','%d','%d','%d')", + scdata_db, account_id, char_id, type, val1, val2, val3, val4) ) + Sql_ShowDebug(sql_handle); + + RFIFOSKIP(fd, 28); + } + break; + + /* individual sc data delete */ + case 0x2741: + if( RFIFOREST(fd) < 12 ) + return 0; + else { + int account_id = RFIFOL(fd, 2), char_id = RFIFOL(fd, 6); + short type = RFIFOW(fd, 10); + + if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '%d' AND `char_id` = '%d' AND `type` = '%d' LIMIT 1", + scdata_db, account_id, char_id, type) ) + Sql_ShowDebug(sql_handle); + + RFIFOSKIP(fd, 12); + } + break; default: @@ -3542,7 +3865,12 @@ void char_delete2_ack(int fd, int char_id, uint32 result, time_t delete_date) WFIFOW(fd,0) = 0x828; WFIFOL(fd,2) = char_id; WFIFOL(fd,6) = result; - WFIFOL(fd,10) = TOL(delete_date); +#if PACKETVER >= 20130000 + WFIFOL(fd,10) = (int)(delete_date - time(NULL)); +#else + WFIFOL(fd,10) = (int)delete_date; + +#endif WFIFOSET(fd,14); } @@ -3557,6 +3885,14 @@ void char_delete2_ack(int fd, int char_id, uint32 result, time_t delete_date) /// Any (0x718): An unknown error has occurred. void char_delete2_accept_ack(int fd, int char_id, uint32 result) {// HC: <082a>.W <char id>.L <Msg:0-5>.L + +#if PACKETVER >= 20130000 /* not sure the exact date -- must refresh or client gets stuck */ + if( result == 1 ) { + struct char_session_data* sd = (struct char_session_data*)session[fd]->session_data; + mmo_char_send099d(fd, sd); + } +#endif + WFIFOHEAD(fd,10); WFIFOW(fd,0) = 0x82a; WFIFOL(fd,2) = char_id; @@ -3740,7 +4076,6 @@ static void char_delete2_cancel(int fd, struct char_session_data* sd) int parse_char(int fd) { - int i, ch; char email[40]; unsigned short cmd; int map_fd; @@ -3769,13 +4104,12 @@ int parse_char(int fd) while( RFIFOREST(fd) >= 2 ) { //For use in packets that depend on an sd being present [Skotlex] - #define FIFOSD_CHECK(rest) { if(RFIFOREST(fd) < rest) return 0; if (sd==NULL || !sd->auth) { RFIFOSKIP(fd,rest); return 0; } } + #define FIFOSD_CHECK(rest) do { if(RFIFOREST(fd) < (rest)) return 0; if (sd==NULL || !sd->auth) { RFIFOSKIP(fd,(rest)); return 0; } } while (0) if( HPM->packetsc[hpParse_Char] ) { - if( (i = HPM->parse_packets(fd,hpParse_Char)) ) { - if( i == 1 ) continue; - if( i == 2 ) return 0; - } + int success = HPM->parse_packets(fd,hpParse_Char); + if( success == 1 ) continue; + else if( success == 2 ) return 0; } cmd = RFIFOW(fd,0); @@ -3818,8 +4152,7 @@ int parse_char(int fd) WFIFOL(fd,0) = account_id; WFIFOSET(fd,4); - if( runflag != CHARSERVER_ST_RUNNING ) - { + if( runflag != CHARSERVER_ST_RUNNING ) { WFIFOHEAD(fd,3); WFIFOW(fd,0) = 0x6c; WFIFOB(fd,2) = 0;// rejected from server @@ -3835,6 +4168,22 @@ int parse_char(int fd) node->login_id2 == login_id2 /*&& node->ip == ipl*/ ) {// authentication found (coming from map server) + /* restrictions apply */ + if( char_server_type == CST_MAINTENANCE && node->group_id < char_maintenance_min_group_id ) { + WFIFOHEAD(fd,3); + WFIFOW(fd,0) = 0x6c; + WFIFOB(fd,2) = 0;// rejected from server + WFIFOSET(fd,3); + break; + } + /* the client will already deny this request, this check is to avoid someone bypassing. */ + if( char_server_type == CST_PAYING && (time_t)node->expiration_time < time(NULL) ) { + WFIFOHEAD(fd,3); + WFIFOW(fd,0) = 0x6c; + WFIFOB(fd,2) = 0;// rejected from server + WFIFOSET(fd,3); + break; + } idb_remove(auth_db, account_id); char_auth_ok(fd, sd); } @@ -3870,9 +4219,12 @@ int parse_char(int fd) int char_id; uint32 subnet_map_ip; struct auth_node* node; + int server_id = 0; + int i; int slot = RFIFOB(fd,2); RFIFOSKIP(fd,3); + #if PACKETVER >= 20110309 if( *pincode->enabled ){ // hack check struct online_char_data* character; @@ -3886,6 +4238,19 @@ int parse_char(int fd) } } #endif + + ARR_FIND( 0, ARRAYLENGTH(server), server_id, server[server_id].fd > 0 && server[server_id].map[0] ); + /* not available, tell it to wait (client wont close; char select will respawn). + * magic response found by Ind thanks to Yommy <3 */ + if( server_id == ARRAYLENGTH(server) ) { + WFIFOHEAD(fd, 24); + WFIFOW(fd, 0) = 0x840; + WFIFOW(fd, 2) = 24; + safestrncpy((char*)WFIFOP(fd,4), "0", 20);/* we can't send empty (otherwise the list will pop up) */ + WFIFOSET(fd, 24); + break; + } + if ( SQL_SUCCESS != SQL->Query(sql_handle, "SELECT `char_id` FROM `%s` WHERE `account_id`='%d' AND `char_num`='%d'", char_db, sd->account_id, slot) || SQL_SUCCESS != SQL->NextRow(sql_handle) || SQL_SUCCESS != SQL->GetData(sql_handle, 0, &data, NULL) ) @@ -3902,6 +4267,15 @@ int parse_char(int fd) char_id = atoi(data); SQL->FreeResult(sql_handle); + /* client doesn't let it get to this point if you're banned, so its a forged packet */ + if( sd->found_char[slot] == char_id && sd->unban_time[slot] > time(NULL) ) { + WFIFOHEAD(fd,3); + WFIFOW(fd,0) = 0x6c; + WFIFOB(fd,2) = 0; // rejected from server + WFIFOSET(fd,3); + break; + } + /* set char as online prior to loading its data so 3rd party applications will realise the sql data is not reliable */ set_char_online(-2,char_id,sd->account_id); if( !mmo_char_fromsql(char_id, &char_dat, true) ) { /* failed? set it back offline */ @@ -3944,22 +4318,22 @@ int parse_char(int fd) WFIFOSET(fd,3); break; } - if ((i = search_mapserver((j=mapindex_name2id(MAP_PRONTERA)),-1,-1)) >= 0) { + if ((i = search_mapserver((j=mapindex->name2id(MAP_PRONTERA)),-1,-1)) >= 0) { cd->last_point.x = 273; cd->last_point.y = 354; - } else if ((i = search_mapserver((j=mapindex_name2id(MAP_GEFFEN)),-1,-1)) >= 0) { + } else if ((i = search_mapserver((j=mapindex->name2id(MAP_GEFFEN)),-1,-1)) >= 0) { cd->last_point.x = 120; cd->last_point.y = 100; - } else if ((i = search_mapserver((j=mapindex_name2id(MAP_MORROC)),-1,-1)) >= 0) { + } else if ((i = search_mapserver((j=mapindex->name2id(MAP_MORROC)),-1,-1)) >= 0) { cd->last_point.x = 160; cd->last_point.y = 94; - } else if ((i = search_mapserver((j=mapindex_name2id(MAP_ALBERTA)),-1,-1)) >= 0) { + } else if ((i = search_mapserver((j=mapindex->name2id(MAP_ALBERTA)),-1,-1)) >= 0) { cd->last_point.x = 116; cd->last_point.y = 57; - } else if ((i = search_mapserver((j=mapindex_name2id(MAP_PAYON)),-1,-1)) >= 0) { + } else if ((i = search_mapserver((j=mapindex->name2id(MAP_PAYON)),-1,-1)) >= 0) { cd->last_point.x = 87; cd->last_point.y = 117; - } else if ((i = search_mapserver((j=mapindex_name2id(MAP_IZLUDE)),-1,-1)) >= 0) { + } else if ((i = search_mapserver((j=mapindex->name2id(MAP_IZLUDE)),-1,-1)) >= 0) { cd->last_point.x = 94; cd->last_point.y = 103; } else { @@ -3993,7 +4367,7 @@ int parse_char(int fd) WFIFOHEAD(fd,28); WFIFOW(fd,0) = 0x71; WFIFOL(fd,2) = cd->char_id; - mapindex_getmapname_ext(mapindex_id2name(cd->last_point.map), (char*)WFIFOP(fd,6)); + mapindex->getmapname_ext(mapindex_id2name(cd->last_point.map), (char*)WFIFOP(fd,6)); subnet_map_ip = lan_subnetcheck(ipl); // Advanced subnet check [LuzZza] WFIFOL(fd,22) = htonl((subnet_map_ip) ? subnet_map_ip : server[i].ip); WFIFOW(fd,26) = ntows(htons(server[i].port)); // [!] LE byte order here [!] @@ -4018,30 +4392,35 @@ int parse_char(int fd) #if PACKETVER >= 20120307 // S 0970 <name>.24B <slot>.B <hair color>.W <hair style>.W case 0x970: + { + int result; FIFOSD_CHECK(31); #else // S 0067 <name>.24B <str>.B <agi>.B <vit>.B <int>.B <dex>.B <luk>.B <slot>.B <hair color>.W <hair style>.W case 0x67: + { + int result; FIFOSD_CHECK(37); #endif if( !char_new ) //turn character creation on/off [Kevin] - i = -2; + result = -2; else #if PACKETVER >= 20120307 - i = make_new_char_sql(sd, (char*)RFIFOP(fd,2),RFIFOB(fd,26),RFIFOW(fd,27),RFIFOW(fd,29)); + result = make_new_char_sql(sd, (char*)RFIFOP(fd,2),RFIFOB(fd,26),RFIFOW(fd,27),RFIFOW(fd,29)); #else - i = make_new_char_sql(sd, (char*)RFIFOP(fd,2),RFIFOB(fd,26),RFIFOB(fd,27),RFIFOB(fd,28),RFIFOB(fd,29),RFIFOB(fd,30),RFIFOB(fd,31),RFIFOB(fd,32),RFIFOW(fd,33),RFIFOW(fd,35)); + result = make_new_char_sql(sd, (char*)RFIFOP(fd,2),RFIFOB(fd,26),RFIFOB(fd,27),RFIFOB(fd,28),RFIFOB(fd,29),RFIFOB(fd,30),RFIFOB(fd,31),RFIFOB(fd,32),RFIFOW(fd,33),RFIFOW(fd,35)); #endif //'Charname already exists' (-1), 'Char creation denied' (-2) and 'You are underaged' (-3) - if (i < 0) { + if (result < 0) { WFIFOHEAD(fd,3); WFIFOW(fd,0) = 0x6e; /* Others I found [Ind] */ /* 0x02 = Symbols in Character Names are forbidden */ /* 0x03 = You are not elegible to open the Character Slot. */ - switch (i) { + /* 0x0B = This service is only available for premium users. */ + switch (result) { case -1: WFIFOB(fd,2) = 0x00; break; case -2: WFIFOB(fd,2) = 0xFF; break; case -3: WFIFOB(fd,2) = 0x01; break; @@ -4052,7 +4431,7 @@ int parse_char(int fd) int len; // retrieve data struct mmo_charstatus char_dat; - mmo_char_fromsql(i, &char_dat, false); //Only the short data is needed. + mmo_char_fromsql(result, &char_dat, false); //Only the short data is needed. // send to player WFIFOHEAD(fd,2+MAX_CHAR_BUF); @@ -4061,15 +4440,14 @@ int parse_char(int fd) WFIFOSET(fd,len); // add new entry to the chars list - ARR_FIND( 0, MAX_CHARS, ch, sd->found_char[ch] == -1 ); - if( ch < MAX_CHARS ) - sd->found_char[ch] = i; // the char_id of the new char + sd->found_char[char_dat.slot] = result; // the char_id of the new char } #if PACKETVER >= 20120307 RFIFOSKIP(fd,31); #else RFIFOSKIP(fd,37); #endif + } break; // delete char @@ -4080,6 +4458,7 @@ int parse_char(int fd) if (cmd == 0x1fb) FIFOSD_CHECK(56); { int cid = RFIFOL(fd,2); + int i; #if PACKETVER >= 20110309 if( *pincode->enabled ){ // hack check struct online_char_data* character; @@ -4122,9 +4501,7 @@ int parse_char(int fd) } // remove char from list and compact it - for(ch = i; ch < MAX_CHARS-1; ch++) - sd->found_char[ch] = sd->found_char[ch+1]; - sd->found_char[MAX_CHARS-1] = -1; + sd->found_char[i] = -1; /* Delete character */ if(delete_char_sql(cid)<0){ @@ -4290,6 +4667,7 @@ int parse_char(int fd) { char* l_user = (char*)RFIFOP(fd,2); char* l_pass = (char*)RFIFOP(fd,26); + int i; l_user[23] = '\0'; l_pass[23] = '\0'; ARR_FIND( 0, ARRAYLENGTH(server), i, server[i].fd <= 0 ); @@ -4317,7 +4695,7 @@ int parse_char(int fd) realloc_fifo(fd, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK); char_mapif_init(fd); } - socket_datasync(fd, true); + sockt->datasync(fd, true); RFIFOSKIP(fd,60); } @@ -4452,8 +4830,7 @@ int mapif_send(int fd, unsigned char *buf, unsigned int len) return 0; } -int broadcast_user_count(int tid, unsigned int tick, int id, intptr_t data) -{ +int broadcast_user_count(int tid, int64 tick, int id, intptr_t data) { uint8 buf[6]; int users = count_users(); @@ -4498,8 +4875,7 @@ static int send_accounts_tologin_sub(DBKey key, DBData *data, va_list ap) return 0; } -int send_accounts_tologin(int tid, unsigned int tick, int id, intptr_t data) -{ +int send_accounts_tologin(int tid, int64 tick, int id, intptr_t data) { if (login_fd > 0 && session[login_fd]) { // send account list to login server @@ -4516,8 +4892,7 @@ int send_accounts_tologin(int tid, unsigned int tick, int id, intptr_t data) return 0; } -int check_connect_login_server(int tid, unsigned int tick, int id, intptr_t data) -{ +int check_connect_login_server(int tid, int64 tick, int id, intptr_t data) { if (login_fd > 0 && session[login_fd] != NULL) return 0; @@ -4541,7 +4916,7 @@ int check_connect_login_server(int tid, unsigned int tick, int id, intptr_t data WFIFOW(login_fd,58) = htons(char_port); memcpy(WFIFOP(login_fd,60), server_name, 20); WFIFOW(login_fd,80) = 0; - WFIFOW(login_fd,82) = char_maintenance; + WFIFOW(login_fd,82) = char_server_type; WFIFOW(login_fd,84) = char_new_display; //only display (New) if they want to [Kevin] WFIFOSET(login_fd,86); @@ -4552,8 +4927,7 @@ int check_connect_login_server(int tid, unsigned int tick, int id, intptr_t data //Invoked 15 seconds after mapif_disconnectplayer in case the map server doesn't //replies/disconnect the player we tried to kick. [Skotlex] //------------------------------------------------ -static int chardb_waiting_disconnect(int tid, unsigned int tick, int id, intptr_t data) -{ +static int chardb_waiting_disconnect(int tid, int64 tick, int id, intptr_t data) { struct online_char_data* character; if ((character = (struct online_char_data*)idb_get(online_char_db, id)) != NULL && character->waiting_disconnect == tid) { //Mark it offline due to timeout. @@ -4579,8 +4953,7 @@ static int online_data_cleanup_sub(DBKey key, DBData *data, va_list ap) return 0; } -static int online_data_cleanup(int tid, unsigned int tick, int id, intptr_t data) -{ +static int online_data_cleanup(int tid, int64 tick, int id, intptr_t data) { online_char_db->foreach(online_char_db, online_data_cleanup_sub); return 0; } @@ -4669,8 +5042,6 @@ void sql_config_read(const char* cfgName) safestrncpy(charlog_db, w2, sizeof(charlog_db)); else if(!strcmpi(w1,"storage_db")) safestrncpy(storage_db, w2, sizeof(storage_db)); - else if(!strcmpi(w1,"reg_db")) - safestrncpy(reg_db, w2, sizeof(reg_db)); else if(!strcmpi(w1,"skill_db")) safestrncpy(skill_db, w2, sizeof(skill_db)); else if(!strcmpi(w1,"interlog_db")) @@ -4721,6 +5092,17 @@ void sql_config_read(const char* cfgName) safestrncpy(elemental_db,w2,sizeof(elemental_db)); else if(!strcmpi(w1,"interreg_db")) safestrncpy(interreg_db,w2,sizeof(interreg_db)); + else if(!strcmpi(w1,"account_data_db")) + safestrncpy(account_data_db,w2,sizeof(account_data_db)); + else if(!strcmpi(w1,"char_reg_num_db")) + safestrncpy(char_reg_num_db, w2, sizeof(char_reg_num_db)); + else if(!strcmpi(w1,"char_reg_str_db")) + safestrncpy(char_reg_str_db, w2, sizeof(char_reg_str_db)); + else if(!strcmpi(w1,"acc_reg_str_db")) + safestrncpy(acc_reg_str_db, w2, sizeof(acc_reg_str_db)); + else if(!strcmpi(w1,"acc_reg_num_db")) + safestrncpy(acc_reg_num_db, w2, sizeof(acc_reg_num_db)); + //support the import command, just like any other config else if(!strcmpi(w1,"import")) sql_config_read(w2); @@ -4801,8 +5183,8 @@ int char_config_read(const char* cfgName) } } else if (strcmpi(w1, "char_port") == 0) { char_port = atoi(w2); - } else if (strcmpi(w1, "char_maintenance") == 0) { - char_maintenance = atoi(w2); + } else if (strcmpi(w1, "char_server_type") == 0) { + char_server_type = atoi(w2); } else if (strcmpi(w1, "char_new") == 0) { char_new = (bool)atoi(w2); } else if (strcmpi(w1, "char_new_display") == 0) { @@ -4824,7 +5206,7 @@ int char_config_read(const char* cfgName) int x, y; if (sscanf(w2, "%15[^,],%d,%d", map, &x, &y) < 3) continue; - start_point.map = mapindex_name2id(map); + start_point.map = mapindex->name2id(map); if (!start_point.map) ShowError("Specified start_point %s not found in map-index cache.\n", map); start_point.x = x; @@ -4835,18 +5217,25 @@ int char_config_read(const char* cfgName) i = 0; split = strtok(w2, ","); - while (split != NULL && i < MAX_START_ITEMS*2) { + while (split != NULL && i < MAX_START_ITEMS*3) { split2 = split; split = strtok(NULL, ","); start_items[i] = atoi(split2); + if (start_items[i] < 0) start_items[i] = 0; + ++i; } - if (i%2) { //we know it must be a even number - ShowError("Specified 'start_items' is missing a parameter. Removing '%d'.\n", start_items[i - 1]); - start_items[i - 1] = 0; + // Format is: id1,quantity1,stackable1,idN,quantityN,stackableN + if( i%3 ) + { + ShowWarning("char_config_read: There are not enough parameters in start_items, ignoring last item...\n"); + if( i%3 == 1 ) + start_items[i-1] = 0; + else + start_items[i-2] = 0; } } else if (strcmpi(w1, "start_zeny") == 0) { start_zeny = atoi(w2); @@ -4889,6 +5278,8 @@ int char_config_read(const char* cfgName) } } else if (strcmpi(w1, "guild_exp_rate") == 0) { guild_exp_rate = atoi(w2); + } else if (strcmpi(w1, "char_maintenance_min_group_id") == 0) { + char_maintenance_min_group_id = atoi(w2); } else if (strcmpi(w1, "import") == 0) { char_config_read(w2); } else @@ -4930,7 +5321,7 @@ void do_final(void) { } SQL->Free(sql_handle); - mapindex_final(); + mapindex->final(); for(i = 0; i < MAX_MAP_SERVERS; i++ ) if( server[i].map ) @@ -4977,13 +5368,13 @@ int do_init(int argc, char **argv) { for(i = 0; i < MAX_MAP_SERVERS; i++ ) server[i].map = NULL; - //Read map indexes - mapindex_init(); - start_point.map = mapindex_name2id("new_zone01"); - - + mapindex_defaults(); pincode_defaults(); + //Read map indexes + mapindex->init(); + start_point.map = mapindex->name2id("new_zone01"); + char_config_read((argc < 2) ? CHAR_CONF_NAME : argv[1]); char_lan_config_read((argc > 3) ? argv[3] : LAN_CONF_NAME); sql_config_read(SQL_CONF_NAME); @@ -5006,11 +5397,11 @@ int do_init(int argc, char **argv) { mmo_char_sql_init(); char_read_fame_list(); //Read fame lists. - if ((naddr_ != 0) && (!login_ip || !char_ip)) { + if ((sockt->naddr_ != 0) && (!login_ip || !char_ip)) { char ip_str[16]; - ip2str(addr_[0], ip_str); + ip2str(sockt->addr_[0], ip_str); - if (naddr_ > 1) + if (sockt->naddr_ > 1) ShowStatus("Multiple interfaces detected.. using %s as our IP address\n", ip_str); else ShowStatus("Defaulting to %s as our IP address\n", ip_str); diff --git a/src/char/char.h b/src/char/char.h index a3bbdd904..372af91f7 100644 --- a/src/char/char.h +++ b/src/char/char.h @@ -1,8 +1,9 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena Dev Teams -#ifndef _CHAR_SQL_H_ -#define _CHAR_SQL_H_ +#ifndef _COMMON_CHAR_H_ +#define _COMMON_CHAR_H_ #include "../config/core.h" #include "../common/core.h" // CORE_ST_LAST @@ -20,6 +21,7 @@ struct char_session_data { bool auth; // whether the session is authed or not int account_id, login_id1, login_id2, sex; int found_char[MAX_CHARS]; // ids of chars on this account + time_t unban_time[MAX_CHARS]; // char unban time array char email[40]; // e-mail (default: a@a.com) by [Yor] time_t expiration_time; // # of seconds 1/1/1970 (timestamp): Validity limit of the account (0 = unlimited) int group_id; // permission @@ -47,7 +49,7 @@ DBMap* online_char_db; // int account_id -> struct online_char_data* #define MAX_MAP_SERVERS 2 -#define DEFAULT_AUTOSAVE_INTERVAL 300*1000 +#define DEFAULT_AUTOSAVE_INTERVAL (300*1000) enum { TABLE_INVENTORY, @@ -61,13 +63,13 @@ int memitemdata_to_sql(const struct item items[], int max, int id, int tableswit int mapif_sendall(unsigned char *buf,unsigned int len); int mapif_sendallwos(int fd,unsigned char *buf,unsigned int len); int mapif_send(int fd,unsigned char *buf,unsigned int len); +void mapif_on_parse_accinfo(int account_id,int u_fd, int aid, int castergroup, int map_fd); int char_married(int pl1,int pl2); int char_child(int parent_id, int child_id); int char_family(int pl1,int pl2,int pl3); int request_accreg2(int account_id, int char_id); -int save_accreg2(unsigned char* buf, int len); int login_fd; extern int char_name_option; extern char char_name_letters[]; @@ -82,7 +84,6 @@ extern char inventory_db[256]; extern char charlog_db[256]; extern char storage_db[256]; extern char interlog_db[256]; -extern char reg_db[256]; extern char skill_db[256]; extern char memo_db[256]; extern char guild_db[256]; @@ -105,6 +106,10 @@ extern char mercenary_owner_db[256]; extern char ragsrvinfo_db[256]; extern char elemental_db[256]; extern char interreg_db[32]; +extern char acc_reg_num_db[32]; +extern char acc_reg_str_db[32]; +extern char char_reg_str_db[32]; +extern char char_reg_num_db[32]; extern int db_use_sql_item_db; extern int db_use_sql_mob_db; @@ -113,4 +118,8 @@ extern int db_use_sql_mob_skill_db; extern int guild_exp_rate; extern int log_inter; -#endif /* _CHAR_SQL_H_ */ +void global_accreg_to_login_start (int account_id, int char_id); +void global_accreg_to_login_send (void); +void global_accreg_to_login_add (const char *key, unsigned int index, intptr_t val, bool is_string); + +#endif /* _COMMON_CHAR_H_ */ diff --git a/src/char/int_auction.c b/src/char/int_auction.c index 0dad9d2de..47f3421c3 100644 --- a/src/char/int_auction.c +++ b/src/char/int_auction.c @@ -22,7 +22,7 @@ static DBMap* auction_db_ = NULL; // int auction_id -> struct auction_data* void auction_delete(struct auction_data *auction); -static int auction_end_timer(int tid, unsigned int tick, int id, intptr_t data); +static int auction_end_timer(int tid, int64 tick, int id, intptr_t data); static int auction_count(int char_id, bool buy) { @@ -108,7 +108,7 @@ unsigned int auction_create(struct auction_data *auction) else { struct auction_data *auction_; - unsigned int tick = auction->hours * 3600000; + int64 tick = auction->hours * 3600000; auction->item.amount = 1; auction->item.identify = 1; @@ -139,8 +139,7 @@ static void mapif_Auction_message(int char_id, unsigned char result) mapif_sendall(buf,7); } -static int auction_end_timer(int tid, unsigned int tick, int id, intptr_t data) -{ +static int auction_end_timer(int tid, int64 tick, int id, intptr_t data) { struct auction_data *auction; if( (auction = (struct auction_data *)idb_get(auction_db_, id)) != NULL ) { @@ -182,7 +181,7 @@ void inter_auctions_fromsql(void) struct item *item; char *data; StringBuf buf; - unsigned int tick = timer->gettick(), endtick; + int64 tick = timer->gettick(), endtick; time_t now = time(NULL); StrBuf->Init(&buf); @@ -230,7 +229,7 @@ void inter_auctions_fromsql(void) } if( auction->timestamp > now ) - endtick = ((unsigned int)(auction->timestamp - now) * 1000) + tick; + endtick = ((int64)(auction->timestamp - now) * 1000) + tick; else endtick = tick + 10000; // 10 Second's to process ended auctions diff --git a/src/char/int_auction.h b/src/char/int_auction.h index bf26b152c..f10794f73 100644 --- a/src/char/int_auction.h +++ b/src/char/int_auction.h @@ -1,12 +1,12 @@ // Copyright (c) Athena Dev Teams - Licensed under GNU GPL // For more information, see LICENCE in the main folder -#ifndef _INT_AUCTION_SQL_H_ -#define _INT_AUCTION_SQL_H_ +#ifndef _CHAR_INT_AUCTION_H_ +#define _CHAR_INT_AUCTION_H_ int inter_auction_parse_frommap(int fd); int inter_auction_sql_init(void); void inter_auction_sql_final(void); -#endif /* _INT_AUCTION_SQL_H_ */ +#endif /* _CHAR_INT_AUCTION_H_ */ diff --git a/src/char/int_elemental.h b/src/char/int_elemental.h index 7eb5c2958..c90891fc4 100644 --- a/src/char/int_elemental.h +++ b/src/char/int_elemental.h @@ -1,8 +1,8 @@ // Copyright (c) Athena Dev Teams - Licensed under GNU GPL // For more information, see LICENCE in the main folder -#ifndef _INT_ELEMENTAL_SQL_H_ -#define _INT_ELEMENTAL_SQL_H_ +#ifndef _CHAR_INT_ELEMENTAL_H_ +#define _CHAR_INT_ELEMENTAL_H_ struct s_elemental; @@ -12,4 +12,4 @@ int inter_elemental_parse_frommap(int fd); bool mapif_elemental_delete(int ele_id); -#endif /* _INT_ELEMENTAL_SQL_H_ */ +#endif /* _CHAR_INT_ELEMENTAL_H_ */ diff --git a/src/char/int_guild.c b/src/char/int_guild.c index fab63894e..0f6814527 100644 --- a/src/char/int_guild.c +++ b/src/char/int_guild.c @@ -35,7 +35,7 @@ static const char dataToHex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9 static DBMap* guild_db_; // int guild_id -> struct guild* static DBMap *castle_db; -static unsigned int guild_exp[100]; +static unsigned int guild_exp[MAX_GUILDLEVEL]; int mapif_parse_GuildLeave(int fd,int guild_id,int account_id,int char_id,int flag,const char *mes); int mapif_guild_broken(int guild_id,int flag); @@ -43,11 +43,9 @@ static bool guild_check_empty(struct guild *g); int guild_calcinfo(struct guild *g); int mapif_guild_basicinfochanged(int guild_id,int type,const void *data,int len); int mapif_guild_info(int fd,struct guild *g); -int guild_break_sub(int key,void *data,va_list ap); int inter_guild_tosql(struct guild *g,int flag); -static int guild_save_timer(int tid, unsigned int tick, int id, intptr_t data) -{ +static int guild_save_timer(int tid, int64 tick, int id, intptr_t data) { static int last_id = 0; //To know in which guild we were. int state = 0; //0: Have not reached last guild. 1: Reached last guild, ready for save. 2: Some guild saved, don't do further saving. DBIterator *iter = db_iterator(guild_db_); @@ -86,7 +84,7 @@ static int guild_save_timer(int tid, unsigned int tick, int id, intptr_t data) state = guild_db_->size(guild_db_); if( state < 1 ) state = 1; //Calculate the time slot for the next save. - timer->add(tick + autosave_interval/state, guild_save_timer, 0, 0); + timer->add(tick + autosave_interval/state, guild_save_timer, 0, 0); return 0; } @@ -448,16 +446,16 @@ struct guild * inter_guild_fromsql(int guild_id) while( SQL_SUCCESS == SQL->NextRow(sql_handle) ) { int position; - struct guild_position* p; + struct guild_position *pos; SQL->GetData(sql_handle, 0, &data, NULL); position = atoi(data); if( position < 0 || position >= MAX_GUILDPOSITION ) continue;// invalid position - p = &g->position[position]; - SQL->GetData(sql_handle, 1, &data, &len); memcpy(p->name, data, min(len, NAME_LENGTH)); - SQL->GetData(sql_handle, 2, &data, NULL); p->mode = atoi(data); - SQL->GetData(sql_handle, 3, &data, NULL); p->exp_mode = atoi(data); - p->modified = GS_POSITION_UNMODIFIED; + pos = &g->position[position]; + SQL->GetData(sql_handle, 1, &data, &len); memcpy(pos->name, data, min(len, NAME_LENGTH)); + SQL->GetData(sql_handle, 2, &data, NULL); pos->mode = atoi(data); + SQL->GetData(sql_handle, 3, &data, NULL); pos->exp_mode = atoi(data); + pos->modified = GS_POSITION_UNMODIFIED; } //printf("- Read guild_alliance %d from sql \n",guild_id); @@ -600,16 +598,15 @@ static struct guild_castle* inter_guildcastle_fromsql(int castle_id) // Read exp_guild.txt -static bool exp_guild_parse_row(char* split[], int column, int current) -{ - unsigned int exp = (unsigned int)atol(split[0]); +static bool exp_guild_parse_row(char* split[], int column, int current) { + int64 exp = strtoll(split[0], NULL, 10); - if (exp >= UINT_MAX) { - ShowError("exp_guild: Invalid exp %d at line %d\n", exp, current); + if (exp < 0 || exp >= UINT_MAX) { + ShowError("exp_guild: Invalid exp %"PRId64" (valid range: 0 - %u) at line %d\n", exp, UINT_MAX, current); return false; } - guild_exp[current] = exp; + guild_exp[current] = (unsigned int)exp; return true; } @@ -727,7 +724,7 @@ int inter_guild_sql_init(void) castle_db = idb_alloc(DB_OPT_RELEASE_DATA); //Read exp file - sv->readdb("db", DBPATH"exp_guild.txt", ',', 1, 1, 100, exp_guild_parse_row); + sv->readdb("db", DBPATH"exp_guild.txt", ',', 1, 1, MAX_GUILDLEVEL, exp_guild_parse_row); timer->add_func_list(guild_save_timer, "guild_save_timer"); timer->add(timer->gettick() + 10000, guild_save_timer, 0, 0); @@ -796,14 +793,13 @@ static bool guild_check_empty(struct guild *g) return true; } -unsigned int guild_nextexp(int level) -{ +unsigned int guild_nextexp(int level) { if (level == 0) return 1; - if (level < 100 && level > 0) // Change by hack - return guild_exp[level-1]; + if (level <= 0 || level >= MAX_GUILDLEVEL) + return 0; - return 0; + return guild_exp[level-1]; } int guild_checkskill(struct guild *g,int id) @@ -827,7 +823,7 @@ int guild_calcinfo(struct guild *g) nextexp = guild_nextexp(g->guild_lv); // Consume guild exp and increase guild level - while(g->exp >= nextexp && nextexp > 0){ //fixed guild exp overflow [Kevin] + while(g->exp >= nextexp && nextexp > 0) { // nextexp would be 0 if g->guild_lv was >= MAX_GUILDLEVEL g->exp-=nextexp; g->guild_lv++; g->skill_point++; @@ -1180,6 +1176,7 @@ int mapif_parse_CreateGuild(int fd,int account_id,char *name,struct guild_member g->max_member=16; g->average_lv=master->lv; g->connect_member=1; + g->guild_lv=1; for(i=0;i<MAX_GUILDSKILL;i++) g->skill[i].id=i + GD_SKILLBASE; @@ -1426,24 +1423,20 @@ int mapif_parse_GuildMessage(int fd,int guild_id,int account_id,char *mes,int le } // Modification of the guild -int mapif_parse_GuildBasicInfoChange(int fd,int guild_id,int type,const char *data,int len) -{ - struct guild * g; - short dw=*((short *)data); +int mapif_parse_GuildBasicInfoChange(int fd, int guild_id, int type, const void *data, int len) { + struct guild *g; + short value = *((const int16 *)data); g = inter_guild_fromsql(guild_id); if(g==NULL) return 0; - switch(type) - { + switch(type) { case GBI_GUILDLV: - if(dw>0 && g->guild_lv+dw<=50) - { - g->guild_lv+=dw; - g->skill_point+=dw; - } - else if(dw<0 && g->guild_lv+dw>=1) - g->guild_lv+=dw; + if (value > 0 && g->guild_lv + value <= MAX_GUILDLEVEL) { + g->guild_lv += value; + g->skill_point += value; + } else if (value < 0 && g->guild_lv + value >= 1) + g->guild_lv += value; mapif_guild_info(-1,g); g->save_flag |= GS_LEVEL; return 0; @@ -1665,7 +1658,7 @@ static int mapif_parse_GuildDeleteAlliance(struct guild *g, int guild_id, int ac int mapif_parse_GuildAlliance(int fd,int guild_id1,int guild_id2,int account_id1,int account_id2,int flag) { // Could speed up - struct guild *g[2]; + struct guild *g[2] = { NULL }; int j,i; g[0] = inter_guild_fromsql(guild_id1); g[1] = inter_guild_fromsql(guild_id2); @@ -1676,25 +1669,19 @@ int mapif_parse_GuildAlliance(int fd,int guild_id1,int guild_id2,int account_id1 if(g[0]==NULL || g[1]==NULL) return 0; - if(flag&GUILD_ALLIANCE_REMOVE) - { + if( flag&GUILD_ALLIANCE_REMOVE ) { // Remove alliance/opposition, in case of alliance, remove on both side - for(i=0;i<2-(flag&GUILD_ALLIANCE_TYPE_MASK);i++) - { + for( i = 0; i < ((flag&GUILD_ALLIANCE_TYPE_MASK) ? 1 : 2); i++ ) { ARR_FIND( 0, MAX_GUILDALLIANCE, j, g[i]->alliance[j].guild_id == g[1-i]->guild_id && g[i]->alliance[j].opposition == (flag&GUILD_ALLIANCE_TYPE_MASK) ); if( j < MAX_GUILDALLIANCE ) g[i]->alliance[j].guild_id = 0; } - } - else - { + } else { // Add alliance, in case of alliance, add on both side - for(i=0;i<2-(flag&GUILD_ALLIANCE_TYPE_MASK);i++) - { + for( i = 0; i < ((flag&GUILD_ALLIANCE_TYPE_MASK) ? 1 : 2); i++ ) { // Search an empty slot ARR_FIND( 0, MAX_GUILDALLIANCE, j, g[i]->alliance[j].guild_id == 0 ); - if( j < MAX_GUILDALLIANCE ) - { + if( j < MAX_GUILDALLIANCE ) { g[i]->alliance[j].guild_id=g[1-i]->guild_id; memcpy(g[i]->alliance[j].name,g[1-i]->name,NAME_LENGTH); // Set alliance type @@ -1845,7 +1832,7 @@ int inter_guild_parse_frommap(int fd) case 0x3035: mapif_parse_GuildChangeMemberInfoShort(fd,RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOB(fd,14),RFIFOW(fd,15),RFIFOW(fd,17)); break; case 0x3036: mapif_parse_BreakGuild(fd,RFIFOL(fd,2)); break; case 0x3037: mapif_parse_GuildMessage(fd,RFIFOL(fd,4),RFIFOL(fd,8),(char*)RFIFOP(fd,12),RFIFOW(fd,2)-12); break; - case 0x3039: mapif_parse_GuildBasicInfoChange(fd,RFIFOL(fd,4),RFIFOW(fd,8),(const char*)RFIFOP(fd,10),RFIFOW(fd,2)-10); break; + case 0x3039: mapif_parse_GuildBasicInfoChange(fd,RFIFOL(fd,4),RFIFOW(fd,8),(const int16 *)RFIFOP(fd,10),RFIFOW(fd,2)-10); break; case 0x303A: mapif_parse_GuildMemberInfoChange(fd,RFIFOL(fd,4),RFIFOL(fd,8),RFIFOL(fd,12),RFIFOW(fd,16),(const char*)RFIFOP(fd,18),RFIFOW(fd,2)-18); break; case 0x303B: mapif_parse_GuildPosition(fd,RFIFOL(fd,4),RFIFOL(fd,8),(struct guild_position *)RFIFOP(fd,12)); break; case 0x303C: mapif_parse_GuildSkillUp(fd,RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOL(fd,14)); break; diff --git a/src/char/int_guild.h b/src/char/int_guild.h index 47c42dcc5..4eb7d310b 100644 --- a/src/char/int_guild.h +++ b/src/char/int_guild.h @@ -1,8 +1,8 @@ // Copyright (c) Athena Dev Teams - Licensed under GNU GPL // For more information, see LICENCE in the main folder -#ifndef _INT_GUILD_SQL_H_ -#define _INT_GUILD_SQL_H_ +#ifndef _CHAR_INT_GUILD_H_ +#define _CHAR_INT_GUILD_H_ enum { GS_BASIC = 0x0001, @@ -34,4 +34,4 @@ int inter_guild_charname_changed(int guild_id,int account_id, int char_id, char int inter_guild_CharOnline(int char_id, int guild_id); int inter_guild_CharOffline(int char_id, int guild_id); -#endif /* _INT_GUILD_SQL_H_ */ +#endif /* _CHAR_INT_GUILD_H_ */ diff --git a/src/char/int_homun.h b/src/char/int_homun.h index 1c0d76269..561dc848f 100644 --- a/src/char/int_homun.h +++ b/src/char/int_homun.h @@ -1,8 +1,8 @@ // Copyright (c) Athena Dev Teams - Licensed under GNU GPL // For more information, see LICENCE in the main folder -#ifndef _INT_HOMUN_SQL_H_ -#define _INT_HOMUN_SQL_H_ +#ifndef _CHAR_INT_HOMUN_H_ +#define _CHAR_INT_HOMUN_H_ struct s_homunculus; @@ -15,4 +15,4 @@ bool mapif_homunculus_load(int homun_id, struct s_homunculus* hd); bool mapif_homunculus_delete(int homun_id); bool mapif_homunculus_rename(char *name); -#endif /* _INT_HOMUN_SQL_H_ */ +#endif /* _CHAR_INT_HOMUN_H_ */ diff --git a/src/char/int_mail.c b/src/char/int_mail.c index e4b88b5bf..b69824d4b 100644 --- a/src/char/int_mail.c +++ b/src/char/int_mail.c @@ -64,6 +64,7 @@ static int mail_fromsql(int char_id, struct mail_data* md) SQL->GetData(sql_handle,14, &data, NULL); item->identify = atoi(data); SQL->GetData(sql_handle,15, &data, NULL); item->unique_id = strtoull(data, NULL, 10); item->expire_time = 0; + item->bound = 0; for (j = 0; j < MAX_SLOTS; j++) { @@ -184,6 +185,7 @@ static bool mail_loadmessage(int mail_id, struct mail_message* msg) SQL->GetData(sql_handle,14, &data, NULL); msg->item.identify = atoi(data); SQL->GetData(sql_handle,15, &data, NULL); msg->item.unique_id = strtoull(data, NULL, 10); msg->item.expire_time = 0; + msg->item.bound = 0; for( j = 0; j < MAX_SLOTS; j++ ) { diff --git a/src/char/int_mail.h b/src/char/int_mail.h index 77db51e5b..7c06cdc1f 100644 --- a/src/char/int_mail.h +++ b/src/char/int_mail.h @@ -1,8 +1,8 @@ // Copyright (c) Athena Dev Teams - Licensed under GNU GPL // For more information, see LICENCE in the main folder -#ifndef _INT_MAIL_SQL_H_ -#define _INT_MAIL_SQL_H_ +#ifndef _CHAR_INT_MAIL_H_ +#define _CHAR_INT_MAIL_H_ int inter_mail_parse_frommap(int fd); void mail_sendmail(int send_id, const char* send_name, int dest_id, const char* dest_name, const char* title, const char* body, int zeny, struct item *item); @@ -13,4 +13,4 @@ void inter_mail_sql_final(void); int mail_savemessage(struct mail_message* msg); void mapif_Mail_new(struct mail_message *msg); -#endif /* _INT_MAIL_SQL_H_ */ +#endif /* _CHAR_INT_MAIL_H_ */ diff --git a/src/char/int_mercenary.h b/src/char/int_mercenary.h index 01e4a841f..b614b8cf7 100644 --- a/src/char/int_mercenary.h +++ b/src/char/int_mercenary.h @@ -1,8 +1,8 @@ // Copyright (c) Athena Dev Teams - Licensed under GNU GPL // For more information, see LICENCE in the main folder -#ifndef _INT_MERCENARY_SQL_H_ -#define _INT_MERCENARY_SQL_H_ +#ifndef _CHAR_INT_MERCENARY_H_ +#define _CHAR_INT_MERCENARY_H_ struct s_mercenary; @@ -17,4 +17,4 @@ bool mercenary_owner_delete(int char_id); bool mapif_mercenary_delete(int merc_id); -#endif /* _INT_MERCENARY_SQL_H_ */ +#endif /* _CHAR_INT_MERCENARY_H_ */ diff --git a/src/char/int_party.c b/src/char/int_party.c index 9cb4ccf80..7c328c452 100644 --- a/src/char/int_party.c +++ b/src/char/int_party.c @@ -241,7 +241,7 @@ struct party_data *inter_party_fromsql(int party_id) SQL->GetData(sql_handle, 1, &data, NULL); m->char_id = atoi(data); SQL->GetData(sql_handle, 2, &data, &len); memcpy(m->name, data, min(len, NAME_LENGTH)); SQL->GetData(sql_handle, 3, &data, NULL); m->lv = atoi(data); - SQL->GetData(sql_handle, 4, &data, NULL); m->map = mapindex_name2id(data); + SQL->GetData(sql_handle, 4, &data, NULL); m->map = mapindex->name2id(data); SQL->GetData(sql_handle, 5, &data, NULL); m->online = (atoi(data) ? 1 : 0); SQL->GetData(sql_handle, 6, &data, NULL); m->class_ = atoi(data); m->leader = (m->account_id == leader_id && m->char_id == leader_char ? 1 : 0); diff --git a/src/char/int_party.h b/src/char/int_party.h index d8cdcdc6a..84f00635a 100644 --- a/src/char/int_party.h +++ b/src/char/int_party.h @@ -1,8 +1,8 @@ // Copyright (c) Athena Dev Teams - Licensed under GNU GPL // For more information, see LICENCE in the main folder -#ifndef _INT_PARTY_SQL_H_ -#define _INT_PARTY_SQL_H_ +#ifndef _CHAR_INT_PARTY_H_ +#define _CHAR_INT_PARTY_H_ //Party Flags on what to save/delete. enum { @@ -23,4 +23,4 @@ int inter_party_leave(int party_id,int account_id, int char_id); int inter_party_CharOnline(int char_id, int party_id); int inter_party_CharOffline(int char_id, int party_id); -#endif /* _INT_PARTY_SQL_H_ */ +#endif /* _CHAR_INT_PARTY_H_ */ diff --git a/src/char/int_pet.h b/src/char/int_pet.h index 733468c77..a16cb7a37 100644 --- a/src/char/int_pet.h +++ b/src/char/int_pet.h @@ -1,8 +1,8 @@ // Copyright (c) Athena Dev Teams - Licensed under GNU GPL // For more information, see LICENCE in the main folder -#ifndef _INT_PET_SQL_H_ -#define _INT_PET_SQL_H_ +#ifndef _CHAR_INT_PET_H_ +#define _CHAR_INT_PET_H_ struct s_pet; @@ -18,4 +18,4 @@ int inter_pet_sql_init(void); //Exported for use in the TXT-SQL converter. int inter_pet_tosql(int pet_id, struct s_pet *p); -#endif /* _INT_PET_SQL_H_ */ +#endif /* _CHAR_INT_PET_H_ */ diff --git a/src/char/int_quest.c b/src/char/int_quest.c index af8f83a5d..061dd89d9 100644 --- a/src/char/int_quest.c +++ b/src/char/int_quest.c @@ -19,45 +19,93 @@ #include <string.h> #include <stdlib.h> -//Load entire questlog for a character -int mapif_quests_fromsql(int char_id, struct quest questlog[]) -{ - int i; +/** + * Loads the entire questlog for a character. + * + * @param char_id Character ID + * @param count Pointer to return the number of found entries. + * @return Array of found entries. It has *count entries, and it is care of the + * caller to aFree() it afterwards. + */ +struct quest *mapif_quests_fromsql(int char_id, int *count) { + struct quest *questlog = NULL; struct quest tmp_quest; - SqlStmt * stmt; + SqlStmt *stmt; + StringBuf buf; + int i; + int sqlerror = SQL_SUCCESS; + + if (!count) + return NULL; stmt = SQL->StmtMalloc(sql_handle); - if( stmt == NULL ) - { + if (stmt == NULL) { SqlStmt_ShowDebug(stmt); - return 0; + *count = 0; + return NULL; + } + + StrBuf->Init(&buf); + StrBuf->AppendStr(&buf, "SELECT `quest_id`, `state`, `time`"); + for (i = 0; i < MAX_QUEST_OBJECTIVES; i++) { + StrBuf->Printf(&buf, ", `count%d`", i+1); } + StrBuf->Printf(&buf, " FROM `%s` WHERE `char_id`=?", quest_db); memset(&tmp_quest, 0, sizeof(struct quest)); - if( SQL_ERROR == SQL->StmtPrepare(stmt, "SELECT `quest_id`, `state`, `time`, `count1`, `count2`, `count3` FROM `%s` WHERE `char_id`=? LIMIT %d", quest_db, MAX_QUEST_DB) - || SQL_ERROR == SQL->StmtBindParam(stmt, 0, SQLDT_INT, &char_id, 0) - || SQL_ERROR == SQL->StmtExecute(stmt) - || SQL_ERROR == SQL->StmtBindColumn(stmt, 0, SQLDT_INT, &tmp_quest.quest_id, 0, NULL, NULL) - || SQL_ERROR == SQL->StmtBindColumn(stmt, 1, SQLDT_INT, &tmp_quest.state, 0, NULL, NULL) - || SQL_ERROR == SQL->StmtBindColumn(stmt, 2, SQLDT_UINT, &tmp_quest.time, 0, NULL, NULL) - || SQL_ERROR == SQL->StmtBindColumn(stmt, 3, SQLDT_INT, &tmp_quest.count[0], 0, NULL, NULL) - || SQL_ERROR == SQL->StmtBindColumn(stmt, 4, SQLDT_INT, &tmp_quest.count[1], 0, NULL, NULL) - || SQL_ERROR == SQL->StmtBindColumn(stmt, 5, SQLDT_INT, &tmp_quest.count[2], 0, NULL, NULL) ) + if (SQL_ERROR == SQL->StmtPrepare(stmt, StrBuf->Value(&buf)) + || SQL_ERROR == SQL->StmtBindParam(stmt, 0, SQLDT_INT, &char_id, 0) + || SQL_ERROR == SQL->StmtExecute(stmt) + || SQL_ERROR == SQL->StmtBindColumn(stmt, 0, SQLDT_INT, &tmp_quest.quest_id, 0, NULL, NULL) + || SQL_ERROR == SQL->StmtBindColumn(stmt, 1, SQLDT_INT, &tmp_quest.state, 0, NULL, NULL) + || SQL_ERROR == SQL->StmtBindColumn(stmt, 2, SQLDT_UINT, &tmp_quest.time, 0, NULL, NULL) + ) + sqlerror = SQL_ERROR; + + StrBuf->Destroy(&buf); + + for (i = 0; sqlerror != SQL_ERROR && i < MAX_QUEST_OBJECTIVES; i++) { // Stop on the first error + sqlerror = SQL->StmtBindColumn(stmt, 3+i, SQLDT_INT, &tmp_quest.count[i], 0, NULL, NULL); + } + + if (sqlerror == SQL_ERROR) { SqlStmt_ShowDebug(stmt); + SQL->StmtFree(stmt); + *count = 0; + return NULL; + } + + *count = (int)SQL->StmtNumRows(stmt); + if (*count > 0) { + i = 0; + questlog = (struct quest *)aCalloc(*count, sizeof(struct quest)); - for( i = 0; i < MAX_QUEST_DB && SQL_SUCCESS == SQL->StmtNextRow(stmt); ++i ) - memcpy(&questlog[i], &tmp_quest, sizeof(tmp_quest)); + while (SQL_SUCCESS == SQL->StmtNextRow(stmt)) { + if (i >= *count) // Sanity check, should never happen + break; + memcpy(&questlog[i++], &tmp_quest, sizeof(tmp_quest)); + } + if (i < *count) { + // Should never happen. Compact array + *count = i; + questlog = aRealloc(questlog, sizeof(struct quest)*i); + } + } SQL->StmtFree(stmt); - return i; + return questlog; } -//Delete a quest -bool mapif_quest_delete(int char_id, int quest_id) -{ - if ( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `quest_id` = '%d' AND `char_id` = '%d'", quest_db, quest_id, char_id) ) - { +/** + * Deletes a quest from a character's questlog. + * + * @param char_id Character ID + * @param quest_id Quest ID + * @return false in case of errors, true otherwise + */ +bool mapif_quest_delete(int char_id, int quest_id) { + if (SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `quest_id` = '%d' AND `char_id` = '%d'", quest_db, quest_id, char_id)) { Sql_ShowDebug(sql_handle); return false; } @@ -65,66 +113,111 @@ bool mapif_quest_delete(int char_id, int quest_id) return true; } -//Add a quest to a questlog -bool mapif_quest_add(int char_id, struct quest qd) -{ - if ( SQL_ERROR == SQL->Query(sql_handle, "INSERT INTO `%s`(`quest_id`, `char_id`, `state`, `time`, `count1`, `count2`, `count3`) VALUES ('%d', '%d', '%d','%d', '%d', '%d', '%d')", quest_db, qd.quest_id, char_id, qd.state, qd.time, qd.count[0], qd.count[1], qd.count[2]) ) - { +/** + * Adds a quest to a character's questlog. + * + * @param char_id Character ID + * @param qd Quest data + * @return false in case of errors, true otherwise + */ +bool mapif_quest_add(int char_id, struct quest qd) { + StringBuf buf; + int i; + + StrBuf->Init(&buf); + StrBuf->Printf(&buf, "INSERT INTO `%s`(`quest_id`, `char_id`, `state`, `time`", quest_db); + for (i = 0; i < MAX_QUEST_OBJECTIVES; i++) { + StrBuf->Printf(&buf, ", `count%d`", i+1); + } + StrBuf->Printf(&buf, ") VALUES ('%d', '%d', '%d', '%d'", qd.quest_id, char_id, qd.state, qd.time); + for (i = 0; i < MAX_QUEST_OBJECTIVES; i++) { + StrBuf->Printf(&buf, ", '%d'", qd.count[i]); + } + StrBuf->AppendStr(&buf, ")"); + if (SQL_ERROR == SQL->Query(sql_handle, StrBuf->Value(&buf))) { Sql_ShowDebug(sql_handle); + StrBuf->Destroy(&buf); return false; } + StrBuf->Destroy(&buf); return true; } -//Update a questlog -bool mapif_quest_update(int char_id, struct quest qd) -{ - if ( SQL_ERROR == SQL->Query(sql_handle, "UPDATE `%s` SET `state`='%d', `count1`='%d', `count2`='%d', `count3`='%d' WHERE `quest_id` = '%d' AND `char_id` = '%d'", quest_db, qd.state, qd.count[0], qd.count[1], qd.count[2], qd.quest_id, char_id) ) - { +/** + * Updates a quest in a character's questlog. + * + * @param char_id Character ID + * @param qd Quest data + * @return false in case of errors, true otherwise + */ +bool mapif_quest_update(int char_id, struct quest qd) { + StringBuf buf; + int i; + + StrBuf->Init(&buf); + StrBuf->Printf(&buf, "UPDATE `%s` SET `state`='%d'", quest_db, qd.state); + for (i = 0; i < MAX_QUEST_OBJECTIVES; i++) { + StrBuf->Printf(&buf, ", `count%d`='%d'", i+1, qd.count[i]); + } + StrBuf->Printf(&buf, " WHERE `quest_id` = '%d' AND `char_id` = '%d'", qd.quest_id, char_id); + + if (SQL_ERROR == SQL->Query(sql_handle, StrBuf->Value(&buf))) { Sql_ShowDebug(sql_handle); + StrBuf->Destroy(&buf); return false; } + StrBuf->Destroy(&buf); return true; } -//Save quests -int mapif_parse_quest_save(int fd) -{ - int i, j, k, num2, num1 = (RFIFOW(fd,2)-8)/sizeof(struct quest); +/** + * Handles the save request from mapserver for a character's questlog. + * + * Received quests are saved, and an ack is sent back to the map server. + * + * @see inter_parse_frommap + */ +int mapif_parse_quest_save(int fd) { + int i, j, k, old_n, new_n = (RFIFOW(fd,2)-8)/sizeof(struct quest); int char_id = RFIFOL(fd,4); - struct quest qd1[MAX_QUEST_DB],qd2[MAX_QUEST_DB]; + struct quest *old_qd = NULL, *new_qd = NULL; bool success = true; - memset(qd1, 0, sizeof(qd1)); - memset(qd2, 0, sizeof(qd2)); - if( num1 ) memcpy(&qd1, RFIFOP(fd,8), RFIFOW(fd,2)-8); - num2 = mapif_quests_fromsql(char_id, qd2); - - for( i = 0; i < num1; i++ ) - { - ARR_FIND( 0, num2, j, qd1[i].quest_id == qd2[j].quest_id ); - if( j < num2 ) // Update existed quests - { // Only states and counts are changable. - ARR_FIND( 0, MAX_QUEST_OBJECTIVES, k, qd1[i].count[k] != qd2[j].count[k] ); - if( k != MAX_QUEST_OBJECTIVES || qd1[i].state != qd2[j].state ) - success &= mapif_quest_update(char_id, qd1[i]); - - if( j < (--num2) ) - { - memmove(&qd2[j],&qd2[j+1],sizeof(struct quest)*(num2-j)); - memset(&qd2[num2], 0, sizeof(struct quest)); - } + if (new_n > 0) + new_qd = (struct quest*)RFIFOP(fd,8); + + old_qd = mapif_quests_fromsql(char_id, &old_n); + + for (i = 0; i < new_n; i++) { + ARR_FIND( 0, old_n, j, new_qd[i].quest_id == old_qd[j].quest_id ); + if (j < old_n) { + // Update existing quests + // Only states and counts are changable. + ARR_FIND( 0, MAX_QUEST_OBJECTIVES, k, new_qd[i].count[k] != old_qd[j].count[k] ); + if (k != MAX_QUEST_OBJECTIVES || new_qd[i].state != old_qd[j].state) + success &= mapif_quest_update(char_id, new_qd[i]); + + if (j < (--old_n)) { + // Compact array + memmove(&old_qd[j],&old_qd[j+1],sizeof(struct quest)*(old_n-j)); + memset(&old_qd[old_n], 0, sizeof(struct quest)); + } + } else { + // Add new quests + success &= mapif_quest_add(char_id, new_qd[i]); } - else // Add new quests - success &= mapif_quest_add(char_id, qd1[i]); } - for( i = 0; i < num2; i++ ) // Quests not in qd1 but in qd2 are to be erased. - success &= mapif_quest_delete(char_id, qd2[i].quest_id); + for (i = 0; i < old_n; i++) // Quests not in new_qd but in old_qd are to be erased. + success &= mapif_quest_delete(char_id, old_qd[i].quest_id); + if (old_qd) + aFree(old_qd); + + // Send ack WFIFOHEAD(fd,7); WFIFOW(fd,0) = 0x3861; WFIFOL(fd,2) = char_id; @@ -134,48 +227,45 @@ int mapif_parse_quest_save(int fd) return 0; } -//Send questlog to map server -int mapif_parse_quest_load(int fd) -{ +/** + * Sends questlog to the map server + * + * Note: Completed quests (state == Q_COMPLETE) are guaranteed to be sent last + * and the map server relies on this behavior (once the first Q_COMPLETE quest, + * all of them are considered to be Q_COMPLETE) + * + * @see inter_parse_frommap + */ +int mapif_parse_quest_load(int fd) { int char_id = RFIFOL(fd,2); - struct quest tmp_questlog[MAX_QUEST_DB]; - int num_quests, i, num_complete = 0; - int complete[MAX_QUEST_DB]; - - memset(tmp_questlog, 0, sizeof(tmp_questlog)); - memset(complete, 0, sizeof(complete)); + struct quest *tmp_questlog = NULL; + int num_quests; - num_quests = mapif_quests_fromsql(char_id, tmp_questlog); + tmp_questlog = mapif_quests_fromsql(char_id, &num_quests); WFIFOHEAD(fd,num_quests*sizeof(struct quest)+8); WFIFOW(fd,0) = 0x3860; WFIFOW(fd,2) = num_quests*sizeof(struct quest)+8; WFIFOL(fd,4) = char_id; - //Active and inactive quests - for( i = 0; i < num_quests; i++ ) - { - if( tmp_questlog[i].state == Q_COMPLETE ) - { - complete[num_complete++] = i; - continue; - } - memcpy(WFIFOP(fd,(i-num_complete)*sizeof(struct quest)+8), &tmp_questlog[i], sizeof(struct quest)); - } - - // Completed quests - for( i = num_quests - num_complete; i < num_quests; i++ ) - memcpy(WFIFOP(fd,i*sizeof(struct quest)+8), &tmp_questlog[complete[i-num_quests+num_complete]], sizeof(struct quest)); + if (num_quests > 0) + memcpy(WFIFOP(fd,8), tmp_questlog, sizeof(struct quest)*num_quests); WFIFOSET(fd,num_quests*sizeof(struct quest)+8); + if (tmp_questlog) + aFree(tmp_questlog); + return 0; } -int inter_quest_parse_frommap(int fd) -{ - switch(RFIFOW(fd,0)) - { +/** + * Parses questlog related packets from the map server. + * + * @see inter_parse_frommap + */ +int inter_quest_parse_frommap(int fd) { + switch(RFIFOW(fd,0)) { case 0x3060: mapif_parse_quest_load(fd); break; case 0x3061: mapif_parse_quest_save(fd); break; default: diff --git a/src/char/int_quest.h b/src/char/int_quest.h index f2a0b626e..6267c74ad 100644 --- a/src/char/int_quest.h +++ b/src/char/int_quest.h @@ -1,13 +1,10 @@ // Copyright (c) Athena Dev Teams - Licensed under GNU GPL // For more information, see LICENCE in the main folder -#ifndef _QUEST_H_ -#define _QUEST_H_ - -/*questlog system*/ -struct quest; +#ifndef _CHAR_QUEST_H_ +#define _CHAR_QUEST_H_ int inter_quest_parse_frommap(int fd); -#endif +#endif /* _CHAR_QUEST_H_ */ diff --git a/src/char/int_storage.c b/src/char/int_storage.c index 429b80105..0313f2a41 100644 --- a/src/char/int_storage.c +++ b/src/char/int_storage.c @@ -39,8 +39,8 @@ int storage_fromsql(int account_id, struct storage_data* p) // storage {`account_id`/`id`/`nameid`/`amount`/`equip`/`identify`/`refine`/`attribute`/`card0`/`card1`/`card2`/`card3`} StrBuf->Init(&buf); - StrBuf->AppendStr(&buf, "SELECT `id`,`nameid`,`amount`,`equip`,`identify`,`refine`,`attribute`,`expire_time`,`unique_id`"); - for( j = 0; j < MAX_SLOTS; ++j ) + StrBuf->AppendStr(&buf, "SELECT `id`,`nameid`,`amount`,`equip`,`identify`,`refine`,`attribute`,`expire_time`,`bound`,`unique_id`"); + for( j = 0; j < MAX_SLOTS; ++j ) StrBuf->Printf(&buf, ",`card%d`", j); StrBuf->Printf(&buf, " FROM `%s` WHERE `account_id`='%d' ORDER BY `nameid`", storage_db, account_id); @@ -60,10 +60,11 @@ int storage_fromsql(int account_id, struct storage_data* p) SQL->GetData(sql_handle, 5, &data, NULL); item->refine = atoi(data); SQL->GetData(sql_handle, 6, &data, NULL); item->attribute = atoi(data); SQL->GetData(sql_handle, 7, &data, NULL); item->expire_time = (unsigned int)atoi(data); - SQL->GetData(sql_handle, 8, &data, NULL); item->unique_id = strtoull(data, NULL, 10); - for( j = 0; j < MAX_SLOTS; ++j ) + SQL->GetData(sql_handle, 8, &data, NULL); item->bound = atoi(data); + SQL->GetData(sql_handle, 9, &data, NULL); item->unique_id = strtoull(data, NULL, 10); + for( j = 0; j < MAX_SLOTS; ++j ) { - SQL->GetData(sql_handle, 9+j, &data, NULL); item->card[j] = atoi(data); + SQL->GetData(sql_handle, 10+j, &data, NULL); item->card[j] = atoi(data); } } p->storage_amount = i; @@ -96,8 +97,8 @@ int guild_storage_fromsql(int guild_id, struct guild_storage* p) // storage {`guild_id`/`id`/`nameid`/`amount`/`equip`/`identify`/`refine`/`attribute`/`card0`/`card1`/`card2`/`card3`} StrBuf->Init(&buf); - StrBuf->AppendStr(&buf, "SELECT `id`,`nameid`,`amount`,`equip`,`identify`,`refine`,`attribute`,`unique_id`"); - for( j = 0; j < MAX_SLOTS; ++j ) + StrBuf->AppendStr(&buf, "SELECT `id`,`nameid`,`amount`,`equip`,`identify`,`refine`,`attribute`,`bound`,`unique_id`"); + for( j = 0; j < MAX_SLOTS; ++j ) StrBuf->Printf(&buf, ",`card%d`", j); StrBuf->Printf(&buf, " FROM `%s` WHERE `guild_id`='%d' ORDER BY `nameid`", guild_storage_db, guild_id); @@ -106,8 +107,7 @@ int guild_storage_fromsql(int guild_id, struct guild_storage* p) StrBuf->Destroy(&buf); - for( i = 0; i < MAX_GUILD_STORAGE && SQL_SUCCESS == SQL->NextRow(sql_handle); ++i ) - { + for( i = 0; i < MAX_GUILD_STORAGE && SQL_SUCCESS == SQL->NextRow(sql_handle); ++i ) { item = &p->items[i]; SQL->GetData(sql_handle, 0, &data, NULL); item->id = atoi(data); SQL->GetData(sql_handle, 1, &data, NULL); item->nameid = atoi(data); @@ -116,11 +116,12 @@ int guild_storage_fromsql(int guild_id, struct guild_storage* p) SQL->GetData(sql_handle, 4, &data, NULL); item->identify = atoi(data); SQL->GetData(sql_handle, 5, &data, NULL); item->refine = atoi(data); SQL->GetData(sql_handle, 6, &data, NULL); item->attribute = atoi(data); - SQL->GetData(sql_handle, 7, &data, NULL); item->unique_id = strtoull(data, NULL, 10); - item->expire_time = 0; - for( j = 0; j < MAX_SLOTS; ++j ) - { - SQL->GetData(sql_handle, 8+j, &data, NULL); item->card[j] = atoi(data); + SQL->GetData(sql_handle, 7, &data, NULL); item->bound = atoi(data); + SQL->GetData(sql_handle, 8, &data, NULL); item->unique_id = strtoull(data, NULL, 10); + item->expire_time = 0; + + for( j = 0; j < MAX_SLOTS; ++j ) { + SQL->GetData(sql_handle, 9+j, &data, NULL); item->card[j] = atoi(data); } } p->storage_amount = i; @@ -159,19 +160,20 @@ int inter_guild_storage_delete(int guild_id) //--------------------------------------------------------- // packet from map server -int mapif_load_guild_storage(int fd,int account_id,int guild_id) +int mapif_load_guild_storage(int fd,int account_id,int guild_id, char flag) { if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `guild_id` FROM `%s` WHERE `guild_id`='%d'", guild_db, guild_id) ) Sql_ShowDebug(sql_handle); else if( SQL->NumRows(sql_handle) > 0 ) {// guild exists - WFIFOHEAD(fd, sizeof(struct guild_storage)+12); + WFIFOHEAD(fd, sizeof(struct guild_storage)+13); WFIFOW(fd,0) = 0x3818; - WFIFOW(fd,2) = sizeof(struct guild_storage)+12; + WFIFOW(fd,2) = sizeof(struct guild_storage)+13; WFIFOL(fd,4) = account_id; WFIFOL(fd,8) = guild_id; - guild_storage_fromsql(guild_id, (struct guild_storage*)WFIFOP(fd,12)); - WFIFOSET(fd, WFIFOW(fd,2)); + WFIFOB(fd,12) = flag; //1 open storage, 0 don't open + guild_storage_fromsql(guild_id, (struct guild_storage*)WFIFOP(fd,13)); + WFIFOSET(fd, WFIFOW(fd,2)); return 0; } // guild does not exist @@ -201,7 +203,7 @@ int mapif_save_guild_storage_ack(int fd,int account_id,int guild_id,int fail) int mapif_parse_LoadGuildStorage(int fd) { RFIFOHEAD(fd); - mapif_load_guild_storage(fd,RFIFOL(fd,2),RFIFOL(fd,6)); + mapif_load_guild_storage(fd,RFIFOL(fd,2),RFIFOL(fd,6),1); return 0; } @@ -235,15 +237,144 @@ int mapif_parse_SaveGuildStorage(int fd) return 0; } +int mapif_itembound_ack(int fd, int aid, int guild_id) +{ +#ifdef GP_BOUND_ITEMS + WFIFOHEAD(fd,8); + WFIFOW(fd,0) = 0x3856; + WFIFOL(fd,2) = aid;/* the value is not being used, drop? */ + WFIFOW(fd,6) = guild_id; + WFIFOSET(fd,8); +#endif + return 0; +} +//------------------------------------------------ +//Guild bound items pull for offline characters [Akinari] +//Revised by [Mhalicot] +//------------------------------------------------ +int mapif_parse_ItemBoundRetrieve_sub(int fd) +{ +#ifdef GP_BOUND_ITEMS + StringBuf buf; + SqlStmt* stmt; + struct item item; + int j, i=0, s; + struct item items[MAX_INVENTORY]; + int char_id = RFIFOL(fd,2); + int aid = RFIFOL(fd,6); + int guild_id = RFIFOW(fd,10); + + StrBuf->Init(&buf); + StrBuf->AppendStr(&buf, "SELECT `id`, `nameid`, `amount`, `equip`, `identify`, `refine`, `attribute`, `expire_time`, `bound`, `unique_id`"); + for( j = 0; j < MAX_SLOTS; ++j ) + StrBuf->Printf(&buf, ", `card%d`", j); + StrBuf->Printf(&buf, " FROM `%s` WHERE `char_id`='%d' AND `bound` = '%d'",inventory_db,char_id,IBT_GUILD); + + stmt = SQL->StmtMalloc(sql_handle); + if( SQL_ERROR == SQL->StmtPrepareStr(stmt, StrBuf->Value(&buf)) + || SQL_ERROR == SQL->StmtExecute(stmt) ) + { + Sql_ShowDebug(sql_handle); + SQL->StmtFree(stmt); + StrBuf->Destroy(&buf); + return 1; + } + + SQL->StmtBindColumn(stmt, 0, SQLDT_INT, &item.id, 0, NULL, NULL); + SQL->StmtBindColumn(stmt, 1, SQLDT_SHORT, &item.nameid, 0, NULL, NULL); + SQL->StmtBindColumn(stmt, 2, SQLDT_SHORT, &item.amount, 0, NULL, NULL); + SQL->StmtBindColumn(stmt, 3, SQLDT_USHORT, &item.equip, 0, NULL, NULL); + SQL->StmtBindColumn(stmt, 4, SQLDT_CHAR, &item.identify, 0, NULL, NULL); + SQL->StmtBindColumn(stmt, 5, SQLDT_CHAR, &item.refine, 0, NULL, NULL); + SQL->StmtBindColumn(stmt, 6, SQLDT_CHAR, &item.attribute, 0, NULL, NULL); + SQL->StmtBindColumn(stmt, 7, SQLDT_UINT, &item.expire_time, 0, NULL, NULL); + SQL->StmtBindColumn(stmt, 8, SQLDT_UCHAR, &item.bound, 0, NULL, NULL); + SQL->StmtBindColumn(stmt, 9, SQLDT_UINT64, &item.unique_id, 0, NULL, NULL); + for( j = 0; j < MAX_SLOTS; ++j ) + SQL->StmtBindColumn(stmt, 10+j, SQLDT_SHORT, &item.card[j], 0, NULL, NULL); + + while( SQL_SUCCESS == SQL->StmtNextRow(stmt) ) { + memcpy(&items[i],&item,sizeof(struct item)); + i++; + } + SQL->FreeResult(sql_handle); + + if(!i) { //No items found - No need to continue + StrBuf->Destroy(&buf); + SQL->StmtFree(stmt); + return 0; + } + + //First we delete the character's items + StrBuf->Clear(&buf); + StrBuf->Printf(&buf, "DELETE FROM `%s` WHERE",inventory_db); + for(j=0; j<i; j++) { + if( j ) + StrBuf->AppendStr(&buf, " OR"); + StrBuf->Printf(&buf, " `id`=%d",items[j].id); + } + + if( SQL_ERROR == SQL->StmtPrepareStr(stmt, StrBuf->Value(&buf)) + || SQL_ERROR == SQL->StmtExecute(stmt) ) + { + Sql_ShowDebug(sql_handle); + SQL->StmtFree(stmt); + StrBuf->Destroy(&buf); + return 1; + } + + //Now let's update the guild storage with those deleted items + StrBuf->Clear(&buf); + StrBuf->Printf(&buf, "INSERT INTO `%s` (`guild_id`, `nameid`, `amount`, `identify`, `refine`, `attribute`, `expire_time`, `bound`, `unique_id`", guild_storage_db); + for( j = 0; j < MAX_SLOTS; ++j ) + StrBuf->Printf(&buf, ", `card%d`", j); + StrBuf->AppendStr(&buf, ") VALUES "); + + for( j = 0; j < i; ++j ) { + if( j ) + StrBuf->AppendStr(&buf, ","); + + StrBuf->Printf(&buf, "('%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d'", + guild_id, items[j].nameid, items[j].amount, items[j].identify, items[j].refine, items[j].attribute, items[j].expire_time, items[j].bound, items[j].unique_id); + for( s = 0; s < MAX_SLOTS; ++s ) + StrBuf->Printf(&buf, ", '%d'", items[j].card[s]); + StrBuf->AppendStr(&buf, ")"); + } + + if( SQL_ERROR == SQL->StmtPrepareStr(stmt, StrBuf->Value(&buf)) + || SQL_ERROR == SQL->StmtExecute(stmt) ) + { + Sql_ShowDebug(sql_handle); + SQL->StmtFree(stmt); + StrBuf->Destroy(&buf); + return 1; + } + + StrBuf->Destroy(&buf); + SQL->StmtFree(stmt); + + //Finally reload storage and tell map we're done + mapif_load_guild_storage(fd,aid,guild_id,0); +#endif + return 0; +} +void mapif_parse_ItemBoundRetrieve(int fd) { + mapif_parse_ItemBoundRetrieve_sub(fd); + /* tell map server the operation is over and it can unlock the storage */ + mapif_itembound_ack(fd,RFIFOL(fd,6),RFIFOW(fd,10)); +} int inter_storage_parse_frommap(int fd) { RFIFOHEAD(fd); switch(RFIFOW(fd,0)){ - case 0x3018: mapif_parse_LoadGuildStorage(fd); break; - case 0x3019: mapif_parse_SaveGuildStorage(fd); break; - default: - return 0; + case 0x3018: mapif_parse_LoadGuildStorage(fd); break; + case 0x3019: mapif_parse_SaveGuildStorage(fd); break; +#ifdef GP_BOUND_ITEMS + case 0x3056: mapif_parse_ItemBoundRetrieve(fd); break; +#endif + default: + return 0; } return 1; } diff --git a/src/char/int_storage.h b/src/char/int_storage.h index 811608f82..1693499a5 100644 --- a/src/char/int_storage.h +++ b/src/char/int_storage.h @@ -1,8 +1,8 @@ // Copyright (c) Athena Dev Teams - Licensed under GNU GPL // For more information, see LICENCE in the main folder -#ifndef _INT_STORAGE_SQL_H_ -#define _INT_STORAGE_SQL_H_ +#ifndef _CHAR_INT_STORAGE_H_ +#define _CHAR_INT_STORAGE_H_ struct storage_data; struct guild_storage; @@ -19,4 +19,4 @@ int storage_fromsql(int account_id, struct storage_data* p); int storage_tosql(int account_id,struct storage_data *p); int guild_storage_tosql(int guild_id, struct guild_storage *p); -#endif /* _INT_STORAGE_SQL_H_ */ +#endif /* _CHAR_INT_STORAGE_H_ */ diff --git a/src/char/inter.c b/src/char/inter.c index 2dc15933b..ff99865f8 100644 --- a/src/char/inter.c +++ b/src/char/inter.c @@ -42,26 +42,25 @@ char char_server_pw[32] = "ragnarok"; char char_server_db[32] = "ragnarok"; char default_codepage[32] = ""; //Feature by irmin. -static struct accreg *accreg_pt; unsigned int party_share_level = 10; // recv. packet list int inter_recv_packet_length[] = { -1,-1, 7,-1, -1,13,36, (2 + 4 + 4 + 4 + NAME_LENGTH), 0, 0, 0, 0, 0, 0, 0, 0, // 3000- - 6,-1, 0, 0, 0, 0, 0, 0, 10,-1, 0, 0, 0, 0, 0, 0, // 3010- - -1,10,-1,14, 14,19, 6,-1, 14,14, 0, 0, 0, 0, 0, 0, // 3020- Party - -1, 6,-1,-1, 55,19, 6,-1, 14,-1,-1,-1, 18,19,186,-1, // 3030- - -1, 9, 0, 0, 0, 0, 0, 0, 7, 6,10,10, 10,-1, 0, 0, // 3040- - -1,-1,10,10, 0,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3050- Auction System [Zephyrus] - 6,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3060- Quest system [Kevin] [Inkfish] - -1,10, 6,-1, 0, 0, 0, 0, 0, 0, 0, 0, -1,10, 6,-1, // 3070- Mercenary packets [Zephyrus], Elemental packets [pakpil] - 48,14,-1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3080- - -1,10,-1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3090- Homunculus packets [albator] + 6,-1, 0, 0, 0, 0, 0, 0, 10,-1, 0, 0, 0, 0, 0, 0, // 3010- + -1,10,-1,14, 14,19, 6,-1, 14,14, 0, 0, 0, 0, 0, 0, // 3020- Party + -1, 6,-1,-1, 55,19, 6,-1, 14,-1,-1,-1, 18,19,186,-1, // 3030- + -1, 9, 0, 0, 0, 0, 0, 0, 7, 6,10,10, 10,-1, 0, 0, // 3040- + -1,-1,10,10, 0,-1,12, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3050- Auction System [Zephyrus], Item Bound [Mhalicot] + 6,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3060- Quest system [Kevin] [Inkfish] + -1,10, 6,-1, 0, 0, 0, 0, 0, 0, 0, 0, -1,10, 6,-1, // 3070- Mercenary packets [Zephyrus], Elemental packets [pakpil] + 48,14,-1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3080- + -1,10,-1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3090- Homunculus packets [albator] }; struct WisData { int id, fd, count, len; - unsigned long tick; + int64 tick; unsigned char src[24], dst[24], msg[512]; }; static DBMap* wis_db = NULL; // int wis_id -> struct WisData* @@ -341,8 +340,11 @@ const char* job_name(int class_) { case JOB_OBORO: return msg_txt(653 - JOB_KAGEROU+class_); - default: + case JOB_REBELLION: return msg_txt(655); + + default: + return msg_txt(656); } } @@ -509,207 +511,287 @@ void mapif_parse_accinfo(int fd) { } /* it will only get here if we have a single match */ + /* and we will send packet with account id to login server asking for account info */ if( account_id ) { - char userid[NAME_LENGTH], user_pass[NAME_LENGTH], email[40], last_ip[20], lastlogin[30], pin_code[5], birthdate[11]; - short level = -1; - int logincount = 0,state = 0; - // FIXME: No, this doesn't really look right. We can't, and shouldn't, access the login table from the char server. - if ( SQL_ERROR == SQL->Query(sql_handle, "SELECT `userid`, `user_pass`, `email`, `last_ip`, `group_id`, `lastlogin`, `logincount`, `state`,`pincode`,`birthdate` FROM `login` WHERE `account_id` = '%d' LIMIT 1", account_id) - || SQL->NumRows(sql_handle) == 0 ) { - if( SQL->NumRows(sql_handle) == 0 ) { - inter_msg_to_fd(fd, u_fd, aid, "No account with ID '%d' was found.", account_id ); - } else { - inter_msg_to_fd(fd, u_fd, aid, "An error occured, bother your admin about it."); - Sql_ShowDebug(sql_handle); - } - } else { - SQL->NextRow(sql_handle); - SQL->GetData(sql_handle, 0, &data, NULL); safestrncpy(userid, data, sizeof(userid)); - SQL->GetData(sql_handle, 1, &data, NULL); safestrncpy(user_pass, data, sizeof(user_pass)); - SQL->GetData(sql_handle, 2, &data, NULL); safestrncpy(email, data, sizeof(email)); - SQL->GetData(sql_handle, 3, &data, NULL); safestrncpy(last_ip, data, sizeof(last_ip)); - SQL->GetData(sql_handle, 4, &data, NULL); level = atoi(data); - SQL->GetData(sql_handle, 5, &data, NULL); safestrncpy(lastlogin, data, sizeof(lastlogin)); - SQL->GetData(sql_handle, 6, &data, NULL); logincount = atoi(data); - SQL->GetData(sql_handle, 7, &data, NULL); state = atoi(data); - SQL->GetData(sql_handle, 8, &data, NULL); safestrncpy(pin_code, data, sizeof(pin_code)); - SQL->GetData(sql_handle, 9, &data, NULL); safestrncpy(birthdate, data, sizeof(birthdate)); - } - - SQL->FreeResult(sql_handle); - - if (level == -1) - return; - - inter_msg_to_fd(fd, u_fd, aid, "-- Account %d --", account_id ); - inter_msg_to_fd(fd, u_fd, aid, "User: %s | GM Group: %d | State: %d", userid, level, state ); - - if (level < castergroup) { /* only show pass if your gm level is greater than the one you're searching for */ - if( strlen(pin_code) ) - inter_msg_to_fd(fd, u_fd, aid, "Password: %s (PIN:%s)", user_pass, pin_code ); - else - inter_msg_to_fd(fd, u_fd, aid, "Password: %s", user_pass ); - } - - inter_msg_to_fd(fd, u_fd, aid, "Account e-mail: %s | Birthdate: %s", email, birthdate); - inter_msg_to_fd(fd, u_fd, aid, "Last IP: %s (%s)", last_ip, geoip_getcountry(str2ip(last_ip)) ); - inter_msg_to_fd(fd, u_fd, aid, "This user has logged %d times, the last time were at %s", logincount, lastlogin ); - inter_msg_to_fd(fd, u_fd, aid, "-- Character Details --" ); - - - if ( SQL_ERROR == SQL->Query(sql_handle, "SELECT `char_id`, `name`, `char_num`, `class`, `base_level`, `job_level`, `online` FROM `%s` WHERE `account_id` = '%d' ORDER BY `char_num` LIMIT %d", char_db, account_id, MAX_CHARS) - || SQL->NumRows(sql_handle) == 0 ) { - - if( SQL->NumRows(sql_handle) == 0 ) - inter_msg_to_fd(fd, u_fd, aid,"This account doesn't have characters."); - else { - inter_msg_to_fd(fd, u_fd, aid,"An error occured, bother your admin about it."); - Sql_ShowDebug(sql_handle); - } - - } else { - while ( SQL_SUCCESS == SQL->NextRow(sql_handle) ) { - int char_id, class_; - short char_num, base_level, job_level, online; - char name[NAME_LENGTH]; - - SQL->GetData(sql_handle, 0, &data, NULL); char_id = atoi(data); - SQL->GetData(sql_handle, 1, &data, NULL); safestrncpy(name, data, sizeof(name)); - SQL->GetData(sql_handle, 2, &data, NULL); char_num = atoi(data); - SQL->GetData(sql_handle, 3, &data, NULL); class_ = atoi(data); - SQL->GetData(sql_handle, 4, &data, NULL); base_level = atoi(data); - SQL->GetData(sql_handle, 5, &data, NULL); job_level = atoi(data); - SQL->GetData(sql_handle, 6, &data, NULL); online = atoi(data); - - inter_msg_to_fd(fd, u_fd, aid, "[Slot/CID: %d/%d] %s | %s | Level: %d/%d | %s", char_num, char_id, name, job_name(class_), base_level, job_level, online?"On":"Off"); - } - } - SQL->FreeResult(sql_handle); + mapif_on_parse_accinfo(account_id, u_fd, aid, castergroup, fd); } return; } -//-------------------------------------------------------- -// Save registry to sql -int inter_accreg_tosql(int account_id, int char_id, struct accreg* reg, int type) -{ - struct global_reg* r; - StringBuf buf; - int i; +void mapif_parse_accinfo2(bool success, int map_fd, int u_fd, int u_aid, int account_id, const char *userid, const char *user_pass, const char *email, const char *last_ip, const char *lastlogin, const char *pin_code, const char *birthdate, int group_id, int logincount, int state) { + if (map_fd <= 0 || !session_isActive(map_fd)) + return; // check if we have a valid fd - if( account_id <= 0 ) - return 0; - reg->account_id = account_id; - reg->char_id = char_id; - - //`global_reg_value` (`type`, `account_id`, `char_id`, `str`, `value`) - switch( type ) - { - case 3: //Char Reg - if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `type`=3 AND `char_id`='%d'", reg_db, char_id) ) - Sql_ShowDebug(sql_handle); - account_id = 0; - break; - case 2: //Account Reg - if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `type`=2 AND `account_id`='%d'", reg_db, account_id) ) - Sql_ShowDebug(sql_handle); - char_id = 0; - break; - case 1: //Account2 Reg - ShowError("inter_accreg_tosql: Char server shouldn't handle type 1 registry values (##). That is the login server's work!\n"); - return 0; - default: - ShowError("inter_accreg_tosql: Invalid type %d\n", type); - return 0; + if (!success) { + inter_msg_to_fd(map_fd, u_fd, u_aid, "No account with ID '%d' was found.", account_id); + return; } - if( reg->reg_num <= 0 ) - return 0; + inter_msg_to_fd(map_fd, u_fd, u_aid, "-- Account %d --", account_id); + inter_msg_to_fd(map_fd, u_fd, u_aid, "User: %s | GM Group: %d | State: %d", userid, group_id, state); - StrBuf->Init(&buf); - StrBuf->Printf(&buf, "INSERT INTO `%s` (`type`,`account_id`,`char_id`,`str`,`value`) VALUES ", reg_db); - - for( i = 0; i < reg->reg_num; ++i ) { - r = ®->reg[i]; - if( r->str[0] != '\0' && r->value[0] != '\0' ) { - char str[32]; - char val[256]; - - if( i > 0 ) - StrBuf->AppendStr(&buf, ","); + if (user_pass && *user_pass != '\0') { /* password is only received if your gm level is greater than the one you're searching for */ + if (pin_code && *pin_code != '\0') + inter_msg_to_fd(map_fd, u_fd, u_aid, "Password: %s (PIN:%s)", user_pass, pin_code); + else + inter_msg_to_fd(map_fd, u_fd, u_aid, "Password: %s", user_pass ); + } - SQL->EscapeString(sql_handle, str, r->str); - SQL->EscapeString(sql_handle, val, r->value); + inter_msg_to_fd(map_fd, u_fd, u_aid, "Account e-mail: %s | Birthdate: %s", email, birthdate); + inter_msg_to_fd(map_fd, u_fd, u_aid, "Last IP: %s (%s)", last_ip, geoip_getcountry(str2ip(last_ip))); + inter_msg_to_fd(map_fd, u_fd, u_aid, "This user has logged %d times, the last time were at %s", logincount, lastlogin); + inter_msg_to_fd(map_fd, u_fd, u_aid, "-- Character Details --"); - StrBuf->Printf(&buf, "('%d','%d','%d','%s','%s')", type, account_id, char_id, str, val); + if ( SQL_ERROR == SQL->Query(sql_handle, "SELECT `char_id`, `name`, `char_num`, `class`, `base_level`, `job_level`, `online` " + "FROM `%s` WHERE `account_id` = '%d' ORDER BY `char_num` LIMIT %d", char_db, account_id, MAX_CHARS) + || SQL->NumRows(sql_handle) == 0 ) { + if (SQL->NumRows(sql_handle) == 0) { + inter_msg_to_fd(map_fd, u_fd, u_aid, "This account doesn't have characters."); + } else { + inter_msg_to_fd(map_fd, u_fd, u_aid, "An error occured, bother your admin about it."); + Sql_ShowDebug(sql_handle); + } + } else { + while ( SQL_SUCCESS == SQL->NextRow(sql_handle) ) { + char *data; + int char_id, class_; + short char_num, base_level, job_level, online; + char name[NAME_LENGTH]; + + SQL->GetData(sql_handle, 0, &data, NULL); char_id = atoi(data); + SQL->GetData(sql_handle, 1, &data, NULL); safestrncpy(name, data, sizeof(name)); + SQL->GetData(sql_handle, 2, &data, NULL); char_num = atoi(data); + SQL->GetData(sql_handle, 3, &data, NULL); class_ = atoi(data); + SQL->GetData(sql_handle, 4, &data, NULL); base_level = atoi(data); + SQL->GetData(sql_handle, 5, &data, NULL); job_level = atoi(data); + SQL->GetData(sql_handle, 6, &data, NULL); online = atoi(data); + + inter_msg_to_fd(map_fd, u_fd, u_aid, "[Slot/CID: %d/%d] %s | %s | Level: %d/%d | %s", char_num, char_id, name, job_name(class_), base_level, job_level, online?"On":"Off"); } } + SQL->FreeResult(sql_handle); - if( SQL_ERROR == SQL->QueryStr(sql_handle, StrBuf->Value(&buf)) ) { - Sql_ShowDebug(sql_handle); + return; +} +/** + * Handles save reg data from map server and distributes accordingly. + * + * @param val either str or int, depending on type + * @param type false when int, true otherwise + **/ +void inter_savereg(int account_id, int char_id, const char *key, unsigned int index, intptr_t val, bool is_string) { + /* to login server we go! */ + if( key[0] == '#' && key[1] == '#' ) {/* global account reg */ + global_accreg_to_login_add(key,index,val,is_string); + } else if ( key[0] == '#' ) {/* local account reg */ + if( is_string ) { + if( val ) { + if( SQL_ERROR == SQL->Query(sql_handle, "REPLACE INTO `%s` (`account_id`,`key`,`index`,`value`) VALUES ('%d','%s','%u','%s')", acc_reg_str_db, account_id, key, index, (char*)val) ) + Sql_ShowDebug(sql_handle); + } else { + if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '%d' AND `key` = '%s' AND `index` = '%u' LIMIT 1", acc_reg_str_db, account_id, key, index) ) + Sql_ShowDebug(sql_handle); + } + } else { + if( val ) { + if( SQL_ERROR == SQL->Query(sql_handle, "REPLACE INTO `%s` (`account_id`,`key`,`index`,`value`) VALUES ('%d','%s','%u','%d')", acc_reg_num_db, account_id, key, index, (int)val) ) + Sql_ShowDebug(sql_handle); + } else { + if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '%d' AND `key` = '%s' AND `index` = '%u' LIMIT 1", acc_reg_num_db, account_id, key, index) ) + Sql_ShowDebug(sql_handle); + } + } + } else { /* char reg */ + if( is_string ) { + if( val ) { + if( SQL_ERROR == SQL->Query(sql_handle, "REPLACE INTO `%s` (`char_id`,`key`,`index`,`value`) VALUES ('%d','%s','%u','%s')", char_reg_str_db, char_id, key, index, (char*)val) ) + Sql_ShowDebug(sql_handle); + } else { + if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `char_id` = '%d' AND `key` = '%s' AND `index` = '%u' LIMIT 1", char_reg_str_db, char_id, key, index) ) + Sql_ShowDebug(sql_handle); + } + } else { + if( val ) { + if( SQL_ERROR == SQL->Query(sql_handle, "REPLACE INTO `%s` (`char_id`,`key`,`index`,`value`) VALUES ('%d','%s','%u','%d')", char_reg_num_db, char_id, key, index, (int)val) ) + Sql_ShowDebug(sql_handle); + } else { + if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `char_id` = '%d' AND `key` = '%s' AND `index` = '%u' LIMIT 1", char_reg_num_db, char_id, key, index) ) + Sql_ShowDebug(sql_handle); + } + } } - - StrBuf->Destroy(&buf); - - return 1; + } // Load account_reg from sql (type=2) -int inter_accreg_fromsql(int account_id,int char_id, struct accreg *reg, int type) +int inter_accreg_fromsql(int account_id,int char_id, int fd, int type) { - struct global_reg* r; char* data; size_t len; - int i; - - if( reg == NULL) - return 0; + unsigned int plen = 0; - memset(reg, 0, sizeof(struct accreg)); - reg->account_id = account_id; - reg->char_id = char_id; + switch( type ) { + case 3: //char reg + if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `key`, `index`, `value` FROM `%s` WHERE `char_id`='%d'", char_reg_str_db, char_id) ) + Sql_ShowDebug(sql_handle); + break; + case 2: //account reg + if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `key`, `index`, `value` FROM `%s` WHERE `account_id`='%d'", acc_reg_str_db, account_id) ) + Sql_ShowDebug(sql_handle); + break; + case 1: //account2 reg + ShowError("inter_accreg_fromsql: Char server shouldn't handle type 1 registry values (##). That is the login server's work!\n"); + return 0; + default: + ShowError("inter_accreg_fromsql: Invalid type %d\n", type); + return 0; + } + + WFIFOHEAD(fd, 60000 + 300); + WFIFOW(fd, 0) = 0x3804; + /* 0x2 = length, set prior to being sent */ + WFIFOL(fd, 4) = account_id; + WFIFOL(fd, 8) = char_id; + WFIFOB(fd, 12) = 0;/* var type (only set when all vars have been sent, regardless of type) */ + WFIFOB(fd, 13) = 1;/* is string type */ + WFIFOW(fd, 14) = 0;/* count */ + plen = 16; + + /** + * Vessel! + * + * str type + * { keyLength(B), key(<keyLength>), index(L), valLength(B), val(<valLength>) } + **/ + while ( SQL_SUCCESS == SQL->NextRow(sql_handle) ) { + + SQL->GetData(sql_handle, 0, &data, NULL); + len = strlen(data)+1; + + WFIFOB(fd, plen) = (unsigned char)len;/* won't be higher; the column size is 32 */ + plen += 1; + + safestrncpy((char*)WFIFOP(fd,plen), data, len); + plen += len; + + SQL->GetData(sql_handle, 1, &data, NULL); + + WFIFOL(fd, plen) = (unsigned int)atol(data); + plen += 4; + + SQL->GetData(sql_handle, 2, &data, NULL); + len = strlen(data)+1; + + WFIFOB(fd, plen) = (unsigned char)len;/* won't be higher; the column size is 254 */ + plen += 1; + + safestrncpy((char*)WFIFOP(fd,plen), data, len); + plen += len; + + WFIFOW(fd, 14) += 1; + + if( plen > 60000 ) { + WFIFOW(fd, 2) = plen; + WFIFOSET(fd, plen); + + /* prepare follow up */ + WFIFOHEAD(fd, 60000 + 300); + WFIFOW(fd, 0) = 0x3804; + /* 0x2 = length, set prior to being sent */ + WFIFOL(fd, 4) = account_id; + WFIFOL(fd, 8) = char_id; + WFIFOB(fd, 12) = 0;/* var type (only set when all vars have been sent, regardless of type) */ + WFIFOB(fd, 13) = 1;/* is string type */ + WFIFOW(fd, 14) = 0;/* count */ + plen = 16; + } + } + + /* mark & go. */ + WFIFOW(fd, 2) = plen; + WFIFOSET(fd, plen); - //`global_reg_value` (`type`, `account_id`, `char_id`, `str`, `value`) - switch( type ) - { - case 3: //char reg - if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `str`, `value` FROM `%s` WHERE `type`=3 AND `char_id`='%d'", reg_db, char_id) ) - Sql_ShowDebug(sql_handle); - break; - case 2: //account reg - if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `str`, `value` FROM `%s` WHERE `type`=2 AND `account_id`='%d'", reg_db, account_id) ) - Sql_ShowDebug(sql_handle); - break; - case 1: //account2 reg - ShowError("inter_accreg_fromsql: Char server shouldn't handle type 1 registry values (##). That is the login server's work!\n"); - return 0; - default: - ShowError("inter_accreg_fromsql: Invalid type %d\n", type); - return 0; + SQL->FreeResult(sql_handle); + + switch( type ) { + case 3: //char reg + if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `key`, `index`, `value` FROM `%s` WHERE `char_id`='%d'", char_reg_num_db, char_id) ) + Sql_ShowDebug(sql_handle); + break; + case 2: //account reg + if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `key`, `index`, `value` FROM `%s` WHERE `account_id`='%d'", acc_reg_num_db, account_id) ) + Sql_ShowDebug(sql_handle); + break; + case 1: //account2 reg + ShowError("inter_accreg_fromsql: Char server shouldn't handle type 1 registry values (##). That is the login server's work!\n"); + return 0; } - for( i = 0; i < MAX_REG_NUM && SQL_SUCCESS == SQL->NextRow(sql_handle); ++i ) - { - r = ®->reg[i]; - // str - SQL->GetData(sql_handle, 0, &data, &len); - memcpy(r->str, data, min(len, sizeof(r->str))); - // value - SQL->GetData(sql_handle, 1, &data, &len); - memcpy(r->value, data, min(len, sizeof(r->value))); + + WFIFOHEAD(fd, 60000 + 300); + WFIFOW(fd, 0) = 0x3804; + /* 0x2 = length, set prior to being sent */ + WFIFOL(fd, 4) = account_id; + WFIFOL(fd, 8) = char_id; + WFIFOB(fd, 12) = 0;/* var type (only set when all vars have been sent, regardless of type) */ + WFIFOB(fd, 13) = 0;/* is int type */ + WFIFOW(fd, 14) = 0;/* count */ + plen = 16; + + /** + * Vessel! + * + * int type + * { keyLength(B), key(<keyLength>), index(L), value(L) } + **/ + while ( SQL_SUCCESS == SQL->NextRow(sql_handle) ) { + + SQL->GetData(sql_handle, 0, &data, NULL); + len = strlen(data)+1; + + WFIFOB(fd, plen) = (unsigned char)len;/* won't be higher; the column size is 32 */ + plen += 1; + + safestrncpy((char*)WFIFOP(fd,plen), data, len); + plen += len; + + SQL->GetData(sql_handle, 1, &data, NULL); + + WFIFOL(fd, plen) = (unsigned int)atol(data); + plen += 4; + + SQL->GetData(sql_handle, 2, &data, NULL); + + WFIFOL(fd, plen) = atoi(data); + plen += 4; + + WFIFOW(fd, 14) += 1; + + if( plen > 60000 ) { + WFIFOW(fd, 2) = plen; + WFIFOSET(fd, plen); + + /* prepare follow up */ + WFIFOHEAD(fd, 60000 + 300); + WFIFOW(fd, 0) = 0x3804; + /* 0x2 = length, set prior to being sent */ + WFIFOL(fd, 4) = account_id; + WFIFOL(fd, 8) = char_id; + WFIFOB(fd, 12) = 0;/* var type (only set when all vars have been sent, regardless of type) */ + WFIFOB(fd, 13) = 0;/* is int type */ + WFIFOW(fd, 14) = 0;/* count */ + plen = 16; + } } - reg->reg_num = i; + + /* mark as complete & go. */ + WFIFOB(fd, 12) = type; + WFIFOW(fd, 2) = plen; + WFIFOSET(fd, plen); + SQL->FreeResult(sql_handle); return 1; } -// Initialize -int inter_accreg_sql_init(void) -{ - CREATE(accreg_pt, struct accreg, 1); - return 0; - -} - /*========================================== * read config file *------------------------------------------*/ @@ -830,7 +912,6 @@ int inter_init_sql(const char *file) inter_homunculus_sql_init(); inter_mercenary_sql_init(); inter_elemental_sql_init(); - inter_accreg_sql_init(); inter_mail_sql_init(); inter_auction_sql_init(); @@ -854,8 +935,6 @@ void inter_final(void) inter_mail_sql_final(); inter_auction_sql_final(); - if (accreg_pt) aFree(accreg_pt); - do_final_msg(); return; } @@ -869,7 +948,7 @@ int inter_mapif_init(int fd) //-------------------------------------------------------- // broadcast sending -int mapif_broadcast(unsigned char *mes, int len, unsigned long fontColor, short fontType, short fontSize, short fontAlign, short fontY, int sfd) +int mapif_broadcast(unsigned char *mes, int len, unsigned int fontColor, short fontType, short fontSize, short fontAlign, short fontY, int sfd) { unsigned char *buf = (unsigned char*)aMalloc((len)*sizeof(unsigned char)); @@ -918,36 +997,15 @@ int mapif_wis_end(struct WisData *wd, int flag) } // Account registry transfer to map-server -static void mapif_account_reg(int fd, unsigned char *src) -{ - WBUFW(src,0)=0x3804; //NOTE: writing to RFIFO - mapif_sendallwos(fd, src, WBUFW(src,2)); -} +//static void mapif_account_reg(int fd, unsigned char *src) +//{ +// WBUFW(src,0)=0x3804; //NOTE: writing to RFIFO +// mapif_sendallwos(fd, src, WBUFW(src,2)); +//} // Send the requested account_reg -int mapif_account_reg_reply(int fd,int account_id,int char_id, int type) -{ - struct accreg *reg=accreg_pt; - WFIFOHEAD(fd, 13 + 5000); - inter_accreg_fromsql(account_id,char_id,reg,type); - - WFIFOW(fd,0)=0x3804; - WFIFOL(fd,4)=account_id; - WFIFOL(fd,8)=char_id; - WFIFOB(fd,12)=type; - if(reg->reg_num==0){ - WFIFOW(fd,2)=13; - }else{ - int i,p; - for (p=13,i = 0; i < reg->reg_num && p < 5000; i++) { - p+= sprintf((char*)WFIFOP(fd,p), "%s", reg->reg[i].str)+1; //We add 1 to consider the '\0' in place. - p+= sprintf((char*)WFIFOP(fd,p), "%s", reg->reg[i].value)+1; - } - WFIFOW(fd,2)=p; - if (p>= 5000) - ShowWarning("Too many acc regs for %d:%d, not all values were loaded.\n", account_id, char_id); - } - WFIFOSET(fd,WFIFOW(fd,2)); +int mapif_account_reg_reply(int fd,int account_id,int char_id, int type) { + inter_accreg_fromsql(account_id,char_id,fd,type); return 0; } @@ -974,9 +1032,9 @@ int mapif_disconnectplayer(int fd, int account_id, int char_id, int reason) */ int check_ttl_wisdata_sub(DBKey key, DBData *data, va_list ap) { - unsigned long tick; + int64 tick; struct WisData *wd = DB->data2ptr(data); - tick = va_arg(ap, unsigned long); + tick = va_arg(ap, int64); if (DIFF_TICK(tick, wd->tick) > WISDATA_TTL && wis_delnum < WISDELLIST_MAX) wis_dellist[wis_delnum++] = wd->id; @@ -986,7 +1044,7 @@ int check_ttl_wisdata_sub(DBKey key, DBData *data, va_list ap) int check_ttl_wisdata(void) { - unsigned long tick = timer->gettick(); + int64 tick = timer->gettick(); int i; do { @@ -1125,34 +1183,50 @@ int mapif_parse_WisToGM(int fd) // Save account_reg into sql (type=2) int mapif_parse_Registry(int fd) { - int j,p,len, max; - struct accreg *reg=accreg_pt; - - memset(accreg_pt,0,sizeof(struct accreg)); - switch (RFIFOB(fd, 12)) { - case 3: //Character registry - max = GLOBAL_REG_NUM; - break; - case 2: //Account Registry - max = ACCOUNT_REG_NUM; - break; - case 1: //Account2 registry, must be sent over to login server. - return save_accreg2(RFIFOP(fd,4), RFIFOW(fd,2)-4); - default: - return 1; - } - for(j=0,p=13;j<max && p<RFIFOW(fd,2);j++){ - sscanf((char*)RFIFOP(fd,p), "%31c%n",reg->reg[j].str,&len); - reg->reg[j].str[len]='\0'; - p +=len+1; //+1 to skip the '\0' between strings. - sscanf((char*)RFIFOP(fd,p), "%255c%n",reg->reg[j].value,&len); - reg->reg[j].value[len]='\0'; - p +=len+1; - } - reg->reg_num=j; + int account_id = RFIFOL(fd, 4), char_id = RFIFOL(fd, 8), count = RFIFOW(fd, 12); + + if( count ) { + int cursor = 14, i; + char key[32], sval[254]; + unsigned int index; + + global_accreg_to_login_start(account_id,char_id); + + for(i = 0; i < count; i++) { + safestrncpy(key, (char*)RFIFOP(fd, cursor + 1), RFIFOB(fd, cursor)); + cursor += RFIFOB(fd, cursor) + 1; + + index = RFIFOL(fd, cursor); + cursor += 4; + + switch (RFIFOB(fd, cursor++)) { + /* int */ + case 0: + inter_savereg(account_id,char_id,key,index,RFIFOL(fd, cursor),false); + cursor += 4; + break; + case 1: + inter_savereg(account_id,char_id,key,index,0,false); + break; + /* str */ + case 2: + safestrncpy(sval, (char*)RFIFOP(fd, cursor + 1), RFIFOB(fd, cursor)); + cursor += RFIFOB(fd, cursor) + 1; + inter_savereg(account_id,char_id,key,index,(intptr_t)sval,true); + break; + case 3: + inter_savereg(account_id,char_id,key,index,0,true); + break; + + default: + ShowError("mapif_parse_Registry: unknown type %d\n",RFIFOB(fd, cursor - 1)); + return 1; + } - inter_accreg_tosql(RFIFOL(fd,4),RFIFOL(fd,8),reg, RFIFOB(fd,12)); - mapif_account_reg(fd,RFIFOP(fd,0)); // Send updated accounts to other map servers. + } + + global_accreg_to_login_send(); + } return 0; } diff --git a/src/char/inter.h b/src/char/inter.h index 88501c9a0..b484a1610 100644 --- a/src/char/inter.h +++ b/src/char/inter.h @@ -2,8 +2,8 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _INTER_SQL_H_ -#define _INTER_SQL_H_ +#ifndef _CHAR_INTER_H_ +#define _CHAR_INTER_H_ struct accreg; #include "../common/sql.h" @@ -15,6 +15,7 @@ int inter_parse_frommap(int fd); int inter_mapif_init(int fd); int mapif_send_gmaccounts(void); int mapif_disconnectplayer(int fd, int account_id, int char_id, int reason); +void mapif_parse_accinfo2(bool success, int map_fd, int u_fd, int u_aid, int account_id, const char *userid, const char *user_pass, const char *email, const char *last_ip, const char *lastlogin, const char *pin_code, const char *birthdate, int group_id, int logincount, int state); int inter_log(char *fmt,...); int inter_vlog(char *fmt, va_list ap); @@ -30,16 +31,15 @@ int inter_accreg_tosql(int account_id, int char_id, struct accreg *reg, int type uint64 inter_chk_lastuid(int8 flag, uint64 value); #ifdef NSI_UNIQUE_ID - #define updateLastUid(val_) inter_chk_lastuid(1, val_) - #define dbUpdateUid(handler_)\ - { \ + #define updateLastUid(val_) inter_chk_lastuid(1, (val_)) + #define dbUpdateUid(handler_) do { \ uint64 unique_id_ = inter_chk_lastuid(0, 0); \ - if (unique_id_ && SQL_ERROR == SQL->Query(handler_, "UPDATE `%s` SET `value`='%"PRIu64"' WHERE `varname`='unique_id'", interreg_db, unique_id_)) \ + if (unique_id_ && SQL_ERROR == SQL->Query((handler_), "UPDATE `%s` SET `value`='%"PRIu64"' WHERE `varname`='unique_id'", interreg_db, unique_id_)) \ Sql_ShowDebug(handler_);\ - } + } while(0) #else #define dbUpdateUid(handler_) #define updateLastUid(val_) #endif -#endif /* _INTER_SQL_H_ */ +#endif /* _CHAR_INTER_H_ */ diff --git a/src/char/pincode.h b/src/char/pincode.h index a17f70de5..3b71eec7c 100644 --- a/src/char/pincode.h +++ b/src/char/pincode.h @@ -2,8 +2,8 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _PINCODE_H_ -#define _PINCODE_H_ +#ifndef _CHAR_PINCODE_H_ +#define _CHAR_PINCODE_H_ #include "char.h" @@ -40,4 +40,4 @@ struct pincode_interface *pincode; void pincode_defaults(void); -#endif /* _PINCODE_H_ */ +#endif /* _CHAR_PINCODE_H_ */ diff --git a/src/common/HPM.c b/src/common/HPM.c index 8be9298f9..bd2ce93ab 100644 --- a/src/common/HPM.c +++ b/src/common/HPM.c @@ -108,6 +108,7 @@ bool hplugin_populate(struct hplugin *plugin, const char *filename) { return true; } +#undef HPM_POP struct hplugin *hplugin_load(const char* filename) { struct hplugin *plugin; struct hplugin_info *info; @@ -115,6 +116,8 @@ struct hplugin *hplugin_load(const char* filename) { bool anyEvent = false; void **import_symbol_ref; Sql **sql_handle; + unsigned int *HPMDataCheckLen; + struct s_HPMDataCheck *HPMDataCheck; if( HPM->exists(filename) ) { ShowWarning("HPM:plugin_load: attempting to load duplicate '"CL_WHITE"%s"CL_RESET"', skipping...\n", filename); @@ -190,6 +193,9 @@ struct hplugin *hplugin_load(const char* filename) { if( ( plugin->hpi->event[HPET_POST_FINAL] = plugin_import(plugin->dll, "server_post_final",void (*)(void)) ) ) anyEvent = true; + if( ( plugin->hpi->event[HPET_PRE_INIT] = plugin_import(plugin->dll, "server_preinit",void (*)(void)) ) ) + anyEvent = true; + if( !anyEvent ) { ShowWarning("HPM:plugin_load: no events found for '"CL_WHITE"%s"CL_RESET"', skipping...\n", filename); HPM->unload(plugin); @@ -199,17 +205,37 @@ struct hplugin *hplugin_load(const char* filename) { if( !HPM->populate(plugin,filename) ) return NULL; + if( !( HPMDataCheckLen = plugin_import(plugin->dll, "HPMDataCheckLen", unsigned int *) ) ) { + ShowWarning("HPM:plugin_load: failed to retrieve 'HPMDataCheckLen' for '"CL_WHITE"%s"CL_RESET"', most likely not including HPMDataCheck.h, skipping...\n", filename); + HPM->unload(plugin); + return NULL; + } + + if( !( HPMDataCheck = plugin_import(plugin->dll, "HPMDataCheck", struct s_HPMDataCheck *) ) ) { + ShowWarning("HPM:plugin_load: failed to retrieve 'HPMDataCheck' for '"CL_WHITE"%s"CL_RESET"', most likely not including HPMDataCheck.h, skipping...\n", filename); + HPM->unload(plugin); + return NULL; + } + + if( HPM->DataCheck && !HPM->DataCheck(HPMDataCheck,*HPMDataCheckLen,plugin->info->name) ) { + ShowWarning("HPM:plugin_load: '"CL_WHITE"%s"CL_RESET"' failed DataCheck, out of sync from the core (recompile plugin), skipping...\n", filename); + HPM->unload(plugin); + return NULL; + } + /* id */ - plugin->hpi->pid = plugin->idx; + plugin->hpi->pid = plugin->idx; /* core */ - plugin->hpi->addCPCommand = HPM->import_symbol("addCPCommand",plugin->idx); - plugin->hpi->addPacket = HPM->import_symbol("addPacket",plugin->idx); - plugin->hpi->addToSession = HPM->import_symbol("addToSession",plugin->idx); - plugin->hpi->getFromSession = HPM->import_symbol("getFromSession",plugin->idx); - plugin->hpi->removeFromSession = HPM->import_symbol("removeFromSession",plugin->idx); - plugin->hpi->AddHook = HPM->import_symbol("AddHook",plugin->idx); - plugin->hpi->HookStop = HPM->import_symbol("HookStop",plugin->idx); - plugin->hpi->HookStopped = HPM->import_symbol("HookStopped",plugin->idx); + plugin->hpi->addCPCommand = HPM->import_symbol("addCPCommand",plugin->idx); + plugin->hpi->addPacket = HPM->import_symbol("addPacket",plugin->idx); + plugin->hpi->addToHPData = HPM->import_symbol("addToHPData",plugin->idx); + plugin->hpi->getFromHPData = HPM->import_symbol("getFromHPData",plugin->idx); + plugin->hpi->removeFromHPData = HPM->import_symbol("removeFromHPData",plugin->idx); + plugin->hpi->AddHook = HPM->import_symbol("AddHook",plugin->idx); + plugin->hpi->HookStop = HPM->import_symbol("HookStop",plugin->idx); + plugin->hpi->HookStopped = HPM->import_symbol("HookStopped",plugin->idx); + plugin->hpi->addArg = HPM->import_symbol("addArg",plugin->idx); + plugin->hpi->addConf = HPM->import_symbol("addConf",plugin->idx); /* server specific */ if( HPM->load_sub ) HPM->load_sub(plugin); @@ -247,22 +273,35 @@ void hplugins_config_read(void) { config_t plugins_conf; config_setting_t *plist = NULL; const char *config_filename = "conf/plugins.conf"; // FIXME hardcoded name + FILE *fp; - if (conf_read_file(&plugins_conf, config_filename)) +// uncomment once login/char support is wrapped up +// if( !HPM->DataCheck ) { +// ShowError("HPM:config_read: HPM->DataCheck not set! Failure\n"); +// return; +// } + + /* yes its ugly, its temporary and will be gone as soon as the new inter-server.conf is set */ + if( (fp = fopen("conf/import/plugins.conf","r")) ) { + config_filename = "conf/import/plugins.conf"; + fclose(fp); + } + + if (libconfig->read_file(&plugins_conf, config_filename)) return; if( HPM->symbol_defaults_sub ) HPM->symbol_defaults_sub(); - plist = config_lookup(&plugins_conf, "plugins_list"); + plist = libconfig->lookup(&plugins_conf, "plugins_list"); if (plist != NULL) { - int length = config_setting_length(plist), i; + int length = libconfig->setting_length(plist), i; char filename[60]; for(i = 0; i < length; i++) { - if( !strcmpi(config_setting_get_string_elem(plist,i),"HPMHooking") ) {//must load it first + if( !strcmpi(libconfig->setting_get_string_elem(plist,i),"HPMHooking") ) {//must load it first struct hplugin *plugin; - snprintf(filename, 60, "plugins/%s%s", config_setting_get_string_elem(plist,i), DLL_EXT); + snprintf(filename, 60, "plugins/%s%s", libconfig->setting_get_string_elem(plist,i), DLL_EXT); if( ( plugin = HPM->load(filename) ) ) { bool (*func)(bool *fr); bool (*addhook_sub) (enum HPluginHookType type, const char *target, void *hook, unsigned int pID); @@ -276,12 +315,12 @@ void hplugins_config_read(void) { } } for(i = 0; i < length; i++) { - if( strcmpi(config_setting_get_string_elem(plist,i),"HPMHooking") ) {//now all others - snprintf(filename, 60, "plugins/%s%s", config_setting_get_string_elem(plist,i), DLL_EXT); + if( strcmpi(libconfig->setting_get_string_elem(plist,i),"HPMHooking") ) {//now all others + snprintf(filename, 60, "plugins/%s%s", libconfig->setting_get_string_elem(plist,i), DLL_EXT); HPM->load(filename); } } - config_destroy(&plugins_conf); + libconfig->destroy(&plugins_conf); } if( HPM->plugin_count ) @@ -300,67 +339,131 @@ CPCMD(plugins) { } } } +void hplugins_grabHPData(struct HPDataOperationStorage *ret, enum HPluginDataTypes type, void *ptr) { + /* record address */ + switch( type ) { + /* core-handled */ + case HPDT_SESSION: + ret->HPDataSRCPtr = (void**)(&((struct socket_data *)ptr)->hdata); + ret->hdatac = &((struct socket_data *)ptr)->hdatac; + break; + /* goes to sub */ + default: + if( HPM->grabHPDataSub ) { + if( HPM->grabHPDataSub(ret,type,ptr) ) + return; + else { + ShowError("HPM:HPM:grabHPData failed, unknown type %d!\n",type); + } + } else + ShowError("HPM:grabHPData failed, type %d needs sub-handler!\n",type); + ret->HPDataSRCPtr = NULL; + ret->hdatac = NULL; + return; + } +} +void hplugins_addToHPData(enum HPluginDataTypes type, unsigned int pluginID, void *ptr, void *data, unsigned int index, bool autofree) { + struct HPluginData *HPData, **HPDataSRC; + struct HPDataOperationStorage action; + unsigned int i, max; + + HPM->grabHPData(&action,type,ptr); -void hplugins_addToSession(struct socket_data *sess, void *data, unsigned int id, unsigned int type, bool autofree) { - struct HPluginData *HPData; - unsigned int i; + if( action.hdatac == NULL ) { /* woo it failed! */ + ShowError("HPM:addToHPData:%s: failed, type %d (%u|%u)\n",HPM->pid2name(pluginID),type,pluginID,index); + return; + } + + /* flag */ + HPDataSRC = *(action.HPDataSRCPtr); + max = *(action.hdatac); - for(i = 0; i < sess->hdatac; i++) { - if( sess->hdata[i]->pluginID == id && sess->hdata[i]->type == type ) { - ShowError("HPM->addToSession:%s: error! attempting to insert duplicate struct of id %u and type %u\n",HPM->pid2name(id),id,type); + /* duplicate check */ + for(i = 0; i < max; i++) { + if( HPDataSRC[i]->pluginID == pluginID && HPDataSRC[i]->type == index ) { + ShowError("HPM:addToHPData:%s: error! attempting to insert duplicate struct of id %u and index %u\n",HPM->pid2name(pluginID),pluginID,index); return; } } - //HPluginData is always same size, probably better to use the ERS + /* HPluginData is always same size, probably better to use the ERS (with reasonable chunk size e.g. 10/25/50) */ CREATE(HPData, struct HPluginData, 1); - HPData->pluginID = id; - HPData->type = type; + /* input */ + HPData->pluginID = pluginID; + HPData->type = index; HPData->flag.free = autofree ? 1 : 0; HPData->data = data; - RECREATE(sess->hdata,struct HPluginData *,++sess->hdatac); - sess->hdata[sess->hdatac - 1] = HPData; + /* resize */ + *(action.hdatac) += 1; + RECREATE(*(action.HPDataSRCPtr),struct HPluginData *,*(action.hdatac)); + + /* RECREATE modified the addresss */ + HPDataSRC = *(action.HPDataSRCPtr); + HPDataSRC[*(action.hdatac) - 1] = HPData; } -void *hplugins_getFromSession(struct socket_data *sess, unsigned int id, unsigned int type) { - unsigned int i; + +void *hplugins_getFromHPData(enum HPluginDataTypes type, unsigned int pluginID, void *ptr, unsigned int index) { + struct HPDataOperationStorage action; + struct HPluginData **HPDataSRC; + unsigned int i, max; - for(i = 0; i < sess->hdatac; i++) { - if( sess->hdata[i]->pluginID == id && sess->hdata[i]->type == type ) { - break; - } + HPM->grabHPData(&action,type,ptr); + + if( action.hdatac == NULL ) { /* woo it failed! */ + ShowError("HPM:getFromHPData:%s: failed, type %d (%u|%u)\n",HPM->pid2name(pluginID),type,pluginID,index); + return NULL; } - if( i != sess->hdatac ) - return sess->hdata[i]->data; + /* flag */ + HPDataSRC = *(action.HPDataSRCPtr); + max = *(action.hdatac); + for(i = 0; i < max; i++) { + if( HPDataSRC[i]->pluginID == pluginID && HPDataSRC[i]->type == index ) + return HPDataSRC[i]->data; + } + return NULL; } -void hplugins_removeFromSession(struct socket_data *sess, unsigned int id, unsigned int type) { - unsigned int i; + +void hplugins_removeFromHPData(enum HPluginDataTypes type, unsigned int pluginID, void *ptr, unsigned int index) { + struct HPDataOperationStorage action; + struct HPluginData **HPDataSRC; + unsigned int i, max; + + HPM->grabHPData(&action,type,ptr); + + if( action.hdatac == NULL ) { /* woo it failed! */ + ShowError("HPM:removeFromHPData:%s: failed, type %d (%u|%u)\n",HPM->pid2name(pluginID),type,pluginID,index); + return; + } - for(i = 0; i < sess->hdatac; i++) { - if( sess->hdata[i]->pluginID == id && sess->hdata[i]->type == type ) { + /* flag */ + HPDataSRC = *(action.HPDataSRCPtr); + max = *(action.hdatac); + + for(i = 0; i < max; i++) { + if( HPDataSRC[i]->pluginID == pluginID && HPDataSRC[i]->type == index ) break; - } } - if( i != sess->hdatac ) { + if( i != max ) { unsigned int cursor; - - aFree(sess->hdata[i]->data); - aFree(sess->hdata[i]); - sess->hdata[i] = NULL; - for(i = 0, cursor = 0; i < sess->hdatac; i++) { - if( sess->hdata[i] == NULL ) + aFree(HPDataSRC[i]->data);/* when its removed we delete it regardless of autofree */ + aFree(HPDataSRC[i]); + HPDataSRC[i] = NULL; + + for(i = 0, cursor = 0; i < max; i++) { + if( HPDataSRC[i] == NULL ) continue; if( i != cursor ) - sess->hdata[cursor] = sess->hdata[i]; + HPDataSRC[cursor] = HPDataSRC[i]; cursor++; } - sess->hdatac = cursor; + *(action.hdatac) = cursor; } } @@ -458,6 +561,9 @@ void* HPM_calloc(size_t num, size_t size, const char *file, int line, const char void* HPM_realloc(void *p, size_t size, const char *file, int line, const char *func) { return iMalloc->realloc(p,size,HPM_file2ptr(file),line,func); } +void* HPM_reallocz(void *p, size_t size, const char *file, int line, const char *func) { + return iMalloc->reallocz(p,size,HPM_file2ptr(file),line,func); +} char* HPM_astrdup(const char *p, const char *file, int line, const char *func) { return iMalloc->astrdup(p,HPM_file2ptr(file),line,func); } @@ -471,6 +577,9 @@ bool HPM_AddHook(enum HPluginHookType type, const char *target, void *hook, unsi /* if not check if a sub-hooking list is available (from the server) and run it by */ if( HPM->addhook_sub && HPM->addhook_sub(type,target,hook,pID) ) return true; + + ShowError("HPM:AddHook: unknown Hooking Point '%s'!\n",target); + return false; } void HPM_HookStop (const char *func, unsigned int pID) { @@ -480,6 +589,93 @@ void HPM_HookStop (const char *func, unsigned int pID) { bool HPM_HookStopped (void) { return HPM->force_return; } +/* command-line args */ +bool hpm_parse_arg(const char *arg, int *index, char *argv[], bool param) { + struct HPMArgData *data; + + if( (data = strdb_get(HPM->arg_db,arg)) ) { + data->func((data->has_param && param)?argv[(*index)+1]:NULL); + if( data->has_param && param ) *index += 1; + return true; + } + + return false; +} +void hpm_arg_help(void) { + DBIterator *iter = db_iterator(HPM->arg_db); + struct HPMArgData *data = NULL; + + for( data = dbi_first(iter); dbi_exists(iter); data = dbi_next(iter) ) { + if( data->help != NULL ) + data->help(); + else + ShowInfo(" %s (%s)\t\t<no description provided>\n",data->name,HPM->pid2name(data->pluginID)); + } + + dbi_destroy(iter); +} +bool hpm_add_arg(unsigned int pluginID, char *name, bool has_param, void (*func) (char *param),void (*help) (void)) { + struct HPMArgData *data = NULL; + + if( strdb_exists(HPM->arg_db, name) ) { + ShowError("HPM:add_arg:%s duplicate! (from %s)\n",name,HPM->pid2name(pluginID)); + return false; + } + + CREATE(data, struct HPMArgData, 1); + + data->pluginID = pluginID; + data->name = aStrdup(name); + data->func = func; + data->help = help; + data->has_param = has_param; + + strdb_put(HPM->arg_db, data->name, data); + + return true; +} +bool hplugins_addconf(unsigned int pluginID, enum HPluginConfType type, char *name, void (*func) (const char *val)) { + struct HPConfListenStorage *conf; + unsigned int i; + + if( type >= HPCT_MAX ) { + ShowError("HPM->addConf:%s: unknown point '%u' specified for config '%s'\n",HPM->pid2name(pluginID),type,name); + return false; + } + + for(i = 0; i < HPM->confsc[type]; i++) { + if( !strcmpi(name,HPM->confs[type][i].key) ) { + ShowError("HPM->addConf:%s: duplicate '%s', already in use by '%s'!",HPM->pid2name(pluginID),name,HPM->pid2name(HPM->confs[type][i].pluginID)); + return false; + } + } + + RECREATE(HPM->confs[type], struct HPConfListenStorage, ++HPM->confsc[type]); + conf = &HPM->confs[type][HPM->confsc[type] - 1]; + + conf->pluginID = pluginID; + safestrncpy(conf->key, name, HPM_ADDCONF_LENGTH); + conf->func = func; + + return true; +} +bool hplugins_parse_conf(const char *w1, const char *w2, enum HPluginConfType point) { + unsigned int i; + + /* exists? */ + for(i = 0; i < HPM->confsc[point]; i++) { + if( !strcmpi(w1,HPM->confs[point][i].key) ) + break; + } + + /* trigger and we're set! */ + if( i != HPM->confsc[point] ) { + HPM->confs[point][i].func(w2); + return true; + } + + return false; +} void hplugins_share_defaults(void) { /* console */ @@ -488,12 +684,14 @@ void hplugins_share_defaults(void) { #endif /* our own */ HPM->share(hplugins_addpacket,"addPacket"); - HPM->share(hplugins_addToSession,"addToSession"); - HPM->share(hplugins_getFromSession,"getFromSession"); - HPM->share(hplugins_removeFromSession,"removeFromSession"); + HPM->share(hplugins_addToHPData,"addToHPData"); + HPM->share(hplugins_getFromHPData,"getFromHPData"); + HPM->share(hplugins_removeFromHPData,"removeFromHPData"); HPM->share(HPM_AddHook,"AddHook"); HPM->share(HPM_HookStop,"HookStop"); HPM->share(HPM_HookStopped,"HookStopped"); + HPM->share(hpm_add_arg,"addArg"); + HPM->share(hplugins_addconf,"addConf"); /* core */ HPM->share(&runflag,"runflag"); HPM->share(arg_v,"arg_v"); @@ -505,11 +703,7 @@ void hplugins_share_defaults(void) { HPM->share(DB, "DB"); HPM->share(HPMiMalloc, "iMalloc"); /* socket */ - HPM->share(RFIFOSKIP,"RFIFOSKIP"); - HPM->share(WFIFOSET,"WFIFOSET"); - HPM->share(do_close,"do_close"); - HPM->share(make_connection,"make_connection"); - //session,fd_max and addr_ are shared from within socket.c + HPM->share(sockt,"sockt"); /* strlib */ HPM->share(strlib,"strlib"); HPM->share(sv,"sv"); @@ -518,7 +712,8 @@ void hplugins_share_defaults(void) { HPM->share(SQL,"SQL"); /* timer */ HPM->share(timer,"timer"); - + /* libconfig */ + HPM->share(libconfig,"libconfig"); } void hpm_init(void) { @@ -534,6 +729,7 @@ void hpm_init(void) { HPMiMalloc->malloc = HPM_mmalloc; HPMiMalloc->calloc = HPM_calloc; HPMiMalloc->realloc = HPM_realloc; + HPMiMalloc->reallocz = HPM_reallocz; HPMiMalloc->astrdup = HPM_astrdup; sscanf(HPM_VERSION, "%u.%u", &HPM->version[0], &HPM->version[1]); @@ -548,6 +744,8 @@ void hpm_init(void) { HPM->packetsc[i] = 0; } + HPM->arg_db = strdb_alloc(DB_OPT_RELEASE_DATA, 0); + HPM->symbol_defaults(); #ifdef CONSOLE_INPUT @@ -566,6 +764,14 @@ void hpm_memdown(void) { if( HPM->fnames ) free(HPM->fnames); + +} +int hpm_arg_db_clear_sub(DBKey key, DBData *data, va_list args) { + struct HPMArgData *a = DB->data2ptr(data); + + aFree(a->name); + + return 0; } void hpm_final(void) { unsigned int i; @@ -591,19 +797,39 @@ void hpm_final(void) { aFree(HPM->packets[i]); } + for( i = 0; i < HPCT_MAX; i++ ) { + if( HPM->confsc[i] ) + aFree(HPM->confs[i]); + } + + HPM->arg_db->destroy(HPM->arg_db,HPM->arg_db_clear_sub); + /* HPM->fnames is cleared after the memory manager goes down */ iMalloc->post_shutdown = hpm_memdown; return; } void hpm_defaults(void) { + unsigned int i; HPM = &HPM_s; HPM->fnames = NULL; HPM->fnamec = 0; HPM->force_return = false; HPM->hooking = false; - + /* */ + HPM->fnames = NULL; + HPM->fnamec = 0; + for(i = 0; i < hpPHP_MAX; i++) { + HPM->packets[i] = NULL; + HPM->packetsc[i] = 0; + } + for(i = 0; i < HPCT_MAX; i++) { + HPM->confs[i] = NULL; + HPM->confsc[i] = 0; + } + HPM->arg_db = NULL; + /* */ HPM->init = hpm_init; HPM->final = hpm_final; @@ -623,4 +849,11 @@ void hpm_defaults(void) { HPM->parse_packets = hplugins_parse_packets; HPM->load_sub = NULL; HPM->addhook_sub = NULL; + HPM->arg_db_clear_sub = hpm_arg_db_clear_sub; + HPM->parse_arg = hpm_parse_arg; + HPM->arg_help = hpm_arg_help; + HPM->grabHPData = hplugins_grabHPData; + HPM->grabHPDataSub = NULL; + HPM->parseConf = hplugins_parse_conf; + HPM->DataCheck = NULL; } diff --git a/src/common/HPM.h b/src/common/HPM.h index 395555948..52ad24a03 100644 --- a/src/common/HPM.h +++ b/src/common/HPM.h @@ -1,8 +1,8 @@ // Copyright (c) Hercules Dev Team, licensed under GNU GPL. // See the LICENSE file -#ifndef _HPM_H_ -#define _HPM_H_ +#ifndef _COMMON_HPM_H_ +#define _COMMON_HPM_H_ #include "../common/cbasetypes.h" #include "../common/HPMi.h" @@ -12,29 +12,31 @@ #define WIN32_LEAN_AND_MEAN #endif #include <windows.h> - #define plugin_open(x) LoadLibraryA(x) - #define plugin_import(x,y,z) (z)GetProcAddress(x,y) - #define plugin_close(x) FreeLibrary(x) + #define plugin_open(x) LoadLibraryA(x) + #define plugin_import(x,y,z) (z)GetProcAddress((x),(y)) + #define plugin_close(x) FreeLibrary(x) - #define DLL_EXT ".dll" - #define DLL HINSTANCE + #define DLL_EXT ".dll" + #define DLL HINSTANCE #else // ! WIN32 #include <dlfcn.h> #ifdef RTLD_DEEPBIND // Certain linux ditributions require this, but it's not available everywhere - #define plugin_open(x) dlopen(x,RTLD_NOW|RTLD_DEEPBIND) + #define plugin_open(x) dlopen((x),RTLD_NOW|RTLD_DEEPBIND) #else // ! RTLD_DEEPBIND - #define plugin_open(x) dlopen(x,RTLD_NOW) + #define plugin_open(x) dlopen((x),RTLD_NOW) #endif // RTLD_DEEPBIND - #define plugin_import(x,y,z) (z)dlsym(x,y) - #define plugin_close(x) dlclose(x) + #define plugin_import(x,y,z) (z)dlsym((x),(y)) + #define plugin_close(x) dlclose(x) - #ifdef CYGWIN - #define DLL_EXT ".dll" + #if defined CYGWIN + #define DLL_EXT ".dll" + #elif defined __DARWIN__ + #define DLL_EXT ".dylib" #else - #define DLL_EXT ".so" + #define DLL_EXT ".so" #endif - #define DLL void * + #define DLL void * #include <string.h> // size_t @@ -74,6 +76,25 @@ struct HPMFileNameCache { char *name; }; +struct HPMArgData { + unsigned int pluginID; + char *name;/* e.g. "--my-arg","-v","--whatever" */ + void (*help) (void);/* to display when --help is used */ + void (*func) (char *param);/* NULL when no param is available */ + bool has_param;/* because of the weird "--arg<space>param" instead of the "--arg=param" */ +}; + +struct HPDataOperationStorage { + void **HPDataSRCPtr; + unsigned int *hdatac; +}; +/* */ +struct HPConfListenStorage { + unsigned int pluginID; + char key[HPM_ADDCONF_LENGTH]; + void (*func) (const char *val); +}; + /* Hercules Plugin Manager Interface */ struct HPM_interface { /* vars */ @@ -93,6 +114,11 @@ struct HPM_interface { /* plugin file ptr caching */ struct HPMFileNameCache *fnames; unsigned int fnamec; + /* config listen */ + struct HPConfListenStorage *confs[HPCT_MAX]; + unsigned int confsc[HPCT_MAX]; + /* --command-line */ + DBMap *arg_db; /* funcs */ void (*init) (void); void (*final) (void); @@ -112,10 +138,20 @@ struct HPM_interface { unsigned char (*parse_packets) (int fd, enum HPluginPacketHookingPoints point); void (*load_sub) (struct hplugin *plugin); bool (*addhook_sub) (enum HPluginHookType type, const char *target, void *hook, unsigned int pID); + bool (*parse_arg) (const char *arg, int* index, char *argv[], bool param); + void (*arg_help) (void); + int (*arg_db_clear_sub) (DBKey key, DBData *data, va_list args); + void (*grabHPData) (struct HPDataOperationStorage *ret, enum HPluginDataTypes type, void *ptr); + /* for server-specific HPData e.g. map_session_data */ + bool (*grabHPDataSub) (struct HPDataOperationStorage *ret, enum HPluginDataTypes type, void *ptr); + /* for custom config parsing */ + bool (*parseConf) (const char *w1, const char *w2, enum HPluginConfType point); + /* validates plugin data */ + bool (*DataCheck) (struct s_HPMDataCheck *src, unsigned int size, char *name); } HPM_s; struct HPM_interface *HPM; void hpm_defaults(void); -#endif /* _HPM_H_ */ +#endif /* _COMMON_HPM_H_ */ diff --git a/src/common/HPMDataCheck.h b/src/common/HPMDataCheck.h new file mode 100644 index 000000000..48089964d --- /dev/null +++ b/src/common/HPMDataCheck.h @@ -0,0 +1,130 @@ +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// +// NOTE: This file was auto-generated and should never be manually edited, +// as it will get overwritten. +#ifndef _HPM_DATA_CHECK_H_ +#define _HPM_DATA_CHECK_H_ + + +HPExport const struct s_HPMDataCheck HPMDataCheck[] = { + #ifdef _COMMON_CONF_H_ + { "libconfig_interface", sizeof(struct libconfig_interface) }, + #else + #define _COMMON_CONF_H_ + #endif // _COMMON_CONF_H_ + #ifdef _COMMON_DB_H_ + { "DBData", sizeof(struct DBData) }, + { "DBIterator", sizeof(struct DBIterator) }, + { "DBMap", sizeof(struct DBMap) }, + #else + #define _COMMON_DB_H_ + #endif // _COMMON_DB_H_ + #ifdef _COMMON_DES_H_ + { "BIT64", sizeof(struct BIT64) }, + #else + #define _COMMON_DES_H_ + #endif // _COMMON_DES_H_ + #ifdef _COMMON_ERS_H_ + { "eri", sizeof(struct eri) }, + #else + #define _COMMON_ERS_H_ + #endif // _COMMON_ERS_H_ + #ifdef _COMMON_MAPINDEX_H_ + { "mapindex_interface", sizeof(struct mapindex_interface) }, + #else + #define _COMMON_MAPINDEX_H_ + #endif // _COMMON_MAPINDEX_H_ + #ifdef _COMMON_MMO_H_ + { "quest", sizeof(struct quest) }, + #else + #define _COMMON_MMO_H_ + #endif // _COMMON_MMO_H_ + #ifdef _COMMON_SOCKET_H_ + { "socket_interface", sizeof(struct socket_interface) }, + #else + #define _COMMON_SOCKET_H_ + #endif // _COMMON_SOCKET_H_ + #ifdef _COMMON_STRLIB_H_ + { "StringBuf", sizeof(struct StringBuf) }, + { "s_svstate", sizeof(struct s_svstate) }, + #else + #define _COMMON_STRLIB_H_ + #endif // _COMMON_STRLIB_H_ + #ifdef _MAP_ATCOMMAND_H_ + { "AliasInfo", sizeof(struct AliasInfo) }, + { "atcommand_interface", sizeof(struct atcommand_interface) }, + #else + #define _MAP_ATCOMMAND_H_ + #endif // _MAP_ATCOMMAND_H_ + #ifdef _MAP_BATTLE_H_ + { "Damage", sizeof(struct Damage) }, + { "battle_interface", sizeof(struct battle_interface) }, + #else + #define _MAP_BATTLE_H_ + #endif // _MAP_BATTLE_H_ + #ifdef _MAP_BUYINGSTORE_H_ + { "buyingstore_interface", sizeof(struct buyingstore_interface) }, + { "s_buyingstore_item", sizeof(struct s_buyingstore_item) }, + #else + #define _MAP_BUYINGSTORE_H_ + #endif // _MAP_BUYINGSTORE_H_ + #ifdef _MAP_CHRIF_H_ + { "auth_node", sizeof(struct auth_node) }, + #else + #define _MAP_CHRIF_H_ + #endif // _MAP_CHRIF_H_ + #ifdef _MAP_CLIF_H_ + { "clif_interface", sizeof(struct clif_interface) }, + #else + #define _MAP_CLIF_H_ + #endif // _MAP_CLIF_H_ + #ifdef _MAP_ELEMENTAL_H_ + { "elemental_skill", sizeof(struct elemental_skill) }, + #else + #define _MAP_ELEMENTAL_H_ + #endif // _MAP_ELEMENTAL_H_ + #ifdef _MAP_GUILD_H_ + { "eventlist", sizeof(struct eventlist) }, + #else + #define _MAP_GUILD_H_ + #endif // _MAP_GUILD_H_ + #ifdef _MAP_MAP_H_ + { "map_data_other_server", sizeof(struct map_data_other_server) }, + #else + #define _MAP_MAP_H_ + #endif // _MAP_MAP_H_ + #ifdef _MAP_PACKETS_STRUCT_H_ + { "EQUIPSLOTINFO", sizeof(struct EQUIPSLOTINFO) }, + #else + #define _MAP_PACKETS_STRUCT_H_ + #endif // _MAP_PACKETS_STRUCT_H_ + #ifdef _MAP_PC_H_ + { "autotrade_vending", sizeof(struct autotrade_vending) }, + { "item_cd", sizeof(struct item_cd) }, + #else + #define _MAP_PC_H_ + #endif // _MAP_PC_H_ + #ifdef _MAP_SCRIPT_H_ + { "Script_Config", sizeof(struct Script_Config) }, + { "script_interface", sizeof(struct script_interface) }, + #else + #define _MAP_SCRIPT_H_ + #endif // _MAP_SCRIPT_H_ + #ifdef _MAP_SEARCHSTORE_H_ + { "searchstore_interface", sizeof(struct searchstore_interface) }, + #else + #define _MAP_SEARCHSTORE_H_ + #endif // _MAP_SEARCHSTORE_H_ + #ifdef _MAP_SKILL_H_ + { "skill_cd", sizeof(struct skill_cd) }, + { "skill_condition", sizeof(struct skill_condition) }, + { "skill_interface", sizeof(struct skill_interface) }, + { "skill_unit_save", sizeof(struct skill_unit_save) }, + #else + #define _MAP_SKILL_H_ + #endif // _MAP_SKILL_H_ +}; +HPExport unsigned int HPMDataCheckLen = ARRAYLENGTH(HPMDataCheck); + +#endif /* _HPM_DATA_CHECK_H_ */ diff --git a/src/common/HPMi.h b/src/common/HPMi.h index 9c2a6184e..95037fd14 100644 --- a/src/common/HPMi.h +++ b/src/common/HPMi.h @@ -1,8 +1,8 @@ // Copyright (c) Hercules Dev Team, licensed under GNU GPL. // See the LICENSE file -#ifndef _HPMi_H_ -#define _HPMi_H_ +#ifndef _COMMON_HPMI_H_ +#define _COMMON_HPMI_H_ #include "../common/cbasetypes.h" #include "../common/core.h" @@ -20,7 +20,7 @@ struct map_session_data; #define HPExport #endif -#ifndef _SHOWMSG_H_ +#ifndef _COMMON_SHOWMSG_H_ HPExport void (*ShowMessage) (const char *, ...); HPExport void (*ShowStatus) (const char *, ...); HPExport void (*ShowSQL) (const char *, ...); @@ -36,6 +36,7 @@ struct map_session_data; #include "../common/showmsg.h" #define HPM_VERSION "1.0" +#define HPM_ADDCONF_LENGTH 40 struct hplugin_info { char* name; @@ -44,18 +45,24 @@ struct hplugin_info { char* req_version; }; +struct s_HPMDataCheck { + char *name; + unsigned int size; +}; + HPExport void *(*import_symbol) (char *name, unsigned int pID); HPExport Sql *mysql_handle; -#define GET_SYMBOL(n) import_symbol(n,HPMi->pid) +#define GET_SYMBOL(n) import_symbol((n),HPMi->pid) -#define SERVER_TYPE_ALL SERVER_TYPE_LOGIN|SERVER_TYPE_CHAR|SERVER_TYPE_MAP +#define SERVER_TYPE_ALL (SERVER_TYPE_LOGIN|SERVER_TYPE_CHAR|SERVER_TYPE_MAP) enum hp_event_types { HPET_INIT,/* server starts */ HPET_FINAL,/* server is shutting down */ HPET_READY,/* server is ready (online) */ HPET_POST_FINAL,/* server is done shutting down */ + HPET_PRE_INIT,/* server is about to start (used to e.g. add custom "--args" handling) */ HPET_MAX, }; @@ -76,12 +83,88 @@ enum HPluginHookType { HOOK_TYPE_POST, }; -#define addHookPre(tname,hook) HPMi->AddHook(HOOK_TYPE_PRE,tname,hook,HPMi->pid) -#define addHookPost(tname,hook) HPMi->AddHook(HOOK_TYPE_POST,tname,hook,HPMi->pid) +enum HPluginDataTypes { + HPDT_SESSION, + HPDT_MSD, + HPDT_NPCD, + HPDT_MAP, + HPDT_INSTANCE, + HPDT_GUILD, + HPDT_PARTY, +}; + +/* used in macros and conf storage */ +enum HPluginConfType { + HPCT_BATTLE, /* battle-conf (map-server */ + HPCT_MAX, +}; + +#define addHookPre(tname,hook) (HPMi->AddHook(HOOK_TYPE_PRE,(tname),(hook),HPMi->pid)) +#define addHookPost(tname,hook) (HPMi->AddHook(HOOK_TYPE_POST,(tname),(hook),HPMi->pid)) /* need better names ;/ */ /* will not run the original function after pre-hook processing is complete (other hooks will run) */ -#define hookStop() HPMi->HookStop(__func__,HPMi->pid) -#define hookStopped() HPMi->HookStopped() +#define hookStop() (HPMi->HookStop(__func__,HPMi->pid)) +#define hookStopped() (HPMi->HookStopped()) + +#define addArg(name,param,func,help) (HPMi->addArg(HPMi->pid,(name),(param),(func),(help))) +/* HPData handy redirects */ +/* session[] */ +#define addToSession(ptr,data,index,autofree) (HPMi->addToHPData(HPDT_SESSION,HPMi->pid,(ptr),(data),(index),(autofree))) +#define getFromSession(ptr,index) (HPMi->getFromHPData(HPDT_SESSION,HPMi->pid,(ptr),(index))) +#define removeFromSession(ptr,index) (HPMi->removeFromHPData(HPDT_SESSION,HPMi->pid,(ptr),(index))) +/* map_session_data */ +#define addToMSD(ptr,data,index,autofree) (HPMi->addToHPData(HPDT_MSD,HPMi->pid,(ptr),(data),(index),(autofree))) +#define getFromMSD(ptr,index) (HPMi->getFromHPData(HPDT_MSD,HPMi->pid,(ptr),(index))) +#define removeFromMSD(ptr,index) (HPMi->removeFromHPData(HPDT_MSD,HPMi->pid,(ptr),(index))) +/* npc_data */ +#define addToNPCD(ptr,data,index,autofree) (HPMi->addToHPData(HPDT_NPCD,HPMi->pid,(ptr),(data),(index),(autofree))) +#define getFromNPCD(ptr,index) (HPMi->getFromHPData(HPDT_NPCD,HPMi->pid,(ptr),(index))) +#define removeFromNPCD(ptr,index) (HPMi->removeFromHPData(HPDT_NPCD,HPMi->pid,(ptr),(index))) +/* map_data */ +#define addToMAPD(ptr,data,index,autofree) (HPMi->addToHPData(HPDT_MAP,HPMi->pid,(ptr),(data),(index),(autofree))) +#define getFromMAPD(ptr,index) (HPMi->getFromHPData(HPDT_MAP,HPMi->pid,(ptr),(index))) +#define removeFromMAPD(ptr,index) (HPMi->removeFromHPData(HPDT_MAP,HPMi->pid,(ptr),(index))) +/* party_data */ +#define addToPAD(ptr,data,index,autofree) (HPMi->addToHPData(HPDT_PARTY,HPMi->pid,(ptr),(data),(index),(autofree))) +#define getFromPAD(ptr,index) (HPMi->getFromHPData(HPDT_PARTY,HPMi->pid,(ptr),(index))) +#define removeFromPAD(ptr,index) (HPMi->removeFromHPData(HPDT_PARTY,HPMi->pid,(ptr),(index))) +/* guild */ +#define addToGLD(ptr,data,index,autofree) (HPMi->addToHPData(HPDT_GUILD,HPMi->pid,(ptr),(data),(index),(autofree))) +#define getFromGLD(ptr,index) (HPMi->getFromHPData(HPDT_GUILD,HPMi->pid,(ptr),(index))) +#define removeFromGLD(ptr,index) (HPMi->removeFromHPData(HPDT_GUILD,HPMi->pid,(ptr),(index))) +/* instance_data */ +#define addToINSTD(ptr,data,index,autofree) (HPMi->addToHPData(HPDT_INSTANCE,HPMi->pid,(ptr),(data),(index),(autofree))) +#define getFromINSTD(ptr,index) (HPMi->getFromHPData(HPDT_INSTANCE,HPMi->pid,(ptr),(index))) +#define removeFromINSTD(ptr,index) (HPMi->removeFromHPData(HPDT_INSTANCE,HPMi->pid,(ptr),(index))) + +/* HPMi->addCommand */ +#define addAtcommand(cname,funcname) \ + if ( HPMi->addCommand != NULL ) { \ + HPMi->addCommand(cname,atcommand_ ## funcname); \ + } else { \ + ShowWarning("HPM (%s):addAtcommand(\"%s\",%s) failed, addCommand sub is NULL!\n",pinfo.name,cname,# funcname);\ + } +/* HPMi->addScript */ +#define addScriptCommand(cname,scinfo,funcname) \ + if ( HPMi->addScript != NULL ) { \ + HPMi->addScript(cname,scinfo,buildin_ ## funcname); \ + } else { \ + ShowWarning("HPM (%s):addScriptCommand(\"%s\",\"%s\",%s) failed, addScript sub is NULL!\n",pinfo.name,cname,scinfo,# funcname);\ + } +/* HPMi->addCPCommand */ +#define addCPCommand(cname,funcname) \ + if ( HPMi->addCPCommand != NULL ) { \ + HPMi->addCPCommand(cname,console_parse_ ## funcname); \ + } else { \ + ShowWarning("HPM (%s):addCPCommand(\"%s\",%s) failed, addCPCommand sub is NULL!\n",pinfo.name,cname,# funcname);\ + } +/* HPMi->addPacket */ +#define addPacket(cmd,len,receive,point) HPMi->addPacket(cmd,len,receive,point,HPMi->pid) +/* HPMi->addBattleConf */ +#define addBattleConf(bcname,funcname) HPMi->addConf(HPMi->pid,HPCT_BATTLE,bcname,funcname) + +/* HPMi->addPCGPermission */ +#define addGroupPermission(pcgname,maskptr) HPMi->addPCGPermission(HPMi->pid,pcgname,&maskptr) /* Hercules Plugin Mananger Include Interface */ HPExport struct HPMi_interface { @@ -92,23 +175,25 @@ HPExport struct HPMi_interface { bool (*addCommand) (char *name, bool (*func)(const int fd, struct map_session_data* sd, const char* command, const char* message,struct AtCommandInfo *info)); bool (*addScript) (char *name, char *args, bool (*func)(struct script_state *st)); void (*addCPCommand) (char *name, CParseFunc func); - /* map_session_data */ - void (*addToMSD) (struct map_session_data *sd, void *data, unsigned int id, unsigned int type, bool autofree); - void *(*getFromMSD) (struct map_session_data *sd, unsigned int id, unsigned int type); - void (*removeFromMSD) (struct map_session_data *sd, unsigned int id, unsigned int type); - /* session[] */ - void (*addToSession) (struct socket_data *sess, void *data, unsigned int id, unsigned int type, bool autofree); - void *(*getFromSession) (struct socket_data *sess, unsigned int id, unsigned int type); - void (*removeFromSession) (struct socket_data *sess, unsigned int id, unsigned int type); + /* HPM Custom Data */ + void (*addToHPData) (enum HPluginDataTypes type, unsigned int pluginID, void *ptr, void *data, unsigned int index, bool autofree); + void *(*getFromHPData) (enum HPluginDataTypes type, unsigned int pluginID, void *ptr, unsigned int index); + void (*removeFromHPData) (enum HPluginDataTypes type, unsigned int pluginID, void *ptr, unsigned int index); /* packet */ bool (*addPacket) (unsigned short cmd, unsigned short length, void (*receive)(int fd), unsigned int point, unsigned int pluginID); /* Hooking */ bool (*AddHook) (enum HPluginHookType type, const char *target, void *hook, unsigned int pID); void (*HookStop) (const char *func, unsigned int pID); bool (*HookStopped) (void); + /* program --arg/-a */ + bool (*addArg) (unsigned int pluginID, char *name, bool has_param,void (*func) (char *param),void (*help) (void)); + /* battle-config recv param */ + bool (*addConf) (unsigned int pluginID, enum HPluginConfType type, char *name, void (*func) (const char *val)); + /* pc group permission */ + void (*addPCGPermission) (unsigned int pluginID, char *name, unsigned int *mask); } HPMi_s; -#ifndef _HPM_H_ +#ifndef _COMMON_HPM_H_ HPExport struct HPMi_interface *HPMi; #endif -#endif /* _HPMi_H_ */ +#endif /* _COMMON_HPMI_H_ */ diff --git a/src/common/Makefile.in b/src/common/Makefile.in index 53b7a472e..7bb9ae630 100644 --- a/src/common/Makefile.in +++ b/src/common/Makefile.in @@ -1,31 +1,37 @@ -MT19937AR_D = ../../3rdparty/mt19937ar -MT19937AR_OBJ = $(MT19937AR_D)/mt19937ar.o -MT19937AR_H = $(MT19937AR_D)/mt19937ar.h -MT19937AR_INCLUDE = -I$(MT19937AR_D) +CONFIG_D = ../config +CONFIG_H = $(wildcard $(CONFIG_D)/*.h) $(wildcard $(CONFIG_D)/*/*.h) LIBCONFIG_D = ../../3rdparty/libconfig LIBCONFIG_OBJ = $(addprefix $(LIBCONFIG_D)/, libconfig.o grammar.o scanctx.o \ - scanner.o strbuf.o) + scanner.o strbuf.o) LIBCONFIG_H = $(addprefix $(LIBCONFIG_D)/, libconfig.h grammar.h parsectx.h \ - scanctx.h scanner.h strbuf.h wincompat.h) + scanctx.h scanner.h strbuf.h wincompat.h) LIBCONFIG_INCLUDE = -I$(LIBCONFIG_D) -COMMON_SHARED_OBJ = conf.o db.o des.o ers.o grfio.o HPM.o mapindex.o \ - md5calc.o mempool.o mutex.o nullpo.o raconf.o random.o \ - showmsg.o strlib.o thread.o timer.o utils.o +MT19937AR_D = ../../3rdparty/mt19937ar +MT19937AR_OBJ = $(MT19937AR_D)/mt19937ar.o +MT19937AR_H = $(MT19937AR_D)/mt19937ar.h +MT19937AR_INCLUDE = -I$(MT19937AR_D) + +COMMON_SHARED_C = conf.c db.c des.c ers.c grfio.c HPM.c mapindex.c md5calc.c \ + mutex.c nullpo.c random.c showmsg.c strlib.c thread.c \ + timer.c utils.c +COMMON_C = $(COMMON_SHARED_C) +COMMON_SHARED_OBJ = $(patsubst %.c,%.o,$(COMMON_SHARED_C)) COMMON_OBJ = $(addprefix obj_all/, $(COMMON_SHARED_OBJ) \ - console.o core.o malloc.o socket.o) + console.o core.o malloc.o socket.o) COMMON_MINI_OBJ = $(addprefix obj_all/, $(COMMON_SHARED_OBJ) \ - miniconsole.o minicore.o minimalloc.o minisocket.o) + miniconsole.o minicore.o minimalloc.o minisocket.o) +COMMON_C += console.c core.c malloc.c socket.c COMMON_H = atomic.h cbasetypes.h conf.h console.h core.h db.h des.h ers.h \ - evdp.h grfio.h HPM.h HPMi.h malloc.h mapindex.h md5calc.h \ - mempool.h mmo.h mutex.h netbuffer.h network.h nullpo.h raconf.h \ - random.h showmsg.h socket.h spinlock.h sql.h strlib.h thread.h \ - timer.h utils.h winapi.h + grfio.h HPM.h HPMi.h malloc.h mapindex.h md5calc.h mmo.h mutex.h \ + nullpo.h random.h showmsg.h socket.h spinlock.h sql.h strlib.h \ + thread.h timer.h utils.h winapi.h COMMON_SQL_OBJ = obj_sql/sql.o COMMON_SQL_H = sql.h +COMMON_C += sql.c HAVE_MYSQL=@HAVE_MYSQL@ ifeq ($(HAVE_MYSQL),yes) diff --git a/src/common/atomic.h b/src/common/atomic.h index b1a4bda92..c2227a9d4 100644 --- a/src/common/atomic.h +++ b/src/common/atomic.h @@ -1,8 +1,8 @@ // Copyright (c) rAthena Project (www.rathena.org) - Licensed under GNU GPL // For more information, see LICENCE in the main folder -#ifndef _rA_ATOMIC_H_ -#define _rA_ATOMIC_H_ +#ifndef _COMMON_ATOMIC_H_ +#define _COMMON_ATOMIC_H_ // Atomic Operations // (Interlocked CompareExchange, Add .. and so on ..) @@ -19,6 +19,9 @@ #if defined(_MSC_VER) #include "../common/winapi.h" +// This checks if C/C++ Compiler Version is 18.00 +#if _MSC_VER < 1800 + #if !defined(_M_X64) // When compiling for windows 32bit, the 8byte interlocked operations are not provided by microsoft // (because they need at least i586 so its not generic enough.. ... ) @@ -80,6 +83,8 @@ forceinline volatile int64 InterlockedExchange64(volatile int64 *target, int64 v #endif //endif 32bit windows +#endif //endif _msc_ver check + #elif defined(__GNUC__) #if !defined(__x86_64__) && !defined(__i386__) @@ -139,4 +144,4 @@ static forceinline int32 InterlockedExchange(volatile int32 *target, int32 val){ #endif //endif compiler decission -#endif +#endif /* _COMMON_ATOMIC_H_ */ diff --git a/src/common/cbasetypes.h b/src/common/cbasetypes.h index 1e4fc04c7..654334a9b 100644 --- a/src/common/cbasetypes.h +++ b/src/common/cbasetypes.h @@ -1,5 +1,5 @@ -#ifndef _CBASETYPES_H_ -#define _CBASETYPES_H_ +#ifndef _COMMON_CBASETYPES_H_ +#define _COMMON_CBASETYPES_H_ /* +--------+-----------+--------+---------+ * | ILP32 | LP64 | ILP64 | (LL)P64 | @@ -37,11 +37,16 @@ #define CYGWIN #endif -// __APPLE__ is the only predefined macro on MacOS X +// __APPLE__ is the only predefined macro on MacOS #if defined(__APPLE__) #define __DARWIN__ #endif +// Necessary for __NetBSD_Version__ (defined as VVRR00PP00) on NetBSD +#ifdef __NETBSD__ +#include <sys/param.h> +#endif // __NETBSD__ + // 64bit OS #if defined(_M_IA64) || defined(_M_X64) || defined(_WIN64) || defined(_LP64) || defined(_ILP64) || defined(__LP64__) || defined(__ppc64__) #define __64BIT__ @@ -92,9 +97,9 @@ // (-20 >= USHRT_MAX) returns true #if defined(__FreeBSD__) && defined(__x86_64) #undef UCHAR_MAX -#define UCHAR_MAX (unsigned char)0xff +#define UCHAR_MAX ((unsigned char)0xff) #undef USHRT_MAX -#define USHRT_MAX (unsigned short)0xffff +#define USHRT_MAX ((unsigned short)0xffff) #endif // ILP64 isn't supported, so always 32 bits? @@ -180,7 +185,7 @@ typedef unsigned long int ppuint32; #if defined(WIN32) && !defined(MINGW) // does not have a signed size_t ////////////////////////////// -#if defined(_WIN64) // naive 64bit windows platform +#if defined(_WIN64) // native 64bit windows platform typedef __int64 ssize_t; #else typedef int ssize_t; @@ -255,6 +260,13 @@ typedef uintptr_t uintptr; #define ra_align(n) __attribute__(( aligned(n) )) #endif +// Directives for the (clang) static analyzer +#ifdef __clang__ +#define analyzer_noreturn __attribute__((analyzer_noreturn)) +#else +#define analyzer_noreturn +#endif + ///////////////////////////// // for those still not building c++ @@ -293,7 +305,9 @@ typedef char bool; // if using macros then something that is type independent //#define swap(a,b) ((a == b) || ((a ^= b), (b ^= a), (a ^= b))) // Avoid "value computed is not used" warning and generates the same assembly code -#define swap(a,b) if (a != b) ((a ^= b), (b ^= a), (a ^= b)) +//#define swap(a,b) if (a != b) ((a ^= b), (b ^= a), (a ^= b)) +// but is vulnerable to 'if (foo) swap(bar, baz); else quux();', causing the else to nest incorrectly. +#define swap(a,b) do { if ((a) != (b)) { (a) ^= (b); (b) ^= (a); (a) ^= (b); } } while(0) #if 0 //to be activated soon, more tests needed on how VS works with the macro above #ifdef WIN32 #undef swap @@ -313,7 +327,7 @@ typedef char bool; #endif #endif -#define swap_ptr(a,b) if ((a) != (b)) ((a) = (void*)((intptr_t)(a) ^ (intptr_t)(b)), (b) = (void*)((intptr_t)(a) ^ (intptr_t)(b)), (a) = (void*)((intptr_t)(a) ^ (intptr_t)(b))) +#define swap_ptr(a,b) do { if ((a) != (b)) (a) = (void*)((intptr_t)(a) ^ (intptr_t)(b)); (b) = (void*)((intptr_t)(a) ^ (intptr_t)(b)); (a) = (void*)((intptr_t)(a) ^ (intptr_t)(b)); } while(0) #ifndef max #define max(a,b) (((a) > (b)) ? (a) : (b)) @@ -341,8 +355,8 @@ typedef char bool; #if defined(WIN32) #define PATHSEP '\\' #define PATHSEP_STR "\\" -#elif defined(__APPLE__) -// FIXME Mac OS X is unix based, is this still correct? +#elif defined(__APPLE__) && !defined(__MACH__) +// __MACH__ indicates OS X ( http://sourceforge.net/p/predef/wiki/OperatingSystems/ ) #define PATHSEP ':' #define PATHSEP_STR ":" #else @@ -351,23 +365,6 @@ typedef char bool; #endif ////////////////////////////////////////////////////////////////////////// -// Assert - -#if ! defined(Assert) -#if defined(RELEASE) -#define Assert(EX) -#else -// extern "C" { -#include <assert.h> -// } -#if !defined(DEFCPP) && defined(WIN32) && !defined(MINGW) -#include <crtdbg.h> -#endif -#define Assert(EX) assert(EX) -#endif -#endif /* ! defined(Assert) */ - -////////////////////////////////////////////////////////////////////////// // Has to be unsigned to avoid problems in some systems // Problems arise when these functions expect an argument in the range [0,256[ and are fed a signed char. #include <ctype.h> @@ -403,7 +400,7 @@ typedef char bool; ////////////////////////////////////////////////////////////////////////// -// Use the preprocessor to 'stringify' stuff (concert to a string). +// Use the preprocessor to 'stringify' stuff (convert to a string). // example: // #define TESTE blabla // QUOTE(TESTE) -> "TESTE" @@ -429,9 +426,9 @@ void SET_FUNCPOINTER(T1& var, T2 p) var = tmp.out; } #else -#define SET_POINTER(var,p) (var) = (p) -#define SET_FUNCPOINTER(var,p) (var) = (p) +#define SET_POINTER(var,p) ((var) = (p)) +#define SET_FUNCPOINTER(var,p) ((var) = (p)) #endif -#endif /* _CBASETYPES_H_ */ +#endif /* _COMMON_CBASETYPES_H_ */ diff --git a/src/common/conf.c b/src/common/conf.c index 6802f728b..b816b2f7f 100644 --- a/src/common/conf.c +++ b/src/common/conf.c @@ -1,18 +1,22 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena Dev Teams #include "conf.h" #include "../../3rdparty/libconfig/libconfig.h" #include "../common/showmsg.h" // ShowError -int conf_read_file(config_t *config, const char *config_filename) -{ - config_init(config); - if (!config_read_file(config, config_filename)) { +/* interface source */ +struct libconfig_interface libconfig_s; + + +int conf_read_file(config_t *config, const char *config_filename) { + libconfig->init(config); + if (!libconfig->read_file_src(config, config_filename)) { ShowError("%s:%d - %s\n", config_error_file(config), config_error_line(config), config_error_text(config)); - config_destroy(config); + libconfig->destroy(config); return 1; } return 0; @@ -21,65 +25,63 @@ int conf_read_file(config_t *config, const char *config_filename) // // Functions to copy settings from libconfig/contrib // -static void config_setting_copy_simple(config_setting_t *parent, const config_setting_t *src); -static void config_setting_copy_elem(config_setting_t *parent, const config_setting_t *src); -static void config_setting_copy_aggregate(config_setting_t *parent, const config_setting_t *src); -int config_setting_copy(config_setting_t *parent, const config_setting_t *src); - -void config_setting_copy_simple(config_setting_t *parent, const config_setting_t *src) -{ +void config_setting_copy_simple(config_setting_t *parent, const config_setting_t *src) { if (config_setting_is_aggregate(src)) { - config_setting_copy_aggregate(parent, src); + libconfig->setting_copy_aggregate(parent, src); } else { - config_setting_t *set = config_setting_add(parent, config_setting_name(src), config_setting_type(src)); - - if (set == NULL) + config_setting_t *set; + + if( libconfig->setting_get_member(parent, config_setting_name(src)) != NULL ) + return; + + if ((set = libconfig->setting_add(parent, config_setting_name(src), config_setting_type(src))) == NULL) return; if (CONFIG_TYPE_INT == config_setting_type(src)) { - config_setting_set_int(set, config_setting_get_int(src)); - config_setting_set_format(set, src->format); + libconfig->setting_set_int(set, libconfig->setting_get_int(src)); + libconfig->setting_set_format(set, src->format); } else if (CONFIG_TYPE_INT64 == config_setting_type(src)) { - config_setting_set_int64(set, config_setting_get_int64(src)); - config_setting_set_format(set, src->format); + libconfig->setting_set_int64(set, libconfig->setting_get_int64(src)); + libconfig->setting_set_format(set, src->format); } else if (CONFIG_TYPE_FLOAT == config_setting_type(src)) { - config_setting_set_float(set, config_setting_get_float(src)); + libconfig->setting_set_float(set, libconfig->setting_get_float(src)); } else if (CONFIG_TYPE_STRING == config_setting_type(src)) { - config_setting_set_string(set, config_setting_get_string(src)); + libconfig->setting_set_string(set, libconfig->setting_get_string(src)); } else if (CONFIG_TYPE_BOOL == config_setting_type(src)) { - config_setting_set_bool(set, config_setting_get_bool(src)); + libconfig->setting_set_bool(set, libconfig->setting_get_bool(src)); } } } -void config_setting_copy_elem(config_setting_t *parent, const config_setting_t *src) -{ +void config_setting_copy_elem(config_setting_t *parent, const config_setting_t *src) { config_setting_t *set = NULL; if (config_setting_is_aggregate(src)) - config_setting_copy_aggregate(parent, src); + libconfig->setting_copy_aggregate(parent, src); else if (CONFIG_TYPE_INT == config_setting_type(src)) { - set = config_setting_set_int_elem(parent, -1, config_setting_get_int(src)); - config_setting_set_format(set, src->format); + set = libconfig->setting_set_int_elem(parent, -1, libconfig->setting_get_int(src)); + libconfig->setting_set_format(set, src->format); } else if (CONFIG_TYPE_INT64 == config_setting_type(src)) { - set = config_setting_set_int64_elem(parent, -1, config_setting_get_int64(src)); - config_setting_set_format(set, src->format); + set = libconfig->setting_set_int64_elem(parent, -1, libconfig->setting_get_int64(src)); + libconfig->setting_set_format(set, src->format); } else if (CONFIG_TYPE_FLOAT == config_setting_type(src)) { - config_setting_set_float_elem(parent, -1, config_setting_get_float(src)); + libconfig->setting_set_float_elem(parent, -1, libconfig->setting_get_float(src)); } else if (CONFIG_TYPE_STRING == config_setting_type(src)) { - config_setting_set_string_elem(parent, -1, config_setting_get_string(src)); + libconfig->setting_set_string_elem(parent, -1, libconfig->setting_get_string(src)); } else if (CONFIG_TYPE_BOOL == config_setting_type(src)) { - config_setting_set_bool_elem(parent, -1, config_setting_get_bool(src)); + libconfig->setting_set_bool_elem(parent, -1, libconfig->setting_get_bool(src)); } } -void config_setting_copy_aggregate(config_setting_t *parent, const config_setting_t *src) -{ +void config_setting_copy_aggregate(config_setting_t *parent, const config_setting_t *src) { config_setting_t *newAgg; int i, n; - newAgg = config_setting_add(parent, config_setting_name(src), config_setting_type(src)); + if( libconfig->setting_get_member(parent, config_setting_name(src)) != NULL ) + return; + + newAgg = libconfig->setting_add(parent, config_setting_name(src), config_setting_type(src)); if (newAgg == NULL) return; @@ -88,22 +90,101 @@ void config_setting_copy_aggregate(config_setting_t *parent, const config_settin for (i = 0; i < n; i++) { if (config_setting_is_group(src)) { - config_setting_copy_simple(newAgg, config_setting_get_elem(src, i)); + libconfig->setting_copy_simple(newAgg, libconfig->setting_get_elem(src, i)); } else { - config_setting_copy_elem(newAgg, config_setting_get_elem(src, i)); + libconfig->setting_copy_elem(newAgg, libconfig->setting_get_elem(src, i)); } } } -int config_setting_copy(config_setting_t *parent, const config_setting_t *src) -{ +int config_setting_copy(config_setting_t *parent, const config_setting_t *src) { + if (!config_setting_is_group(parent) && !config_setting_is_list(parent)) return CONFIG_FALSE; if (config_setting_is_aggregate(src)) { - config_setting_copy_aggregate(parent, src); + libconfig->setting_copy_aggregate(parent, src); } else { - config_setting_copy_simple(parent, src); + libconfig->setting_copy_simple(parent, src); } return CONFIG_TRUE; } + +void libconfig_defaults(void) { + libconfig = &libconfig_s; + + libconfig->read = config_read; + libconfig->write = config_write; + /* */ + libconfig->set_auto_convert = config_set_auto_convert; + libconfig->get_auto_convert = config_get_auto_convert; + /* */ + libconfig->read_string = config_read_string; + libconfig->read_file_src = config_read_file; + libconfig->write_file = config_write_file; + /* */ + libconfig->set_destructor = config_set_destructor; + libconfig->set_include_dir = config_set_include_dir; + /* */ + libconfig->init = config_init; + libconfig->destroy = config_destroy; + /* */ + libconfig->setting_get_int = config_setting_get_int; + libconfig->setting_get_int64 = config_setting_get_int64; + libconfig->setting_get_float = config_setting_get_float; + libconfig->setting_get_bool = config_setting_get_bool; + libconfig->setting_get_string = config_setting_get_string; + /* */ + libconfig->setting_lookup_int = config_setting_lookup_int; + libconfig->setting_lookup_int64 = config_setting_lookup_int64; + libconfig->setting_lookup_float = config_setting_lookup_float; + libconfig->setting_lookup_bool = config_setting_lookup_bool; + libconfig->setting_lookup_string = config_setting_lookup_string; + /* */ + libconfig->setting_set_int = config_setting_set_int; + libconfig->setting_set_int64 = config_setting_set_int64; + libconfig->setting_set_bool = config_setting_set_bool; + libconfig->setting_set_string = config_setting_set_string; + /* */ + libconfig->setting_set_format = config_setting_set_format; + libconfig->setting_get_format = config_setting_get_format; + /* */ + libconfig->setting_get_int_elem = config_setting_get_int_elem; + libconfig->setting_get_int64_elem = config_setting_get_int64_elem; + libconfig->setting_get_float_elem = config_setting_get_float_elem; + libconfig->setting_get_bool_elem = config_setting_get_bool_elem; + libconfig->setting_get_string_elem = config_setting_get_string_elem; + /* */ + libconfig->setting_set_int_elem = config_setting_set_int_elem; + libconfig->setting_set_int64_elem = config_setting_set_int64_elem; + libconfig->setting_set_float_elem = config_setting_set_float_elem; + libconfig->setting_set_bool_elem = config_setting_set_bool_elem; + libconfig->setting_set_string_elem = config_setting_set_string_elem; + /* */ + libconfig->setting_index = config_setting_index; + libconfig->setting_length = config_setting_length; + /* */ + libconfig->setting_get_elem = config_setting_get_elem; + libconfig->setting_get_member = config_setting_get_member; + /* */ + libconfig->setting_add = config_setting_add; + libconfig->setting_remove = config_setting_remove; + libconfig->setting_remove_elem = config_setting_remove_elem; + /* */ + libconfig->setting_set_hook = config_setting_set_hook; + /* */ + libconfig->lookup = config_lookup; + libconfig->lookup_from = config_lookup_from; + /* */ + libconfig->lookup_int = config_lookup_int; + libconfig->lookup_int64 = config_lookup_int64; + libconfig->lookup_float = config_lookup_float; + libconfig->lookup_bool = config_lookup_bool; + libconfig->lookup_string = config_lookup_string; + /* those are custom and are from src/common/conf.c */ + libconfig->read_file = conf_read_file; + libconfig->setting_copy_simple = config_setting_copy_simple; + libconfig->setting_copy_elem = config_setting_copy_elem; + libconfig->setting_copy_aggregate = config_setting_copy_aggregate; + libconfig->setting_copy = config_setting_copy; +} diff --git a/src/common/conf.h b/src/common/conf.h index d223505db..9aff3df47 100644 --- a/src/common/conf.h +++ b/src/common/conf.h @@ -1,13 +1,97 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena Dev Teams -#ifndef _CONF_H_ -#define _CONF_H_ +#ifndef _COMMON_CONF_H_ +#define _COMMON_CONF_H_ #include "../common/cbasetypes.h" #include "../../3rdparty/libconfig/libconfig.h" -int conf_read_file(config_t *config, const char *config_filename); -int config_setting_copy(config_setting_t *parent, const config_setting_t *src); +/** + * The libconfig interface -- specially for plugins, but we enforce it throughought the core to be consistent + **/ +struct libconfig_interface { + int (*read) (config_t *config, FILE *stream); + void (*write) (const config_t *config, FILE *stream); + /* */ + void (*set_auto_convert) (config_t *config, int flag); + int (*get_auto_convert) (const config_t *config); + /* */ + int (*read_string) (config_t *config, const char *str); + int (*read_file_src) (config_t *config, const char *filename); + int (*write_file) (config_t *config, const char *filename); + + void (*set_destructor) (config_t *config, void (*destructor)(void *)); + void (*set_include_dir) (config_t *config, const char *include_dir); + + void (*init) (config_t *config); + void (*destroy) (config_t *config); + + int (*setting_get_int) (const config_setting_t *setting); + long long (*setting_get_int64) (const config_setting_t *setting); + double (*setting_get_float) (const config_setting_t *setting); + + int (*setting_get_bool) (const config_setting_t *setting); + + const char * (*setting_get_string) (const config_setting_t *setting); + + int (*setting_lookup_int) (const config_setting_t *setting, const char *name, int *value); + int (*setting_lookup_int64) (const config_setting_t *setting, const char *name, long long *value); + int (*setting_lookup_float) (const config_setting_t *setting, const char *name, double *value); + int (*setting_lookup_bool) (const config_setting_t *setting, const char *name, int *value); + int (*setting_lookup_string) (const config_setting_t *setting, const char *name, const char **value); + int (*setting_set_int) (config_setting_t *setting ,int value); + int (*setting_set_int64) (config_setting_t *setting, long long value); + int (*setting_set_float) (config_setting_t *setting, double value); + int (*setting_set_bool) (config_setting_t *setting, int value); + int (*setting_set_string) (config_setting_t *setting, const char *value); + + int (*setting_set_format) (config_setting_t *setting, short format); + short (*setting_get_format) (const config_setting_t *setting); + + int (*setting_get_int_elem) (const config_setting_t *setting, int idx); + long long (*setting_get_int64_elem) (const config_setting_t *setting, int idx); + double (*setting_get_float_elem) (const config_setting_t *setting, int idx); + int (*setting_get_bool_elem) (const config_setting_t *setting, int idx); + const char * (*setting_get_string_elem) (const config_setting_t *setting, int idx); + config_setting_t * (*setting_set_int_elem) (config_setting_t *setting, int idx, int value); + config_setting_t * (*setting_set_int64_elem) (config_setting_t *setting, int idx, long long value); + config_setting_t * (*setting_set_float_elem) (config_setting_t *setting, int idx, double value); + config_setting_t * (*setting_set_bool_elem) (config_setting_t *setting, int idx, int value); + config_setting_t * (*setting_set_string_elem) (config_setting_t *setting, int idx, const char *value); + + int (*setting_index) (const config_setting_t *setting); + int (*setting_length) (const config_setting_t *setting); + + config_setting_t * (*setting_get_elem) (const config_setting_t *setting, unsigned int idx); + config_setting_t * (*setting_get_member) (const config_setting_t *setting, const char *name); + + config_setting_t * (*setting_add) (config_setting_t *parent, const char *name, int type); + int (*setting_remove) (config_setting_t *parent, const char *name); + + int (*setting_remove_elem) (config_setting_t *parent, unsigned int idx); + void (*setting_set_hook) (config_setting_t *setting, void *hook); + + config_setting_t * (*lookup) (const config_t *config, const char *path); + config_setting_t * (*lookup_from) (config_setting_t *setting, const char *path); + int (*lookup_int) (const config_t *config, const char *path, int *value); + int (*lookup_int64) (const config_t *config, const char *path, long long *value); + int (*lookup_float) (const config_t *config, const char *path, double *value); + int (*lookup_bool) (const config_t *config, const char *path, int *value); + int (*lookup_string) (const config_t *config, const char *path, const char **value); + + /* those are custom and are from src/common/conf.c */ + /* Functions to copy settings from libconfig/contrib */ + int (*read_file) (config_t *config, const char *config_filename); + void (*setting_copy_simple) (config_setting_t *parent, const config_setting_t *src); + void (*setting_copy_elem) (config_setting_t *parent, const config_setting_t *src); + void (*setting_copy_aggregate) (config_setting_t *parent, const config_setting_t *src); + int (*setting_copy) (config_setting_t *parent, const config_setting_t *src); +}; -#endif // _CONF_H_ +struct libconfig_interface *libconfig; + +void libconfig_defaults(void); + +#endif // _COMMON_CONF_H_ diff --git a/src/common/console.c b/src/common/console.c index b25de84b3..94824dc25 100644 --- a/src/common/console.c +++ b/src/common/console.c @@ -175,6 +175,10 @@ void console_load_defaults(void) { } } } +#undef CP_DEF_C +#undef CP_DEF_C2 +#undef CP_DEF_S +#undef CP_DEF void console_parse_create(char *name, CParseFunc func) { unsigned int i; char *tok; @@ -344,7 +348,7 @@ void *cThread_main(void *x) { return NULL; } -int console_parse_timer(int tid, unsigned int tick, int id, intptr_t data) { +int console_parse_timer(int tid, int64 tick, int id, intptr_t data) { int i; EnterSpinLock(&console->ptlock); for(i = 0; i < cinput.count; i++) { diff --git a/src/common/console.h b/src/common/console.h index cef898f17..513c769ff 100644 --- a/src/common/console.h +++ b/src/common/console.h @@ -1,8 +1,8 @@ // Copyright (c) Hercules Dev Team, licensed under GNU GPL. // See the LICENSE file -#ifndef _CONSOLE_H_ -#define _CONSOLE_H_ +#ifndef _COMMON_CONSOLE_H_ +#define _COMMON_CONSOLE_H_ #include "../common/thread.h" #include "../common/mutex.h" @@ -56,7 +56,7 @@ struct console_interface { /* */ void (*parse_init) (void); void (*parse_final) (void); - int (*parse_timer) (int tid, unsigned int tick, int id, intptr_t data); + int (*parse_timer) (int tid, int64 tick, int id, intptr_t data); void *(*pthread_main) (void *x); void (*parse) (char* line); void (*parse_sub) (char* line); @@ -72,4 +72,4 @@ struct console_interface *console; void console_defaults(void); -#endif /* _CONSOLE_H_ */ +#endif /* _COMMON_CONSOLE_H_ */ diff --git a/src/common/core.c b/src/common/core.c index 6a73d2d39..86634ec4b 100644 --- a/src/common/core.c +++ b/src/common/core.c @@ -8,17 +8,18 @@ #include "../common/strlib.h" #include "core.h" #include "../common/console.h" +#include "../common/random.h" #ifndef MINICORE #include "../common/db.h" #include "../common/socket.h" #include "../common/timer.h" #include "../common/thread.h" - #include "../common/mempool.h" #include "../common/sql.h" #include "../config/core.h" #include "../common/HPM.h" #include "../common/utils.h" + #include "../common/conf.h" #endif #include <stdio.h> @@ -52,7 +53,7 @@ char *SERVER_NAME = NULL; #endif #ifndef POSIX -#define compat_signal(signo, func) signal(signo, func) +#define compat_signal(signo, func) signal((signo), (func)) #else sigfunc *compat_signal(int signo, sigfunc *func) { struct sigaction sact, oact; @@ -282,9 +283,11 @@ void core_defaults(void) { strlib_defaults(); malloc_defaults(); #ifndef MINICORE + libconfig_defaults(); sql_defaults(); timer_defaults(); db_defaults(); + socket_defaults(); #endif } /*====================================== @@ -302,10 +305,20 @@ int main (int argc, char **argv) { arg_v = argv; } core_defaults(); + + { + int i; + for(i = 0; i < argc; i++) { + if( strcmp(argv[i], "--script-check") == 0 ) { + msg_silent = 0x7; // silence information and status messages + } + } + } iMalloc->init();// needed for Show* in display_title() [FlavioJS] - - console->display_title(); + + if (!(msg_silent&0x1)) + console->display_title(); #ifdef MINICORE // minimalist Core usercheck(); @@ -317,7 +330,6 @@ int main (int argc, char **argv) { Sql_Init(); rathread_init(); - mempool_init(); DB->init(); signals_init(); @@ -327,6 +339,10 @@ int main (int argc, char **argv) { timer->init(); + /* timer first */ + rnd_init(); + srand((unsigned int)timer->gettick()); + console->init(); HCache->init(); @@ -335,14 +351,14 @@ int main (int argc, char **argv) { HPM->init(); #endif - socket_init(); + sockt->init(); do_init(argc,argv); {// Main runtime cycle int next; while (runflag != CORE_ST_STOP) { - next = timer->do_timer(timer->gettick_nocache()); - do_sockets(next); + next = timer->perform(timer->gettick_nocache()); + sockt->perform(next); } } @@ -353,9 +369,8 @@ int main (int argc, char **argv) { HPM->final(); #endif timer->final(); - socket_final(); + sockt->final(); DB->final(); - mempool_final(); rathread_final(); #endif diff --git a/src/common/core.h b/src/common/core.h index 8fdcdcfc3..72f956e1d 100644 --- a/src/common/core.h +++ b/src/common/core.h @@ -2,8 +2,8 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _CORE_H_ -#define _CORE_H_ +#ifndef _COMMON_CORE_H_ +#define _COMMON_CORE_H_ #include "../common/db.h" #include "../common/mmo.h" @@ -50,4 +50,4 @@ enum E_CORE_ST { /// If NULL, runflag is set to CORE_ST_STOP instead. extern void (*shutdown_callback)(void); -#endif /* _CORE_H_ */ +#endif /* _COMMON_CORE_H_ */ diff --git a/src/common/db.c b/src/common/db.c index b3a58e0a4..8c15c0feb 100644 --- a/src/common/db.c +++ b/src/common/db.c @@ -47,6 +47,7 @@ * - create a db that organizes itself by splaying * * HISTORY: + * 2013/08/25 - Added int64/uint64 support for keys [Ind/Hercules] * 2013/04/27 - Added ERS to speed up iterator memory allocation [Ind/Hercules] * 2012/03/09 - Added enum for data types (int, uint, void*) * 2008/02/19 - Fixed db_obj_get not handling deleted entries correctly. @@ -236,10 +237,14 @@ static struct db_stats { uint32 db_uint_alloc; uint32 db_string_alloc; uint32 db_istring_alloc; + uint32 db_int64_alloc; + uint32 db_uint64_alloc; uint32 db_int_destroy; uint32 db_uint_destroy; uint32 db_string_destroy; uint32 db_istring_destroy; + uint32 db_int64_destroy; + uint32 db_uint64_destroy; // Function usage counters uint32 db_rotate_left; uint32 db_rotate_right; @@ -256,10 +261,14 @@ static struct db_stats { uint32 db_uint_cmp; uint32 db_string_cmp; uint32 db_istring_cmp; + uint32 db_int64_cmp; + uint32 db_uint64_cmp; uint32 db_int_hash; uint32 db_uint_hash; uint32 db_string_hash; uint32 db_istring_hash; + uint32 db_int64_hash; + uint32 db_uint64_hash; uint32 db_release_nothing; uint32 db_release_key; uint32 db_release_data; @@ -298,6 +307,8 @@ static struct db_stats { uint32 db_i2key; uint32 db_ui2key; uint32 db_str2key; + uint32 db_i642key; + uint32 db_ui642key; uint32 db_i2data; uint32 db_ui2data; uint32 db_ptr2data; @@ -315,7 +326,7 @@ static struct db_stats { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -#define DB_COUNTSTAT(token) if (stats. ## token != UINT32_MAX) ++stats. ## token +#define DB_COUNTSTAT(token) do { if (stats. ## token != UINT32_MAX) ++stats. ## token ; } while(0) #else /* !defined(DB_ENABLE_STATS) */ #define DB_COUNTSTAT(token) #endif /* !defined(DB_ENABLE_STATS) */ @@ -830,10 +841,14 @@ static void db_free_unlock(DBMap_impl* db) * db_uint_cmp - Default comparator for DB_UINT databases. * * db_string_cmp - Default comparator for DB_STRING databases. * * db_istring_cmp - Default comparator for DB_ISTRING databases. * + * db_int64_cmp - Default comparator for DB_INT64 databases. * + * db_uint64_cmp - Default comparator for DB_UINT64 databases. * * db_int_hash - Default hasher for DB_INT databases. * * db_uint_hash - Default hasher for DB_UINT databases. * * db_string_hash - Default hasher for DB_STRING databases. * * db_istring_hash - Default hasher for DB_ISTRING databases. * + * db_int64_hash - Default hasher for DB_INT64 databases. * + * db_uint64_hash - Default hasher for DB_UINT64 databases. * * db_release_nothing - Releaser that releases nothing. * * db_release_key - Releaser that only releases the key. * * db_release_data - Releaser that only releases the data. * @@ -921,6 +936,51 @@ static int db_istring_cmp(DBKey key1, DBKey key2, unsigned short maxlen) } /** + * Default comparator for DB_INT64 databases. + * Compares key1 to key2. + * Return 0 if equal, negative if lower and positive if higher. + * <code>maxlen</code> is ignored. + * @param key1 Key to be compared + * @param key2 Key being compared to + * @param maxlen Maximum length of the key to hash + * @return 0 if equal, negative if lower and positive if higher + * @see DBType#DB_INT64 + * @see #DBComparator + * @see #db_default_cmp(DBType) + */ +static int db_int64_cmp(DBKey key1, DBKey key2, unsigned short maxlen) +{ + (void)maxlen;//not used + DB_COUNTSTAT(db_int64_cmp); + if (key1.i64 < key2.i64) return -1; + if (key1.i64 > key2.i64) return 1; + return 0; +} + +/** + * Default comparator for DB_UINT64 databases. + * Compares key1 to key2. + * Return 0 if equal, negative if lower and positive if higher. + * <code>maxlen</code> is ignored. + * @param key1 Key to be compared + * @param key2 Key being compared to + * @param maxlen Maximum length of the key to hash + * @return 0 if equal, negative if lower and positive if higher + * @see DBType#DB_UINT64 + * @see #DBComparator + * @see #db_default_cmp(DBType) + */ +static int db_uint64_cmp(DBKey key1, DBKey key2, unsigned short maxlen) +{ + (void)maxlen;//not used + DB_COUNTSTAT(db_uint64_cmp); + if (key1.ui64 < key2.ui64) return -1; + if (key1.ui64 > key2.ui64) return 1; + return 0; +} + + +/** * Default hasher for DB_INT databases. * Returns the value of the key as an unsigned int. * <code>maxlen</code> is ignored. @@ -931,11 +991,11 @@ static int db_istring_cmp(DBKey key1, DBKey key2, unsigned short maxlen) * @see #DBHasher * @see #db_default_hash(DBType) */ -static unsigned int db_int_hash(DBKey key, unsigned short maxlen) +static uint64 db_int_hash(DBKey key, unsigned short maxlen) { (void)maxlen;//not used DB_COUNTSTAT(db_int_hash); - return (unsigned int)key.i; + return (uint64)key.i; } /** @@ -949,11 +1009,11 @@ static unsigned int db_int_hash(DBKey key, unsigned short maxlen) * @see #DBHasher * @see #db_default_hash(DBType) */ -static unsigned int db_uint_hash(DBKey key, unsigned short maxlen) +static uint64 db_uint_hash(DBKey key, unsigned short maxlen) { (void)maxlen;//not used DB_COUNTSTAT(db_uint_hash); - return key.ui; + return (uint64)key.ui; } /** @@ -965,7 +1025,7 @@ static unsigned int db_uint_hash(DBKey key, unsigned short maxlen) * @see #DBHasher * @see #db_default_hash(DBType) */ -static unsigned int db_string_hash(DBKey key, unsigned short maxlen) +static uint64 db_string_hash(DBKey key, unsigned short maxlen) { const char *k = key.str; unsigned int hash = 0; @@ -980,7 +1040,7 @@ static unsigned int db_string_hash(DBKey key, unsigned short maxlen) break; } - return hash; + return (uint64)hash; } /** @@ -991,7 +1051,7 @@ static unsigned int db_string_hash(DBKey key, unsigned short maxlen) * @see DBType#DB_ISTRING * @see #db_default_hash(DBType) */ -static unsigned int db_istring_hash(DBKey key, unsigned short maxlen) +static uint64 db_istring_hash(DBKey key, unsigned short maxlen) { const char *k = key.str; unsigned int hash = 0; @@ -1006,7 +1066,43 @@ static unsigned int db_istring_hash(DBKey key, unsigned short maxlen) break; } - return hash; + return (uint64)hash; +} + +/** + * Default hasher for DB_INT64 databases. + * Returns the value of the key as an unsigned int. + * <code>maxlen</code> is ignored. + * @param key Key to be hashed + * @param maxlen Maximum length of the key to hash + * @return hash of the key + * @see DBType#DB_INT64 + * @see #DBHasher + * @see #db_default_hash(DBType) + */ +static uint64 db_int64_hash(DBKey key, unsigned short maxlen) +{ + (void)maxlen;//not used + DB_COUNTSTAT(db_int64_hash); + return (uint64)key.i64; +} + +/** + * Default hasher for DB_UINT64 databases. + * Just returns the value of the key. + * <code>maxlen</code> is ignored. + * @param key Key to be hashed + * @param maxlen Maximum length of the key to hash + * @return hash of the key + * @see DBType#DB_UINT64 + * @see #DBHasher + * @see #db_default_hash(DBType) + */ +static uint64 db_uint64_hash(DBKey key, unsigned short maxlen) +{ + (void)maxlen;//not used + DB_COUNTSTAT(db_uint64_hash); + return key.ui64; } /** @@ -1696,7 +1792,7 @@ static DBData* db_obj_vensure(DBMap* self, DBKey key, DBCreateData create, va_li if (db->options&DB_OPT_DUP_KEY) { node->key = db_dup_key(db, key); if (db->options&DB_OPT_RELEASE_KEY) - db->release(key, *data, DB_RELEASE_KEY); + db->release(key, node->data, DB_RELEASE_KEY); } else { node->key = key; } @@ -2122,6 +2218,8 @@ static int db_obj_vdestroy(DBMap* self, DBApply func, va_list args) case DB_UINT: DB_COUNTSTAT(db_uint_destroy); break; case DB_STRING: DB_COUNTSTAT(db_string_destroy); break; case DB_ISTRING: DB_COUNTSTAT(db_istring_destroy); break; + case DB_INT64: DB_COUNTSTAT(db_int64_destroy); break; + case DB_UINT64: DB_COUNTSTAT(db_uint64_destroy); break; } #endif /* DB_ENABLE_STATS */ db_free_lock(db); @@ -2246,6 +2344,8 @@ static DBOptions db_obj_options(DBMap* self) * db_i2key - Manual cast from 'int' to 'DBKey'. * db_ui2key - Manual cast from 'unsigned int' to 'DBKey'. * db_str2key - Manual cast from 'unsigned char *' to 'DBKey'. + * db_i642key - Manual cast from 'int64' to 'DBKey'. + * db_ui642key - Manual cast from 'uin64' to 'DBKey'. * db_i2data - Manual cast from 'int' to 'DBData'. * db_ui2data - Manual cast from 'unsigned int' to 'DBData'. * db_ptr2data - Manual cast from 'void*' to 'DBData'. @@ -2272,7 +2372,9 @@ DBOptions db_fix_options(DBType type, DBOptions options) DB_COUNTSTAT(db_fix_options); switch (type) { case DB_INT: - case DB_UINT: // Numeric database, do nothing with the keys + case DB_UINT: + case DB_INT64: + case DB_UINT64: // Numeric database, do nothing with the keys return (DBOptions)(options&~(DB_OPT_DUP_KEY|DB_OPT_RELEASE_KEY)); default: @@ -2292,6 +2394,8 @@ DBOptions db_fix_options(DBType type, DBOptions options) * @see #db_uint_cmp(DBKey,DBKey,unsigned short) * @see #db_string_cmp(DBKey,DBKey,unsigned short) * @see #db_istring_cmp(DBKey,DBKey,unsigned short) + * @see #db_int64_cmp(DBKey,DBKey,unsigned short) + * @see #db_uint64_cmp(DBKey,DBKey,unsigned short) */ DBComparator db_default_cmp(DBType type) { @@ -2301,6 +2405,8 @@ DBComparator db_default_cmp(DBType type) case DB_UINT: return &db_uint_cmp; case DB_STRING: return &db_string_cmp; case DB_ISTRING: return &db_istring_cmp; + case DB_INT64: return &db_int64_cmp; + case DB_UINT64: return &db_uint64_cmp; default: ShowError("db_default_cmp: Unknown database type %u\n", type); return NULL; @@ -2316,6 +2422,8 @@ DBComparator db_default_cmp(DBType type) * @see #db_uint_hash(DBKey,unsigned short) * @see #db_string_hash(DBKey,unsigned short) * @see #db_istring_hash(DBKey,unsigned short) + * @see #db_int64_hash(DBKey,unsigned short) + * @see #db_uint64_hash(DBKey,unsigned short) */ DBHasher db_default_hash(DBType type) { @@ -2325,6 +2433,8 @@ DBHasher db_default_hash(DBType type) case DB_UINT: return &db_uint_hash; case DB_STRING: return &db_string_hash; case DB_ISTRING: return &db_istring_hash; + case DB_INT64: return &db_int64_hash; + case DB_UINT64: return &db_uint64_hash; default: ShowError("db_default_hash: Unknown database type %u\n", type); return NULL; @@ -2412,6 +2522,8 @@ DBMap* db_alloc(const char *file, const char *func, int line, DBType type, DBOpt case DB_UINT: DB_COUNTSTAT(db_uint_alloc); break; case DB_STRING: DB_COUNTSTAT(db_string_alloc); break; case DB_ISTRING: DB_COUNTSTAT(db_istring_alloc); break; + case DB_INT64: DB_COUNTSTAT(db_int64_alloc); break; + case DB_UINT64: DB_COUNTSTAT(db_uint64_alloc); break; } #endif /* DB_ENABLE_STATS */ db = ers_alloc(db_alloc_ers, struct DBMap_impl); @@ -2446,7 +2558,7 @@ DBMap* db_alloc(const char *file, const char *func, int line, DBType type, DBOpt db->free_lock = 0; /* Other */ snprintf(ers_name, 50, "db_alloc:nodes:%s:%s:%d",func,file,line); - db->nodes = ers_new(sizeof(struct dbn),ers_name,ERS_OPT_WAIT|ERS_OPT_FREE_NAME); + db->nodes = ers_new(sizeof(struct dbn),ers_name,ERS_OPT_WAIT|ERS_OPT_FREE_NAME|ERS_OPT_CLEAN); db->cmp = DB->default_cmp(type); db->hash = DB->default_hash(type); db->release = DB->default_release(type, options); @@ -2511,6 +2623,36 @@ DBKey db_str2key(const char *key) } /** + * Manual cast from 'int64' to the union DBKey. + * @param key Key to be casted + * @return The key as a DBKey union + * @public + */ +DBKey db_i642key(int64 key) +{ + DBKey ret; + + DB_COUNTSTAT(db_i642key); + ret.i64 = key; + return ret; +} + +/** + * Manual cast from 'uin64' to the union DBKey. + * @param key Key to be casted + * @return The key as a DBKey union + * @public + */ +DBKey db_ui642key(uint64 key) +{ + DBKey ret; + + DB_COUNTSTAT(db_ui642key); + ret.ui64 = key; + return ret; +} + +/** * Manual cast from 'int' to the struct DBData. * @param data Data to be casted * @return The data as a DBData struct @@ -2609,9 +2751,10 @@ void* db_data2ptr(DBData *data) * @see #db_final(void) */ void db_init(void) { - db_iterator_ers = ers_new(sizeof(struct DBIterator_impl),"db.c::db_iterator_ers",ERS_OPT_NONE); - db_alloc_ers = ers_new(sizeof(struct DBMap_impl),"db.c::db_alloc_ers",ERS_OPT_NONE); + db_iterator_ers = ers_new(sizeof(struct DBIterator_impl),"db.c::db_iterator_ers",ERS_OPT_CLEAN|ERS_OPT_FLEX_CHUNK); + db_alloc_ers = ers_new(sizeof(struct DBMap_impl),"db.c::db_alloc_ers",ERS_OPT_CLEAN|ERS_OPT_FLEX_CHUNK); ers_chunk_size(db_alloc_ers, 50); + ers_chunk_size(db_iterator_ers, 10); DB_COUNTSTAT(db_init); } @@ -2632,10 +2775,14 @@ void db_final(void) "DB_UINT : allocated %10u, destroyed %10u\n" "DB_STRING : allocated %10u, destroyed %10u\n" "DB_ISTRING : allocated %10u, destroyed %10u\n", + "DB_INT64 : allocated %10u, destroyed %10u\n" + "DB_UINT64 : allocated %10u, destroyed %10u\n" stats.db_int_alloc, stats.db_int_destroy, stats.db_uint_alloc, stats.db_uint_destroy, stats.db_string_alloc, stats.db_string_destroy, - stats.db_istring_alloc, stats.db_istring_destroy); + stats.db_istring_alloc, stats.db_istring_destroy, + stats.db_int64_alloc, stats.db_int64_destroy, + stats.db_uint64_alloc, stats.db_uint64_destroy,); ShowInfo(CL_WHITE"Database function counters"CL_RESET":\n" "db_rotate_left %10u, db_rotate_right %10u,\n" "db_rebalance %10u, db_rebalance_erase %10u,\n" @@ -2645,8 +2792,10 @@ void db_final(void) "db_free_lock %10u, db_free_unlock %10u,\n" "db_int_cmp %10u, db_uint_cmp %10u,\n" "db_string_cmp %10u, db_istring_cmp %10u,\n" + "db_int64_cmp %10u, db_uint64_cmp %10u,\n" "db_int_hash %10u, db_uint_hash %10u,\n" "db_string_hash %10u, db_istring_hash %10u,\n" + "db_int64_hash %10u, db_uint64_hash %10u,\n" "db_release_nothing %10u, db_release_key %10u,\n" "db_release_data %10u, db_release_both %10u,\n" "dbit_first %10u, dbit_last %10u,\n" @@ -2666,6 +2815,7 @@ void db_final(void) "db_default_release %10u, db_custom_release %10u,\n" "db_alloc %10u, db_i2key %10u,\n" "db_ui2key %10u, db_str2key %10u,\n" + "db_i642key %10u, db_ui642key %10u,\n" "db_i2data %10u, db_ui2data %10u,\n" "db_ptr2data %10u, db_data2i %10u,\n" "db_data2ui %10u, db_data2ptr %10u,\n" @@ -2678,8 +2828,10 @@ void db_final(void) stats.db_free_lock, stats.db_free_unlock, stats.db_int_cmp, stats.db_uint_cmp, stats.db_string_cmp, stats.db_istring_cmp, + stats.db_int64_cmp, stats.db_uint64_cmp, stats.db_int_hash, stats.db_uint_hash, stats.db_string_hash, stats.db_istring_hash, + stats.db_int64_hash, stats.db_uint64_hash, stats.db_release_nothing, stats.db_release_key, stats.db_release_data, stats.db_release_both, stats.dbit_first, stats.dbit_last, @@ -2699,6 +2851,7 @@ void db_final(void) stats.db_default_release, stats.db_custom_release, stats.db_alloc, stats.db_i2key, stats.db_ui2key, stats.db_str2key, + stats.db_i642key, stats.db_ui642key, stats.db_i2data, stats.db_ui2data, stats.db_ptr2data, stats.db_data2i, stats.db_data2ui, stats.db_data2ptr, @@ -2855,4 +3008,7 @@ void db_defaults(void) { DB->str2key = db_str2key; DB->ui2data = db_ui2data; DB->ui2key = db_ui2key; + DB->i642key = db_i642key; + DB->ui642key = db_ui642key; + } diff --git a/src/common/db.h b/src/common/db.h index dffd2356d..67abe6f19 100644 --- a/src/common/db.h +++ b/src/common/db.h @@ -20,6 +20,7 @@ * - see what functions need or should be added to the database interface * * * * HISTORY: * + * 2013/08/25 - Added int64/uint64 support for keys * * 2012/03/09 - Added enum for data types (int, uint, void*) * * 2007/11/09 - Added an iterator to the database. * * 2.1 (Athena build #???#) - Portability fix * @@ -38,8 +39,8 @@ * @encoding US-ASCII * * @see common#db.c * \*****************************************************************************/ -#ifndef _DB_H_ -#define _DB_H_ +#ifndef _COMMON_DB_H_ +#define _COMMON_DB_H_ #include "../common/cbasetypes.h" #include <stdarg.h> @@ -83,6 +84,8 @@ typedef enum DBRelease { * @param DB_UINT Uses unsigned int's for keys * @param DB_STRING Uses strings for keys. * @param DB_ISTRING Uses case insensitive strings for keys. + * @param DB_INT64 Uses int64's for keys + * @param DB_UINT64 Uses uint64's for keys * @public * @see #DBOptions * @see #DBKey @@ -96,7 +99,9 @@ typedef enum DBType { DB_INT, DB_UINT, DB_STRING, - DB_ISTRING + DB_ISTRING, + DB_INT64, + DB_UINT64, } DBType; /** @@ -145,6 +150,8 @@ typedef union DBKey { int i; unsigned int ui; const char *str; + int64 i64; + uint64 ui64; } DBKey; /** @@ -158,7 +165,7 @@ typedef union DBKey { typedef enum DBDataType { DB_DATA_INT, DB_DATA_UINT, - DB_DATA_PTR + DB_DATA_PTR, } DBDataType; /** @@ -245,7 +252,7 @@ typedef int (*DBComparator)(DBKey key1, DBKey key2, unsigned short maxlen); * @public * @see #db_default_hash(DBType) */ -typedef unsigned int (*DBHasher)(DBKey key, unsigned short maxlen); +typedef uint64 (*DBHasher)(DBKey key, unsigned short maxlen); /** * Format of the releaser used by the database system. @@ -598,75 +605,96 @@ struct DBMap { // For easy access to the common functions. -#define db_exists(db,k) ( (db)->exists((db),(k)) ) -#define idb_exists(db,k) ( (db)->exists((db),DB->i2key(k)) ) -#define uidb_exists(db,k) ( (db)->exists((db),DB->ui2key(k)) ) -#define strdb_exists(db,k) ( (db)->exists((db),DB->str2key(k)) ) +#define db_exists(db,k) ( (db)->exists((db),(k)) ) +#define idb_exists(db,k) ( (db)->exists((db),DB->i2key(k)) ) +#define uidb_exists(db,k) ( (db)->exists((db),DB->ui2key(k)) ) +#define strdb_exists(db,k) ( (db)->exists((db),DB->str2key(k)) ) +#define i64db_exists(db,k) ( (db)->exists((db),DB->i642key(k)) ) +#define ui64db_exists(db,k) ( (db)->exists((db),DB->ui642key(k)) ) // Get pointer-type data from DBMaps of various key types -#define db_get(db,k) ( DB->data2ptr((db)->get((db),(k))) ) -#define idb_get(db,k) ( DB->data2ptr((db)->get((db),DB->i2key(k))) ) -#define uidb_get(db,k) ( DB->data2ptr((db)->get((db),DB->ui2key(k))) ) -#define strdb_get(db,k) ( DB->data2ptr((db)->get((db),DB->str2key(k))) ) +#define db_get(db,k) ( DB->data2ptr((db)->get((db),(k))) ) +#define idb_get(db,k) ( DB->data2ptr((db)->get((db),DB->i2key(k))) ) +#define uidb_get(db,k) ( DB->data2ptr((db)->get((db),DB->ui2key(k))) ) +#define strdb_get(db,k) ( DB->data2ptr((db)->get((db),DB->str2key(k))) ) +#define i64db_get(db,k) ( DB->data2ptr((db)->get((db),DB->i642key(k))) ) +#define ui64db_get(db,k) ( DB->data2ptr((db)->get((db),DB->ui642key(k))) ) + // Get int-type data from DBMaps of various key types -#define db_iget(db,k) ( DB->data2i((db)->get((db),(k))) ) -#define idb_iget(db,k) ( DB->data2i((db)->get((db),DB->i2key(k))) ) -#define uidb_iget(db,k) ( DB->data2i((db)->get((db),DB->ui2key(k))) ) -#define strdb_iget(db,k) ( DB->data2i((db)->get((db),DB->str2key(k))) ) +#define db_iget(db,k) ( DB->data2i((db)->get((db),(k))) ) +#define idb_iget(db,k) ( DB->data2i((db)->get((db),DB->i2key(k))) ) +#define uidb_iget(db,k) ( DB->data2i((db)->get((db),DB->ui2key(k))) ) +#define strdb_iget(db,k) ( DB->data2i((db)->get((db),DB->str2key(k))) ) +#define i64db_iget(db,k) ( DB->data2i((db)->get((db),DB->i642key(k))) ) +#define ui64db_iget(db,k) ( DB->data2i((db)->get((db),DB->ui642key(k))) ) // Get uint-type data from DBMaps of various key types -#define db_uiget(db,k) ( DB->data2ui((db)->get((db),(k))) ) -#define idb_uiget(db,k) ( DB->data2ui((db)->get((db),DB->i2key(k))) ) -#define uidb_uiget(db,k) ( DB->data2ui((db)->get((db),DB->ui2key(k))) ) -#define strdb_uiget(db,k) ( DB->data2ui((db)->get((db),DB->str2key(k))) ) +#define db_uiget(db,k) ( DB->data2ui((db)->get((db),(k))) ) +#define idb_uiget(db,k) ( DB->data2ui((db)->get((db),DB->i2key(k))) ) +#define uidb_uiget(db,k) ( DB->data2ui((db)->get((db),DB->ui2key(k))) ) +#define strdb_uiget(db,k) ( DB->data2ui((db)->get((db),DB->str2key(k))) ) +#define i64db_uiget(db,k) ( DB->data2ui((db)->get((db),DB->i642key(k))) ) +#define ui64db_uiget(db,k) ( DB->data2ui((db)->get((db),DB->ui642key(k))) ) // Put pointer-type data into DBMaps of various key types -#define db_put(db,k,d) ( (db)->put((db),(k),DB->ptr2data(d),NULL) ) -#define idb_put(db,k,d) ( (db)->put((db),DB->i2key(k),DB->ptr2data(d),NULL) ) -#define uidb_put(db,k,d) ( (db)->put((db),DB->ui2key(k),DB->ptr2data(d),NULL) ) -#define strdb_put(db,k,d) ( (db)->put((db),DB->str2key(k),DB->ptr2data(d),NULL) ) +#define db_put(db,k,d) ( (db)->put((db),(k),DB->ptr2data(d),NULL) ) +#define idb_put(db,k,d) ( (db)->put((db),DB->i2key(k),DB->ptr2data(d),NULL) ) +#define uidb_put(db,k,d) ( (db)->put((db),DB->ui2key(k),DB->ptr2data(d),NULL) ) +#define strdb_put(db,k,d) ( (db)->put((db),DB->str2key(k),DB->ptr2data(d),NULL) ) +#define i64db_put(db,k,d) ( (db)->put((db),DB->i642key(k),DB->ptr2data(d),NULL) ) +#define ui64db_put(db,k,d) ( (db)->put((db),DB->ui642key(k),DB->ptr2data(d),NULL) ) // Put int-type data into DBMaps of various key types -#define db_iput(db,k,d) ( (db)->put((db),(k),DB->i2data(d),NULL) ) -#define idb_iput(db,k,d) ( (db)->put((db),DB->i2key(k),DB->i2data(d),NULL) ) -#define uidb_iput(db,k,d) ( (db)->put((db),DB->ui2key(k),DB->i2data(d),NULL) ) -#define strdb_iput(db,k,d) ( (db)->put((db),DB->str2key(k),DB->i2data(d),NULL) ) +#define db_iput(db,k,d) ( (db)->put((db),(k),DB->i2data(d),NULL) ) +#define idb_iput(db,k,d) ( (db)->put((db),DB->i2key(k),DB->i2data(d),NULL) ) +#define uidb_iput(db,k,d) ( (db)->put((db),DB->ui2key(k),DB->i2data(d),NULL) ) +#define strdb_iput(db,k,d) ( (db)->put((db),DB->str2key(k),DB->i2data(d),NULL) ) +#define i64db_iput(db,k,d) ( (db)->put((db),DB->i642key(k),DB->i2data(d),NULL) ) +#define ui64db_iput(db,k,d) ( (db)->put((db),DB->ui642key(k),DB->i2data(d),NULL) ) // Put uint-type data into DBMaps of various key types -#define db_uiput(db,k,d) ( (db)->put((db),(k),DB->ui2data(d),NULL) ) -#define idb_uiput(db,k,d) ( (db)->put((db),DB->i2key(k),DB->ui2data(d),NULL) ) -#define uidb_uiput(db,k,d) ( (db)->put((db),DB->ui2key(k),DB->ui2data(d),NULL) ) -#define strdb_uiput(db,k,d) ( (db)->put((db),DB->str2key(k),DB->ui2data(d),NULL) ) +#define db_uiput(db,k,d) ( (db)->put((db),(k),DB->ui2data(d),NULL) ) +#define idb_uiput(db,k,d) ( (db)->put((db),DB->i2key(k),DB->ui2data(d),NULL) ) +#define uidb_uiput(db,k,d) ( (db)->put((db),DB->ui2key(k),DB->ui2data(d),NULL) ) +#define strdb_uiput(db,k,d) ( (db)->put((db),DB->str2key(k),DB->ui2data(d),NULL) ) +#define i64db_uiput(db,k,d) ( (db)->put((db),DB->i642key(k),DB->ui2data(d),NULL) ) +#define ui64db_uiput(db,k,d) ( (db)->put((db),DB->ui642key(k),DB->ui2data(d),NULL) ) // Remove entry from DBMaps of various key types -#define db_remove(db,k) ( (db)->remove((db),(k),NULL) ) -#define idb_remove(db,k) ( (db)->remove((db),DB->i2key(k),NULL) ) -#define uidb_remove(db,k) ( (db)->remove((db),DB->ui2key(k),NULL) ) -#define strdb_remove(db,k) ( (db)->remove((db),DB->str2key(k),NULL) ) +#define db_remove(db,k) ( (db)->remove((db),(k),NULL) ) +#define idb_remove(db,k) ( (db)->remove((db),DB->i2key(k),NULL) ) +#define uidb_remove(db,k) ( (db)->remove((db),DB->ui2key(k),NULL) ) +#define strdb_remove(db,k) ( (db)->remove((db),DB->str2key(k),NULL) ) +#define i64db_remove(db,k) ( (db)->remove((db),DB->i642key(k),NULL) ) +#define ui64db_remove(db,k) ( (db)->remove((db),DB->ui642key(k),NULL) ) //These are discarding the possible vargs you could send to the function, so those //that require vargs must not use these defines. -#define db_ensure(db,k,f) ( DB->data2ptr((db)->ensure((db),(k),(f))) ) -#define idb_ensure(db,k,f) ( DB->data2ptr((db)->ensure((db),DB->i2key(k),(f))) ) -#define uidb_ensure(db,k,f) ( DB->data2ptr((db)->ensure((db),DB->ui2key(k),(f))) ) -#define strdb_ensure(db,k,f) ( DB->data2ptr((db)->ensure((db),DB->str2key(k),(f))) ) +#define db_ensure(db,k,f) ( DB->data2ptr((db)->ensure((db),(k),(f))) ) +#define idb_ensure(db,k,f) ( DB->data2ptr((db)->ensure((db),DB->i2key(k),(f))) ) +#define uidb_ensure(db,k,f) ( DB->data2ptr((db)->ensure((db),DB->ui2key(k),(f))) ) +#define strdb_ensure(db,k,f) ( DB->data2ptr((db)->ensure((db),DB->str2key(k),(f))) ) +#define i64db_ensure(db,k,f) ( DB->data2ptr((db)->ensure((db),DB->i642key(k),(f))) ) +#define ui64db_ensure(db,k,f) ( DB->data2ptr((db)->ensure((db),DB->ui642key(k),(f))) ) // Database creation and destruction macros #define idb_alloc(opt) DB->alloc(__FILE__,__func__,__LINE__,DB_INT,(opt),sizeof(int)) #define uidb_alloc(opt) DB->alloc(__FILE__,__func__,__LINE__,DB_UINT,(opt),sizeof(unsigned int)) #define strdb_alloc(opt,maxlen) DB->alloc(__FILE__,__func__,__LINE__,DB_STRING,(opt),(maxlen)) #define stridb_alloc(opt,maxlen) DB->alloc(__FILE__,__func__,__LINE__,DB_ISTRING,(opt),(maxlen)) +#define i64db_alloc(opt) DB->alloc(__FILE__,__func__,__LINE__,DB_INT64,(opt),sizeof(int64)) +#define ui64db_alloc(opt) DB->alloc(__FILE__,__func__,__LINE__,DB_UINT64,(opt),sizeof(uint64)) #define db_destroy(db) ( (db)->destroy((db),NULL) ) // Other macros -#define db_clear(db) ( (db)->clear(db,NULL) ) +#define db_clear(db) ( (db)->clear((db),NULL) ) #define db_size(db) ( (db)->size(db) ) #define db_iterator(db) ( (db)->iterator(db) ) -#define dbi_first(dbi) ( DB->data2ptr((dbi)->first(dbi,NULL)) ) -#define dbi_last(dbi) ( DB->data2ptr((dbi)->last(dbi,NULL)) ) -#define dbi_next(dbi) ( DB->data2ptr((dbi)->next(dbi,NULL)) ) -#define dbi_prev(dbi) ( DB->data2ptr((dbi)->prev(dbi,NULL)) ) -#define dbi_remove(dbi) ( (dbi)->remove(dbi,NULL) ) +#define dbi_first(dbi) ( DB->data2ptr((dbi)->first((dbi),NULL)) ) +#define dbi_last(dbi) ( DB->data2ptr((dbi)->last((dbi),NULL)) ) +#define dbi_next(dbi) ( DB->data2ptr((dbi)->next((dbi),NULL)) ) +#define dbi_prev(dbi) ( DB->data2ptr((dbi)->prev((dbi),NULL)) ) +#define dbi_remove(dbi) ( (dbi)->remove((dbi),NULL) ) #define dbi_exists(dbi) ( (dbi)->exists(dbi) ) #define dbi_destroy(dbi) ( (dbi)->destroy(dbi) ) @@ -682,6 +710,8 @@ struct DBMap { * db_i2key - Manual cast from 'int' to 'DBKey'. * * db_ui2key - Manual cast from 'unsigned int' to 'DBKey'. * * db_str2key - Manual cast from 'unsigned char *' to 'DBKey'. * + * db_i642key - Manual cast from 'int64' to 'DBKey'. * + * db_ui642key - Manual cast from 'uint64' to 'DBKey'. * * db_i2data - Manual cast from 'int' to 'DBData'. * * db_ui2data - Manual cast from 'unsigned int' to 'DBData'. * * db_ptr2data - Manual cast from 'void*' to 'DBData'. * @@ -803,6 +833,22 @@ DBKey (*ui2key) (unsigned int key); DBKey (*str2key) (const char *key); /** + * Manual cast from 'int64' to the union DBKey. + * @param key Key to be casted + * @return The key as a DBKey union + * @public + */ +DBKey (*i642key) (int64 key); + +/** + * Manual cast from 'uint64' to the union DBKey. + * @param key Key to be casted + * @return The key as a DBKey union + * @public + */ +DBKey (*ui642key) (uint64 key); + +/** * Manual cast from 'int' to the struct DBData. * @param data Data to be casted * @return The data as a DBData struct @@ -882,8 +928,8 @@ struct linkdb_node { typedef void (*LinkDBFunc)(void* key, void* data, va_list args); -void linkdb_insert (struct linkdb_node** head, void *key, void* data); // d•¡‚ðl—¶‚µ‚È‚¢ -void linkdb_replace (struct linkdb_node** head, void *key, void* data); // d•¡‚ðl—¶‚·‚é +void linkdb_insert (struct linkdb_node** head, void *key, void* data); // Doesn't take into account duplicate keys +void linkdb_replace (struct linkdb_node** head, void *key, void* data); // Takes into account duplicate keys void* linkdb_search (struct linkdb_node** head, void *key); void* linkdb_erase (struct linkdb_node** head, void *key); void linkdb_final (struct linkdb_node** head); @@ -1121,8 +1167,10 @@ void linkdb_foreach (struct linkdb_node** head, LinkDBFunc func, ...); #define VECTOR_ENSURE(__vec,__n,__step) \ do{ \ size_t _empty_ = VECTOR_CAPACITY(__vec)-VECTOR_LENGTH(__vec); \ - while( (__n) > _empty_ ) _empty_ += (__step); \ - if( _empty_ != VECTOR_CAPACITY(__vec)-VECTOR_LENGTH(__vec) ) VECTOR_RESIZE(__vec,_empty_+VECTOR_LENGTH(__vec)); \ + if( (__n) > _empty_ ) { \ + while( (__n) > _empty_ ) _empty_ += (__step); \ + VECTOR_RESIZE(__vec,_empty_+VECTOR_LENGTH(__vec)); \ + } \ }while(0) @@ -1500,4 +1548,4 @@ void linkdb_foreach (struct linkdb_node** head, LinkDBFunc func, ...); -#endif /* _DB_H_ */ +#endif /* _COMMON_DB_H_ */ diff --git a/src/common/des.h b/src/common/des.h index e42136436..3f55448ba 100644 --- a/src/common/des.h +++ b/src/common/des.h @@ -1,7 +1,7 @@ // Copyright (c) Athena Dev Teams - Licensed under GNU GPL // For more information, see LICENCE in the main folder -#ifndef _DES_H_ -#define _DES_H_ +#ifndef _COMMON_DES_H_ +#define _COMMON_DES_H_ /// One 64-bit block. @@ -12,4 +12,4 @@ void des_decrypt_block(BIT64* block); void des_decrypt(unsigned char* data, size_t size); -#endif // _DES_H_ +#endif // _COMMON_DES_H_ diff --git a/src/common/ers.c b/src/common/ers.c index 22269a51f..eb351a988 100644 --- a/src/common/ers.c +++ b/src/common/ers.c @@ -40,10 +40,12 @@ * @see common#ers.h * \*****************************************************************************/ #include <stdlib.h> +#include <string.h> #include "../common/cbasetypes.h" #include "../common/malloc.h" // CREATE, RECREATE, aMalloc, aFree #include "../common/showmsg.h" // ShowMessage, ShowError, ShowFatalError, CL_BOLD, CL_NORMAL +#include "../common/nullpo.h" #include "ers.h" #ifndef DISABLE_ERS @@ -87,6 +89,9 @@ typedef struct ers_cache // Default = ERS_BLOCK_ENTRIES, can be adjusted for performance for individual cache sizes. unsigned int ChunkSize; + // Misc options, some options are shared from the instance + enum ERSOptions Options; + // Linked list struct ers_cache *Next, *Prev; } ers_cache_t; @@ -122,12 +127,14 @@ static ers_cache_t *CacheList = NULL; static struct ers_instance_t *InstanceList = NULL; #endif -static ers_cache_t *ers_find_cache(unsigned int size) -{ +/** + * @param Options the options from the instance seeking a cache, we use it to give it a cache with matching configuration + **/ +static ers_cache_t *ers_find_cache(unsigned int size, enum ERSOptions Options) { ers_cache_t *cache; for (cache = CacheList; cache; cache = cache->Next) - if (cache->ObjectSize == size) + if ( cache->ObjectSize == size && cache->Options == ( Options & ERS_CACHE_OPTIONS ) ) return cache; CREATE(cache, ers_cache_t, 1); @@ -140,6 +147,7 @@ static ers_cache_t *ers_find_cache(unsigned int size) cache->UsedObjs = 0; cache->Max = 0; cache->ChunkSize = ERS_BLOCK_ENTRIES; + cache->Options = (Options & ERS_CACHE_OPTIONS); if (CacheList == NULL) { @@ -238,6 +246,9 @@ static void ers_obj_free_entry(ERS self, void *entry) return; } + if( instance->Cache->Options & ERS_OPT_CLEAN ) + memset((unsigned char*)reuse + sizeof(struct ers_list), 0, instance->Cache->ObjectSize - sizeof(struct ers_list)); + reuse->Next = instance->Cache->ReuseList; instance->Cache->ReuseList = reuse; instance->Count--; @@ -293,9 +304,10 @@ static void ers_obj_destroy(ERS self) void ers_cache_size(ERS self, unsigned int new_size) { struct ers_instance_t *instance = (struct ers_instance_t *)self; - if (instance == NULL) {//change as per piotrhalaczkiewicz comment - ShowError("ers_cache_size: NULL object, skipping...\n"); - return; + nullpo_retv(instance); + + if( !(instance->Cache->Options&ERS_OPT_FLEX_CHUNK) ) { + ShowWarning("ers_cache_size: '%s' has adjusted its chunk size to '%d', however ERS_OPT_FLEX_CHUNK is missing!\n",instance->Name,new_size); } instance->Cache->ChunkSize = new_size; @@ -320,7 +332,8 @@ ERS ers_new(uint32 size, char *name, enum ERSOptions options) instance->Name = ( options & ERS_OPT_FREE_NAME ) ? aStrdup(name) : name; instance->Options = options; - instance->Cache = ers_find_cache(size); + instance->Cache = ers_find_cache(size,instance->Options); + instance->Cache->ReferenceCount++; #ifdef DEBUG if (InstanceList == NULL) { diff --git a/src/common/ers.h b/src/common/ers.h index 51701d778..4dae19f3b 100644 --- a/src/common/ers.h +++ b/src/common/ers.h @@ -37,8 +37,8 @@ * @author Flavio @ Amazon Project * * @encoding US-ASCII * \*****************************************************************************/ -#ifndef _ERS_H_ -#define _ERS_H_ +#ifndef _COMMON_ERS_H_ +#define _COMMON_ERS_H_ #include "../common/cbasetypes.h" @@ -71,10 +71,15 @@ #endif /* not ERS_ALIGN_ENTRY */ enum ERSOptions { - ERS_OPT_NONE = 0x0, - ERS_OPT_CLEAR = 0x1,/* silently clears any entries left in the manager upon destruction */ - ERS_OPT_WAIT = 0x2,/* wait for entries to come in order to list! */ - ERS_OPT_FREE_NAME = 0x4,/* name is dynamic memory, and should be freed */ + ERS_OPT_NONE = 0x0, + ERS_OPT_CLEAR = 0x1,/* silently clears any entries left in the manager upon destruction */ + ERS_OPT_WAIT = 0x2,/* wait for entries to come in order to list! */ + ERS_OPT_FREE_NAME = 0x4,/* name is dynamic memory, and should be freed */ + ERS_OPT_CLEAN = 0x8,/* clears used memory upon ers_free so that its all new to be reused on the next alloc */ + ERS_OPT_FLEX_CHUNK = 0x10,/* signs that it should look for its own cache given it'll have a dynamic chunk size, so that it doesn't affect the other ERS it'd otherwise be sharing */ + + /* Compound, is used to determine whether it should be looking for a cache of matching options */ + ERS_CACHE_OPTIONS = ERS_OPT_CLEAN|ERS_OPT_FLEX_CHUNK, }; /** @@ -137,11 +142,11 @@ typedef struct eri { #else /* not DISABLE_ERS */ // These defines should be used to allow the code to keep working whenever // the system is disabled -# define ers_alloc(obj,type) (type *)(obj)->alloc(obj) -# define ers_free(obj,entry) (obj)->free((obj),(entry)) -# define ers_entry_size(obj) (obj)->entry_size(obj) -# define ers_destroy(obj) (obj)->destroy(obj) -# define ers_chunk_size(obj,size) (obj)->chunk_size(obj,size) +# define ers_alloc(obj,type) ((type *)(obj)->alloc(obj)) +# define ers_free(obj,entry) ((obj)->free((obj),(entry))) +# define ers_entry_size(obj) ((obj)->entry_size(obj)) +# define ers_destroy(obj) ((obj)->destroy(obj)) +# define ers_chunk_size(obj,size) ((obj)->chunk_size((obj),(size))) /** * Get a new instance of the manager that handles the specified entry size. @@ -175,4 +180,4 @@ void ers_report(void); void ers_force_destroy_all(void); #endif /* DISABLE_ERS / not DISABLE_ERS */ -#endif /* _ERS_H_ */ +#endif /* _COMMON_ERS_H_ */ diff --git a/src/common/grfio.c b/src/common/grfio.c index 77b976926..57e8a5187 100644 --- a/src/common/grfio.c +++ b/src/common/grfio.c @@ -8,6 +8,7 @@ #include "../common/showmsg.h" #include "../common/strlib.h" #include "../common/utils.h" +#include "../common/nullpo.h" #include "grfio.h" #include <stdio.h> @@ -305,17 +306,21 @@ static FILELIST* filelist_find(const char* fname) // returns the original file name char* grfio_find_file(const char* fname) { - FILELIST *filelist = filelist_find(fname); - if (!filelist) return NULL; - return (!filelist->fnd ? filelist->fn : filelist->fnd); + FILELIST *flist = filelist_find(fname); + if (!flist) return NULL; + return (!flist->fnd ? flist->fn : flist->fnd); } // adds a FILELIST entry into the list of loaded files -static FILELIST* filelist_add(FILELIST* entry) -{ +static FILELIST* filelist_add(FILELIST* entry) { int hash; + nullpo_ret(entry); +#ifdef __clang_analyzer__ + // Make clang's static analyzer shut up about a possible NULL pointer in &filelist[filelist_entrys] + nullpo_ret(&filelist[filelist_entrys]); +#endif // __clang_analyzer__ - #define FILELIST_ADDS 1024 // number increment of file lists ` +#define FILELIST_ADDS 1024 // number increment of file lists ` if (filelist_entrys >= filelist_maxentry) { filelist = (FILELIST *)aRealloc(filelist, (filelist_maxentry + FILELIST_ADDS) * sizeof(FILELIST)); @@ -323,7 +328,9 @@ static FILELIST* filelist_add(FILELIST* entry) filelist_maxentry += FILELIST_ADDS; } - memcpy (&filelist[filelist_entrys], entry, sizeof(FILELIST)); +#undef FILELIST_ADDS + + memcpy(&filelist[filelist_entrys], entry, sizeof(FILELIST)); hash = filehash(entry->fn); filelist[filelist_entrys].next = filelist_hash[hash]; @@ -405,7 +412,7 @@ void* grfio_reads(const char* fname, int* size) if( in != NULL ) { int declen; fseek(in,0,SEEK_END); - declen = ftell(in); + declen = (int)ftell(in); fseek(in,0,SEEK_SET); buf2 = (unsigned char *)aMalloc(declen+1); // +1 for resnametable zero-termination if(fread(buf2, 1, declen, in) != (size_t)declen) ShowError("An error occured in fread grfio_reads, fname=%s \n",fname); diff --git a/src/common/grfio.h b/src/common/grfio.h index c5a56a14e..4f5d0d6bc 100644 --- a/src/common/grfio.h +++ b/src/common/grfio.h @@ -1,17 +1,17 @@ // Copyright (c) Athena Dev Teams - Licensed under GNU GPL // For more information, see LICENCE in the main folder -#ifndef _GRFIO_H_ -#define _GRFIO_H_ +#ifndef _COMMON_GRFIO_H_ +#define _COMMON_GRFIO_H_ void grfio_init(const char* fname); void grfio_final(void); void* grfio_reads(const char* fname, int* size); char* grfio_find_file(const char* fname); -#define grfio_read(fn) grfio_reads(fn, NULL) +#define grfio_read(fn) grfio_reads((fn), NULL) unsigned long grfio_crc32(const unsigned char *buf, unsigned int len); int decode_zip(void* dest, unsigned long* destLen, const void* source, unsigned long sourceLen); int encode_zip(void* dest, unsigned long* destLen, const void* source, unsigned long sourceLen); -#endif /* _GRFIO_H_ */ +#endif /* _COMMON_GRFIO_H_ */ diff --git a/src/common/malloc.c b/src/common/malloc.c index 4d2c93b77..f7f108304 100644 --- a/src/common/malloc.c +++ b/src/common/malloc.c @@ -19,28 +19,28 @@ struct malloc_interface iMalloc_s; # include <string.h> # include "memwatch.h" -# define MALLOC(n,file,line,func) mwMalloc((n),(file),(line)) -# define CALLOC(m,n,file,line,func) mwCalloc((m),(n),(file),(line)) -# define REALLOC(p,n,file,line,func) mwRealloc((p),(n),(file),(line)) -# define STRDUP(p,file,line,func) mwStrdup((p),(file),(line)) -# define FREE(p,file,line,func) mwFree((p),(file),(line)) -# define MEMORY_USAGE() 0 -# define MEMORY_VERIFY(ptr) mwIsSafeAddr(ptr, 1) -# define MEMORY_CHECK() CHECK() +# define MALLOC(n,file,line,func) mwMalloc((n),(file),(line)) +# define CALLOC(m,n,file,line,func) mwCalloc((m),(n),(file),(line)) +# define REALLOC(p,n,file,line,func) mwRealloc((p),(n),(file),(line)) +# define STRDUP(p,file,line,func) mwStrdup((p),(file),(line)) +# define FREE(p,file,line,func) mwFree((p),(file),(line)) +# define MEMORY_USAGE() (size_t)0 +# define MEMORY_VERIFY(ptr) mwIsSafeAddr((ptr), 1) +# define MEMORY_CHECK() CHECK() #elif defined(DMALLOC) # include <string.h> # include <stdlib.h> # include "dmalloc.h" -# define MALLOC(n,file,line,func) dmalloc_malloc((file),(line),(n),DMALLOC_FUNC_MALLOC,0,0) -# define CALLOC(m,n,file,line,func) dmalloc_malloc((file),(line),(m)*(n),DMALLOC_FUNC_CALLOC,0,0) -# define REALLOC(p,n,file,line,func) dmalloc_realloc((file),(line),(p),(n),DMALLOC_FUNC_REALLOC,0) -# define STRDUP(p,file,line,func) strdup(p) -# define FREE(p,file,line,func) free(p) -# define MEMORY_USAGE() dmalloc_memory_allocated() -# define MEMORY_VERIFY(ptr) (dmalloc_verify(ptr) == DMALLOC_VERIFY_NOERROR) -# define MEMORY_CHECK() dmalloc_log_stats(); dmalloc_log_unfreed() +# define MALLOC(n,file,line,func) dmalloc_malloc((file),(line),(n),DMALLOC_FUNC_MALLOC,0,0) +# define CALLOC(m,n,file,line,func) dmalloc_malloc((file),(line),(m)*(n),DMALLOC_FUNC_CALLOC,0,0) +# define REALLOC(p,n,file,line,func) dmalloc_realloc((file),(line),(p),(n),DMALLOC_FUNC_REALLOC,0) +# define STRDUP(p,file,line,func) strdup(p) +# define FREE(p,file,line,func) free(p) +# define MEMORY_USAGE() dmalloc_memory_allocated() +# define MEMORY_VERIFY(ptr) (dmalloc_verify(ptr) == DMALLOC_VERIFY_NOERROR) +# define MEMORY_CHECK() do { dmalloc_log_stats(); dmalloc_log_unfreed() } while(0) #elif defined(GCOLLECT) @@ -50,24 +50,26 @@ struct malloc_interface iMalloc_s; # else # define RETURN_ADDR # endif -# define MALLOC(n,file,line,func) GC_debug_malloc((n), RETURN_ADDR (file),(line)) -# define CALLOC(m,n,file,line,func) GC_debug_malloc((m)*(n), RETURN_ADDR (file),(line)) -# define REALLOC(p,n,file,line,func) GC_debug_realloc((p),(n), RETURN_ADDR (file),(line)) -# define STRDUP(p,file,line,func) GC_debug_strdup((p), RETURN_ADDR (file),(line)) -# define FREE(p,file,line,func) GC_debug_free(p) -# define MEMORY_USAGE() GC_get_heap_size() -# define MEMORY_VERIFY(ptr) (GC_base(ptr) != NULL) -# define MEMORY_CHECK() GC_gcollect() +# define MALLOC(n,file,line,func) GC_debug_malloc((n), RETURN_ADDR (file),(line)) +# define CALLOC(m,n,file,line,func) GC_debug_malloc((m)*(n), RETURN_ADDR (file),(line)) +# define REALLOC(p,n,file,line,func) GC_debug_realloc((p),(n), RETURN_ADDR (file),(line)) +# define STRDUP(p,file,line,func) GC_debug_strdup((p), RETURN_ADDR (file),(line)) +# define FREE(p,file,line,func) GC_debug_free(p) +# define MEMORY_USAGE() GC_get_heap_size() +# define MEMORY_VERIFY(ptr) (GC_base(ptr) != NULL) +# define MEMORY_CHECK() GC_gcollect() + +# undef RETURN_ADDR #else -# define MALLOC(n,file,line,func) malloc(n) -# define CALLOC(m,n,file,line,func) calloc((m),(n)) -# define REALLOC(p,n,file,line,func) realloc((p),(n)) -# define STRDUP(p,file,line,func) strdup(p) -# define FREE(p,file,line,func) free(p) -# define MEMORY_USAGE() 0 -# define MEMORY_VERIFY(ptr) true +# define MALLOC(n,file,line,func) malloc(n) +# define CALLOC(m,n,file,line,func) calloc((m),(n)) +# define REALLOC(p,n,file,line,func) realloc((p),(n)) +# define STRDUP(p,file,line,func) strdup(p) +# define FREE(p,file,line,func) free(p) +# define MEMORY_USAGE() (size_t)0 +# define MEMORY_VERIFY(ptr) true # define MEMORY_CHECK() #endif @@ -367,6 +369,37 @@ void* _mrealloc(void *memblock, size_t size, const char *file, int line, const c } } +/* a _mrealloc clone with the difference it 'z'eroes the newly created memory */ +void* _mreallocz(void *memblock, size_t size, const char *file, int line, const char *func ) { + size_t old_size; + void *p = NULL; + + if(memblock == NULL) { + p = iMalloc->malloc(size,file,line,func); + memset(p,0,size); + return p; + } + + old_size = ((struct unit_head *)((char *)memblock - sizeof(struct unit_head) + sizeof(long)))->size; + if( old_size == 0 ) { + old_size = ((struct unit_head_large *)((char *)memblock - sizeof(struct unit_head_large) + sizeof(long)))->size; + } + if(old_size > size) { + // Size reduction - return> as it is (negligence) + return memblock; + } else { + // Size Large + p = iMalloc->malloc(size,file,line,func); + if(p != NULL) { + memcpy(p,memblock,old_size); + memset((char*)p+old_size,0,size-old_size); + } + iMalloc->free(memblock,file,line,func); + return p; + } +} + + char* _mstrdup(const char *p, const char *file, int line, const char *func ) { if(p == NULL) { @@ -667,7 +700,7 @@ void memmgr_report (int extra) { struct { const char *file; unsigned short line; - unsigned int size; + size_t size; unsigned int count; } data[100]; memset(&data, 0, sizeof(data)); @@ -820,12 +853,14 @@ void malloc_defaults(void) { iMalloc->malloc = _mmalloc; iMalloc->calloc = _mcalloc; iMalloc->realloc = _mrealloc; + iMalloc->reallocz= _mreallocz; iMalloc->astrdup = _mstrdup; iMalloc->free = _mfree; #else iMalloc->malloc = aMalloc_; iMalloc->calloc = aCalloc_; iMalloc->realloc = aRealloc_; + iMalloc->reallocz= aRealloc_;/* not using memory manager huhum o.o perhaps we could still do something about */ iMalloc->astrdup = aStrdup_; iMalloc->free = aFree_; #endif diff --git a/src/common/malloc.h b/src/common/malloc.h index bc8aa9a20..7309bb0f7 100644 --- a/src/common/malloc.h +++ b/src/common/malloc.h @@ -1,8 +1,8 @@ // Copyright (c) Athena Dev Teams - Licensed under GNU GPL // For more information, see LICENCE in the main folder -#ifndef _MALLOC_H_ -#define _MALLOC_H_ +#ifndef _COMMON_MALLOC_H_ +#define _COMMON_MALLOC_H_ #include "../common/cbasetypes.h" @@ -30,11 +30,12 @@ #undef LOG_MEMMGR #endif -# define aMalloc(n) iMalloc->malloc (n,ALC_MARK) -# define aCalloc(m,n) iMalloc->calloc (m,n,ALC_MARK) -# define aRealloc(p,n) iMalloc->realloc (p,n,ALC_MARK) -# define aStrdup(p) iMalloc->astrdup (p,ALC_MARK) -# define aFree(p) iMalloc->free (p,ALC_MARK) +# define aMalloc(n) (iMalloc->malloc((n),ALC_MARK)) +# define aCalloc(m,n) (iMalloc->calloc((m),(n),ALC_MARK)) +# define aRealloc(p,n) (iMalloc->realloc((p),(n),ALC_MARK)) +# define aReallocz(p,n) (iMalloc->reallocz((p),(n),ALC_MARK)) +# define aStrdup(p) (iMalloc->astrdup((p),ALC_MARK)) +# define aFree(p) (iMalloc->free((p),ALC_MARK)) /////////////// Buffer Creation ///////////////// // Full credit for this goes to Shinomori [Ajarn] @@ -46,15 +47,15 @@ #else // others don't, so we emulate them -#define CREATE_BUFFER(name, type, size) type *name = (type *) aCalloc (size, sizeof(type)) +#define CREATE_BUFFER(name, type, size) type *name = (type *) aCalloc((size), sizeof(type)) #define DELETE_BUFFER(name) aFree(name) #endif ////////////// Others ////////////////////////// // should be merged with any of above later -#define CREATE(result, type, number) (result) = (type *) aCalloc ((number), sizeof(type)) -#define RECREATE(result, type, number) (result) = (type *) aRealloc ((result), sizeof(type) * (number)) +#define CREATE(result, type, number) ((result) = (type *) aCalloc((number), sizeof(type))) +#define RECREATE(result, type, number) ((result) = (type *) aReallocz((result), sizeof(type) * (number))) //////////////////////////////////////////////// @@ -73,6 +74,7 @@ struct malloc_interface { void* (*malloc )(size_t size, const char *file, int line, const char *func); void* (*calloc )(size_t num, size_t size, const char *file, int line, const char *func); void* (*realloc )(void *p, size_t size, const char *file, int line, const char *func); + void* (*reallocz)(void *p, size_t size, const char *file, int line, const char *func); char* (*astrdup )(const char *p, const char *file, int line, const char *func); void (*free )(void *p, const char *file, int line, const char *func); /* */ @@ -86,4 +88,4 @@ struct malloc_interface { void memmgr_report (int extra); struct malloc_interface *iMalloc; -#endif /* _MALLOC_H_ */ +#endif /* _COMMON_MALLOC_H_ */ diff --git a/src/common/mapindex.c b/src/common/mapindex.c index 83de21b2b..3128a3cb0 100644 --- a/src/common/mapindex.c +++ b/src/common/mapindex.c @@ -13,15 +13,9 @@ #include <stdio.h> #include <stdlib.h> -struct _indexes { - char name[MAP_NAME_LENGTH]; //Stores map name -} indexes[MAX_MAPINDEX]; +/* mapindex.c interface source */ +struct mapindex_interface mapindex_s; -int max_index = 0; - -char mapindex_cfgfile[80] = "db/map_index.txt"; - -#define mapindex_exists(id) (indexes[id].name[0] != '\0') /// Retrieves the map name from 'string' (removing .gat extension if present). /// Result gets placed either into 'buf' or in a static local buffer. const char* mapindex_getmapname(const char* string, char* output) { @@ -78,9 +72,8 @@ int mapindex_addmap(int index, const char* name) { char map_name[MAP_NAME_LENGTH]; if (index == -1){ - for (index = 1; index < max_index; index++) { - //if (strcmp(indexes[index].name,"#CLEARED#")==0) - if (indexes[index].name[0] == '\0') + for (index = 1; index < mapindex->num; index++) { + if (mapindex->list[index].name[0] == '\0') break; } } @@ -90,7 +83,7 @@ int mapindex_addmap(int index, const char* name) { return 0; } - mapindex_getmapname(name, map_name); + mapindex->getmapname(name, map_name); if (map_name[0] == '\0') { ShowError("(mapindex_add) Cannot add maps with no name.\n"); @@ -103,14 +96,15 @@ int mapindex_addmap(int index, const char* name) { } if (mapindex_exists(index)) { - ShowWarning("(mapindex_add) Overriding index %d: map \"%s\" -> \"%s\"\n", index, indexes[index].name, map_name); - strdb_remove(mapindex_db, indexes[index].name); + ShowWarning("(mapindex_add) Overriding index %d: map \"%s\" -> \"%s\"\n", index, mapindex->list[index].name, map_name); + strdb_remove(mapindex->db, mapindex->list[index].name); } - safestrncpy(indexes[index].name, map_name, MAP_NAME_LENGTH); - strdb_iput(mapindex_db, map_name, index); - if (max_index <= index) - max_index = index+1; + safestrncpy(mapindex->list[index].name, map_name, MAP_NAME_LENGTH); + strdb_iput(mapindex->db, map_name, index); + + if (mapindex->num <= index) + mapindex->num = index+1; return index; } @@ -119,9 +113,9 @@ unsigned short mapindex_name2id(const char* name) { int i; char map_name[MAP_NAME_LENGTH]; - mapindex_getmapname(name, map_name); + mapindex->getmapname(name, map_name); - if( (i = strdb_iget(mapindex_db, map_name)) ) + if( (i = strdb_iget(mapindex->db, map_name)) ) return i; ShowDebug("mapindex_name2id: Map \"%s\" not found in index list!\n", map_name); @@ -131,24 +125,25 @@ unsigned short mapindex_name2id(const char* name) { const char* mapindex_id2name_sub(unsigned short id,const char *file, int line, const char *func) { if (id > MAX_MAPINDEX || !mapindex_exists(id)) { ShowDebug("mapindex_id2name: Requested name for non-existant map index [%d] in cache. %s:%s:%d\n", id,file,func,line); - return indexes[0].name; // dummy empty string so that the callee doesn't crash + return mapindex->list[0].name; // dummy empty string so that the callee doesn't crash } - return indexes[id].name; + return mapindex->list[id].name; } -void mapindex_init(void) { +int mapindex_init(void) { FILE *fp; char line[1024]; int last_index = -1; - int index; + int index, total = 0; char map_name[12]; - if( ( fp = fopen(mapindex_cfgfile,"r") ) == NULL ){ - ShowFatalError("Unable to read mapindex config file %s!\n", mapindex_cfgfile); + if( ( fp = fopen(mapindex->config_file,"r") ) == NULL ){ + ShowFatalError("Unable to read mapindex config file %s!\n", mapindex->config_file); exit(EXIT_FAILURE); //Server can't really run without this file. } - memset (&indexes, 0, sizeof (indexes)); - mapindex_db = strdb_alloc(DB_OPT_DUP_KEY, MAP_NAME_LENGTH); + + mapindex->db = strdb_alloc(DB_OPT_DUP_KEY, MAP_NAME_LENGTH); + while(fgets(line, sizeof(line), fp)) { if(line[0] == '/' && line[1] == '/') continue; @@ -157,7 +152,8 @@ void mapindex_init(void) { case 1: //Map with no ID given, auto-assign index = last_index+1; case 2: //Map with ID given - mapindex_addmap(index,map_name); + mapindex->addmap(index,map_name); + total++; break; default: continue; @@ -166,16 +162,40 @@ void mapindex_init(void) { } fclose(fp); - if( !strdb_iget(mapindex_db, MAP_DEFAULT) ) { + if( !strdb_iget(mapindex->db, MAP_DEFAULT) ) { ShowError("mapindex_init: MAP_DEFAULT '%s' not found in cache! update mapindex.h MAP_DEFAULT var!!!\n",MAP_DEFAULT); } + + return total; } -int mapindex_removemap(int index){ - indexes[index].name[0] = '\0'; - return 0; +void mapindex_removemap(int index){ + strdb_remove(mapindex->db, mapindex->list[index].name); + mapindex->list[index].name[0] = '\0'; } void mapindex_final(void) { - db_destroy(mapindex_db); + db_destroy(mapindex->db); +} + +void mapindex_defaults(void) { + mapindex = &mapindex_s; + + /* TODO: place it in inter-server.conf? */ + snprintf(mapindex->config_file, 80, "%s","db/map_index.txt"); + /* */ + mapindex->db = NULL; + mapindex->num = 0; + memset (&mapindex->list, 0, sizeof (mapindex->list)); + + /* */ + mapindex->init = mapindex_init; + mapindex->final = mapindex_final; + /* */ + mapindex->addmap = mapindex_addmap; + mapindex->removemap = mapindex_removemap; + mapindex->getmapname = mapindex_getmapname; + mapindex->getmapname_ext = mapindex_getmapname_ext; + mapindex->name2id = mapindex_name2id; + mapindex->id2name = mapindex_id2name_sub; } diff --git a/src/common/mapindex.h b/src/common/mapindex.h index 43953a8e0..fa9b9e920 100644 --- a/src/common/mapindex.h +++ b/src/common/mapindex.h @@ -2,21 +2,20 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _MAPINDEX_H_ -#define _MAPINDEX_H_ +#ifndef _COMMON_MAPINDEX_H_ +#define _COMMON_MAPINDEX_H_ #include "../common/db.h" +#include "../common/mmo.h" + +#define MAX_MAPINDEX 2000 + +/* wohoo, someone look at all those |: map_default could (or *should*) be a char-server.conf */ // When a map index search fails, return results from what map? default:prontera #define MAP_DEFAULT "prontera" #define MAP_DEFAULT_X 150 #define MAP_DEFAULT_Y 150 -DBMap *mapindex_db; - -//File in charge of assigning a numberic ID to each map in existance for space saving when passing map info between servers. -extern char mapindex_cfgfile[80]; - -#define MAX_MAPINDEX 2000 //Some definitions for the mayor city maps. #define MAP_PRONTERA "prontera" @@ -56,15 +55,39 @@ extern char mapindex_cfgfile[80]; #define MAP_MALAYA "malaya" #define MAP_ECLAGE "eclage" -const char* mapindex_getmapname(const char* string, char* output); -const char* mapindex_getmapname_ext(const char* string, char* output); -unsigned short mapindex_name2id(const char*); -#define mapindex_id2name(n) mapindex_id2name_sub(n,__FILE__, __LINE__, __func__) -const char* mapindex_id2name_sub(unsigned short,const char *file, int line, const char *func); -void mapindex_init(void); -void mapindex_final(void); +#define mapindex_id2name(n) mapindex->id2name((n),__FILE__, __LINE__, __func__) +#define mapindex_exists(n) ( mapindex->list[(n)].name[0] != '\0' ) + +/** + * mapindex.c interface + **/ +struct mapindex_interface { + char config_file[80]; + /* mapname (str) -> index (int) */ + DBMap *db; + /* number of entries in the index table */ + int num; + /* index list -- since map server map count is *unlimited* this should be too */ + struct { + char name[MAP_NAME_LENGTH]; + } list[MAX_MAPINDEX]; + /* */ + int (*init) (void); + void (*final) (void); + /* */ + int (*addmap) (int index, const char* name); + void (*removemap) (int index); + const char* (*getmapname) (const char* string, char* output); + /* TODO: server shouldn't be handling the extension, game client automatically adds .gat/.rsw/.whatever + * and there are official map names taking advantage of it that we cant support due to the .gat room being saved */ + const char* (*getmapname_ext) (const char* string, char* output); + /* TODO: Hello World! make up your mind, this thing is int on some places and unsigned short on others */ + unsigned short (*name2id) (const char*); + const char* (*id2name) (unsigned short,const char *file, int line, const char *func); +}; + +struct mapindex_interface *mapindex; -int mapindex_addmap(int index, const char* name); -int mapindex_removemap(int index); +void mapindex_defaults(void); -#endif /* _MAPINDEX_H_ */ +#endif /* _COMMON_MAPINDEX_H_ */ diff --git a/src/common/md5calc.h b/src/common/md5calc.h index 323affa2c..d0caf6787 100644 --- a/src/common/md5calc.h +++ b/src/common/md5calc.h @@ -1,8 +1,8 @@ -#ifndef _MD5CALC_H_ -#define _MD5CALC_H_ +#ifndef _COMMON_MD5CALC_H_ +#define _COMMON_MD5CALC_H_ void MD5_String(const char * string, char * output); void MD5_Binary(const char * string, unsigned char * output); void MD5_Salt(unsigned int len, char * output); -#endif /* _MD5CALC_H_ */ +#endif /* _COMMON_MD5CALC_H_ */ diff --git a/src/common/mempool.c b/src/common/mempool.c index 5eccbf178..4559d8f2a 100644 --- a/src/common/mempool.c +++ b/src/common/mempool.c @@ -30,16 +30,16 @@ #include "../common/malloc.h" #include "../common/mutex.h" -#define ALIGN16 ra_align(16) -#define ALIGN_TO(x, a) (x + ( a - ( x % a) ) ) -#define ALIGN_TO_16(x) ALIGN_TO(x, 16) +#define ALIGN16 ra_align(16) +#define ALIGN_TO(x, a) ((x) + ( (a) - ( (x) % (a)) ) ) +#define ALIGN_TO_16(x) ALIGN_TO((x), 16) #undef MEMPOOL_DEBUG #define MEMPOOLASSERT -#define NODE_TO_DATA(x) ( ((char*)x) + sizeof(struct node) ) -#define DATA_TO_NODE(x) ( (struct node*)(((char*)x) - sizeof(struct node)) ) +#define NODE_TO_DATA(x) ( ((char*)(x)) + sizeof(struct node) ) +#define DATA_TO_NODE(x) ( (struct node*)(((char*)(x)) - sizeof(struct node)) ) struct ra_align(16) node{ void *next; void *segment; diff --git a/src/common/mmo.h b/src/common/mmo.h index 205cf8425..2b66c516c 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -2,8 +2,8 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _MMO_H_ -#define _MMO_H_ +#ifndef _COMMON_MMO_H_ +#define _COMMON_MMO_H_ #include "cbasetypes.h" #include "../common/db.h" @@ -48,18 +48,20 @@ // 20120307 - 2012-03-07aRagexeRE+ - 0x970 #ifndef PACKETVER - #define PACKETVER 20120418 -#endif + #define PACKETVER 20131223 +#endif // PACKETVER -// Comment the following line if your client is NOT ragexeRE (required because of conflicting packets in ragexe vs ragexeRE). -#define PACKETVER_RE +//Uncomment the following line if your client is ragexeRE instead of ragexe (required because of conflicting packets in ragexe vs ragexeRE). +//#define ENABLE_PACKETVER_RE +#ifdef ENABLE_PACKETVER_RE + #define PACKETVER_RE + #undef ENABLE_PACKETVER_RE +#endif // DISABLE_PACKETVER_RE // Client support for experimental RagexeRE UI present in 2012-04-10 and 2012-04-18 -#ifdef PACKETVER_RE -#if (PACKETVER == 20120410) || (PACKETVER == 20120418) - #define PARTY_RECRUIT -#endif -#endif +#if defined(PACKETVER_RE) && ( PACKETVER == 20120410 || PACKETVER == 20120418 ) +#define PARTY_RECRUIT +#endif // PACKETVER_RE && (PACKETVER == 20120410 || PACKETVER == 10120418) // Comment the following line to disable sc_data saving. [Skotlex] #define ENABLE_SC_SAVING @@ -90,6 +92,10 @@ //Max amount of a single stacked item #define MAX_AMOUNT 30000 #define MAX_ZENY 1000000000 + +//Official Limit: 2.1b ( the var that stores the money doesn't go much higher than this by default ) +#define MAX_BANK_ZENY 2100000000 + #define MAX_FAME 1000000000 #define MAX_CART 100 #define MAX_SKILL 1478 @@ -97,25 +103,19 @@ //Update this max as necessary. 55 is the value needed for Super Baby currently //Raised to 84 since Expanded Super Novice needs it. #define MAX_SKILL_TREE 84 -#define GLOBAL_REG_NUM 256 // Max permanent character variables per char -#define ACCOUNT_REG_NUM 64 // Max permanent local account variables per account -#define ACCOUNT_REG2_NUM 16 // Max permanent global account variables per account -//Should hold the max of GLOBAL/ACCOUNT/ACCOUNT2 (needed for some arrays that hold all three) -#define MAX_REG_NUM 256 #define DEFAULT_WALK_SPEED 150 -#define MIN_WALK_SPEED 0 +#define MIN_WALK_SPEED 20 /* below 20 clips animation */ #define MAX_WALK_SPEED 1000 #define MAX_STORAGE 600 #define MAX_GUILD_STORAGE 600 #define MAX_PARTY 12 -#define MAX_GUILD 16+10*6 // Increased max guild members +6 per 1 extension levels [Lupus] +#define MAX_GUILD (16+10*6) // Increased max guild members +6 per 1 extension levels [Lupus] #define MAX_GUILDPOSITION 20 // Increased max guild positions to accomodate for all members [Valaris] (removed) [PoW] #define MAX_GUILDEXPULSION 32 #define MAX_GUILDALLIANCE 16 #define MAX_GUILDSKILL 15 // Increased max guild skills because of new skills [Sara-chan] #define MAX_GUILDLEVEL 50 #define MAX_GUARDIANS 8 // Local max per castle. [Skotlex] -#define MAX_QUEST_DB 2662 // Max quests that the server will load #define MAX_QUEST_OBJECTIVES 3 // Max quest objectives for a quest #define MAX_START_ITEMS 32 // Max number of items allowed to be given to a char whenever it's created. [mkbu95] @@ -180,6 +180,8 @@ #define EL_CLASS_BASE 2114 #define EL_CLASS_MAX (EL_CLASS_BASE+MAX_ELEMENTAL_CLASS-1) +struct HPluginData; + enum item_types { IT_HEALING = 0, IT_UNKNOWN, //1 @@ -198,27 +200,33 @@ enum item_types { }; -// Questlog system [Kevin] [Inkfish] -typedef enum quest_state { Q_INACTIVE, Q_ACTIVE, Q_COMPLETE } quest_state; +// Questlog states +enum quest_state { + Q_INACTIVE, ///< Inactive quest (the user can toggle between active and inactive quests) + Q_ACTIVE, ///< Active quest + Q_COMPLETE, ///< Completed quest +}; +/// Questlog entry struct quest { - int quest_id; - unsigned int time; - int count[MAX_QUEST_OBJECTIVES]; - quest_state state; + int quest_id; ///< Quest ID + unsigned int time; ///< Expiration time + int count[MAX_QUEST_OBJECTIVES]; ///< Kill counters of each quest objective + enum quest_state state; ///< Current quest state }; struct item { int id; short nameid; short amount; - unsigned short equip; // Location(s) where item is equipped (using enum equip_pos for bitmasking). + unsigned int equip; // Location(s) where item is equipped (using enum equip_pos for bitmasking). char identify; char refine; char attribute; short card[MAX_SLOTS]; unsigned int expire_time; char favorite; + unsigned char bound; uint64 unique_id; }; @@ -245,28 +253,41 @@ enum e_mmo_charstatus_opt { OPT_ALLOW_PARTY = 0x2, }; +enum e_item_bound_type { + IBT_MIN = 0x1, + IBT_ACCOUNT = 0x1, + IBT_GUILD = 0x2, + IBT_PARTY = 0x3, + IBT_CHARACTER = 0x4, + IBT_MAX = 0x4, +}; + struct s_skill { unsigned short id; unsigned char lv; unsigned char flag; // See enum e_skill_flag }; -struct global_reg { - char str[32]; - char value[256]; +struct script_reg_state { + unsigned int type : 1;/* because I'm a memory hoarder and having them in the same struct would be a 8-byte/instance waste while ints outnumber str on a 10000-to-1 ratio. */ + unsigned int update : 1;/* whether it needs to be sent to char server for insertion/update/delete */ }; -// Holds array of global registries, used by the char server and converter. -struct accreg { - int account_id, char_id; - int reg_num; - struct global_reg reg[MAX_REG_NUM]; +struct script_reg_num { + struct script_reg_state flag; + int value; +}; + +struct script_reg_str { + struct script_reg_state flag; + char *value; }; // For saving status changes across sessions. [Skotlex] struct status_change_data { unsigned short type; //SC_type - long val1, val2, val3, val4, tick; //Remaining duration. + int val1, val2, val3, val4; + unsigned int tick; //Remaining duration. }; struct storage_data { @@ -366,6 +387,7 @@ struct mmo_charstatus { unsigned int base_exp,job_exp; int zeny; + int bank_vault; short class_; unsigned int status_point,skill_point; @@ -409,6 +431,11 @@ struct mmo_charstatus { unsigned short slotchange; time_t delete_date; + + /* `account_data` modifiers */ + unsigned short mod_exp,mod_drop,mod_death; + + unsigned char font; }; typedef enum mail_status { @@ -458,15 +485,6 @@ struct auction_data { int auction_end_timer; }; -struct registry { - int global_num; - struct global_reg global[GLOBAL_REG_NUM]; - int account_num; - struct global_reg account[ACCOUNT_REG_NUM]; - int account2_num; - struct global_reg account2[ACCOUNT_REG2_NUM]; -}; - struct party_member { int account_id; int char_id; @@ -484,7 +502,7 @@ struct party { unsigned char count; //Count of online characters. unsigned exp : 1, item : 2; //&1: Party-Share (round-robin), &2: pickup style: shared. - struct party_member member[MAX_PARTY]; + struct party_member member[MAX_PARTY]; }; struct map_session_data; @@ -522,6 +540,7 @@ struct guild_skill { int id,lv; }; +struct hChSysCh; struct guild { int guild_id; short guild_lv, connect_member, max_member, average_lv; @@ -538,13 +557,17 @@ struct guild { struct guild_expulsion expulsion[MAX_GUILDEXPULSION]; struct guild_skill skill[MAX_GUILDSKILL]; - /* TODO: still used for something?|: */ - unsigned short save_flag; // for TXT saving + /* used on char.c to state what kind of data is being saved/processed */ + unsigned short save_flag; short *instance; unsigned short instances; - void *channel; + struct hChSysCh *channel; + + /* HPM Custom Struct */ + struct HPluginData **hdata; + unsigned int hdatac; }; struct guild_castle { @@ -833,10 +856,34 @@ enum ammo_type { A_THROWWEAPON //9 }; +enum e_char_server_type { + CST_NORMAL = 0, + CST_MAINTENANCE = 1, + CST_OVER18 = 2, + CST_PAYING = 3, + CST_F2P = 4, +}; + +enum e_pc_reg_loading { + PRL_NONE = 0x0, + PRL_CHAR = 0x1, + PRL_ACCL = 0x2,/* local */ + PRL_ACCG = 0x4,/* global */ + PRL_ALL = 0xFF, +}; + +/* packet size constant for itemlist */ +#if MAX_INVENTORY > MAX_STORAGE && MAX_INVENTORY > MAX_CART +#define MAX_ITEMLIST MAX_INVENTORY +#elif MAX_CART > MAX_INVENTORY && MAX_CART > MAX_STORAGE +#define MAX_ITEMLIST MAX_CART +#else +#define MAX_ITEMLIST MAX_STORAGE +#endif // sanity checks... #if MAX_ZENY > INT_MAX #error MAX_ZENY is too big #endif -#endif /* _MMO_H_ */ +#endif /* _COMMON_MMO_H_ */ diff --git a/src/common/mutex.h b/src/common/mutex.h index 1999627cd..eeb24e6ff 100644 --- a/src/common/mutex.h +++ b/src/common/mutex.h @@ -1,8 +1,8 @@ // Copyright (c) rAthena Project (www.rathena.org) - Licensed under GNU GPL // For more information, see LICENCE in the main folder -#ifndef _rA_MUTEX_H_ -#define _rA_MUTEX_H_ +#ifndef _COMMON_MUTEX_H_ +#define _COMMON_MUTEX_H_ typedef struct ramutex *ramutex; // Mutex @@ -89,4 +89,4 @@ void racond_signal( racond c ); void racond_broadcast( racond c ); -#endif +#endif /* _COMMON_MUTEX_H_ */ diff --git a/src/common/netbuffer.h b/src/common/netbuffer.h index 844241226..6ddecfdd9 100644 --- a/src/common/netbuffer.h +++ b/src/common/netbuffer.h @@ -73,11 +73,9 @@ void netbuffer_incref( netbuf buf ); // Some Useful macros -#define NBUFP(netbuf,pos) (((uint8*)(netbuf->buf)) + (pos)) -#define NBUFB(netbuf,pos) (*(uint8*)((netbuf->buf) + (pos))) -#define NBUFW(netbuf,pos) (*(uint16*)((netbuf->buf) + (pos))) -#define NBUFL(netbuf,pos) (*(uint32*)((netbuf->buf) + (pos))) - - +#define NBUFP(netbuf,pos) (((uint8*)((netbuf)->buf)) + (pos)) +#define NBUFB(netbuf,pos) (*(uint8*)(((netbuf)->buf) + (pos))) +#define NBUFW(netbuf,pos) (*(uint16*)(((netbuf)->buf) + (pos))) +#define NBUFL(netbuf,pos) (*(uint32*)(((netbuf)->buf) + (pos))) #endif diff --git a/src/common/network.c b/src/common/network.c index 1f1621363..a40cbd602 100644 --- a/src/common/network.c +++ b/src/common/network.c @@ -50,7 +50,7 @@ SESSION g_Session[MAXCONN]; static bool onSend(int32 fd); -#define _network_free_netbuf_async( buf ) add_timer( 0, _network_async_free_netbuf_proc, 0, (intptr_t) buf) +#define _network_free_netbuf_async( buf ) add_timer( 0, _network_async_free_netbuf_proc, 0, (intptr_t)(buf)) static int _network_async_free_netbuf_proc(int tid, unsigned int tick, int id, intptr_t data){ // netbuf is in data netbuffer_put( (netbuf)data ); diff --git a/src/common/nullpo.c b/src/common/nullpo.c index 4383109a7..1cb471aff 100644 --- a/src/common/nullpo.c +++ b/src/common/nullpo.c @@ -1,91 +1,30 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena Dev Teams #include <stdio.h> #include <stdarg.h> #include <string.h> -#include "nullpo.h" +#include "../common/nullpo.h" #include "../common/showmsg.h" -// #include "logs.h" // •z΂µ‚Ă݂é -static void nullpo_info_core(const char *file, int line, const char *func, - const char *fmt, va_list ap); - -/*====================================== - * Nullƒ`ƒFƒbƒN ‹y‚Ñ î•ño—Í - *--------------------------------------*/ -int nullpo_chk_f(const char *file, int line, const char *func, const void *target, - const char *fmt, ...) -{ - va_list ap; - - if (target != NULL) - return 0; - - va_start(ap, fmt); - nullpo_info_core(file, line, func, fmt, ap); - va_end(ap); - return 1; -} - -int nullpo_chk(const char *file, int line, const char *func, const void *target) -{ - if (target != NULL) - return 0; - - nullpo_info_core(file, line, func, NULL, NULL); - return 1; -} - - -/*====================================== - * nullpoî•ño—Í(ŠO•”ŒÄo‚µŒü‚¯ƒ‰ƒbƒp) - *--------------------------------------*/ -void nullpo_info_f(const char *file, int line, const char *func, - const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - nullpo_info_core(file, line, func, fmt, ap); - va_end(ap); -} - -void nullpo_info(const char *file, int line, const char *func) -{ - nullpo_info_core(file, line, func, NULL, NULL); -} - - -/*====================================== - * nullpoî•ño—Í(Main) - *--------------------------------------*/ -static void nullpo_info_core(const char *file, int line, const char *func, - const char *fmt, va_list ap) -{ +/** + * Reports failed assertions or NULL pointers + * + * @param file Source file where the error was detected + * @param line Line + * @param func Function + * @param targetname Name of the checked symbol + * @param title Message title to display (i.e. failed assertion or nullpo info) + */ +void assert_report(const char *file, int line, const char *func, const char *targetname, const char *title) { if (file == NULL) file = "??"; - func = - func == NULL ? "unknown": - func[0] == '\0' ? "unknown": - func; - - ShowMessage("--- nullpo info --------------------------------------------\n"); - ShowMessage("%s:%d: in func `%s'\n", file, line, func); - if (fmt != NULL) - { - if (fmt[0] != '\0') - { - vprintf(fmt, ap); - - // ÅŒã‚ɉüs‚µ‚½‚©Šm”F - if (fmt[strlen(fmt)-1] != '\n') - ShowMessage("\n"); - } - } - ShowMessage("--- end nullpo info ----------------------------------------\n"); + if (func == NULL || *func == '\0') + func = "unknown"; - // ‚±‚±‚ç‚ÅnullpoƒƒO‚ðƒtƒ@ƒCƒ‹‚É‘‚«o‚¹‚½‚ç - // ‚܂Ƃ߂Ēño‚Å‚«‚é‚ȂƎv‚Á‚Ä‚¢‚½‚èB + ShowError("--- %s --------------------------------------------\n", title); + ShowError("%s:%d: '%s' in function `%s'\n", file, line, targetname, func); + ShowError("--- end %s ----------------------------------------\n", title); } diff --git a/src/common/nullpo.h b/src/common/nullpo.h index 8ee86a782..fb1cf0feb 100644 --- a/src/common/nullpo.h +++ b/src/common/nullpo.h @@ -1,225 +1,128 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder - -#ifndef _NULLPO_H_ -#define _NULLPO_H_ +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena Dev Teams +#ifndef _COMMON_NULLPO_H_ +#define _COMMON_NULLPO_H_ #include "../common/cbasetypes.h" -#define NLP_MARK __FILE__, __LINE__, __func__ - // enabled by default on debug builds #if defined(DEBUG) && !defined(NULLPO_CHECK) #define NULLPO_CHECK #endif -/*---------------------------------------------------------------------------- - * Macros - *---------------------------------------------------------------------------- - */ -/*====================================== - * Nullƒ`ƒFƒbƒN ‹y‚Ñ î•ño—ÍŒã return - *E“WŠJ‚·‚邯if‚Æ‚©return“™‚ªo‚é‚̂Š- * ˆês’P‘̂Ŏg‚Á‚Ä‚‚¾‚³‚¢B - *Enullpo_ret(x = func()); - * ‚̂悤‚ÈŽg—p–@‚à‘z’肵‚Ä‚¢‚Ü‚·B - *-------------------------------------- - * nullpo_ret(t) - * –ß‚è’l 0ŒÅ’è - * [ˆø”] - * t ƒ`ƒFƒbƒN‘ÎÛ - *-------------------------------------- - * nullpo_retv(t) - * –ß‚è’l ‚È‚µ - * [ˆø”] - * t ƒ`ƒFƒbƒN‘ÎÛ - *-------------------------------------- - * nullpo_retr(ret, t) - * –ß‚è’l Žw’è - * [ˆø”] - * ret return(ret); - * t ƒ`ƒFƒbƒN‘ÎÛ - *-------------------------------------- - * nullpo_ret_f(t, fmt, ...) - * Ú×î•ño—Í—p - * –ß‚è’l 0 - * [ˆø”] - * t ƒ`ƒFƒbƒN‘ÎÛ - * fmt ... vprintf‚É“n‚³‚ê‚é - * ”õl‚âŠÖŒW•Ï”‚Ì‘‚«o‚µ‚È‚Ç‚É - *-------------------------------------- - * nullpo_retv_f(t, fmt, ...) - * Ú×î•ño—Í—p - * –ß‚è’l ‚È‚µ - * [ˆø”] - * t ƒ`ƒFƒbƒN‘ÎÛ - * fmt ... vprintf‚É“n‚³‚ê‚é - * ”õl‚âŠÖŒW•Ï”‚Ì‘‚«o‚µ‚È‚Ç‚É - *-------------------------------------- - * nullpo_retr_f(ret, t, fmt, ...) - * Ú×î•ño—Í—p - * –ß‚è’l Žw’è - * [ˆø”] - * ret return(ret); - * t ƒ`ƒFƒbƒN‘ÎÛ - * fmt ... vprintf‚É“n‚³‚ê‚é - * ”õl‚âŠÖŒW•Ï”‚Ì‘‚«o‚µ‚È‚Ç‚É - *-------------------------------------- - */ +// Skip assert checks on release builds +#if !defined(RELEASE) && !defined(ASSERT_CHECK) +#define ASSERT_CHECK +#endif + +/** Assert */ + +#if defined(ASSERT_CHECK) +// extern "C" { +#include <assert.h> +// } +#if !defined(DEFCPP) && defined(WIN32) && !defined(MINGW) +#include <crtdbg.h> +#endif // !DEFCPP && WIN && !MINGW +#define Assert(EX) assert(EX) +#define Assert_chk(EX) ( (EX) ? false : (assert_report(__FILE__, __LINE__, __func__, #EX, "failed assertion"), true) ) +#else // ! ASSERT_CHECK +#define Assert(EX) (EX) +#define Assert_chk(EX) ((EX), false) +#endif // ASSERT_CHECK #if defined(NULLPO_CHECK) +/** + * Reports NULL pointer information if the passed pointer is NULL + * + * @param t pointer to check + * @return true if the passed pointer is NULL, false otherwise + */ +#define nullpo_chk(t) ( (t) != NULL ? false : (assert_report(__FILE__, __LINE__, __func__, #t, "nullpo info"), true) ) +#else // ! NULLPO_CHECK +#define nullpo_chk(t) ((void)(t), false) +#endif // NULLPO_CHECK + +/** + * The following macros check for NULL pointers and return from the current + * function or block in case one is found. + * + * It is guaranteed that the argument is evaluated once and only once, so it + * is safe to call them as: + * nullpo_ret(x = func()); + * The macros can be used safely in any context, as they expand to a do/while + * construct, except nullpo_retb, which expands to an if/else construct. + */ +/** + * Returns 0 if a NULL pointer is found. + * + * @param t pointer to check + */ #define nullpo_ret(t) \ - if (nullpo_chk(NLP_MARK, (void *)(t))) {return(0);} - -#define nullpo_retv(t) \ - if (nullpo_chk(NLP_MARK, (void *)(t))) {return;} - -#define nullpo_retr(ret, t) \ - if (nullpo_chk(NLP_MARK, (void *)(t))) {return(ret);} - -#define nullpo_retb(t) \ - if (nullpo_chk(NLP_MARK, (void *)(t))) {break;} - -// ‰Â•ψø”ƒ}ƒNƒ‚ÉŠÖ‚·‚éðŒƒRƒ“ƒpƒCƒ‹ -#if __STDC_VERSION__ >= 199901L -/* C99‚ɑΉž */ -#define nullpo_ret_f(t, fmt, ...) \ - if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), __VA_ARGS__)) {return(0);} - -#define nullpo_retv_f(t, fmt, ...) \ - if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), __VA_ARGS__)) {return;} - -#define nullpo_retr_f(ret, t, fmt, ...) \ - if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), __VA_ARGS__)) {return(ret);} - -#define nullpo_retb_f(t, fmt, ...) \ - if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), __VA_ARGS__)) {break;} + do { if (nullpo_chk(t)) return(0); } while(0) -#elif __GNUC__ >= 2 -/* GCC—p */ -#define nullpo_ret_f(t, fmt, args...) \ - if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), ## args)) {return(0);} - -#define nullpo_retv_f(t, fmt, args...) \ - if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), ## args)) {return;} - -#define nullpo_retr_f(ret, t, fmt, args...) \ - if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), ## args)) {return(ret);} - -#define nullpo_retb_f(t, fmt, args...) \ - if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), ## args)) {break;} - -#else - -/* ‚»‚Ì‘¼‚Ìê‡EEE orz */ - -#endif - -#else /* NULLPO_CHECK */ -/* No Nullpo check */ - -// if((t)){;} -// —Ç‚¢•û–@‚ªŽv‚¢‚‚©‚È‚©‚Á‚½‚Ì‚ÅEEE‹ê“÷‚Ìô‚Å‚·B -// ˆê‰žƒ[ƒjƒ“ƒO‚Ío‚È‚¢‚Í‚¸ - -#define nullpo_ret(t) (void)(t) -#define nullpo_retv(t) (void)(t) -#define nullpo_retr(ret, t) (void)(t) -#define nullpo_retb(t) (void)(t) - -// ‰Â•ψø”ƒ}ƒNƒ‚ÉŠÖ‚·‚éðŒƒRƒ“ƒpƒCƒ‹ -#if __STDC_VERSION__ >= 199901L -/* C99‚ɑΉž */ -#define nullpo_ret_f(t, fmt, ...) (void)(t) -#define nullpo_retv_f(t, fmt, ...) (void)(t) -#define nullpo_retr_f(ret, t, fmt, ...) (void)(t) -#define nullpo_retb_f(t, fmt, ...) (void)(t) - -#elif __GNUC__ >= 2 -/* GCC—p */ -#define nullpo_ret_f(t, fmt, args...) (void)(t) -#define nullpo_retv_f(t, fmt, args...) (void)(t) -#define nullpo_retr_f(ret, t, fmt, args...) (void)(t) -#define nullpo_retb_f(t, fmt, args...) (void)(t) - -#else -/* ‚»‚Ì‘¼‚Ìê‡EEE orz */ -#endif +/** + * Returns 0 if the given assertion fails. + * + * @param t statement to check + */ +#define Assert_ret(t) \ + do { if (Assert_chk(t)) return(0); } while(0) -#endif /* NULLPO_CHECK */ +/** + * Returns void if a NULL pointer is found. + * + * @param t pointer to check + */ +#define nullpo_retv(t) \ + do { if (nullpo_chk(t)) return; } while(0) -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------- +/** + * Returns void if the given assertion fails. + * + * @param t statement to check */ -/*====================================== - * nullpo_chk - * Nullƒ`ƒFƒbƒN ‹y‚Ñ î•ño—Í - * [ˆø”] - * file __FILE__ - * line __LINE__ - * func __func__ (ŠÖ”–¼) - * ‚±‚ê‚ç‚É‚Í NLP_MARK ‚ðŽg‚¤‚Ƃ悢 - * target ƒ`ƒFƒbƒN‘ÎÛ - * [•Ô‚è’l] - * 0 OK - * 1 NULL - *-------------------------------------- +#define Assert_retv(t) \ + do { if (Assert_chk(t)) return; } while(0) + +/** + * Returns the given value if a NULL pointer is found. + * + * @param ret value to return + * @param t pointer to check */ -int nullpo_chk(const char *file, int line, const char *func, const void *target); - - -/*====================================== - * nullpo_chk_f - * Nullƒ`ƒFƒbƒN ‹y‚Ñ ÚׂÈî•ño—Í - * [ˆø”] - * file __FILE__ - * line __LINE__ - * func __func__ (ŠÖ”–¼) - * ‚±‚ê‚ç‚É‚Í NLP_MARK ‚ðŽg‚¤‚Ƃ悢 - * target ƒ`ƒFƒbƒN‘ÎÛ - * fmt ... vprintf‚É“n‚³‚ê‚é - * ”õl‚âŠÖŒW•Ï”‚Ì‘‚«o‚µ‚È‚Ç‚É - * [•Ô‚è’l] - * 0 OK - * 1 NULL - *-------------------------------------- +#define nullpo_retr(ret, t) \ + do { if (nullpo_chk(t)) return(ret); } while(0) + +/** + * Returns the given value if the given assertion fails. + * + * @param ret value to return + * @param t statement to check */ -int nullpo_chk_f(const char *file, int line, const char *func, const void *target, - const char *fmt, ...) - __attribute__((format(printf,5,6))); - - -/*====================================== - * nullpo_info - * nullpoî•ño—Í - * [ˆø”] - * file __FILE__ - * line __LINE__ - * func __func__ (ŠÖ”–¼) - * ‚±‚ê‚ç‚É‚Í NLP_MARK ‚ðŽg‚¤‚Ƃ悢 - *-------------------------------------- +#define Assert_retr(ret, t) \ + do { if (Assert_chk(t)) return(ret); } while(0) + +/** + * Breaks from the current loop/switch if a NULL pointer is found. + * + * @param t pointer to check */ -void nullpo_info(const char *file, int line, const char *func); - - -/*====================================== - * nullpo_info_f - * nullpoÚ×î•ño—Í - * [ˆø”] - * file __FILE__ - * line __LINE__ - * func __func__ (ŠÖ”–¼) - * ‚±‚ê‚ç‚É‚Í NLP_MARK ‚ðŽg‚¤‚Ƃ悢 - * fmt ... vprintf‚É“n‚³‚ê‚é - * ”õl‚âŠÖŒW•Ï”‚Ì‘‚«o‚µ‚È‚Ç‚É - *-------------------------------------- +#define nullpo_retb(t) \ + if (nullpo_chk(t)) break; else (void)0 + +/** + * Breaks from the current loop/switch if the given assertion fails. + * + * @param t statement to check */ -void nullpo_info_f(const char *file, int line, const char *func, - const char *fmt, ...) - __attribute__((format(printf,4,5))); +#define Assert_retb(t) \ + if (Assert_chk(t)) break; else (void)0 + +void assert_report(const char *file, int line, const char *func, const char *targetname, const char *title); -#endif /* _NULLPO_H_ */ +#endif /* _COMMON_NULLPO_H_ */ diff --git a/src/common/raconf.c b/src/common/raconf.c index f7d1284b7..abeed444b 100644 --- a/src/common/raconf.c +++ b/src/common/raconf.c @@ -382,21 +382,20 @@ static bool configParse(raconf inst, const char *fileName){ }//end: configParse() -#define MAKEKEY(dest, section, key) { size_t section_len, key_len; \ - if(section == NULL || *section == '\0'){ \ - strncpy(dest, "<unnamed>", 9); \ - section_len = 9; \ - }else{ \ - section_len = strlen(section); \ - strncpy(dest, section, section_len); \ - } \ - \ - dest[section_len] = '.'; \ - \ - key_len = strlen(key); \ - strncpy(&dest[section_len+1], key, key_len); \ - dest[section_len + key_len + 1] = '\0'; \ - } +#define MAKEKEY(dest, section, key) do { \ + size_t section_len_, key_len_; \ + if((section) == NULL || *(section) == '\0'){ \ + strncpy((dest), "<unnamed>", 9); \ + section_len_ = 9; \ + } else { \ + section_len_ = strlen(section); \ + strncpy((dest), (section), section_len_); \ + } \ + (dest)[section_len_] = '.'; \ + key_len_ = strlen(key); \ + strncpy(&(dest)[section_len_+1], (key), key_len_); \ + (dest)[section_len_ + key_len_ + 1] = '\0'; \ +} while(0) raconf raconf_parse(const char *file_name){ diff --git a/src/common/random.c b/src/common/random.c index 2f1b62934..e46c52cad 100644 --- a/src/common/random.c +++ b/src/common/random.c @@ -17,17 +17,17 @@ /// Initializes the random number generator with an appropriate seed. void rnd_init(void) { - uint32 seed = timer->gettick(); - seed += (uint32)time(NULL); + unsigned long seed = (unsigned long)timer->gettick(); + seed += (unsigned long)time(NULL); #if defined(WIN32) - seed += GetCurrentProcessId(); - seed += GetCurrentThreadId(); + seed += (unsigned long)GetCurrentProcessId(); + seed += (unsigned long)GetCurrentThreadId(); #else #if defined(HAVE_GETPID) - seed += (uint32)getpid(); + seed += (unsigned long)getpid(); #endif // HAVE_GETPID #if defined(HAVE_GETTID) - seed += (uint32)gettid(); + seed += (unsigned long)gettid(); #endif // HAVE_GETTID #endif init_genrand(seed); diff --git a/src/common/random.h b/src/common/random.h index 43dfd36c0..ab83fb4d4 100644 --- a/src/common/random.h +++ b/src/common/random.h @@ -1,8 +1,8 @@ // Copyright (c) Athena Dev Teams - Licensed under GNU GPL // For more information, see LICENCE in the main folder -#ifndef _RANDOM_H_ -#define _RANDOM_H_ +#ifndef _COMMON_RANDOM_H_ +#define _COMMON_RANDOM_H_ #include "../common/cbasetypes.h" @@ -15,4 +15,4 @@ int32 rnd_value(int32 min, int32 max);// [min, max] double rnd_uniform(void);// [0.0, 1.0) double rnd_uniform53(void);// [0.0, 1.0) -#endif /* _RANDOM_H_ */ +#endif /* _COMMON_RANDOM_H_ */ diff --git a/src/common/showmsg.c b/src/common/showmsg.c index 9e0f63003..14342fe5e 100644 --- a/src/common/showmsg.c +++ b/src/common/showmsg.c @@ -16,33 +16,17 @@ #include "../../3rdparty/libconfig/libconfig.h" #ifdef WIN32 - #include "../common/winapi.h" - - #ifdef DEBUGLOGMAP - #define DEBUGLOGPATH "log\\map-server.log" - #else - #ifdef DEBUGLOGCHAR - #define DEBUGLOGPATH "log\\char-server.log" - #else - #ifdef DEBUGLOGLOGIN - #define DEBUGLOGPATH "log\\login-server.log" - #endif - #endif - #endif -#else - #include <unistd.h> - - #ifdef DEBUGLOGMAP - #define DEBUGLOGPATH "log/map-server.log" - #else - #ifdef DEBUGLOGCHAR - #define DEBUGLOGPATH "log/char-server.log" - #else - #ifdef DEBUGLOGLOGIN - #define DEBUGLOGPATH "log/login-server.log" - #endif - #endif - #endif +#include "../common/winapi.h" +#else // not WIN32 +#include <unistd.h> +#endif // WIN32 + +#if defined(DEBUGLOGMAP) +#define DEBUGLOGPATH "log"PATHSEP_STR"map-server.log" +#elif defined(DEBUGLOGCHAR) +#define DEBUGLOGPATH "log"PATHSEP_STR"char-server.log" +#elif defined(DEBUGLOGLOGIN) +#define DEBUGLOGPATH "log"PATHSEP_STR"login-server.log" #endif /////////////////////////////////////////////////////////////////////////////// @@ -61,41 +45,40 @@ int console_msg_log = 0;//[Ind] msg error logging #define SBUF_SIZE 2054 // never put less that what's required for the debug message -#define NEWBUF(buf) \ - struct { \ - char s_[SBUF_SIZE]; \ - StringBuf *d_; \ - char *v_; \ - int l_; \ - } buf ={"",NULL,NULL,0}; \ +#define NEWBUF(buf) \ + struct { \ + char s_[SBUF_SIZE]; \ + StringBuf *d_; \ + char *v_; \ + int l_; \ + } buf ={"",NULL,NULL,0}; \ //define NEWBUF -#define BUFVPRINTF(buf,fmt,args) \ - buf.l_ = vsnprintf(buf.s_, SBUF_SIZE, fmt, args); \ - if( buf.l_ >= 0 && buf.l_ < SBUF_SIZE ) \ - {/* static buffer */ \ - buf.v_ = buf.s_; \ - } \ - else \ - {/* dynamic buffer */ \ - buf.d_ = StrBuf->Malloc(); \ - buf.l_ = StrBuf->Vprintf(buf.d_, fmt, args); \ - buf.v_ = StrBuf->Value(buf.d_); \ - ShowDebug("showmsg: dynamic buffer used, increase the static buffer size to %d or more.\n", buf.l_+1);\ - } \ -//define BUFVPRINTF - -#define BUFVAL(buf) buf.v_ -#define BUFLEN(buf) buf.l_ - -#define FREEBUF(buf) \ - if( buf.d_ ) \ - { \ - StrBuf->Free(buf.d_); \ - buf.d_ = NULL; \ - } \ - buf.v_ = NULL; \ -//define FREEBUF +#define BUFVPRINTF(buf,fmt,args) do { \ + (buf).l_ = vsnprintf((buf).s_, SBUF_SIZE, (fmt), args); \ + if( (buf).l_ >= 0 && (buf).l_ < SBUF_SIZE ) \ + {/* static buffer */ \ + (buf).v_ = (buf).s_; \ + } \ + else \ + {/* dynamic buffer */ \ + (buf).d_ = StrBuf->Malloc(); \ + (buf).l_ = StrBuf->Vprintf((buf).d_, (fmt), args); \ + (buf).v_ = StrBuf->Value((buf).d_); \ + ShowDebug("showmsg: dynamic buffer used, increase the static buffer size to %d or more.\n", (buf).l_+1); \ + } \ +} while(0) //define BUFVPRINTF + +#define BUFVAL(buf) ((buf).v_) +#define BUFLEN(buf) ((buf).l_) + +#define FREEBUF(buf) do {\ + if( (buf).d_ ) { \ + StrBuf->Free((buf).d_); \ + (buf).d_ = NULL; \ + } \ + (buf).v_ = NULL; \ +} while(0) //define FREEBUF /////////////////////////////////////////////////////////////////////////////// #ifdef _WIN32 @@ -666,14 +649,6 @@ int FPRINTF(FILE *file, const char *fmt, ...) #endif// not _WIN32 - - - - - - - - char timestamp_format[20] = ""; //For displaying Timestamps int _vShowMessage(enum msg_type flag, const char *string, va_list ap) diff --git a/src/common/showmsg.h b/src/common/showmsg.h index 59a0d9538..49fbc34fb 100644 --- a/src/common/showmsg.h +++ b/src/common/showmsg.h @@ -2,12 +2,15 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _SHOWMSG_H_ -#define _SHOWMSG_H_ +#ifndef _COMMON_SHOWMSG_H_ +#define _COMMON_SHOWMSG_H_ -#ifndef _HPMi_H_ +#ifndef _COMMON_HPMI_H_ #include "../../3rdparty/libconfig/libconfig.h" #endif + +#include <stdarg.h> + // for help with the console colors look here: // http://www.edoceo.com/liberum/?doc=printf-with-color // some code explanation (used here): @@ -87,7 +90,7 @@ enum msg_type { }; extern void ClearScreen(void); -#ifndef _HPMi_H_ +#ifndef _COMMON_HPMI_H_ extern void ShowMessage(const char *, ...); extern void ShowStatus(const char *, ...); extern void ShowSQL(const char *, ...); @@ -99,5 +102,6 @@ extern void ClearScreen(void); extern void ShowFatalError(const char *, ...); extern void ShowConfigWarning(config_setting_t *config, const char *string, ...); #endif +extern int _vShowMessage(enum msg_type flag, const char *string, va_list ap); -#endif /* _SHOWMSG_H_ */ +#endif /* _COMMON_SHOWMSG_H_ */ diff --git a/src/common/socket.c b/src/common/socket.c index 7c8b3738b..35d350e95 100644 --- a/src/common/socket.c +++ b/src/common/socket.c @@ -10,6 +10,9 @@ #include "../common/strlib.h" #include "../config/core.h" #include "../common/HPM.h" + +#define _H_SOCKET_C_ + #include "socket.h" #include <stdio.h> @@ -43,6 +46,19 @@ #endif #endif +/** + * Socket Interface Source + **/ +struct socket_interface sockt_s; + +#ifdef SEND_SHORTLIST + // Add a fd to the shortlist so that it'll be recognized as a fd that needs + // sending done on it. + void send_shortlist_add_fd(int fd); + // Do pending network sends (and eof handling) from the shortlist. + void send_shortlist_do_sends(); +#endif + ///////////////////////////////////////////////////////////////////// #if defined(WIN32) ///////////////////////////////////////////////////////////////////// @@ -157,19 +173,19 @@ char* sErr(int code) return sbuf; } -#define sBind(fd,name,namelen) bind(fd2sock(fd),name,namelen) -#define sConnect(fd,name,namelen) connect(fd2sock(fd),name,namelen) -#define sIoctl(fd,cmd,argp) ioctlsocket(fd2sock(fd),cmd,argp) -#define sListen(fd,backlog) listen(fd2sock(fd),backlog) -#define sRecv(fd,buf,len,flags) recv(fd2sock(fd),buf,len,flags) -#define sSelect select -#define sSend(fd,buf,len,flags) send(fd2sock(fd),buf,len,flags) -#define sSetsockopt(fd,level,optname,optval,optlen) setsockopt(fd2sock(fd),level,optname,optval,optlen) -#define sShutdown(fd,how) shutdown(fd2sock(fd),how) -#define sFD_SET(fd,set) FD_SET(fd2sock(fd),set) -#define sFD_CLR(fd,set) FD_CLR(fd2sock(fd),set) -#define sFD_ISSET(fd,set) FD_ISSET(fd2sock(fd),set) -#define sFD_ZERO FD_ZERO +#define sBind(fd,name,namelen) bind(fd2sock(fd),(name),(namelen)) +#define sConnect(fd,name,namelen) connect(fd2sock(fd),(name),(namelen)) +#define sIoctl(fd,cmd,argp) ioctlsocket(fd2sock(fd),(cmd),(argp)) +#define sListen(fd,backlog) listen(fd2sock(fd),(backlog)) +#define sRecv(fd,buf,len,flags) recv(fd2sock(fd),(buf),(len),(flags)) +#define sSelect select +#define sSend(fd,buf,len,flags) send(fd2sock(fd),(buf),(len),(flags)) +#define sSetsockopt(fd,level,optname,optval,optlen) setsockopt(fd2sock(fd),(level),(optname),(optval),(optlen)) +#define sShutdown(fd,how) shutdown(fd2sock(fd),(how)) +#define sFD_SET(fd,set) FD_SET(fd2sock(fd),(set)) +#define sFD_CLR(fd,set) FD_CLR(fd2sock(fd),(set)) +#define sFD_ISSET(fd,set) FD_ISSET(fd2sock(fd),(set)) +#define sFD_ZERO FD_ZERO ///////////////////////////////////////////////////////////////////// #else @@ -212,12 +228,6 @@ char* sErr(int code) #endif fd_set readfds; -int fd_max; -time_t last_tick; -time_t stall_time = 60; - -uint32 addr_[16]; // ip addresses of local host (host byte order) -int naddr_ = 0; // # of ip addresses // Maximum packet size in bytes, which the client is able to handle. // Larger packets cause a buffer overflow and stack corruption. @@ -328,7 +338,7 @@ void setsocketopts(int fd, struct hSockOpt *opt) { *--------------------------------------*/ void set_eof(int fd) { - if( session_isActive(fd) ) + if( sockt->session_isActive(fd) ) { #ifdef SEND_SHORTLIST // Add this socket to the shortlist for eof handling. @@ -340,9 +350,9 @@ void set_eof(int fd) int recv_to_fifo(int fd) { - int len; + ssize_t len; - if( !session_isActive(fd) ) + if( !sockt->session_isActive(fd) ) return -1; len = sRecv(fd, (char *) session[fd]->rdata + session[fd]->rdata_size, (int)RFIFOSPACE(fd), 0); @@ -363,7 +373,7 @@ int recv_to_fifo(int fd) } session[fd]->rdata_size += len; - session[fd]->rdata_tick = last_tick; + session[fd]->rdata_tick = sockt->last_tick; #ifdef SHOW_SERVER_STATS socket_data_i += len; socket_data_qi += len; @@ -377,9 +387,9 @@ int recv_to_fifo(int fd) int send_from_fifo(int fd) { - int len; + ssize_t len; - if( !session_isValid(fd) ) + if( !sockt->session_isValid(fd) ) return -1; if( session[fd]->wdata_size == 0 ) @@ -431,8 +441,8 @@ void flush_fifo(int fd) void flush_fifos(void) { int i; - for(i = 1; i < fd_max; i++) - flush_fifo(i); + for(i = 1; i < sockt->fd_max; i++) + sockt->flush_fifo(i); } /*====================================== @@ -466,12 +476,12 @@ int connect_client(int listen_fd) { #ifndef MINICORE if( ip_rules && !connect_check(ntohl(client_address.sin_addr.s_addr)) ) { - do_close(fd); + sockt->close(fd); return -1; } #endif - if( fd_max <= fd ) fd_max = fd + 1; + if( sockt->fd_max <= fd ) sockt->fd_max = fd + 1; sFD_SET(fd,&readfds); create_session(fd, recv_to_fifo, send_from_fifo, default_func_parse); @@ -521,7 +531,7 @@ int make_listen_bind(uint32 ip, uint16 port) exit(EXIT_FAILURE); } - if(fd_max <= fd) fd_max = fd + 1; + if(sockt->fd_max <= fd) sockt->fd_max = fd + 1; sFD_SET(fd, &readfds); create_session(fd, connect_client, null_send, null_parse); @@ -566,13 +576,13 @@ int make_connection(uint32 ip, uint16 port, struct hSockOpt *opt) { if( result == SOCKET_ERROR ) { if( !( opt && opt->silent ) ) ShowError("make_connection: connect failed (socket #%d, %s)!\n", fd, error_msg()); - do_close(fd); + sockt->close(fd); return -1; } //Now the socket can be made non-blocking. [Skotlex] set_nonblocking(fd, 1); - if (fd_max <= fd) fd_max = fd + 1; + if (sockt->fd_max <= fd) sockt->fd_max = fd + 1; sFD_SET(fd,&readfds); create_session(fd, recv_to_fifo, send_from_fifo, default_func_parse); @@ -591,7 +601,7 @@ static int create_session(int fd, RecvFunc func_recv, SendFunc func_send, ParseF session[fd]->func_recv = func_recv; session[fd]->func_send = func_send; session[fd]->func_parse = func_parse; - session[fd]->rdata_tick = last_tick; + session[fd]->rdata_tick = sockt->last_tick; session[fd]->session_data = NULL; session[fd]->hdata = NULL; session[fd]->hdatac = 0; @@ -600,7 +610,7 @@ static int create_session(int fd, RecvFunc func_recv, SendFunc func_send, ParseF static void delete_session(int fd) { - if( session_isValid(fd) ) { + if( sockt->session_isValid(fd) ) { unsigned int i; #ifdef SHOW_SERVER_STATS socket_data_qi -= session[fd]->rdata_size - session[fd]->rdata_pos; @@ -613,8 +623,8 @@ static void delete_session(int fd) for(i = 0; i < session[fd]->hdatac; i++) { if( session[fd]->hdata[i]->flag.free ) { aFree(session[fd]->hdata[i]->data); - aFree(session[fd]->hdata[i]); } + aFree(session[fd]->hdata[i]); } if( session[fd]->hdata ) aFree(session[fd]->hdata); @@ -625,7 +635,7 @@ static void delete_session(int fd) int realloc_fifo(int fd, unsigned int rfifo_size, unsigned int wfifo_size) { - if( !session_isValid(fd) ) + if( !sockt->session_isValid(fd) ) return 0; if( session[fd]->max_rdata != rfifo_size && session[fd]->rdata_size < rfifo_size) { @@ -644,7 +654,7 @@ int realloc_writefifo(int fd, size_t addition) { size_t newsize; - if( !session_isValid(fd) ) // might not happen + if( !sockt->session_isValid(fd) ) // might not happen return 0; if( session[fd]->wdata_size + addition > session[fd]->max_wdata ) @@ -672,7 +682,7 @@ int RFIFOSKIP(int fd, size_t len) { struct socket_data *s; - if ( !session_isActive(fd) ) + if ( !sockt->session_isActive(fd) ) return 0; s = session[fd]; @@ -695,7 +705,7 @@ int WFIFOSET(int fd, size_t len) size_t newreserve; struct socket_data* s = session[fd]; - if( !session_isValid(fd) || s->wdata == NULL ) + if( !sockt->session_isValid(fd) || s->wdata == NULL ) return 0; // we have written len bytes to the buffer already before calling WFIFOSET @@ -771,7 +781,7 @@ int do_sockets(int next) #ifdef SEND_SHORTLIST send_shortlist_do_sends(); #else - for (i = 1; i < fd_max; i++) + for (i = 1; i < sockt->fd_max; i++) { if(!session[i]) continue; @@ -786,7 +796,7 @@ int do_sockets(int next) timeout.tv_usec = next%1000*1000; memcpy(&rfd, &readfds, sizeof(rfd)); - ret = sSelect(fd_max, &rfd, NULL, NULL, &timeout); + ret = sSelect(sockt->fd_max, &rfd, NULL, NULL, &timeout); if( ret == SOCKET_ERROR ) { @@ -798,7 +808,7 @@ int do_sockets(int next) return 0; // interrupted by a signal, just loop and try again } - last_tick = time(NULL); + sockt->last_tick = time(NULL); #if defined(WIN32) // on windows, enumerating all members of the fd_set is way faster if we access the internals @@ -810,7 +820,7 @@ int do_sockets(int next) } #else // otherwise assume that the fd_set is a bit-array and enumerate it in a standard way - for( i = 1; ret && i < fd_max; ++i ) + for( i = 1; ret && i < sockt->fd_max; ++i ) { if(sFD_ISSET(i,&rfd) && session[i]) { @@ -824,7 +834,7 @@ int do_sockets(int next) #ifdef SEND_SHORTLIST send_shortlist_do_sends(); #else - for (i = 1; i < fd_max; i++) + for (i = 1; i < sockt->fd_max; i++) { if(!session[i]) continue; @@ -840,12 +850,12 @@ int do_sockets(int next) #endif // parse input data on each socket - for(i = 1; i < fd_max; i++) + for(i = 1; i < sockt->fd_max; i++) { if(!session[i]) continue; - if (session[i]->rdata_tick && DIFF_TICK(last_tick, session[i]->rdata_tick) > stall_time) { + if (session[i]->rdata_tick && DIFF_TICK(sockt->last_tick, session[i]->rdata_tick) > sockt->stall_time) { if( session[i]->flag.server ) {/* server is special */ if( session[i]->flag.ping != 2 )/* only update if necessary otherwise it'd resend the ping unnecessarily */ session[i]->flag.ping = 1; @@ -855,21 +865,25 @@ int do_sockets(int next) } } +#ifdef __clang_analyzer__ + // Let Clang's static analyzer know this never happens (it thinks it might because of a NULL check in session_isValid) + if (!session[i]) continue; +#endif // __clang_analyzer__ session[i]->func_parse(i); if(!session[i]) continue; - + + RFIFOFLUSH(i); // after parse, check client's RFIFO size to know if there is an invalid packet (too big and not parsed) if (session[i]->rdata_size == session[i]->max_rdata) { set_eof(i); continue; } - RFIFOFLUSH(i); } #ifdef SHOW_SERVER_STATS - if (last_tick != socket_data_last_tick) + if (sockt->last_tick != socket_data_last_tick) { char buf[1024]; @@ -879,7 +893,7 @@ int do_sockets(int next) #else ShowMessage("\033[s\033[1;1H\033[2K%s\033[u", buf); #endif - socket_data_last_tick = last_tick; + socket_data_last_tick = sockt->last_tick; socket_data_i = socket_data_ci = 0; socket_data_o = socket_data_co = 0; } @@ -896,7 +910,7 @@ int do_sockets(int next) typedef struct _connect_history { struct _connect_history* next; uint32 ip; - uint32 tick; + int64 tick; int count; unsigned ddos : 1; } ConnectHistory; @@ -1043,8 +1057,7 @@ static int connect_check_(uint32 ip) /// Timer function. /// Deletes old connection history records. -static int connect_check_clear(int tid, unsigned int tick, int id, intptr_t data) -{ +static int connect_check_clear(int tid, int64 tick, int id, intptr_t data) { int i; int clear = 0; int list = 0; @@ -1145,9 +1158,9 @@ int socket_config_read(const char* cfgName) continue; if (!strcmpi(w1, "stall_time")) { - stall_time = atoi(w2); - if( stall_time < 3 ) - stall_time = 3;/* a minimum is required to refrain it from killing itself */ + sockt->stall_time = atoi(w2); + if( sockt->stall_time < 3 ) + sockt->stall_time = 3;/* a minimum is required to refrain it from killing itself */ } #ifndef MINICORE else if (!strcmpi(w1, "enable_ip_rules")) { @@ -1215,9 +1228,9 @@ void socket_final(void) aFree(access_deny); #endif - for( i = 1; i < fd_max; i++ ) + for( i = 1; i < sockt->fd_max; i++ ) if(session[i]) - do_close(i); + sockt->close(i); // session[0] ‚̃_ƒ~[ƒf[ƒ^‚ðíœ aFree(session[0]->rdata); @@ -1331,7 +1344,7 @@ int socket_getips(uint32* ips, int max) void socket_init(void) { char *SOCKET_CONF_FILENAME = "conf/packet.conf"; - unsigned int rlim_cur = FD_SETSIZE; + uint64 rlim_cur = FD_SETSIZE; #ifdef WIN32 {// Start up windows networking @@ -1379,7 +1392,7 @@ void socket_init(void) #endif // Get initial local ips - naddr_ = socket_getips(addr_,16); + sockt->naddr_ = socket_getips(sockt->addr_,16); sFD_ZERO(&readfds); #if defined(SEND_SHORTLIST) @@ -1391,7 +1404,7 @@ void socket_init(void) socket_config_read(SOCKET_CONF_FILENAME); // initialise last send-receive tick - last_tick = time(NULL); + sockt->last_tick = time(NULL); // session[0] is now currently used for disconnected sessions of the map server, and as such, // should hold enough buffer (it is a vacuum so to speak) as it is never flushed. [Skotlex] @@ -1404,12 +1417,10 @@ void socket_init(void) timer->add_interval(timer->gettick()+1000, connect_check_clear, 0, 0, 5*60*1000); #endif - ShowInfo("Server supports up to '"CL_WHITE"%u"CL_RESET"' concurrent connections.\n", rlim_cur); + ShowInfo("Server supports up to '"CL_WHITE"%"PRId64""CL_RESET"' concurrent connections.\n", rlim_cur); /* Hercules Plugin Manager */ HPM->share(session,"session"); - HPM->share(&fd_max,"fd_max"); - HPM->share(addr_,"addr"); } bool session_isValid(int fd) @@ -1419,7 +1430,7 @@ bool session_isValid(int fd) bool session_isActive(int fd) { - return ( session_isValid(fd) && !session[fd]->flag.eof ); + return ( sockt->session_isValid(fd) && !session[fd]->flag.eof ); } // Resolves hostname into a numeric ip. @@ -1461,8 +1472,6 @@ void socket_datasync(int fd, bool send) { { sizeof(struct item) }, { sizeof(struct point) }, { sizeof(struct s_skill) }, - { sizeof(struct global_reg) }, - { sizeof(struct accreg) }, { sizeof(struct status_change_data) }, { sizeof(struct storage_data) }, { sizeof(struct guild_storage) }, @@ -1473,7 +1482,6 @@ void socket_datasync(int fd, bool send) { { sizeof(struct s_friend) }, { sizeof(struct mail_message) }, { sizeof(struct mail_data) }, - { sizeof(struct registry) }, { sizeof(struct party_member) }, { sizeof(struct party) }, { sizeof(struct guild_member) }, @@ -1484,6 +1492,7 @@ void socket_datasync(int fd, bool send) { { sizeof(struct guild) }, { sizeof(struct guild_castle) }, { sizeof(struct fame_list) }, + { PACKETVER }, }; unsigned short i; unsigned int alen = ARRAYLENGTH(data_list); @@ -1525,7 +1534,7 @@ void send_shortlist_add_fd(int fd) int i; int bit; - if( !session_isValid(fd) ) + if( !sockt->session_isValid(fd) ) return;// out of range i = fd/32; @@ -1594,3 +1603,44 @@ void send_shortlist_do_sends() } } #endif + +void socket_defaults(void) { + sockt = &sockt_s; + + sockt->fd_max = 0; + /* */ + sockt->stall_time = 60; + sockt->last_tick = 0; + /* */ + memset(&sockt->addr_, 0, sizeof(sockt->addr_)); + sockt->naddr_ = 0; + /* */ + sockt->init = socket_init; + sockt->final = socket_final; + /* */ + sockt->perform = do_sockets; + /* */ + sockt->datasync = socket_datasync; + /* */ + sockt->make_listen_bind = make_listen_bind; + sockt->make_connection = make_connection; + sockt->realloc_fifo = realloc_fifo; + sockt->realloc_writefifo = realloc_writefifo; + sockt->WFIFOSET = WFIFOSET; + sockt->RFIFOSKIP = RFIFOSKIP; + sockt->close = do_close; + /* */ + sockt->session_isValid = session_isValid; + sockt->session_isActive = session_isActive; + /* */ + sockt->flush_fifo = flush_fifo; + sockt->flush_fifos = flush_fifos; + sockt->set_nonblocking = set_nonblocking; + sockt->set_defaultparse = set_defaultparse; + sockt->host2ip = host2ip; + sockt->ip2str = ip2str; + sockt->str2ip = str2ip; + sockt->ntows = ntows; + sockt->getips = socket_getips; + sockt->set_eof = set_eof; +} diff --git a/src/common/socket.h b/src/common/socket.h index 0e34da660..ca9141716 100644 --- a/src/common/socket.h +++ b/src/common/socket.h @@ -2,8 +2,8 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _SOCKET_H_ -#define _SOCKET_H_ +#ifndef _COMMON_SOCKET_H_ +#define _COMMON_SOCKET_H_ #include "../common/cbasetypes.h" @@ -24,18 +24,18 @@ struct HPluginData; // socket I/O macros #define RFIFOHEAD(fd) -#define WFIFOHEAD(fd, size) do{ if((fd) && session[fd]->wdata_size + (size) > session[fd]->max_wdata ) realloc_writefifo(fd, size); }while(0) +#define WFIFOHEAD(fd, size) do{ if((fd) && session[fd]->wdata_size + (size) > session[fd]->max_wdata ) realloc_writefifo((fd), (size)); }while(0) #define RFIFOP(fd,pos) (session[fd]->rdata + session[fd]->rdata_pos + (pos)) #define WFIFOP(fd,pos) (session[fd]->wdata + session[fd]->wdata_size + (pos)) -#define RFIFOB(fd,pos) (*(uint8*)RFIFOP(fd,pos)) -#define WFIFOB(fd,pos) (*(uint8*)WFIFOP(fd,pos)) -#define RFIFOW(fd,pos) (*(uint16*)RFIFOP(fd,pos)) -#define WFIFOW(fd,pos) (*(uint16*)WFIFOP(fd,pos)) -#define RFIFOL(fd,pos) (*(uint32*)RFIFOP(fd,pos)) -#define WFIFOL(fd,pos) (*(uint32*)WFIFOP(fd,pos)) -#define RFIFOQ(fd,pos) (*(uint64*)RFIFOP(fd,pos)) -#define WFIFOQ(fd,pos) (*(uint64*)WFIFOP(fd,pos)) +#define RFIFOB(fd,pos) (*(uint8*)RFIFOP((fd),(pos))) +#define WFIFOB(fd,pos) (*(uint8*)WFIFOP((fd),(pos))) +#define RFIFOW(fd,pos) (*(uint16*)RFIFOP((fd),(pos))) +#define WFIFOW(fd,pos) (*(uint16*)WFIFOP((fd),(pos))) +#define RFIFOL(fd,pos) (*(uint32*)RFIFOP((fd),(pos))) +#define WFIFOL(fd,pos) (*(uint32*)WFIFOP((fd),(pos))) +#define RFIFOQ(fd,pos) (*(uint64*)RFIFOP((fd),(pos))) +#define WFIFOQ(fd,pos) (*(uint64*)WFIFOP((fd),(pos))) #define RFIFOSPACE(fd) (session[fd]->max_rdata - session[fd]->rdata_size) #define WFIFOSPACE(fd) (session[fd]->max_wdata - session[fd]->wdata_size) @@ -77,8 +77,7 @@ typedef int (*RecvFunc)(int fd); typedef int (*SendFunc)(int fd); typedef int (*ParseFunc)(int fd); -struct socket_data -{ +struct socket_data { struct { unsigned char eof : 1; unsigned char server : 1; @@ -108,72 +107,93 @@ struct hSockOpt { unsigned int setTimeo : 1; }; -// Data prototype declaration - -struct socket_data **session; - -extern int fd_max; - -extern time_t last_tick; -extern time_t stall_time; - -////////////////////////////////// -// some checking on sockets -extern bool session_isValid(int fd); -extern bool session_isActive(int fd); -////////////////////////////////// - -// Function prototype declaration - -int make_listen_bind(uint32 ip, uint16 port); -int make_connection(uint32 ip, uint16 port, struct hSockOpt *opt); -int realloc_fifo(int fd, unsigned int rfifo_size, unsigned int wfifo_size); -int realloc_writefifo(int fd, size_t addition); -int WFIFOSET(int fd, size_t len); -int RFIFOSKIP(int fd, size_t len); - -int do_sockets(int next); -void do_close(int fd); -void socket_init(void); -void socket_final(void); - -extern void flush_fifo(int fd); -extern void flush_fifos(void); -extern void set_nonblocking(int fd, unsigned long yes); - -void set_defaultparse(ParseFunc defaultparse); - -// hostname/ip conversion functions -uint32 host2ip(const char* hostname); -const char* ip2str(uint32 ip, char ip_str[16]); -uint32 str2ip(const char* ip_str); -#define CONVIP(ip) ((ip)>>24)&0xFF,((ip)>>16)&0xFF,((ip)>>8)&0xFF,((ip)>>0)&0xFF -#define MAKEIP(a,b,c,d) (uint32)( ( ( (a)&0xFF ) << 24 ) | ( ( (b)&0xFF ) << 16 ) | ( ( (c)&0xFF ) << 8 ) | ( ( (d)&0xFF ) << 0 ) ) -uint16 ntows(uint16 netshort); - -int socket_getips(uint32* ips, int max); - -extern uint32 addr_[16]; // ip addresses of local host (host byte order) -extern int naddr_; // # of ip addresses - -void set_eof(int fd); - -/* [Ind/Hercules] - socket_datasync */ -void socket_datasync(int fd, bool send); - -/// Use a shortlist of sockets instead of iterating all sessions for sockets +/// Use a shortlist of sockets instead of iterating all sessions for sockets /// that have data to send or need eof handling. /// Adapted to use a static array instead of a linked list. /// /// @author Buuyo-tama #define SEND_SHORTLIST -#ifdef SEND_SHORTLIST -// Add a fd to the shortlist so that it'll be recognized as a fd that needs -// sending done on it. -void send_shortlist_add_fd(int fd); -// Do pending network sends (and eof handling) from the shortlist. -void send_shortlist_do_sends(); -#endif +// Note: purposely returns four comma-separated arguments +#define CONVIP(ip) ((ip)>>24)&0xFF,((ip)>>16)&0xFF,((ip)>>8)&0xFF,((ip)>>0)&0xFF +#define MAKEIP(a,b,c,d) ((uint32)( ( ( (a)&0xFF ) << 24 ) | ( ( (b)&0xFF ) << 16 ) | ( ( (c)&0xFF ) << 8 ) | ( ( (d)&0xFF ) << 0 ) )) + +/** + * This stays out of the interface. + **/ +struct socket_data **session; + +/** + * Socket.c interface, mostly for reading however. + **/ +struct socket_interface { + int fd_max; + /* */ + time_t stall_time; + time_t last_tick; + /* */ + uint32 addr_[16]; // ip addresses of local host (host byte order) + int naddr_; // # of ip addresses + /* */ + void (*init) (void); + void (*final) (void); + /* */ + int (*perform) (int next); + /* [Ind/Hercules] - socket_datasync */ + void (*datasync) (int fd, bool send); + /* */ + int (*make_listen_bind) (uint32 ip, uint16 port); + int (*make_connection) (uint32 ip, uint16 port, struct hSockOpt *opt); + int (*realloc_fifo) (int fd, unsigned int rfifo_size, unsigned int wfifo_size); + int (*realloc_writefifo) (int fd, size_t addition); + int (*WFIFOSET) (int fd, size_t len); + int (*RFIFOSKIP) (int fd, size_t len); + void (*close) (int fd); + /* */ + bool (*session_isValid) (int fd); + bool (*session_isActive) (int fd); + /* */ + void (*flush_fifo) (int fd); + void (*flush_fifos) (void); + void (*set_nonblocking) (int fd, unsigned long yes); + void (*set_defaultparse) (ParseFunc defaultparse); + /* hostname/ip conversion functions */ + uint32 (*host2ip) (const char* hostname); + const char * (*ip2str) (uint32 ip, char ip_str[16]); + uint32 (*str2ip) (const char* ip_str); + /* */ + uint16 (*ntows) (uint16 netshort); + /* */ + int (*getips) (uint32* ips, int max); + /* */ + void (*set_eof) (int fd); +}; -#endif /* _SOCKET_H_ */ +struct socket_interface *sockt; + +void socket_defaults(void); + +/* the purpose of these macros is simply to not make calling them be an annoyance */ +#ifndef _H_SOCKET_C_ + #define make_listen_bind(ip, port) ( sockt->make_listen_bind(ip, port) ) + #define make_connection(ip, port, opt) ( sockt->make_connection(ip, port, opt) ) + #define realloc_fifo(fd, rfifo_size, wfifo_size) ( sockt->realloc_fifo(fd, rfifo_size, wfifo_size) ) + #define realloc_writefifo(fd, addition) ( sockt->realloc_writefifo(fd, addition) ) + #define WFIFOSET(fd, len) ( sockt->WFIFOSET(fd, len) ) + #define RFIFOSKIP(fd, len) ( sockt->RFIFOSKIP(fd, len) ) + #define do_close(fd) ( sockt->close(fd) ) + #define session_isValid(fd) ( sockt->session_isValid(fd) ) + #define session_isActive(fd) ( sockt->session_isActive(fd) ) + #define flush_fifo(fd) ( sockt->flush_fifo(fd) ) + #define flush_fifos() ( sockt->flush_fifos() ) + #define set_nonblocking(fd, yes) ( sockt->set_nonblocking(fd, yes) ) + #define set_defaultparse(defaultparse) ( sockt->set_defaultparse(defaultparse) ) + #define host2ip(hostname) ( sockt->host2ip(hostname) ) + #define ip2str(ip, ip_str) ( sockt->ip2str(ip, ip_str) ) + #define str2ip(ip_str) ( sockt->str2ip(ip_str) ) + #define ntows(netshort) ( sockt->ntows(netshort) ) + #define getips(ips, max) ( sockt->getips(ips, max) ) + #define set_eof(fd) ( sockt->set_eof(fd) ) +#endif /* _H_SOCKET_C_ */ + +#endif /* _COMMON_SOCKET_H_ */ diff --git a/src/common/spinlock.h b/src/common/spinlock.h index 3419bfdd5..29fbb355b 100644 --- a/src/common/spinlock.h +++ b/src/common/spinlock.h @@ -1,6 +1,6 @@ #pragma once -#ifndef _rA_SPINLOCK_H_ -#define _rA_SPINLOCK_H_ +#ifndef _COMMON_SPINLOCK_H_ +#define _COMMON_SPINLOCK_H_ // // CAS based Spinlock Implementation @@ -52,8 +52,8 @@ static forceinline void FinalizeSpinLock(PSPIN_LOCK lck){ } -#define getsynclock(l) { while(1){ if(InterlockedCompareExchange(l, 1, 0) == 0) break; rathread_yield(); } } -#define dropsynclock(l) { InterlockedExchange(l, 0); } +#define getsynclock(l) do { if(InterlockedCompareExchange((l), 1, 0) == 0) break; rathread_yield(); } while(/*always*/1) +#define dropsynclock(l) do { InterlockedExchange((l), 0); } while(0) static forceinline void EnterSpinLock(PSPIN_LOCK lck){ int tid = rathread_get_tid(); @@ -101,4 +101,4 @@ static forceinline void LeaveSpinLock(PSPIN_LOCK lck){ -#endif +#endif /* _COMMON_SPINLOCK_H_ */ diff --git a/src/common/sql.c b/src/common/sql.c index 9b7fe4108..79ccc8e92 100644 --- a/src/common/sql.c +++ b/src/common/sql.c @@ -180,7 +180,7 @@ int Sql_Ping(Sql* self) /// Wrapper function for Sql_Ping. /// /// @private -static int Sql_P_KeepaliveTimer(int tid, unsigned int tick, int id, intptr_t data) +static int Sql_P_KeepaliveTimer(int tid, int64 tick, int id, intptr_t data) { Sql* self = (Sql*)data; ShowInfo("Pinging SQL server to keep connection alive...\n"); @@ -1005,6 +1005,9 @@ void Sql_HerculesUpdateCheck(Sql* self) { unsigned int performed = 0; StringBuf buf; + if( self == NULL ) + return;/* return silently, build has no mysql connection */ + if( !( ifp = fopen("sql-files/upgrades/index.txt", "r") ) ) { ShowError("SQL upgrade index was not found!\n"); return; @@ -1033,7 +1036,7 @@ void Sql_HerculesUpdateCheck(Sql* self) { fseek (ufp,1,SEEK_SET);/* woo. skip the # */ if( fgets(timestamp,sizeof(timestamp),ufp) ) { - unsigned int timestampui = atol(timestamp); + unsigned int timestampui = (unsigned int)atol(timestamp); if( SQL_ERROR == SQL->Query(self, "SELECT 1 FROM `sql_updates` WHERE `timestamp` = '%u' LIMIT 1", timestampui) ) Sql_ShowDebug(self); if( Sql_NumRows(self) != 1 ) { @@ -1076,7 +1079,7 @@ void Sql_HerculesUpdateSkip(Sql* self,const char *filename) { fseek (ifp,1,SEEK_SET);/* woo. skip the # */ if( fgets(timestamp,sizeof(timestamp),ifp) ) { - unsigned int timestampui = atol(timestamp); + unsigned int timestampui = (unsigned int)atol(timestamp); if( SQL_ERROR == SQL->Query(self, "SELECT 1 FROM `sql_updates` WHERE `timestamp` = '%u' LIMIT 1", timestampui) ) Sql_ShowDebug(self); else if( Sql_NumRows(self) == 1 ) { diff --git a/src/common/sql.h b/src/common/sql.h index da00edf2d..1fb436853 100644 --- a/src/common/sql.h +++ b/src/common/sql.h @@ -11,7 +11,7 @@ // Return codes -#define SQL_ERROR -1 +#define SQL_ERROR (-1) #define SQL_SUCCESS 0 #define SQL_NO_DATA 100 @@ -277,7 +277,7 @@ void sql_defaults(void); #if defined(SQL_REMOVE_SHOWDEBUG) #define Sql_ShowDebug(self) (void)0 #else -#define Sql_ShowDebug(self) SQL->ShowDebug_(self, __FILE__, __LINE__) +#define Sql_ShowDebug(self) (SQL->ShowDebug_((self), __FILE__, __LINE__)) #endif void Sql_HerculesUpdateCheck(Sql* self); @@ -286,16 +286,10 @@ void Sql_HerculesUpdateSkip(Sql* self,const char *filename); #if defined(SQL_REMOVE_SHOWDEBUG) #define SqlStmt_ShowDebug(self) (void)0 #else -#define SqlStmt_ShowDebug(self) SQL->StmtShowDebug_(self, __FILE__, __LINE__) -#endif /// Shows debug information (with statement). - - - - - +#define SqlStmt_ShowDebug(self) (SQL->StmtShowDebug_((self), __FILE__, __LINE__)) +#endif void Sql_Init(void); - #endif /* _COMMON_SQL_H_ */ diff --git a/src/common/strlib.c b/src/common/strlib.c index e45cb0789..361595b07 100644 --- a/src/common/strlib.c +++ b/src/common/strlib.c @@ -240,16 +240,19 @@ char* _strtok_r(char *s1, const char *s2, char **lasts) { } #endif +// TODO: The _MSC_VER check can probably be removed (we no longer support VS +// versions <= 2003, do we?), but this implementation might be still necessary +// for NetBSD 5.x and possibly some Solaris versions. #if !(defined(WIN32) && defined(_MSC_VER) && _MSC_VER >= 1400) && !defined(HAVE_STRNLEN) /* Find the length of STRING, but scan at most MAXLEN characters. If no '\0' terminator is found in that many characters, return MAXLEN. */ -size_t strnlen (const char* string, size_t maxlen) -{ - const char* end = (const char*)memchr(string, '\0', maxlen); - return end ? (size_t) (end - string) : maxlen; +size_t strnlen(const char* string, size_t maxlen) { + const char* end = (const char*)memchr(string, '\0', maxlen); + return end ? (size_t) (end - string) : maxlen; } #endif +// TODO: This should probably be removed, I don't think we support MSVC++ 6.0 anymore. #if defined(WIN32) && defined(_MSC_VER) && _MSC_VER <= 1200 uint64 strtoull(const char* str, char** endptr, int base) { @@ -331,13 +334,22 @@ int e_mail_check(char* email) //-------------------------------------------------- // Return numerical value of a switch configuration -// on/off, english, français, deutsch, español +// on/off, yes/no, true/false, number //-------------------------------------------------- -int config_switch(const char* str) -{ - if (strcmpi(str, "on") == 0 || strcmpi(str, "yes") == 0 || strcmpi(str, "oui") == 0 || strcmpi(str, "ja") == 0 || strcmpi(str, "si") == 0) +int config_switch(const char* str) { + size_t len = strlen(str); + if ((len == 2 && strcmpi(str, "on") == 0) + || (len == 3 && strcmpi(str, "yes") == 0) + || (len == 4 && strcmpi(str, "true") == 0) + // || (len == 3 && strcmpi(str, "oui") == 0) // Uncomment and edit to add your own localized versions + ) return 1; - if (strcmpi(str, "off") == 0 || strcmpi(str, "no") == 0 || strcmpi(str, "non") == 0 || strcmpi(str, "nein") == 0) + + if ((len == 3 && strcmpi(str, "off") == 0) + || (len == 2 && strcmpi(str, "no") == 0) + || (len == 5 && strcmpi(str, "false") == 0) + // || (len == 3 && strcmpi(str, "non") == 0) // Uncomment and edit to add your own localized versions + ) return 0; return (int)strtol(str, NULL, 0); @@ -952,7 +964,7 @@ bool sv_readdb(const char* directory, const char* filename, char delim, int minc if( line[0] == '\0' || line[0] == '\n' || line[0] == '\r') continue; - columns = sv_split(line, strlen(line), 0, delim, fields, fields_length, (e_svopt)(SV_TERMINATE_LF|SV_TERMINATE_CRLF)); + columns = sv_split(line, (int)strlen(line), 0, delim, fields, fields_length, (e_svopt)(SV_TERMINATE_LF|SV_TERMINATE_CRLF)); if( columns < mincols ) { ShowError("sv_readdb: Insufficient columns in line %d of \"%s\" (found %d, need at least %d).\n", lines, path, columns, mincols); @@ -1018,7 +1030,8 @@ int StringBuf_Printf(StringBuf* self, const char* fmt, ...) { /// Appends the result of vprintf to the StringBuf int StringBuf_Vprintf(StringBuf* self, const char* fmt, va_list ap) { - int n, size, off; + int n, off; + size_t size; for(;;) { va_list apcopy; @@ -1028,7 +1041,7 @@ int StringBuf_Vprintf(StringBuf* self, const char* fmt, va_list ap) { n = vsnprintf(self->ptr_, size, fmt, apcopy); va_end(apcopy); /* If that worked, return the length. */ - if( n > -1 && n < size ) { + if( n > -1 && (size_t)n < size ) { self->ptr_ += n; return (int)(self->ptr_ - self->buf_); } @@ -1042,11 +1055,11 @@ int StringBuf_Vprintf(StringBuf* self, const char* fmt, va_list ap) { /// Appends the contents of another StringBuf to the StringBuf int StringBuf_Append(StringBuf* self, const StringBuf* sbuf) { - int available = self->max_ - (self->ptr_ - self->buf_); - int needed = (int)(sbuf->ptr_ - sbuf->buf_); + size_t available = self->max_ - (self->ptr_ - self->buf_); + size_t needed = sbuf->ptr_ - sbuf->buf_; if( needed >= available ) { - int off = (int)(self->ptr_ - self->buf_); + size_t off = (self->ptr_ - self->buf_); self->max_ += needed; self->buf_ = (char*)aRealloc(self->buf_, self->max_ + 1); self->ptr_ = self->buf_ + off; @@ -1059,12 +1072,12 @@ int StringBuf_Append(StringBuf* self, const StringBuf* sbuf) { // Appends str to the StringBuf int StringBuf_AppendStr(StringBuf* self, const char* str) { - int available = self->max_ - (self->ptr_ - self->buf_); - int needed = (int)strlen(str); + size_t available = self->max_ - (self->ptr_ - self->buf_); + size_t needed = strlen(str); if( needed >= available ) { // not enough space, expand the buffer (minimum expansion = 1024) - int off = (int)(self->ptr_ - self->buf_); + size_t off = (self->ptr_ - self->buf_); self->max_ += max(needed, 1024); self->buf_ = (char*)aRealloc(self->buf_, self->max_ + 1); self->ptr_ = self->buf_ + off; @@ -1118,10 +1131,14 @@ void strlib_defaults(void) { #if !(defined(WIN32) && defined(_MSC_VER) && _MSC_VER >= 1400) && !defined(HAVE_STRNLEN) strlib->strnlen = strnlen; +#else + strlib->strnlen = NULL; #endif #if defined(WIN32) && defined(_MSC_VER) && _MSC_VER <= 1200 strlib->strtoull = strtoull; +#else + strlib->strtoull = NULL; #endif strlib->e_mail_check = e_mail_check; strlib->config_switch = config_switch; diff --git a/src/common/strlib.h b/src/common/strlib.h index 5ef455a0e..10844d257 100644 --- a/src/common/strlib.h +++ b/src/common/strlib.h @@ -2,8 +2,8 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _STRLIB_H_ -#define _STRLIB_H_ +#ifndef _COMMON_STRLIB_H_ +#define _COMMON_STRLIB_H_ #include "../common/cbasetypes.h" #include <stdarg.h> @@ -70,13 +70,11 @@ struct strlib_interface { char *(*normalize_name) (char* str,const char* delims); const char *(*stristr) (const char *haystack, const char *needle); -#if !(defined(WIN32) && defined(_MSC_VER) && _MSC_VER >= 1400) && !defined(HAVE_STRNLEN) + /* only used when '!(defined(WIN32) && defined(_MSC_VER) && _MSC_VER >= 1400) && !defined(HAVE_STRNLEN)', needs to be defined at all times however */ size_t (*strnlen) (const char* string, size_t maxlen); -#endif - -#if defined(WIN32) && defined(_MSC_VER) && _MSC_VER <= 1200 + + /* only used when 'defined(WIN32) && defined(_MSC_VER) && _MSC_VER <= 1200', needs to be defined at all times however */ uint64 (*strtoull) (const char* str, char** endptr, int base); -#endif int (*e_mail_check) (char* email); int (*config_switch) (const char* str); @@ -168,28 +166,29 @@ void strlib_defaults(void); /* the purpose of these macros is simply to not make calling them be an annoyance */ #ifndef STRLIB_C - #define jstrescape(pt) strlib->jstrescape(pt) - #define jstrescapecpy(pt,spt) strlib->jstrescapecpy(pt,spt) - #define jmemescapecpy(pt,spt,size) strlib->jmemescapecpy(pt,spt,size) - #define remove_control_chars(str) strlib->remove_control_chars(str) - #define trim(str) strlib->trim(str) - #define normalize_name(str,delims) strlib->normalize_name(str,delims) - #define stristr(haystack,needle) strlib->stristr(haystack,needle) + #define jstrescape(pt) (strlib->jstrescape(pt)) + #define jstrescapecpy(pt,spt) (strlib->jstrescapecpy((pt),(spt))) + #define jmemescapecpy(pt,spt,size) (strlib->jmemescapecpy((pt),(spt),(size))) + #define remove_control_chars(str) (strlib->remove_control_chars(str)) + #define trim(str) (strlib->trim(str)) + #define normalize_name(str,delims) (strlib->normalize_name((str),(delims))) + #define stristr(haystack,needle) (strlib->stristr((haystack),(needle))) #if !(defined(WIN32) && defined(_MSC_VER) && _MSC_VER >= 1400) && !defined(HAVE_STRNLEN) - #define strnln(string,maxlen) strlib->strnlen(string,maxlen) + #define strnlen(string,maxlen) (strlib->strnlen((string),(maxlen))) #endif #if defined(WIN32) && defined(_MSC_VER) && _MSC_VER <= 1200 - #define strtoull(str,endptr,base) strlib->strtoull(str,endptr,base) + #define strtoull(str,endptr,base) (strlib->strtoull((str),(endptr),(base))) #endif - #define e_mail_check(email) strlib->e_mail_check(email) - #define config_switch(str) strlib->config_switch(str) - #define safestrncpy(dst,src,n) strlib->safestrncpy(dst,src,n) - #define safestrnlen(string,maxlen) strlib->safestrnlen(string,maxlen) - #define safesnprintf(buf,sz,fmt,...) strlib->safesnprintf(buf,sz,fmt,##__VA_ARGS__) - #define strline(str,pos) strlib->strline(str,pos) - #define bin2hex(output,input,count) strlib->bin2hex(output,input,count) + #define e_mail_check(email) (strlib->e_mail_check(email)) + #define config_switch(str) (strlib->config_switch(str)) + #define safestrncpy(dst,src,n) (strlib->safestrncpy((dst),(src),(n))) + #define safestrnlen(string,maxlen) (strlib->safestrnlen((string),(maxlen))) + #define safesnprintf(buf,sz,fmt,...) (strlib->safesnprintf((buf),(sz),(fmt),##__VA_ARGS__)) + #define strline(str,pos) (strlib->strline((str),(pos))) + #define bin2hex(output,input,count) (strlib->bin2hex((output),(input),(count))) #endif /* STRLIB_C */ -#endif /* _STRLIB_H_ */ + +#endif /* _COMMON_STRLIB_H_ */ diff --git a/src/common/thread.h b/src/common/thread.h index a5a66e954..d6b2bbc6e 100644 --- a/src/common/thread.h +++ b/src/common/thread.h @@ -2,8 +2,8 @@ // For more information, see LICENCE in the main folder #pragma once -#ifndef _rA_THREAD_H_ -#define _rA_THREAD_H_ +#ifndef _COMMON_THREAD_H_ +#define _COMMON_THREAD_H_ #include "../common/cbasetypes.h" @@ -116,4 +116,4 @@ void rathread_init(); void rathread_final(); -#endif +#endif /* _COMMON_THREAD_H_ */ diff --git a/src/common/timer.c b/src/common/timer.c index a2378a5aa..526854582 100644 --- a/src/common/timer.c +++ b/src/common/timer.c @@ -65,8 +65,7 @@ struct timer_func_list { } *tfl_root = NULL; /// Sets the name of a timer function. -int timer_add_func_list(TimerFunc func, char* name) -{ +int timer_add_func_list(TimerFunc func, char* name) { struct timer_func_list* tfl; if (name) { @@ -139,22 +138,62 @@ static void rdtsc_calibrate(){ #endif -/// platform-abstracted tick retrieval -static unsigned int tick(void) { +/** + * platform-abstracted tick retrieval + * @return server's current tick + */ +static int64 sys_tick(void) { #if defined(WIN32) - return GetTickCount(); + // Windows: GetTickCount/GetTickCount64: Return the number of + // milliseconds that have elapsed since the system was started. + + // TODO: GetTickCount/GetTickCount64 has a resolution of only 10~15ms. + // Ai4rei recommends that we replace it with either performance + // counters or multimedia timers if we want it to be more accurate. + // I'm leaving this for a future follow-up patch. + + // GetTickCount64 is only available in Windows Vista / Windows Server + // 2008 or newer. Since we still support older versions, this runtime + // check is required in order not to crash. + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms724411%28v=vs.85%29.aspx + static bool first = true; + static ULONGLONG (WINAPI *pGetTickCount64)(void) = NULL; + + if( first ) { + HMODULE hlib = GetModuleHandle(TEXT("KERNEL32.DLL")); + if( hlib != NULL ) + pGetTickCount64 = (ULONGLONG (WINAPI *)(void))GetProcAddress(hlib, "GetTickCount64"); + first = false; + } + if (pGetTickCount64) + return (int64)pGetTickCount64(); + // 32-bit fallback. Note: This will wrap around every ~49 days since system startup!!! + return (int64)GetTickCount(); #elif defined(ENABLE_RDTSC) - // - return (unsigned int)((_rdtsc() - RDTSC_BEGINTICK) / RDTSC_CLOCK); - // + // RDTSC: Returns the number of CPU cycles since reset. Unreliable if + // the CPU frequency is variable. + return (int64)((_rdtsc() - RDTSC_BEGINTICK) / RDTSC_CLOCK); #elif defined(HAVE_MONOTONIC_CLOCK) + // Monotinic clock: Implementation-defined. + // Clock that cannot be set and represents monotonic time since some + // unspecified starting point. This clock is not affected by + // discontinâ€uous jumps in the system time (e.g., if the system + // administrator manually changes the clock), but is affected by + // the incremental adjustments performed by adjtime(3) and NTP. struct timespec tval; clock_gettime(CLOCK_MONOTONIC, &tval); - return tval.tv_sec * 1000 + tval.tv_nsec / 1000000; + // int64 cast to avoid overflows on platforms where time_t is 32 bit + return (int64)tval.tv_sec * 1000 + tval.tv_nsec / 1000000; #else + // Fallback, regular clock: Number of milliseconds since epoch. + // The time returned by gettimeofday() is affected by discontinuous + // jumps in the system time (e.g., if the system administrator + // manually changes the system time). If you need a monotonically + // increasing clock, see clock_gettime(2). struct timeval tval; gettimeofday(&tval, NULL); - return tval.tv_sec * 1000 + tval.tv_usec / 1000; + // int64 cast to avoid overflows on platforms where time_t is 32 bit + return (int64)tval.tv_sec * 1000 + tval.tv_usec / 1000; #endif } @@ -162,29 +201,29 @@ static unsigned int tick(void) { #if defined(TICK_CACHE) && TICK_CACHE > 1 ////////////////////////////////////////////////////////////////////////// // tick is cached for TICK_CACHE calls -static unsigned int gettick_cache; +static int64 gettick_cache; static int gettick_count = 1; -unsigned int timer_gettick_nocache(void) { +int64 timer_gettick_nocache(void) { gettick_count = TICK_CACHE; - gettick_cache = tick(); + gettick_cache = sys_tick(); return gettick_cache; } -unsigned int timer_gettick(void) { +int64 timer_gettick(void) { return ( --gettick_count == 0 ) ? gettick_nocache() : gettick_cache; } ////////////////////////////// #else ////////////////////////////// // tick doesn't get cached -unsigned int timer_gettick_nocache(void) +int64 timer_gettick_nocache(void) { - return tick(); + return sys_tick(); } -unsigned int timer_gettick(void) { - return tick(); +int64 timer_gettick(void) { + return sys_tick(); } ////////////////////////////////////////////////////////////////////////// #endif @@ -237,7 +276,7 @@ static int acquire_timer(void) { /// Starts a new timer that is deleted once it expires (single-use). /// Returns the timer's id. -int timer_add(unsigned int tick, TimerFunc func, int id, intptr_t data) { +int timer_add(int64 tick, TimerFunc func, int id, intptr_t data) { int tid; tid = acquire_timer(); @@ -254,12 +293,11 @@ int timer_add(unsigned int tick, TimerFunc func, int id, intptr_t data) { /// Starts a new timer that automatically restarts itself (infinite loop until manually removed). /// Returns the timer's id, or INVALID_TIMER if it fails. -int timer_add_interval(unsigned int tick, TimerFunc func, int id, intptr_t data, int interval) -{ +int timer_add_interval(int64 tick, TimerFunc func, int id, intptr_t data, int interval) { int tid; if( interval < 1 ) { - ShowError("timer_add_interval: invalid interval (tick=%u %p[%s] id=%d data=%d diff_tick=%d)\n", tick, func, search_timer_func_list(func), id, data, DIFF_TICK(tick, timer->gettick())); + ShowError("timer_add_interval: invalid interval (tick=%"PRId64" %p[%s] id=%d data=%d diff_tick=%"PRId64")\n", tick, func, search_timer_func_list(func), id, data, DIFF_TICK(tick, timer->gettick())); return INVALID_TIMER; } @@ -301,13 +339,13 @@ int timer_do_delete(int tid, TimerFunc func) { /// Adjusts a timer's expiration time. /// Returns the new tick value, or -1 if it fails. -int timer_addtick(int tid, unsigned int tick) { +int64 timer_addtick(int tid, int64 tick) { return timer->settick(tid, timer_data[tid].tick+tick); } /// Modifies a timer's expiration time (an alternative to deleting a timer and starting a new one). /// Returns the new tick value, or -1 if it fails. -int timer_settick(int tid, unsigned int tick) { +int64 timer_settick(int tid, int64 tick) { size_t i; // search timer position @@ -317,23 +355,23 @@ int timer_settick(int tid, unsigned int tick) { return -1; } - if( (int)tick == -1 ) - tick = 0;// add 1ms to avoid the error value -1 + if( tick == -1 ) + tick = 0; // add 1ms to avoid the error value -1 if( timer_data[tid].tick == tick ) - return (int)tick;// nothing to do, already in propper position + return tick; // nothing to do, already in proper position // pop and push adjusted timer BHEAP_POPINDEX(timer_heap, i, DIFFTICK_MINTOPCMP, swap); timer_data[tid].tick = tick; BHEAP_PUSH(timer_heap, tid, DIFFTICK_MINTOPCMP, swap); - return (int)tick; + return tick; } /// Executes all expired timers. /// Returns the value of the smallest non-expired timer (or 1 second if there aren't any). -int do_timer(unsigned int tick) { - int diff = TIMER_MAX_INTERVAL; // return value +int do_timer(int64 tick) { + int64 diff = TIMER_MAX_INTERVAL; // return value // process all timers one by one while( BHEAP_LENGTH(timer_heap) ) { @@ -381,7 +419,7 @@ int do_timer(unsigned int tick) { } } - return cap_value(diff, TIMER_MIN_INTERVAL, TIMER_MAX_INTERVAL); + return (int)cap_value(diff, TIMER_MIN_INTERVAL, TIMER_MAX_INTERVAL); } unsigned long timer_get_uptime(void) { @@ -430,7 +468,7 @@ void timer_defaults(void) { timer->addtick = timer_addtick; timer->settick = timer_settick; timer->get_uptime = timer_get_uptime; - timer->do_timer = do_timer; + timer->perform = do_timer; timer->init = timer_init; timer->final = timer_final; } diff --git a/src/common/timer.h b/src/common/timer.h index 600f9fd02..ab3ffc21f 100644 --- a/src/common/timer.h +++ b/src/common/timer.h @@ -1,13 +1,16 @@ // Copyright (c) Hercules Dev Team, licensed under GNU GPL. // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _TIMER_H_ -#define _TIMER_H_ + +#ifndef _COMMON_TIMER_H_ +#define _COMMON_TIMER_H_ + #include "../common/cbasetypes.h" -#define DIFF_TICK(a,b) ((int)((a)-(b))) +#define DIFF_TICK(a,b) ((a)-(b)) +#define DIFF_TICK32(a,b) ((int32)((a)-(b))) -#define INVALID_TIMER -1 +#define INVALID_TIMER (-1) // timer flags enum { @@ -18,10 +21,10 @@ enum { // Struct declaration -typedef int (*TimerFunc)(int tid, unsigned int tick, int id, intptr_t data); +typedef int (*TimerFunc)(int tid, int64 tick, int id, intptr_t data); struct TimerData { - unsigned int tick; + int64 tick; TimerFunc func; unsigned char type; int interval; @@ -40,22 +43,22 @@ struct TimerData { struct timer_interface { /* funcs */ - unsigned int (*gettick) (void); - unsigned int (*gettick_nocache) (void); + int64 (*gettick) (void); + int64 (*gettick_nocache) (void); - int (*add) (unsigned int tick, TimerFunc func, int id, intptr_t data); - int (*add_interval) (unsigned int tick, TimerFunc func, int id, intptr_t data, int interval); + int (*add) (int64 tick, TimerFunc func, int id, intptr_t data); + int (*add_interval) (int64 tick, TimerFunc func, int id, intptr_t data, int interval); const struct TimerData *(*get) (int tid); int (*delete) (int tid, TimerFunc func); - int (*addtick) (int tid, unsigned int tick); - int (*settick) (int tid, unsigned int tick); + int64 (*addtick) (int tid, int64 tick); + int64 (*settick) (int tid, int64 tick); int (*add_func_list) (TimerFunc func, char* name); unsigned long (*get_uptime) (void); - int (*do_timer) (unsigned int tick); + int (*perform) (int64 tick); void (*init) (void); void (*final) (void); }; @@ -64,4 +67,4 @@ struct timer_interface *timer; void timer_defaults(void); -#endif /* _TIMER_H_ */ +#endif /* _COMMON_TIMER_H_ */ diff --git a/src/common/utils.c b/src/common/utils.c index 9e3dbac47..9a7d4971b 100644 --- a/src/common/utils.c +++ b/src/common/utils.c @@ -287,6 +287,17 @@ unsigned int get_percentage(const unsigned int A, const unsigned int B) return (unsigned int)floor(result); } +//----------------------------------------------------- +// custom timestamp formatting (from eApp) +//----------------------------------------------------- +const char* timestamp2string(char* str, size_t size, time_t timestamp, const char* format) +{ + size_t len = strftime(str, size, format, localtime(×tamp)); + memset(str + len, '\0', size - len); + return str; +} + + /* [Ind/Hercules] Caching */ bool HCache_check(const char *file) { struct stat bufa, bufb; diff --git a/src/common/utils.h b/src/common/utils.h index 32087d78f..68dd01ac4 100644 --- a/src/common/utils.h +++ b/src/common/utils.h @@ -2,8 +2,8 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _UTILS_H_ -#define _UTILS_H_ +#ifndef _COMMON_UTILS_H_ +#define _COMMON_UTILS_H_ #include "../common/cbasetypes.h" #include <stdio.h> // FILE* @@ -20,11 +20,13 @@ void findfile(const char *p, const char *pat, void (func)(const char*)); bool exists(const char* filename); //Caps values to min/max -#define cap_value(a, min, max) ((a >= max) ? max : (a <= min) ? min : a) +#define cap_value(a, min, max) (((a) >= (max)) ? (max) : ((a) <= (min)) ? (min) : (a)) /// calculates the value of A / B, in percent (rounded down) unsigned int get_percentage(const unsigned int A, const unsigned int B); +const char* timestamp2string(char* str, size_t size, time_t timestamp, const char* format); + ////////////////////////////////////////////////////////////////////////// // byte word dword access [Shinomori] ////////////////////////////////////////////////////////////////////////// @@ -52,4 +54,4 @@ struct HCache_interface *HCache; void HCache_defaults(void); -#endif /* _UTILS_H_ */ +#endif /* _COMMON_UTILS_H_ */ diff --git a/src/config/classes/general.h b/src/config/classes/general.h index 206f57b37..147fddb55 100644 --- a/src/config/classes/general.h +++ b/src/config/classes/general.h @@ -10,8 +10,8 @@ /** * Default Magical Reflection Behavior - * - When reflecting, reflected damage depends on gears caster is wearing, not target - * - When disabled damage depends on gears target is wearing, not caster. + * - When reflecting, reflected damage depends on gears caster is wearing, not target (official) + * - When disabled damage depends on gears target is wearing, not caster. (old/eathena) * @values 1 (enabled) or 0 (disabled) **/ #define MAGIC_REFLECTION_TYPE 1 @@ -22,6 +22,12 @@ #define MAX_SPIRITBALL 15 /** + * when enabled, reflect damage doesn't bypass devotion (and thus damage is passed to crusader) + * uncomment to enable + **/ +//#define DEVOTION_REFLECT_DAMAGE + +/** * No settings past this point **/ diff --git a/src/config/const.h b/src/config/const.h index 6f0dc6311..6557cb987 100644 --- a/src/config/const.h +++ b/src/config/const.h @@ -1,8 +1,9 @@ // Copyright (c) Hercules Dev Team, licensed under GNU GPL. // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _H_CONSTANTS_ -#define _H_CONSTANTS_ + +#ifndef _CONFIG_CONSTANTS_H_ +#define _CONFIG_CONSTANTS_H_ /** * Hercules configuration file (http://hercules.ws) @@ -114,14 +115,7 @@ #undef CONSOLE_INPUT #endif -#ifdef RENEWAL - #define ITEMDB_SQL_COLUMNS 24 -#else - #define ITEMDB_SQL_COLUMNS 22 -#endif - - /** * End of File **/ -#endif /* _H_CONSTANTS_ */ +#endif /* _CONFIG_CONSTANTS_H_ */ diff --git a/src/config/core.h b/src/config/core.h index b5ad1b794..edd5c2b2a 100644 --- a/src/config/core.h +++ b/src/config/core.h @@ -61,9 +61,16 @@ /// By enabling it, the system will create an unique id for each new non stackable item created //#define NSI_UNIQUE_ID +/// Comment to disable Guild/Party Bound item system +#define GP_BOUND_ITEMS + /// Uncomment to enable real-time server stats (in and out data and ram usage). [Ai4rei] //#define SHOW_SERVER_STATS + +/// Comment to disable autotrade persistency (where autotrading merchants survive server restarts) +#define AUTOTRADE_PERSISTENCY + /** * No settings past this point **/ diff --git a/src/config/renewal.h b/src/config/renewal.h index a7fd22c37..36615d63b 100644 --- a/src/config/renewal.h +++ b/src/config/renewal.h @@ -13,6 +13,7 @@ * @INFO: This file holds general-purpose renewal settings, for class-specific ones check /src/config/classes folder **/ +//#define DISABLE_RENEWAL #ifndef DISABLE_RENEWAL /// game renewal server mode @@ -59,6 +60,7 @@ /// - damage is NOT increased by 400% /// - it does NOT affect grimtooth /// - weapon and status ATK are increased +/// - some skill's damage ratio has modified #define RENEWAL_EDP /// renewal ASPD [malufett] diff --git a/src/config/secure.h b/src/config/secure.h index 7f16ba55a..e5e3662d1 100644 --- a/src/config/secure.h +++ b/src/config/secure.h @@ -47,4 +47,15 @@ **/ #define SECURE_NPCTIMEOUT_INTERVAL 1 +/** + * Uncomment to disable + * while enabled, movement of invisible (cloaking, hide, etca [not chase walk]) units is not informed to nearby foes, + * rendering any client-side cheat, that would otherwise make these units visible, to not function. + * - "Why is this a setting?" because theres a cost, while enabled if a hidden character uses a skill with cast time, + * - for example "cloaking -> walk a bit -> soul break another player" the character display will be momentarily abrupted + * - on the action of unhiding (its a quick effect, ~0.007s in duration), and due to the nature of the skill cast on the client + * - it was not possible to work around this, and thus why it is optional, comment the line to disable. + **/ +#define ANTI_MAYAP_CHEAT + #endif // _CONFIG_SECURE_H_ diff --git a/src/login/Makefile.in b/src/login/Makefile.in index a97d17f68..fa5f92105 100644 --- a/src/login/Makefile.in +++ b/src/login/Makefile.in @@ -1,26 +1,29 @@ -COMMON_H = $(shell ls ../common/*.h) -CONFIG_H = $(shell ls ../config/*.h ../config/*/*.h) +CONFIG_D = ../config +CONFIG_H = $(wildcard $(CONFIG_D)/*.h) $(wildcard $(CONFIG_D)/*/*.h) -MT19937AR_D = ../../3rdparty/mt19937ar -MT19937AR_OBJ = $(MT19937AR_D)/mt19937ar.o -MT19937AR_H = $(MT19937AR_D)/mt19937ar.h -MT19937AR_INCLUDE = -I$(MT19937AR_D) +COMMON_D = ../common +COMMON_H = $(wildcard $(COMMON_D)/*.h) LIBCONFIG_D = ../../3rdparty/libconfig LIBCONFIG_OBJ = $(addprefix $(LIBCONFIG_D)/, libconfig.o grammar.o scanctx.o \ - scanner.o strbuf.o) + scanner.o strbuf.o) LIBCONFIG_H = $(addprefix $(LIBCONFIG_D)/, libconfig.h grammar.h parsectx.h \ - scanctx.h scanner.h strbuf.h wincompat.h) + scanctx.h scanner.h strbuf.h wincompat.h) LIBCONFIG_INCLUDE = -I$(LIBCONFIG_D) -LOGIN_OBJ = $(addprefix obj_sql/, account_sql.o ipban_sql.o login.o \ - loginlog_sql.o) +MT19937AR_D = ../../3rdparty/mt19937ar +MT19937AR_OBJ = $(MT19937AR_D)/mt19937ar.o +MT19937AR_H = $(MT19937AR_D)/mt19937ar.h +MT19937AR_INCLUDE = -I$(MT19937AR_D) + +LOGIN_C = account_sql.c ipban_sql.c login.c loginlog_sql.c +LOGIN_OBJ = $(addprefix obj_sql/, $(patsubst %.c,%.o,$(LOGIN_C))) LOGIN_H = login.h account.h ipban.h loginlog.h HAVE_MYSQL=@HAVE_MYSQL@ ifeq ($(HAVE_MYSQL),yes) - LOGIN_SERVER_SQL_DEPENDS=$(LOGIN_OBJ) ../common/obj_sql/common_sql.a ../common/obj_all/common.a $(MT19937AR_OBJ) $(LIBCONFIG_OBJ) + LOGIN_SERVER_SQL_DEPENDS=$(LOGIN_OBJ) $(COMMON_D)/obj_sql/common_sql.a $(COMMON_D)/obj_all/common.a $(MT19937AR_OBJ) $(LIBCONFIG_OBJ) else LOGIN_SERVER_SQL_DEPENDS=needs_mysql endif @@ -75,22 +78,23 @@ login-server: ../../login-server@EXEEXT@ ../../login-server@EXEEXT@: $(LOGIN_SERVER_SQL_DEPENDS) Makefile @echo " LD $(notdir $@)" - @$(CC) @LDFLAGS@ -o ../../login-server@EXEEXT@ $(LOGIN_OBJ) ../common/obj_sql/common_sql.a ../common/obj_all/common.a $(MT19937AR_OBJ) $(LIBCONFIG_OBJ) @LIBS@ @MYSQL_LIBS@ + @$(CC) @LDFLAGS@ -o ../../login-server@EXEEXT@ $(LOGIN_OBJ) $(COMMON_D)/obj_sql/common_sql.a \ + $(COMMON_D)/obj_all/common.a $(MT19937AR_OBJ) $(LIBCONFIG_OBJ) @LIBS@ @MYSQL_LIBS@ # login object files obj_sql/%.o: %.c $(LOGIN_H) $(COMMON_H) $(CONFIG_H) $(MT19937AR_H) $(LIBCONFIG_H) | obj_sql @echo " CC $<" - @$(CC) @CFLAGS@ $(MT19937AR_INCLUDE) $(LIBCONFIG_INCLUDE) -DWITH_SQL @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $< + @$(CC) @CFLAGS@ $(MT19937AR_INCLUDE) $(LIBCONFIG_INCLUDE) @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $< # missing object files -../common/obj_all/common.a: +$(COMMON_D)/obj_all/common.a: @echo " MAKE $@" - @$(MAKE) -C ../common sql + @$(MAKE) -C $(COMMON_D) sql -../common/obj_sql/common_sql.a: +$(COMMON_D)/obj_sql/common_sql.a: @echo " MAKE $@" - @$(MAKE) -C ../common sql + @$(MAKE) -C $(COMMON_D) sql $(MT19937AR_OBJ): @echo " MAKE $@" diff --git a/src/login/account.h b/src/login/account.h index f55e38b0c..234e7c0c1 100644 --- a/src/login/account.h +++ b/src/login/account.h @@ -1,8 +1,9 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena Dev Teams -#ifndef __ACCOUNT_H_INCLUDED__ -#define __ACCOUNT_H_INCLUDED__ +#ifndef _LOGIN_ACCOUNT_H_ +#define _LOGIN_ACCOUNT_H_ #include "../common/cbasetypes.h" #include "../common/mmo.h" // ACCOUNT_REG2_NUM @@ -32,8 +33,6 @@ struct mmo_account char lastlogin[24]; // date+time of last successful login char last_ip[16]; // save of last IP of connection char birthdate[10+1]; // assigned birth date (format: YYYY-MM-DD, default: 0000-00-00) - int account_reg2_num; - struct global_reg account_reg2[ACCOUNT_REG2_NUM]; // account script variables (stored on login server) }; @@ -137,4 +136,7 @@ struct AccountDB Sql *account_db_sql_up(AccountDB* self); -#endif // __ACCOUNT_H_INCLUDED__ +void mmo_send_accreg2(AccountDB* self, int fd, int account_id, int char_id); +void mmo_save_accreg2(AccountDB* self, int fd, int account_id, int char_id); + +#endif /* _LOGIN_ACCOUNT_H_ */ diff --git a/src/login/account_sql.c b/src/login/account_sql.c index 533b3d860..1483196ab 100644 --- a/src/login/account_sql.c +++ b/src/login/account_sql.c @@ -9,6 +9,7 @@ #include "../common/strlib.h" #include "../common/timer.h" #include "../common/console.h" +#include "../common/socket.h" #include "account.h" #include <stdlib.h> #include <string.h> @@ -40,7 +41,9 @@ typedef struct AccountDB_SQL // other settings bool case_sensitive; char account_db[32]; - char accreg_db[32]; + char global_acc_reg_num_db[32]; + char global_acc_reg_str_db[32]; + } AccountDB_SQL; @@ -106,7 +109,8 @@ AccountDB* account_db_sql(void) // other settings db->case_sensitive = false; safestrncpy(db->account_db, "login", sizeof(db->account_db)); - safestrncpy(db->accreg_db, "global_reg_value", sizeof(db->accreg_db)); + safestrncpy(db->global_acc_reg_num_db, "global_acc_reg_num_db", sizeof(db->global_acc_reg_num_db)); + safestrncpy(db->global_acc_reg_str_db, "global_acc_reg_str_db", sizeof(db->global_acc_reg_str_db)); return &db->vtable; } @@ -250,8 +254,11 @@ static bool account_db_sql_get_property(AccountDB* self, const char* key, char* if( strcmpi(key, "account_db") == 0 ) safesnprintf(buf, buflen, "%s", db->account_db); else - if( strcmpi(key, "accreg_db") == 0 ) - safesnprintf(buf, buflen, "%s", db->accreg_db); + if( strcmpi(key, "global_acc_reg_str_db") == 0 ) + safesnprintf(buf, buflen, "%s", db->global_acc_reg_str_db); + else + if( strcmpi(key, "global_acc_reg_num_db") == 0 ) + safesnprintf(buf, buflen, "%s", db->global_acc_reg_num_db); else return false;// not found return true; @@ -321,8 +328,11 @@ static bool account_db_sql_set_property(AccountDB* self, const char* key, const if( strcmpi(key, "account_db") == 0 ) safestrncpy(db->account_db, value, sizeof(db->account_db)); else - if( strcmpi(key, "accreg_db") == 0 ) - safestrncpy(db->accreg_db, value, sizeof(db->accreg_db)); + if( strcmpi(key, "global_acc_reg_str_db") == 0 ) + safestrncpy(db->global_acc_reg_str_db, value, sizeof(db->global_acc_reg_str_db)); + else + if( strcmpi(key, "global_acc_reg_num_db") == 0 ) + safestrncpy(db->global_acc_reg_num_db, value, sizeof(db->global_acc_reg_num_db)); else return false;// not found return true; @@ -393,7 +403,9 @@ static bool account_db_sql_remove(AccountDB* self, const int account_id) if( SQL_SUCCESS != SQL->QueryStr(sql_handle, "START TRANSACTION") || SQL_SUCCESS != SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = %d", db->account_db, account_id) - || SQL_SUCCESS != SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = %d", db->accreg_db, account_id) ) + || SQL_SUCCESS != SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = %d", db->global_acc_reg_num_db, account_id) + || SQL_SUCCESS != SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = %d", db->global_acc_reg_str_db, account_id) + ) Sql_ShowDebug(sql_handle); else result = true; @@ -520,7 +532,6 @@ static bool mmo_auth_fromsql(AccountDB_SQL* db, struct mmo_account* acc, int acc { Sql* sql_handle = db->accounts; char* data; - int i = 0; // retrieve login entry for the specified account if( SQL_ERROR == SQL->Query(sql_handle, @@ -543,41 +554,19 @@ static bool mmo_auth_fromsql(AccountDB_SQL* db, struct mmo_account* acc, int acc SQL->GetData(sql_handle, 3, &data, NULL); acc->sex = data[0]; SQL->GetData(sql_handle, 4, &data, NULL); safestrncpy(acc->email, data, sizeof(acc->email)); SQL->GetData(sql_handle, 5, &data, NULL); acc->group_id = atoi(data); - SQL->GetData(sql_handle, 6, &data, NULL); acc->state = strtoul(data, NULL, 10); + SQL->GetData(sql_handle, 6, &data, NULL); acc->state = (unsigned int)strtoul(data, NULL, 10); SQL->GetData(sql_handle, 7, &data, NULL); acc->unban_time = atol(data); SQL->GetData(sql_handle, 8, &data, NULL); acc->expiration_time = atol(data); - SQL->GetData(sql_handle, 9, &data, NULL); acc->logincount = strtoul(data, NULL, 10); + SQL->GetData(sql_handle, 9, &data, NULL); acc->logincount = (unsigned int)strtoul(data, NULL, 10); SQL->GetData(sql_handle, 10, &data, NULL); safestrncpy(acc->lastlogin, data, sizeof(acc->lastlogin)); SQL->GetData(sql_handle, 11, &data, NULL); safestrncpy(acc->last_ip, data, sizeof(acc->last_ip)); SQL->GetData(sql_handle, 12, &data, NULL); safestrncpy(acc->birthdate, data, sizeof(acc->birthdate)); SQL->GetData(sql_handle, 13, &data, NULL); acc->char_slots = (uint8)atoi(data); SQL->GetData(sql_handle, 14, &data, NULL); safestrncpy(acc->pincode, data, sizeof(acc->pincode)); - SQL->GetData(sql_handle, 15, &data, NULL); acc->pincode_change = atol(data); + SQL->GetData(sql_handle, 15, &data, NULL); acc->pincode_change = (unsigned int)atol(data); SQL->FreeResult(sql_handle); - - // retrieve account regs for the specified user - if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `str`,`value` FROM `%s` WHERE `type`='1' AND `account_id`='%d'", db->accreg_db, acc->account_id) ) - { - Sql_ShowDebug(sql_handle); - return false; - } - - acc->account_reg2_num = (int)SQL->NumRows(sql_handle); - - while( SQL_SUCCESS == SQL->NextRow(sql_handle) ) - { - char* data; - SQL->GetData(sql_handle, 0, &data, NULL); safestrncpy(acc->account_reg2[i].str, data, sizeof(acc->account_reg2[i].str)); - SQL->GetData(sql_handle, 1, &data, NULL); safestrncpy(acc->account_reg2[i].value, data, sizeof(acc->account_reg2[i].value)); - ++i; - } - SQL->FreeResult(sql_handle); - - if( i != acc->account_reg2_num ) - return false; - return true; } @@ -586,7 +575,6 @@ static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, boo Sql* sql_handle = db->accounts; SqlStmt* stmt = SQL->StmtMalloc(sql_handle); bool result = false; - int i; // try do @@ -648,34 +636,6 @@ static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, boo } } - // remove old account regs - if( SQL_SUCCESS != SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `type`='1' AND `account_id`='%d'", db->accreg_db, acc->account_id) ) - { - Sql_ShowDebug(sql_handle); - break; - } - // insert new account regs - if( SQL_SUCCESS != SQL->StmtPrepare(stmt, "INSERT INTO `%s` (`type`, `account_id`, `str`, `value`) VALUES ( 1 , '%d' , ? , ? );", db->accreg_db, acc->account_id) ) - { - SqlStmt_ShowDebug(stmt); - break; - } - for( i = 0; i < acc->account_reg2_num; ++i ) - { - if( SQL_SUCCESS != SQL->StmtBindParam(stmt, 0, SQLDT_STRING, (void*)acc->account_reg2[i].str, strlen(acc->account_reg2[i].str)) - || SQL_SUCCESS != SQL->StmtBindParam(stmt, 1, SQLDT_STRING, (void*)acc->account_reg2[i].value, strlen(acc->account_reg2[i].value)) - || SQL_SUCCESS != SQL->StmtExecute(stmt) - ) { - SqlStmt_ShowDebug(stmt); - break; - } - } - if( i < acc->account_reg2_num ) - { - result = false; - break; - } - // if we got this far, everything was successful result = true; @@ -687,6 +647,7 @@ static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, boo return result; } + Sql* account_db_sql_up(AccountDB* self) { AccountDB_SQL* db = (AccountDB_SQL*)self; Sql_HerculesUpdateCheck(db->accounts); @@ -695,3 +656,196 @@ Sql* account_db_sql_up(AccountDB* self) { #endif return db->accounts; } +void mmo_save_accreg2(AccountDB* self, int fd, int account_id, int char_id) { + Sql* sql_handle = ((AccountDB_SQL*)self)->accounts; + AccountDB_SQL* db = (AccountDB_SQL*)self; + int count = RFIFOW(fd, 12); + + if( count ) { + int cursor = 14, i; + char key[32], sval[254]; + unsigned int index; + + for(i = 0; i < count; i++) { + safestrncpy(key, (char*)RFIFOP(fd, cursor + 1), RFIFOB(fd, cursor)); + cursor += RFIFOB(fd, cursor) + 1; + + index = RFIFOL(fd, cursor); + cursor += 4; + + switch (RFIFOB(fd, cursor++)) { + /* int */ + case 0: + if( SQL_ERROR == SQL->Query(sql_handle, "REPLACE INTO `%s` (`account_id`,`key`,`index`,`value`) VALUES ('%d','%s','%u','%d')", db->global_acc_reg_num_db, account_id, key, index, RFIFOL(fd, cursor)) ) + Sql_ShowDebug(sql_handle); + cursor += 4; + break; + case 1: + if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '%d' AND `key` = '%s' AND `index` = '%u' LIMIT 1", db->global_acc_reg_num_db, account_id, key, index) ) + Sql_ShowDebug(sql_handle); + break; + /* str */ + case 2: + safestrncpy(sval, (char*)RFIFOP(fd, cursor + 1), RFIFOB(fd, cursor)); + cursor += RFIFOB(fd, cursor) + 1; + if( SQL_ERROR == SQL->Query(sql_handle, "REPLACE INTO `%s` (`account_id`,`key`,`index`,`value`) VALUES ('%d','%s','%u','%s')", db->global_acc_reg_str_db, account_id, key, index, sval) ) + Sql_ShowDebug(sql_handle); + break; + case 3: + if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = '%d' AND `key` = '%s' AND `index` = '%u' LIMIT 1", db->global_acc_reg_str_db, account_id, key, index) ) + Sql_ShowDebug(sql_handle); + break; + + default: + ShowError("mmo_save_accreg2: DA HOO UNKNOWN TYPE %d\n",RFIFOB(fd, cursor - 1)); + return; + } + + } + + } + +} +void mmo_send_accreg2(AccountDB* self, int fd, int account_id, int char_id) { + Sql* sql_handle = ((AccountDB_SQL*)self)->accounts; + AccountDB_SQL* db = (AccountDB_SQL*)self; + char* data; + int plen = 0; + size_t len; + + if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `key`, `index`, `value` FROM `%s` WHERE `account_id`='%d'", db->global_acc_reg_str_db, account_id) ) + Sql_ShowDebug(sql_handle); + + WFIFOHEAD(fd, 60000 + 300); + WFIFOW(fd, 0) = 0x3804; + /* 0x2 = length, set prior to being sent */ + WFIFOL(fd, 4) = account_id; + WFIFOL(fd, 8) = char_id; + WFIFOB(fd, 12) = 0;/* var type (only set when all vars have been sent, regardless of type) */ + WFIFOB(fd, 13) = 1;/* is string type */ + WFIFOW(fd, 14) = 0;/* count */ + plen = 16; + + /** + * Vessel! + * + * str type + * { keyLength(B), key(<keyLength>), index(L), valLength(B), val(<valLength>) } + **/ + while ( SQL_SUCCESS == SQL->NextRow(sql_handle) ) { + + SQL->GetData(sql_handle, 0, &data, NULL); + len = strlen(data)+1; + + WFIFOB(fd, plen) = (unsigned char)len;/* won't be higher; the column size is 32 */ + plen += 1; + + safestrncpy((char*)WFIFOP(fd,plen), data, len); + plen += len; + + SQL->GetData(sql_handle, 1, &data, NULL); + + WFIFOL(fd, plen) = (unsigned int)atol(data); + plen += 4; + + SQL->GetData(sql_handle, 2, &data, NULL); + len = strlen(data)+1; + + WFIFOB(fd, plen) = (unsigned char)len;/* won't be higher; the column size is 254 */ + plen += 1; + + safestrncpy((char*)WFIFOP(fd,plen), data, len); + plen += len; + + WFIFOW(fd, 14) += 1; + + if( plen > 60000 ) { + WFIFOW(fd, 2) = plen; + WFIFOSET(fd, plen); + + /* prepare follow up */ + WFIFOHEAD(fd, 60000 + 300); + WFIFOW(fd, 0) = 0x3804; + /* 0x2 = length, set prior to being sent */ + WFIFOL(fd, 4) = account_id; + WFIFOL(fd, 8) = char_id; + WFIFOB(fd, 12) = 0;/* var type (only set when all vars have been sent, regardless of type) */ + WFIFOB(fd, 13) = 1;/* is string type */ + WFIFOW(fd, 14) = 0;/* count */ + plen = 16; + } + } + + /* mark & go. */ + WFIFOW(fd, 2) = plen; + WFIFOSET(fd, plen); + + SQL->FreeResult(sql_handle); + + if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `key`, `index`, `value` FROM `%s` WHERE `account_id`='%d'", db->global_acc_reg_num_db, account_id) ) + Sql_ShowDebug(sql_handle); + + WFIFOHEAD(fd, 60000 + 300); + WFIFOW(fd, 0) = 0x3804; + /* 0x2 = length, set prior to being sent */ + WFIFOL(fd, 4) = account_id; + WFIFOL(fd, 8) = char_id; + WFIFOB(fd, 12) = 0;/* var type (only set when all vars have been sent, regardless of type) */ + WFIFOB(fd, 13) = 0;/* is int type */ + WFIFOW(fd, 14) = 0;/* count */ + plen = 16; + + /** + * Vessel! + * + * int type + * { keyLength(B), key(<keyLength>), index(L), value(L) } + **/ + while ( SQL_SUCCESS == SQL->NextRow(sql_handle) ) { + + SQL->GetData(sql_handle, 0, &data, NULL); + len = strlen(data)+1; + + WFIFOB(fd, plen) = (unsigned char)len;/* won't be higher; the column size is 32 */ + plen += 1; + + safestrncpy((char*)WFIFOP(fd,plen), data, len); + plen += len; + + SQL->GetData(sql_handle, 1, &data, NULL); + + WFIFOL(fd, plen) = (unsigned int)atol(data); + plen += 4; + + SQL->GetData(sql_handle, 2, &data, NULL); + + WFIFOL(fd, plen) = atoi(data); + plen += 4; + + WFIFOW(fd, 14) += 1; + + if( plen > 60000 ) { + WFIFOW(fd, 2) = plen; + WFIFOSET(fd, plen); + + /* prepare follow up */ + WFIFOHEAD(fd, 60000 + 300); + WFIFOW(fd, 0) = 0x3804; + /* 0x2 = length, set prior to being sent */ + WFIFOL(fd, 4) = account_id; + WFIFOL(fd, 8) = char_id; + WFIFOB(fd, 12) = 0;/* var type (only set when all vars have been sent, regardless of type) */ + WFIFOB(fd, 13) = 0;/* is int type */ + WFIFOW(fd, 14) = 0;/* count */ + + plen = 16; + } + } + + /* mark as complete & go. */ + WFIFOB(fd, 12) = 1; + WFIFOW(fd, 2) = plen; + WFIFOSET(fd, plen); + + SQL->FreeResult(sql_handle); +} diff --git a/src/login/ipban.h b/src/login/ipban.h index b2a1a7d9e..e6851d8dd 100644 --- a/src/login/ipban.h +++ b/src/login/ipban.h @@ -1,8 +1,8 @@ // Copyright (c) Athena Dev Teams - Licensed under GNU GPL // For more information, see LICENCE in the main folder -#ifndef __IPBAN_H_INCLUDED__ -#define __IPBAN_H_INCLUDED__ +#ifndef _LOGIN_IPBAN_H_ +#define _LOGIN_IPBAN_H_ #include "../common/cbasetypes.h" @@ -22,4 +22,4 @@ void ipban_log(uint32 ip); bool ipban_config_read(const char* key, const char* value); -#endif // __IPBAN_H_INCLUDED__ +#endif /* _LOGIN_IPBAN_H_ */ diff --git a/src/login/ipban_sql.c b/src/login/ipban_sql.c index 9b074b368..74f45e418 100644 --- a/src/login/ipban_sql.c +++ b/src/login/ipban_sql.c @@ -36,7 +36,7 @@ static Sql* sql_handle = NULL; static int cleanup_timer_id = INVALID_TIMER; static bool ipban_inited = false; -int ipban_cleanup(int tid, unsigned int tick, int id, intptr_t data); +int ipban_cleanup(int tid, int64 tick, int id, intptr_t data); // initialize @@ -247,8 +247,7 @@ void ipban_log(uint32 ip) } // remove expired bans -int ipban_cleanup(int tid, unsigned int tick, int id, intptr_t data) -{ +int ipban_cleanup(int tid, int64 tick, int id, intptr_t data) { if( !login_config.ipban ) return 0;// ipban disabled diff --git a/src/login/login.c b/src/login/login.c index b603117e4..252031bb8 100644 --- a/src/login/login.c +++ b/src/login/login.c @@ -11,6 +11,7 @@ #include "../common/socket.h" #include "../common/strlib.h" #include "../common/timer.h" +#include "../common/utils.h" #include "../common/HPM.h" #include "account.h" #include "ipban.h" @@ -65,6 +66,8 @@ struct auth_node { char sex; uint32 version; uint8 clienttype; + int group_id; + time_t expiration_time; }; static DBMap* auth_db; // int account_id -> struct auth_node* @@ -81,7 +84,7 @@ struct online_login_data { }; static DBMap* online_db; // int account_id -> struct online_login_data* -static int waiting_disconnect_timer(int tid, unsigned int tick, int id, intptr_t data); +static int waiting_disconnect_timer(int tid, int64 tick, int id, intptr_t data); /** * @see DBCreateData @@ -121,8 +124,7 @@ void remove_online_user(int account_id) idb_remove(online_db, account_id); } -static int waiting_disconnect_timer(int tid, unsigned int tick, int id, intptr_t data) -{ +static int waiting_disconnect_timer(int tid, int64 tick, int id, intptr_t data) { struct online_login_data* p = (struct online_login_data*)idb_get(online_db, id); if( p != NULL && p->waiting_disconnect == tid && p->account_id == id ) { @@ -139,8 +141,8 @@ static int waiting_disconnect_timer(int tid, unsigned int tick, int id, intptr_t static int online_db_setoffline(DBKey key, DBData *data, va_list ap) { struct online_login_data* p = DB->data2ptr(data); - int server = va_arg(ap, int); - if( server == -1 ) + int server_id = va_arg(ap, int); + if( server_id == -1 ) { p->char_server = -1; if( p->waiting_disconnect != INVALID_TIMER ) @@ -149,7 +151,7 @@ static int online_db_setoffline(DBKey key, DBData *data, va_list ap) p->waiting_disconnect = INVALID_TIMER; } } - else if( p->char_server == server ) + else if( p->char_server == server_id ) p->char_server = -2; //Char server disconnected. return 0; } @@ -165,8 +167,7 @@ static int online_data_cleanup_sub(DBKey key, DBData *data, va_list ap) return 0; } -static int online_data_cleanup(int tid, unsigned int tick, int id, intptr_t data) -{ +static int online_data_cleanup(int tid, int64 tick, int id, intptr_t data) { online_db->foreach(online_db, online_data_cleanup_sub); return 0; } @@ -234,8 +235,7 @@ void chrif_on_disconnect(int id) //----------------------------------------------------- // periodic ip address synchronization //----------------------------------------------------- -static int sync_ip_addresses(int tid, unsigned int tick, int id, intptr_t data) -{ +static int sync_ip_addresses(int tid, int64 tick, int id, intptr_t data) { uint8 buf[2]; ShowInfo("IP Sync in progress...\n"); WBUFW(buf,0) = 0x2735; @@ -273,18 +273,6 @@ bool check_password(const char* md5key, int passwdenc, const char* passwd, const } } - -//----------------------------------------------------- -// custom timestamp formatting (from eApp) -//----------------------------------------------------- -const char* timestamp2string(char* str, size_t size, time_t timestamp, const char* format) -{ - size_t len = strftime(str, size, format, localtime(×tamp)); - memset(str + len, '\0', size - len); - return str; -} - - //-------------------------------------------- // Test to know if an IP come from LAN or WAN. //-------------------------------------------- @@ -411,7 +399,7 @@ int parse_fromchar(int fd) //ShowStatus("Char-server '%s': authentication of the account %d accepted (ip: %s).\n", server[id].name, account_id, ip); // send ack - WFIFOHEAD(fd,25); + WFIFOHEAD(fd,33); WFIFOW(fd,0) = 0x2713; WFIFOL(fd,2) = account_id; WFIFOL(fd,6) = login_id1; @@ -421,7 +409,9 @@ int parse_fromchar(int fd) WFIFOL(fd,16) = request_id; WFIFOL(fd,20) = node->version; WFIFOB(fd,24) = node->clienttype; - WFIFOSET(fd,25); + WFIFOL(fd,25) = node->group_id; + WFIFOL(fd,29) = (unsigned int)node->expiration_time; + WFIFOSET(fd,33); // each auth entry can only be used once idb_remove(auth_db, account_id); @@ -429,7 +419,7 @@ int parse_fromchar(int fd) else {// authentication not found ShowStatus("Char-server '%s': authentication of the account %d REFUSED (ip: %s).\n", server[id].name, account_id, ip); - WFIFOHEAD(fd,25); + WFIFOHEAD(fd,33); WFIFOW(fd,0) = 0x2713; WFIFOL(fd,2) = account_id; WFIFOL(fd,6) = login_id1; @@ -439,7 +429,9 @@ int parse_fromchar(int fd) WFIFOL(fd,16) = request_id; WFIFOL(fd,20) = 0; WFIFOB(fd,24) = 0; - WFIFOSET(fd,25); + WFIFOL(fd,25) = 0; + WFIFOL(fd,29) = 0; + WFIFOSET(fd,33); } } break; @@ -712,30 +704,8 @@ int parse_fromchar(int fd) if( !accounts->load_num(accounts, &acc, account_id) ) ShowStatus("Char-server '%s': receiving (from the char-server) of account_reg2 (account: %d not found, ip: %s).\n", server[id].name, account_id, ip); - else - { - int len; - int p; - ShowNotice("char-server '%s': receiving (from the char-server) of account_reg2 (account: %d, ip: %s).\n", server[id].name, account_id, ip); - for( j = 0, p = 13; j < ACCOUNT_REG2_NUM && p < RFIFOW(fd,2); ++j ) - { - sscanf((char*)RFIFOP(fd,p), "%31c%n", acc.account_reg2[j].str, &len); - acc.account_reg2[j].str[len]='\0'; - p +=len+1; //+1 to skip the '\0' between strings. - sscanf((char*)RFIFOP(fd,p), "%255c%n", acc.account_reg2[j].value, &len); - acc.account_reg2[j].value[len]='\0'; - p +=len+1; - remove_control_chars(acc.account_reg2[j].str); - remove_control_chars(acc.account_reg2[j].value); - } - acc.account_reg2_num = j; - - // Save - accounts->save(accounts, &acc); - - // Sending information towards the other char-servers. - RFIFOW(fd,0) = 0x2729;// reusing read buffer - charif_sendallwos(fd, RFIFOP(fd,0), RFIFOW(fd,2)); + else { + mmo_save_accreg2(accounts,fd,account_id,RFIFOL(fd, 8)); } RFIFOSKIP(fd,RFIFOW(fd,2)); } @@ -805,34 +775,11 @@ int parse_fromchar(int fd) if (RFIFOREST(fd) < 10) return 0; { - struct mmo_account acc; - size_t off; - int account_id = RFIFOL(fd,2); int char_id = RFIFOL(fd,6); RFIFOSKIP(fd,10); - WFIFOHEAD(fd,ACCOUNT_REG2_NUM*sizeof(struct global_reg)); - WFIFOW(fd,0) = 0x2729; - WFIFOL(fd,4) = account_id; - WFIFOL(fd,8) = char_id; - WFIFOB(fd,12) = 1; //Type 1 for Account2 registry - - off = 13; - if( accounts->load_num(accounts, &acc, account_id) ) - { - for( j = 0; j < acc.account_reg2_num; j++ ) - { - if( acc.account_reg2[j].str[0] != '\0' ) - { - off += sprintf((char*)WFIFOP(fd,off), "%s", acc.account_reg2[j].str)+1; //We add 1 to consider the '\0' in place. - off += sprintf((char*)WFIFOP(fd,off), "%s", acc.account_reg2[j].value)+1; - } - } - } - - WFIFOW(fd,2) = (uint16)off; - WFIFOSET(fd,WFIFOW(fd,2)); + mmo_send_accreg2(accounts,fd,account_id,char_id); } break; @@ -885,6 +832,46 @@ int parse_fromchar(int fd) } break; + case 0x2740: // Accinfo request forwarded by charserver on mapserver's account + if( RFIFOREST(fd) < 22 ) + return 0; + else { + struct mmo_account acc; + int account_id = RFIFOL(fd, 2), u_fd = RFIFOL(fd, 6), u_aid = RFIFOL(fd, 10), u_group = RFIFOL(fd, 14), map_fd = RFIFOL(fd, 18); + if (accounts->load_num(accounts, &acc, account_id)) { + WFIFOHEAD(fd,183); + WFIFOW(fd,0) = 0x2737; + safestrncpy((char*)WFIFOP(fd,2), acc.userid, NAME_LENGTH); + if (u_group >= acc.group_id) { + safestrncpy((char*)WFIFOP(fd,26), acc.pass, 33); + } + safestrncpy((char*)WFIFOP(fd,59), acc.email, 40); + safestrncpy((char*)WFIFOP(fd,99), acc.last_ip, 16); + WFIFOL(fd,115) = acc.group_id; + safestrncpy((char*)WFIFOP(fd,119), acc.lastlogin, 24); + WFIFOL(fd,143) = acc.logincount; + WFIFOL(fd,147) = acc.state; + if (u_group >= acc.group_id) { + safestrncpy((char*)WFIFOP(fd,151), acc.pincode, 5); + } + safestrncpy((char*)WFIFOP(fd,156), acc.birthdate, 11); + WFIFOL(fd,167) = map_fd; + WFIFOL(fd,171) = u_fd; + WFIFOL(fd,175) = u_aid; + WFIFOL(fd,179) = account_id; + WFIFOSET(fd,183); + } else { + WFIFOHEAD(fd,18); + WFIFOW(fd,0) = 0x2736; + WFIFOL(fd,2) = map_fd; + WFIFOL(fd,6) = u_fd; + WFIFOL(fd,10) = u_aid; + WFIFOL(fd,14) = account_id; + WFIFOSET(fd,18); + } + RFIFOSKIP(fd,22); + } + break; default: ShowError("parse_fromchar: Unknown packet 0x%x from a char-server! Disconnecting!\n", command); set_eof(fd); @@ -901,8 +888,8 @@ int parse_fromchar(int fd) //------------------------------------- int mmo_auth_new(const char* userid, const char* pass, const char sex, const char* last_ip) { static int num_regs = 0; // registration counter - static unsigned int new_reg_tick = 0; - unsigned int tick = timer->gettick(); + static int64 new_reg_tick = 0; + int64 tick = timer->gettick(); struct mmo_account acc; //Account Registration Flood Protection by [Kevin] @@ -959,7 +946,7 @@ int mmo_auth_new(const char* userid, const char* pass, const char sex, const cha //----------------------------------------------------- int mmo_auth(struct login_session_data* sd, bool isServer) { struct mmo_account acc; - int len; + size_t len; char ip[16]; ip2str(session[sd->fd]->client_addr, ip); @@ -1017,11 +1004,6 @@ int mmo_auth(struct login_session_data* sd, bool isServer) { return 1; // 1 = Incorrect Password } - if( acc.expiration_time != 0 && acc.expiration_time < time(NULL) ) { - ShowNotice("Connection refused (account: %s, pass: %s, expired ID, ip: %s)\n", sd->userid, sd->passwd, ip); - return 2; // 2 = This ID is expired - } - if( acc.unban_time != 0 && acc.unban_time > time(NULL) ) { char tmpstr[24]; timestamp2string(tmpstr, sizeof(tmpstr), acc.unban_time, login_config.date_format); @@ -1035,27 +1017,29 @@ int mmo_auth(struct login_session_data* sd, bool isServer) { } if( login_config.client_hash_check && !isServer ) { - struct client_hash_node *node = login_config.client_hash_nodes; + struct client_hash_node *node = NULL; bool match = false; - if( !sd->has_client_hash ) { - ShowNotice("Client doesn't sent client hash (account: %s, pass: %s, ip: %s)\n", sd->userid, sd->passwd, acc.state, ip); - return 5; - } - - while( node ) { - if( node->group_id <= acc.group_id && memcmp(node->hash, sd->client_hash, 16) == 0 ) { + for( node = login_config.client_hash_nodes; node; node = node->next ) { + if( acc.group_id < node->group_id ) + continue; + if( *node->hash == '\0' // Allowed to login without hash + || (sd->has_client_hash && memcmp(node->hash, sd->client_hash, 16) == 0 ) // Correct hash + ) { match = true; break; } - - node = node->next; } if( !match ) { char smd5[33]; int i; + if( !sd->has_client_hash ) { + ShowNotice("Client didn't send client hash (account: %s, pass: %s, ip: %s)\n", sd->userid, sd->passwd, acc.state, ip); + return 5; + } + for( i = 0; i < 16; i++ ) sprintf(&smd5[i * 2], "%02x", sd->client_hash[i]); @@ -1073,6 +1057,7 @@ int mmo_auth(struct login_session_data* sd, bool isServer) { safestrncpy(sd->lastlogin, acc.lastlogin, sizeof(sd->lastlogin)); sd->sex = acc.sex; sd->group_id = (uint8)acc.group_id; + sd->expiration_time = acc.expiration_time; // update account data timestamp2string(acc.lastlogin, sizeof(acc.lastlogin), time(NULL), "%Y-%m-%d %H:%M:%S"); @@ -1194,7 +1179,12 @@ void login_auth_ok(struct login_session_data* sd) WFIFOW(fd,47+n*32+4) = ntows(htons(server[i].port)); // [!] LE byte order here [!] memcpy(WFIFOP(fd,47+n*32+6), server[i].name, 20); WFIFOW(fd,47+n*32+26) = server[i].users; - WFIFOW(fd,47+n*32+28) = server[i].type; + + if( server[i].type == CST_PAYING && sd->expiration_time > time(NULL) ) + WFIFOW(fd,47+n*32+28) = CST_NORMAL; + else + WFIFOW(fd,47+n*32+28) = server[i].type; + WFIFOW(fd,47+n*32+30) = server[i].new_; n++; } @@ -1209,6 +1199,8 @@ void login_auth_ok(struct login_session_data* sd) node->ip = ip; node->version = sd->version; node->clienttype = sd->clienttype; + node->group_id = sd->group_id; + node->expiration_time = sd->expiration_time; idb_put(auth_db, sd->account_id, node); { @@ -1383,11 +1375,11 @@ int parse_login(int fd) { uint32 version; char username[NAME_LENGTH]; - char password[NAME_LENGTH]; + char password[PASSWD_LEN]; unsigned char passhash[16]; uint8 clienttype; bool israwpass = (command==0x0064 || command==0x0277 || command==0x02b0 || command == 0x0825); - + // Shinryo: For the time being, just use token as password. if(command == 0x0825) { @@ -1397,15 +1389,14 @@ int parse_login(int fd) size_t uTokenLen = RFIFOREST(fd) - 0x5C; version = RFIFOL(fd,4); - - if(uAccLen > NAME_LENGTH - 1 || uAccLen <= 0 || uTokenLen > NAME_LENGTH - 1 || uTokenLen <= 0) - { + + if(uAccLen <= 0 || uTokenLen <= 0) { login_auth_failed(sd, 3); return 0; } - safestrncpy(username, accname, uAccLen + 1); - safestrncpy(password, token, uTokenLen + 1); + safestrncpy(username, accname, NAME_LENGTH); + safestrncpy(password, token, min(uTokenLen+1, PASSWD_LEN)); // Variable-length field, don't copy more than necessary clienttype = RFIFOB(fd, 8); } else @@ -1431,7 +1422,7 @@ int parse_login(int fd) if( israwpass ) { ShowStatus("Request for connection of %s (ip: %s).\n", sd->userid, ip); - safestrncpy(sd->passwd, password, NAME_LENGTH); + safestrncpy(sd->passwd, password, PASSWD_LEN); if( login_config.use_md5_passwds ) MD5_String(sd->passwd, sd->passwd); sd->passwdenc = 0; @@ -1626,7 +1617,7 @@ int login_config_read(const char* cfgName) else if(!strcmpi(w1, "check_client_version")) login_config.check_client_version = (bool)config_switch(w2); else if(!strcmpi(w1, "client_version_to_connect")) - login_config.client_version_to_connect = strtoul(w2, NULL, 10); + login_config.client_version_to_connect = (unsigned int)strtoul(w2, NULL, 10); else if(!strcmpi(w1, "use_MD5_passwords")) login_config.use_md5_passwds = (bool)config_switch(w2); else if(!strcmpi(w1, "group_id_to_connect")) @@ -1658,15 +1649,19 @@ int login_config_read(const char* cfgName) int i; CREATE(nnode, struct client_hash_node, 1); - for (i = 0; i < 32; i += 2) { - char buf[3]; - unsigned int byte; + if (strcmpi(md5, "disabled") == 0) { + nnode->hash[0] = '\0'; + } else { + for (i = 0; i < 32; i += 2) { + char buf[3]; + unsigned int byte; - memcpy(buf, &md5[i], 2); - buf[2] = 0; + memcpy(buf, &md5[i], 2); + buf[2] = 0; - sscanf(buf, "%x", &byte); - nnode->hash[i / 2] = (uint8)(byte & 0xFF); + sscanf(buf, "%x", &byte); + nnode->hash[i / 2] = (uint8)(byte & 0xFF); + } } nnode->group_id = group; @@ -1781,8 +1776,6 @@ int do_init(int argc, char** argv) login_set_defaults(); login_config_read((argc > 1) ? argv[1] : LOGIN_CONF_NAME); login_lan_config_read((argc > 2) ? argv[2] : LAN_CONF_NAME); - - rnd_init(); for( i = 0; i < ARRAYLENGTH(server); ++i ) chrif_server_init(i); diff --git a/src/login/login.h b/src/login/login.h index 8a5eabb09..14c361a15 100644 --- a/src/login/login.h +++ b/src/login/login.h @@ -1,8 +1,9 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena Dev Teams -#ifndef _LOGIN_H_ -#define _LOGIN_H_ +#ifndef _LOGIN_LOGIN_H_ +#define _LOGIN_LOGIN_H_ #include "../common/mmo.h" // NAME_LENGTH,SEX_* #include "../common/core.h" // CORE_ST_LAST @@ -19,15 +20,16 @@ enum E_LOGINSERVER_ST // supported encryption types: 1- passwordencrypt, 2- passwordencrypt2, 3- both #define PASSWORDENC 3 +#define PASSWD_LEN 32+1 // 23+1 for plaintext, 32+1 for md5-ed passwords struct login_session_data { int account_id; - long login_id1; - long login_id2; + int login_id1; + int login_id2; char sex;// 'F','M','S' char userid[NAME_LENGTH]; - char passwd[32+1]; // 23+1 for plaintext, 32+1 for md5-ed passwords + char passwd[PASSWD_LEN]; int passwdenc; char md5key[20]; uint16 md5keylen; @@ -41,6 +43,8 @@ struct login_session_data { int has_client_hash; int fd; + + time_t expiration_time; }; struct mmo_char_server { @@ -88,12 +92,12 @@ struct Login_Config { struct client_hash_node *client_hash_nodes; // linked list containg md5 hash for each gm group }; -#define sex_num2str(num) ( (num == SEX_FEMALE ) ? 'F' : (num == SEX_MALE ) ? 'M' : 'S' ) -#define sex_str2num(str) ( (str == 'F' ) ? SEX_FEMALE : (str == 'M' ) ? SEX_MALE : SEX_SERVER ) +#define sex_num2str(num) ( ((num) == SEX_FEMALE) ? 'F' : ((num) == SEX_MALE) ? 'M' : 'S' ) +#define sex_str2num(str) ( ((str) == 'F') ? SEX_FEMALE : ((str) == 'M') ? SEX_MALE : SEX_SERVER ) #define MAX_SERVERS 30 extern struct mmo_char_server server[MAX_SERVERS]; extern struct Login_Config login_config; -#endif /* _LOGIN_H_ */ +#endif /* _LOGIN_LOGIN_H_ */ diff --git a/src/login/loginlog.h b/src/login/loginlog.h index a1ffaae85..730fb6e62 100644 --- a/src/login/loginlog.h +++ b/src/login/loginlog.h @@ -1,8 +1,8 @@ // Copyright (c) Athena Dev Teams - Licensed under GNU GPL // For more information, see LICENCE in the main folder -#ifndef __LOGINLOG_H_INCLUDED__ -#define __LOGINLOG_H_INCLUDED__ +#ifndef _LOGIN_LOGINLOG_H_ +#define _LOGIN_LOGINLOG_H_ unsigned long loginlog_failedattempts(uint32 ip, unsigned int minutes); @@ -12,4 +12,4 @@ bool loginlog_final(void); bool loginlog_config_read(const char* w1, const char* w2); -#endif // __LOGINLOG_H_INCLUDED__ +#endif /* _LOGIN_LOGINLOG_H_ */ diff --git a/src/map/HPMmap.c b/src/map/HPMmap.c index 3ba9ae725..061479d87 100644 --- a/src/map/HPMmap.c +++ b/src/map/HPMmap.c @@ -5,102 +5,211 @@ #include "../common/malloc.h" #include "../common/showmsg.h" #include "../common/HPM.h" +#include "../common/conf.h" +#include "../common/db.h" +#include "../common/des.h" +#include "../common/ers.h" +#include "../common/mapindex.h" +#include "../common/mmo.h" +#include "../common/socket.h" +#include "../common/strlib.h" + #include "HPMmap.h" #include "pc.h" #include "map.h" // +#include "atcommand.h" +#include "battle.h" +#include "battleground.h" #include "chat.h" #include "chrif.h" +#include "clif.h" +#include "date.h" #include "duel.h" #include "elemental.h" +#include "guild.h" #include "homunculus.h" #include "instance.h" #include "intif.h" #include "irc-bot.h" +#include "itemdb.h" +#include "log.h" #include "mail.h" #include "mapreg.h" #include "mercenary.h" +#include "mob.h" +#include "npc.h" #include "party.h" +#include "path.h" +#include "pc_groups.h" #include "pet.h" #include "quest.h" +#include "script.h" +#include "searchstore.h" +#include "skill.h" +#include "status.h" #include "storage.h" #include "trade.h" +#include "unit.h" +#include "vending.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> -void HPM_map_addToMSD(struct map_session_data *sd, void *data, unsigned int id, unsigned int type, bool autofree) { - struct HPluginData *HPData; - unsigned int i; +#include "../common/HPMDataCheck.h" + +struct HPM_atcommand_list { + //tracking currently not enabled + // - requires modifying how plugins calls atcommand creation + // - needs load/unload during runtime support + //unsigned int pID;/* plugin id */ + char name[ATCOMMAND_LENGTH]; + AtCommandFunc func; +}; + +struct HPM_atcommand_list *atcommand_list = NULL; +unsigned int atcommand_list_items = 0; + +/** + * (char*) data name -> (unsigned int) HPMDataCheck[] index + **/ +DBMap *datacheck_db; + +bool HPM_map_grabHPData(struct HPDataOperationStorage *ret, enum HPluginDataTypes type, void *ptr) { + /* record address */ + switch( type ) { + case HPDT_MSD: + ret->HPDataSRCPtr = (void**)(&((struct map_session_data *)ptr)->hdata); + ret->hdatac = &((struct map_session_data *)ptr)->hdatac; + break; + case HPDT_NPCD: + ret->HPDataSRCPtr = (void**)(&((struct npc_data *)ptr)->hdata); + ret->hdatac = &((struct npc_data *)ptr)->hdatac; + break; + case HPDT_MAP: + ret->HPDataSRCPtr = (void**)(&((struct map_data *)ptr)->hdata); + ret->hdatac = &((struct map_data *)ptr)->hdatac; + break; + case HPDT_PARTY: + ret->HPDataSRCPtr = (void**)(&((struct party_data *)ptr)->hdata); + ret->hdatac = &((struct party_data *)ptr)->hdatac; + break; + case HPDT_GUILD: + ret->HPDataSRCPtr = (void**)(&((struct guild *)ptr)->hdata); + ret->hdatac = &((struct guild *)ptr)->hdatac; + break; + case HPDT_INSTANCE: + ret->HPDataSRCPtr = (void**)(&((struct instance_data *)ptr)->hdata); + ret->hdatac = &((struct instance_data *)ptr)->hdatac; + break; + default: + return false; + } + return true; +} + +void HPM_map_plugin_load_sub(struct hplugin *plugin) { + plugin->hpi->addCommand = HPM->import_symbol("addCommand",plugin->idx); + plugin->hpi->addScript = HPM->import_symbol("addScript",plugin->idx); + plugin->hpi->addPCGPermission = HPM->import_symbol("addGroupPermission",plugin->idx); +} + +bool HPM_map_add_atcommand(char *name, AtCommandFunc func) { + unsigned int i = 0; - for(i = 0; i < sd->hdatac; i++) { - if( sd->hdata[i]->pluginID == id && sd->hdata[i]->type == type ) { - ShowError("HPMi->addToMSD:%s: error! attempting to insert duplicate struct of type %u on '%s'\n",HPM->pid2name(id),type,sd->status.name); - return; + for(i = 0; i < atcommand_list_items; i++) { + if( !strcmpi(atcommand_list[i].name,name) ) { + ShowDebug("HPM_map_add_atcommand: duplicate command '%s', skipping...\n", name); + return false; } } - CREATE(HPData, struct HPluginData, 1); - - HPData->pluginID = id; - HPData->type = type; - HPData->flag.free = autofree ? 1 : 0; - HPData->data = data; + i = atcommand_list_items; + + RECREATE(atcommand_list, struct HPM_atcommand_list , ++atcommand_list_items); - RECREATE(sd->hdata,struct HPluginData *,++sd->hdatac); - sd->hdata[sd->hdatac - 1] = HPData; + safestrncpy(atcommand_list[i].name, name, sizeof(atcommand_list[i].name)); + atcommand_list[i].func = func; + + return true; } -void *HPM_map_getFromMSD(struct map_session_data *sd, unsigned int id, unsigned int type) { + +void HPM_map_atcommands(void) { unsigned int i; - for(i = 0; i < sd->hdatac; i++) { - if( sd->hdata[i]->pluginID == id && sd->hdata[i]->type == type ) { - break; + for(i = 0; i < atcommand_list_items; i++) { + atcommand->add(atcommand_list[i].name,atcommand_list[i].func,true); + } +} + +/** + * Called by HPM->DataCheck on a plugins incoming data, ensures data structs in use are matching! + **/ +bool HPM_map_DataCheck (struct s_HPMDataCheck *src, unsigned int size, char *name) { + unsigned int i, j; + + for(i = 0; i < size; i++) { + + if( !strdb_exists(datacheck_db, src[i].name) ) { + ShowError("HPMDataCheck:%s: '%s' was not found\n",name,src[i].name); + return false; + } else { + j = strdb_uiget(datacheck_db, src[i].name);/* not double lookup; exists sets cache to found data */ + if( src[i].size != HPMDataCheck[j].size ) { + ShowWarning("HPMDataCheck:%s: '%s' size mismatch %u != %u\n",name,src[i].name,src[i].size,HPMDataCheck[j].size); + return false; + } } } + + return true; +} - if( i != sd->hdatac ) - return sd->hdata[i]->data; +/** + * Adds a new group permission to the HPM-provided list + **/ +void HPM_map_add_group_permission(unsigned int pluginID, char *name, unsigned int *mask) { + unsigned char index = pcg->HPMpermissions_count; + + RECREATE(pcg->HPMpermissions, struct pc_groups_new_permission, ++pcg->HPMpermissions_count); - return NULL; + pcg->HPMpermissions[index].pID = pluginID; + pcg->HPMpermissions[index].name = aStrdup(name); + pcg->HPMpermissions[index].mask = mask; } -void HPM_map_removeFromMSD(struct map_session_data *sd, unsigned int id, unsigned int type) { + +void HPM_map_do_init(void) { unsigned int i; - for(i = 0; i < sd->hdatac; i++) { - if( sd->hdata[i]->pluginID == id && sd->hdata[i]->type == type ) { - break; - } + /** + * Populates datacheck_db for easy lookup later on + **/ + datacheck_db = strdb_alloc(DB_OPT_BASE,0); + + for(i = 0; i < HPMDataCheckLen; i++) { + strdb_uiput(datacheck_db, HPMDataCheck[i].name, i); } - if( i != sd->hdatac ) { - unsigned int cursor; - - aFree(sd->hdata[i]->data); - aFree(sd->hdata[i]); - sd->hdata[i] = NULL; - - for(i = 0, cursor = 0; i < sd->hdatac; i++) { - if( sd->hdata[i] == NULL ) - continue; - if( i != cursor ) - sd->hdata[cursor] = sd->hdata[i]; - cursor++; - } - - sd->hdatac = cursor; +} + +void HPM_map_do_final(void) { + unsigned char i; + + if( atcommand_list ) + aFree(atcommand_list); + /** + * why is pcg->HPM being cleared here? because PCG's do_final is not final, + * is used on reload, and would thus cause plugin-provided permissions to go away + **/ + for( i = 0; i < pcg->HPMpermissions_count; i++ ) { + aFree(pcg->HPMpermissions[i].name); } + if( pcg->HPMpermissions ) + aFree(pcg->HPMpermissions); + db_destroy(datacheck_db); } -void HPM_map_plugin_load_sub(struct hplugin *plugin) { - plugin->hpi->addCommand = HPM->import_symbol("addCommand",plugin->idx); - plugin->hpi->addScript = HPM->import_symbol("addScript",plugin->idx); - /* */ - plugin->hpi->addToMSD = HPM->import_symbol("addToMSD",plugin->idx); - plugin->hpi->getFromMSD = HPM->import_symbol("getFromMSD",plugin->idx); - plugin->hpi->removeFromMSD = HPM->import_symbol("removeFromMSD",plugin->idx); -}
\ No newline at end of file diff --git a/src/map/HPMmap.h b/src/map/HPMmap.h index a6cac4ace..f291575fb 100644 --- a/src/map/HPMmap.h +++ b/src/map/HPMmap.h @@ -1,18 +1,29 @@ // Copyright (c) Hercules Dev Team, licensed under GNU GPL. // See the LICENSE file -#ifndef _HPM_MAP_ -#define _HPM_MAP_ +#ifndef _MAP_HPMMAP_H_ +#define _MAP_HPMMAP_H_ #include "../common/cbasetypes.h" +#include "../map/atcommand.h" +#include "../common/HPM.h" struct hplugin; struct map_session_data; -void HPM_map_addToMSD(struct map_session_data *sd, void *data, unsigned int id, unsigned int type, bool autofree); -void *HPM_map_getFromMSD(struct map_session_data *sd, unsigned int id, unsigned int type); -void HPM_map_removeFromMSD(struct map_session_data *sd, unsigned int id, unsigned int type); +bool HPM_map_grabHPData(struct HPDataOperationStorage *ret, enum HPluginDataTypes type, void *ptr); + +bool HPM_map_add_atcommand(char *name, AtCommandFunc func); +void HPM_map_atcommands(void); void HPM_map_plugin_load_sub(struct hplugin *plugin); -#endif /* _HPM_MAP_ */ +void HPM_map_do_final(void); + +void HPM_map_add_group_permission(unsigned int pluginID, char *name, unsigned int *mask); + +bool HPM_map_DataCheck(struct s_HPMDataCheck *src, unsigned int size, char *name); + +void HPM_map_do_init(void); + +#endif /* _MAP_HPMMAP_H_ */ diff --git a/src/map/Makefile.in b/src/map/Makefile.in index b516c61ca..e3a47abeb 100644 --- a/src/map/Makefile.in +++ b/src/map/Makefile.in @@ -1,35 +1,39 @@ -COMMON_H = $(shell ls ../common/*.h) -CONFIG_H = $(shell ls ../config/*.h ../config/*/*.h) +CONFIG_D = ../config +CONFIG_H = $(wildcard $(CONFIG_D)/*.h) $(wildcard $(CONFIG_D)/*/*.h) -MT19937AR_D = ../../3rdparty/mt19937ar -MT19937AR_OBJ = $(MT19937AR_D)/mt19937ar.o -MT19937AR_H = $(MT19937AR_D)/mt19937ar.h -MT19937AR_INCLUDE = -I$(MT19937AR_D) +COMMON_D = ../common +COMMON_H = $(wildcard $(COMMON_D)/*.h) LIBCONFIG_D = ../../3rdparty/libconfig LIBCONFIG_OBJ = $(addprefix $(LIBCONFIG_D)/, libconfig.o grammar.o scanctx.o \ - scanner.o strbuf.o) + scanner.o strbuf.o) LIBCONFIG_H = $(addprefix $(LIBCONFIG_D)/, libconfig.h grammar.h parsectx.h \ - scanctx.h scanner.h strbuf.h wincompat.h) + scanctx.h scanner.h strbuf.h wincompat.h) LIBCONFIG_INCLUDE = -I$(LIBCONFIG_D) -MAP_OBJ = $(addprefix obj_sql/, atcommand.o battle.o battleground.o \ - buyingstore.o chat.o chrif.o clif.o date.o duel.o elemental.o \ - guild.o homunculus.o HPMmap.o instance.o intif.o irc-bot.o itemdb.o \ - log.o mail.o map.o mapreg_sql.o mercenary.o mob.o npc.o npc_chat.o \ - party.o path.o pc.o pc_groups.o pet.o quest.o script.o \ - searchstore.o skill.o status.o storage.o trade.o unit.o vending.o) +MT19937AR_D = ../../3rdparty/mt19937ar +MT19937AR_OBJ = $(MT19937AR_D)/mt19937ar.o +MT19937AR_H = $(MT19937AR_D)/mt19937ar.h +MT19937AR_INCLUDE = -I$(MT19937AR_D) + +MAP_C = atcommand.c battle.c battleground.c buyingstore.c chat.c chrif.c \ + clif.c date.c duel.c elemental.c guild.c homunculus.c HPMmap.c \ + instance.c intif.c irc-bot.c itemdb.c log.c mail.c map.c mapreg_sql.c \ + mercenary.c mob.c npc.c npc_chat.c party.c path.c pc.c pc_groups.c \ + pet.c quest.c script.c searchstore.c skill.c status.c storage.c \ + trade.c unit.c vending.c +MAP_OBJ = $(addprefix obj_sql/, $(patsubst %c,%o,$(MAP_C))) MAP_H = atcommand.h battle.h battleground.h buyingstore.h chat.h chrif.h \ - clif.h date.h duel.h elemental.h guild.h homunculus.h HPMmap.h \ - instance.h intif.h irc-bot.h itemdb.h log.h mail.h map.h mapreg.h \ - mercenary.h mob.h npc.h packets.h packets_struct.h party.h path.h \ - pc.h pc_groups.h pet.h quest.h script.h searchstore.h skill.h \ - status.h storage.h trade.h unit.h vending.h + clif.h date.h duel.h elemental.h guild.h homunculus.h HPMmap.h \ + instance.h intif.h irc-bot.h itemdb.h log.h mail.h map.h mapreg.h \ + mercenary.h mob.h npc.h packets.h packets_struct.h party.h path.h \ + pc.h pc_groups.h pet.h quest.h script.h searchstore.h skill.h \ + status.h storage.h trade.h unit.h vending.h HAVE_MYSQL=@HAVE_MYSQL@ ifeq ($(HAVE_MYSQL),yes) - MAP_SERVER_SQL_DEPENDS=$(MAP_OBJ) ../common/obj_sql/common_sql.a ../common/obj_all/common.a $(MT19937AR_OBJ) $(LIBCONFIG_OBJ) + MAP_SERVER_SQL_DEPENDS=$(MAP_OBJ) $(COMMON_D)/obj_sql/common_sql.a $(COMMON_D)/obj_all/common.a $(MT19937AR_OBJ) $(LIBCONFIG_OBJ) else MAP_SERVER_SQL_DEPENDS=needs_mysql endif @@ -63,12 +67,12 @@ clean: buildclean help: @echo "possible targets are 'map-server' 'all' 'clean' 'help'" - @echo "'map-server' - map server" - @echo "'all' - builds all above targets" - @echo "'clean' - cleans builds and objects" - @echo "'buildclean' - cleans build temporary (object) files, without deleting the" - @echo " executables" - @echo "'help' - outputs this message" + @echo "'map-server' - map server" + @echo "'all' - builds all above targets" + @echo "'clean' - cleans builds and objects" + @echo "'buildclean' - cleans build temporary (object) files, without deleting the" + @echo " executables" + @echo "'help' - outputs this message" ##################################################################### @@ -91,7 +95,8 @@ map-server: ../../map-server@EXEEXT@ ../../map-server@EXEEXT@: $(MAP_SERVER_SQL_DEPENDS) Makefile @echo " LD $(notdir $@)" - @$(CC) @LDFLAGS@ -o ../../map-server@EXEEXT@ $(MAP_OBJ) ../common/obj_sql/common_sql.a ../common/obj_all/common.a $(MT19937AR_OBJ) $(LIBCONFIG_OBJ) @LIBS@ @PCRE_LIBS@ @MYSQL_LIBS@ + @$(CC) @LDFLAGS@ -o ../../map-server@EXEEXT@ $(MAP_OBJ) $(COMMON_D)/obj_sql/common_sql.a \ + $(COMMON_D)/obj_all/common.a $(MT19937AR_OBJ) $(LIBCONFIG_OBJ) @LIBS@ @PCRE_LIBS@ @MYSQL_LIBS@ # map object files @@ -100,14 +105,14 @@ obj_sql/%.o: %.c $(MAP_H) $(COMMON_H) $(CONFIG_H) $(MT19937AR_H) $(LIBCONFIG_H) @$(CC) @CFLAGS@ $(MT19937AR_INCLUDE) $(LIBCONFIG_INCLUDE) $(PCRE_CFLAGS) @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $< # missing object files -../common/obj_all/common.a: +$(COMMON_D)/obj_all/common.a: @echo " MAKE $@" - @$(MAKE) -C ../common sql - -../common/obj_sql/common_sql.a: + @$(MAKE) -C $(COMMON_D) sql + +$(COMMON_D)/obj_sql/common_sql.a: @echo " MAKE $@" - @$(MAKE) -C ../common sql - + @$(MAKE) -C $(COMMON_D) sql + $(MT19937AR_OBJ): @echo " MAKE $@" @$(MAKE) -C $(MT19937AR_D) diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 3d04a6bff..6a0c75db3 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -45,6 +45,7 @@ #include "mapreg.h" #include "quest.h" #include "searchstore.h" +#include "HPMmap.h" #include <stdio.h> #include <stdlib.h> @@ -63,7 +64,7 @@ struct atcmd_binding_data* get_atcommandbind_byname(const char* name) { if( *name == atcommand->at_symbol || *name == atcommand->char_symbol ) name++; // for backwards compatibility - ARR_FIND( 0, atcommand->binding_count, i, strcmp(atcommand->binding[i]->command, name) == 0 ); + ARR_FIND( 0, atcommand->binding_count, i, strcmpi(atcommand->binding[i]->command, name) == 0 ); return ( i < atcommand->binding_count ) ? atcommand->binding[i] : NULL; } @@ -71,8 +72,7 @@ struct atcmd_binding_data* get_atcommandbind_byname(const char* name) { //----------------------------------------------------------- // Return the message string of the specified number by [Yor] //----------------------------------------------------------- -const char* msg_txt(int msg_number) -{ +const char* atcommand_msg(int msg_number) { if (msg_number >= 0 && msg_number < MAX_MSG && atcommand->msg_table[msg_number] != NULL && atcommand->msg_table[msg_number][0] != '\0') return atcommand->msg_table[msg_number]; @@ -83,7 +83,7 @@ const char* msg_txt(int msg_number) /*========================================== * Read Message Data *------------------------------------------*/ -int msg_config_read(const char* cfgName) +bool msg_config_read(const char* cfgName) { int msg_number; char line[1024], w1[1024], w2[1024]; @@ -92,7 +92,7 @@ int msg_config_read(const char* cfgName) if ((fp = fopen(cfgName, "r")) == NULL) { ShowError("Messages file not found: %s\n", cfgName); - return 1; + return false; } if ((--called) == 0) @@ -123,7 +123,7 @@ int msg_config_read(const char* cfgName) fclose(fp); - return 0; + return true; } /*========================================== @@ -163,38 +163,32 @@ ACMD(send) clif->message(fd, msg_txt(i)); return false; } - -#define PARSE_ERROR(error,p) \ -{\ -clif->message(fd, (error));\ -sprintf(atcmd_output, ">%s", (p));\ -clif->message(fd, atcmd_output);\ -} - //define PARSE_ERROR - -#define CHECK_EOS(p) \ -if(*(p) == 0){\ -clif->message(fd, "Unexpected end of string");\ -return false;\ -} - //define CHECK_EOS - -#define SKIP_VALUE(p) \ -{\ -while(*(p) && !ISSPACE(*(p))) ++(p); /* non-space */\ -while(*(p) && ISSPACE(*(p))) ++(p); /* space */\ -} - //define SKIP_VALUE - -#define GET_VALUE(p,num) \ -{\ -if(sscanf((p), "x%lx", &(num)) < 1 && sscanf((p), "%ld ", &(num)) < 1){\ -PARSE_ERROR("Invalid number in:",(p));\ -return false;\ -}\ -} - //define GET_VALUE - + +#define PARSE_ERROR(error,p) do {\ + clif->message(fd, (error));\ + sprintf(atcmd_output, ">%s", (p));\ + clif->message(fd, atcmd_output);\ +} while(0) //define PARSE_ERROR + +#define CHECK_EOS(p) do { \ + if(*(p) == 0){ \ + clif->message(fd, "Unexpected end of string");\ + return false;\ + } \ +} while(0) //define CHECK_EOS + +#define SKIP_VALUE(p) do { \ + while(*(p) && !ISSPACE(*(p))) ++(p); /* non-space */\ + while(*(p) && ISSPACE(*(p))) ++(p); /* space */\ +} while(0) //define SKIP_VALUE + +#define GET_VALUE(p,num) do { \ + if(sscanf((p), "x%lx", &(num)) < 1 && sscanf((p), "%ld ", &(num)) < 1){\ + PARSE_ERROR("Invalid number in:",(p));\ + return false;\ + }\ +} while(0) //define GET_VALUE + if (type > 0 && type < MAX_PACKET_DB) { if(len) @@ -216,8 +210,8 @@ return false;\ len=SHRT_MAX-4; // maximum length off=4; } - WFIFOHEAD(fd, len); - WFIFOW(fd,0)=TOW(type); + WFIFOHEAD(sd->fd, len); + WFIFOW(sd->fd,0)=TOW(type); // parse packet contents SKIP_VALUE(message); @@ -225,25 +219,25 @@ return false;\ if(ISDIGIT(*message) || *message == '-' || *message == '+') {// default (byte) GET_VALUE(message,num); - WFIFOB(fd,off)=TOB(num); + WFIFOB(sd->fd,off)=TOB(num); ++off; } else if(TOUPPER(*message) == 'B') {// byte ++message; GET_VALUE(message,num); - WFIFOB(fd,off)=TOB(num); + WFIFOB(sd->fd,off)=TOB(num); ++off; } else if(TOUPPER(*message) == 'W') {// word (2 bytes) ++message; GET_VALUE(message,num); - WFIFOW(fd,off)=TOW(num); + WFIFOW(sd->fd,off)=TOW(num); off+=2; } else if(TOUPPER(*message) == 'L') {// long word (4 bytes) ++message; GET_VALUE(message,num); - WFIFOL(fd,off)=TOL(num); + WFIFOL(sd->fd,off)=TOL(num); off+=4; } else if(TOUPPER(*message) == 'S') {// string - escapes are valid @@ -296,7 +290,7 @@ return false;\ num<<=8; num+=(ISDIGIT(*message)?*message-'0':TOLOWER(*message)-'a'+10); } - WFIFOB(fd,off)=TOB(num); + WFIFOB(sd->fd,off)=TOB(num); ++message; CHECK_EOS(message); continue; @@ -325,13 +319,13 @@ return false;\ CHECK_EOS(message); } } - WFIFOB(fd,off)=TOB(num); + WFIFOB(sd->fd,off)=TOB(num); continue; } } } else num=*message; - WFIFOB(fd,off)=TOB(num); + WFIFOB(sd->fd,off)=TOB(num); ++message; CHECK_EOS(message); }//for @@ -344,7 +338,7 @@ return false;\ // terminate the string if(off < end) {// fill the rest with 0's - memset(WFIFOP(fd,off),0,end-off); + memset(WFIFOP(sd->fd,off),0,end-off); off=end; } } else @@ -356,12 +350,12 @@ return false;\ } if(packet_db[type].len == -1) {// send dynamic packet - WFIFOW(fd,2)=TOW(off); - WFIFOSET(fd,off); + WFIFOW(sd->fd,2)=TOW(off); + WFIFOSET(sd->fd,off); } else {// send static packet if(off < len) - memset(WFIFOP(fd,off),0,len-off); - WFIFOSET(fd,len); + memset(WFIFOP(sd->fd,off),0,len-off); + WFIFOSET(sd->fd,len); } } else { clif->message(fd, msg_txt(259)); // Invalid packet @@ -381,12 +375,10 @@ return false;\ *------------------------------------------*/ ACMD(mapmove) { char map_name[MAP_NAME_LENGTH_EXT]; - unsigned short mapindex; + unsigned short map_index; short x = 0, y = 0; int16 m = -1; - - nullpo_retr(-1, sd); - + memset(map_name, '\0', sizeof(map_name)); if (!message || !*message || @@ -397,30 +389,30 @@ ACMD(mapmove) { return false; } - mapindex = mapindex_name2id(map_name); - if (mapindex) - m = map->mapindex2mapid(mapindex); + map_index = mapindex->name2id(map_name); + if (map_index) + m = map->mapindex2mapid(map_index); - if (!mapindex || m < 0) { // m < 0 means on different server or that map is disabled! [Kevin] + if (!map_index || m < 0) { // m < 0 means on different server or that map is disabled! [Kevin] clif->message(fd, msg_txt(1)); // Map not found. return false; } - if ((x || y) && map->getcell(m, x, y, CELL_CHKNOPASS) && pc->get_group_level(sd) < battle_config.gm_ignore_warpable_area) { + if ((x || y) && map->getcell(m, x, y, CELL_CHKNOPASS) && pc_get_group_level(sd) < battle_config.gm_ignore_warpable_area) { //This is to prevent the pc->setpos call from printing an error. clif->message(fd, msg_txt(2)); if (!map->search_freecell(NULL, m, &x, &y, 10, 10, 1)) x = y = 0; //Invalid cell, use random spot. } - if (map->list[m].flag.nowarpto && !pc->has_permission(sd, PC_PERM_WARP_ANYWHERE)) { + if (map->list[m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif->message(fd, msg_txt(247)); return false; } - if (sd->bl.m >= 0 && map->list[sd->bl.m].flag.nowarp && !pc->has_permission(sd, PC_PERM_WARP_ANYWHERE)) { + if (sd->bl.m >= 0 && map->list[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif->message(fd, msg_txt(248)); return false; } - if (pc->setpos(sd, mapindex, x, y, CLR_TELEPORT) != 0) { + if (pc->setpos(sd, map_index, x, y, CLR_TELEPORT) != 0) { clif->message(fd, msg_txt(1)); // Map not found. return false; } @@ -435,7 +427,6 @@ ACMD(mapmove) { ACMD(where) { struct map_session_data* pl_sd; - nullpo_retr(-1, sd); memset(atcmd_player_name, '\0', sizeof atcmd_player_name); if (!message || !*message || sscanf(message, "%23[^\n]", atcmd_player_name) < 1) { @@ -446,7 +437,7 @@ ACMD(where) { pl_sd = map->nick2sd(atcmd_player_name); if (pl_sd == NULL || strncmp(pl_sd->status.name, atcmd_player_name, NAME_LENGTH) != 0 || - (pc->has_permission(pl_sd, PC_PERM_HIDE_SESSION) && pc->get_group_level(pl_sd) > pc->get_group_level(sd) && !pc->has_permission(sd, PC_PERM_WHO_DISPLAY_AID)) + (pc_has_permission(pl_sd, PC_PERM_HIDE_SESSION) && pc_get_group_level(pl_sd) > pc_get_group_level(sd) && !pc_has_permission(sd, PC_PERM_WHO_DISPLAY_AID)) ) { clif->message(fd, msg_txt(3)); // Character not found. return false; @@ -463,9 +454,7 @@ ACMD(where) { *------------------------------------------*/ ACMD(jumpto) { struct map_session_data *pl_sd = NULL; - - nullpo_retr(-1, sd); - + if (!message || !*message) { clif->message(fd, msg_txt(911)); // Please enter a player name (usage: @jumpto/@warpto/@goto <char name/ID>). return false; @@ -476,12 +465,12 @@ ACMD(jumpto) { return false; } - if (pl_sd->bl.m >= 0 && map->list[pl_sd->bl.m].flag.nowarpto && !pc->has_permission(sd, PC_PERM_WARP_ANYWHERE)) { + if (pl_sd->bl.m >= 0 && map->list[pl_sd->bl.m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif->message(fd, msg_txt(247)); // You are not authorized to warp to this map. return false; } - if (sd->bl.m >= 0 && map->list[sd->bl.m].flag.nowarp && !pc->has_permission(sd, PC_PERM_WARP_ANYWHERE)) { + if (sd->bl.m >= 0 && map->list[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif->message(fd, msg_txt(248)); // You are not authorized to warp from your current map. return false; } @@ -504,14 +493,12 @@ ACMD(jumpto) { ACMD(jump) { short x = 0, y = 0; - - nullpo_retr(-1, sd); - + memset(atcmd_output, '\0', sizeof(atcmd_output)); sscanf(message, "%hd %hd", &x, &y); - if (map->list[sd->bl.m].flag.noteleport && !pc->has_permission(sd, PC_PERM_WARP_ANYWHERE)) { + if (map->list[sd->bl.m].flag.noteleport && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif->message(fd, msg_txt(248)); // You are not authorized to warp from your current map. return false; } @@ -554,27 +541,25 @@ ACMD(who) { */ int display_type = 1; int map_id = -1; - - nullpo_retr(-1, sd); - - if (strstr(command, "map") != NULL) { + + if (stristr(info->command, "map") != NULL) { if (sscanf(message, "%15s %23s", map_name, player_name) < 1 || (map_id = map->mapname2mapid(map_name)) < 0) map_id = sd->bl.m; } else { sscanf(message, "%23s", player_name); } - if (strstr(command, "2") != NULL) + if (stristr(info->command, "2") != NULL) display_type = 2; - else if (strstr(command, "3") != NULL) + else if (stristr(info->command, "3") != NULL) display_type = 3; - level = pc->get_group_level(sd); + level = pc_get_group_level(sd); StrBuf->Init(&buf); iter = mapit_getallusers(); for (pl_sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); pl_sd = (TBL_PC*)mapit->next(iter)) { - if (!((pc->has_permission(pl_sd, PC_PERM_HIDE_SESSION) || (pl_sd->sc.option & OPTION_INVISIBLE)) && pc->get_group_level(pl_sd) > level)) { // you can look only lower or same level + if (!((pc_has_permission(pl_sd, PC_PERM_HIDE_SESSION) || (pl_sd->sc.option & OPTION_INVISIBLE)) && pc_get_group_level(pl_sd) > level)) { // you can look only lower or same level if (stristr(pl_sd->status.name, player_name) == NULL // search with no case sensitive || (map_id >= 0 && pl_sd->bl.m != map_id)) continue; @@ -582,17 +567,17 @@ ACMD(who) { case 2: { StrBuf->Printf(&buf, msg_txt(343), pl_sd->status.name); // "Name: %s " if (pc_get_group_id(pl_sd) > 0) // Player title, if exists - StrBuf->Printf(&buf, msg_txt(344), pc_group_get_name(pl_sd->group)); // "(%s) " + StrBuf->Printf(&buf, msg_txt(344), pcg->get_name(pl_sd->group)); // "(%s) " StrBuf->Printf(&buf, msg_txt(347), pl_sd->status.base_level, pl_sd->status.job_level, pc->job_name(pl_sd->status.class_)); // "| Lv:%d/%d | Job: %s" break; } case 3: { - if (pc->has_permission(sd, PC_PERM_WHO_DISPLAY_AID)) + if (pc_has_permission(sd, PC_PERM_WHO_DISPLAY_AID)) StrBuf->Printf(&buf, msg_txt(912), pl_sd->status.char_id, pl_sd->status.account_id); // "(CID:%d/AID:%d) " StrBuf->Printf(&buf, msg_txt(343), pl_sd->status.name); // "Name: %s " if (pc_get_group_id(pl_sd) > 0) // Player title, if exists - StrBuf->Printf(&buf, msg_txt(344), pc_group_get_name(pl_sd->group)); // "(%s) " + StrBuf->Printf(&buf, msg_txt(344), pcg->get_name(pl_sd->group)); // "(%s) " StrBuf->Printf(&buf, msg_txt(348), mapindex_id2name(pl_sd->mapindex), pl_sd->bl.x, pl_sd->bl.y); // "| Location: %s %d %d" break; } @@ -602,7 +587,7 @@ ACMD(who) { StrBuf->Printf(&buf, msg_txt(343), pl_sd->status.name); // "Name: %s " if (pc_get_group_id(pl_sd) > 0) // Player title, if exists - StrBuf->Printf(&buf, msg_txt(344), pc_group_get_name(pl_sd->group)); // "(%s) " + StrBuf->Printf(&buf, msg_txt(344), pcg->get_name(pl_sd->group)); // "(%s) " if (p != NULL) StrBuf->Printf(&buf, msg_txt(345), p->party.name); // " | Party: '%s'" if (g != NULL) @@ -650,9 +635,7 @@ ACMD(whogm) char player_name[NAME_LENGTH]; struct guild *g; struct party_data *p; - - nullpo_retr(-1, sd); - + memset(atcmd_output, '\0', sizeof(atcmd_output)); memset(match_text, '\0', sizeof(match_text)); memset(player_name, '\0', sizeof(player_name)); @@ -663,12 +646,12 @@ ACMD(whogm) match_text[j] = TOLOWER(match_text[j]); count = 0; - level = pc->get_group_level(sd); + level = pc_get_group_level(sd); iter = mapit_getallusers(); for( pl_sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); pl_sd = (TBL_PC*)mapit->next(iter) ) { - pl_level = pc->get_group_level(pl_sd); + pl_level = pc_get_group_level(pl_sd); if (!pl_level) continue; @@ -726,9 +709,7 @@ ACMD(whogm) /*========================================== * *------------------------------------------*/ -ACMD(save) -{ - nullpo_retr(-1, sd); +ACMD(save) { pc->setsavepoint(sd, sd->mapindex, sd->bl.x, sd->bl.y); if (sd->status.pet_id > 0 && sd->pd) @@ -746,15 +727,13 @@ ACMD(save) *------------------------------------------*/ ACMD(load) { int16 m; - - nullpo_retr(-1, sd); - + m = map->mapindex2mapid(sd->status.save_point.map); - if (m >= 0 && map->list[m].flag.nowarpto && !pc->has_permission(sd, PC_PERM_WARP_ANYWHERE)) { + if (m >= 0 && map->list[m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif->message(fd, msg_txt(249)); // You are not authorized to warp to your save map. return false; } - if (sd->bl.m >= 0 && map->list[sd->bl.m].flag.nowarp && !pc->has_permission(sd, PC_PERM_WARP_ANYWHERE)) { + if (sd->bl.m >= 0 && map->list[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif->message(fd, msg_txt(248)); // You are not authorized to warp from your current map. return false; } @@ -771,9 +750,7 @@ ACMD(load) { ACMD(speed) { int speed; - - nullpo_retr(-1, sd); - + memset(atcmd_output, '\0', sizeof(atcmd_output)); if (!message || !*message || sscanf(message, "%d", &speed) < 1) { @@ -782,15 +759,21 @@ ACMD(speed) return false; } - if (speed < 0) { + sd->state.permanent_speed = 0; + + if (speed < 0) sd->base_status.speed = DEFAULT_WALK_SPEED; - sd->state.permanent_speed = 0; // Remove lock when set back to default speed. - } else { + else sd->base_status.speed = cap_value(speed, MIN_WALK_SPEED, MAX_WALK_SPEED); + + if( sd->base_status.speed != DEFAULT_WALK_SPEED ) { sd->state.permanent_speed = 1; // Set lock when set to non-default speed. - } + clif->message(fd, msg_txt(8)); // Speed changed. + } else + clif->message(fd, msg_txt(172)); //Speed returned to normal. + status_calc_bl(&sd->bl, SCB_SPEED); - clif->message(fd, msg_txt(8)); // Speed changed. + return true; } @@ -799,8 +782,6 @@ ACMD(speed) *------------------------------------------*/ ACMD(storage) { - nullpo_retr(-1, sd); - if (sd->npc_id || sd->state.vending || sd->state.buyingstore || sd->state.trading || sd->state.storage_flag) return false; @@ -820,8 +801,6 @@ ACMD(storage) *------------------------------------------*/ ACMD(guildstorage) { - nullpo_retr(-1, sd); - if (!sd->status.guild_id) { clif->message(fd, msg_txt(252)); return false; @@ -851,7 +830,6 @@ ACMD(guildstorage) ACMD(option) { int param1 = 0, param2 = 0, param3 = 0; - nullpo_retr(-1, sd); if (!message || !*message || sscanf(message, "%d %d %d", ¶m1, ¶m2, ¶m3) < 1 || param1 < 0 || param2 < 0 || param3 < 0) {// failed to match the parameters so inform the user of the options @@ -883,7 +861,6 @@ ACMD(option) * *------------------------------------------*/ ACMD(hide) { - nullpo_retr(-1, sd); if (sd->sc.option & OPTION_INVISIBLE) { sd->sc.option &= ~OPTION_INVISIBLE; if (sd->disguise != -1 ) @@ -923,51 +900,52 @@ ACMD(hide) { /*========================================== * Changes a character's class *------------------------------------------*/ -ACMD(jobchange) -{ +ACMD(jobchange) { int job = 0, upper = 0; const char* text; - nullpo_retr(-1, sd); - if (!message || !*message || sscanf(message, "%d %d", &job, &upper) < 1) { - int i; - bool found = false; - + if (!message || !*message || sscanf(message, "%d %d", &job, &upper) < 1) { upper = 0; - - // Normal Jobs - for( i = JOB_NOVICE; i < JOB_MAX_BASIC && !found; i++ ){ - if (strncmpi(message, pc->job_name(i), 16) == 0) { - job = i; - found = true; + + if( message ) { + int i; + bool found = false; + + // Normal Jobs + for( i = JOB_NOVICE; i < JOB_MAX_BASIC && !found; i++ ) { + if (strncmpi(message, pc->job_name(i), 16) == 0) { + job = i; + found = true; + } } - } - - // High Jobs, Babys and Third - for( i = JOB_NOVICE_HIGH; i < JOB_MAX && !found; i++ ){ - if (strncmpi(message, pc->job_name(i), 16) == 0) { - job = i; - found = true; + + // High Jobs, Babys and Third + for( i = JOB_NOVICE_HIGH; i < JOB_MAX && !found; i++ ){ + if (strncmpi(message, pc->job_name(i), 16) == 0) { + job = i; + found = true; + } + } + + if (!found) { + text = atcommand_help_string(info); + if (text) + clif->messageln(fd, text); + return false; } - } - - if (!found) { - text = atcommand_help_string(info); - if (text) - clif->messageln(fd, text); - return false; } } - + /* WHY DO WE LIST THEM THEN? */ + // Deny direct transformation into dummy jobs if (job == JOB_KNIGHT2 || job == JOB_CRUSADER2 || job == JOB_WEDDING || job == JOB_XMAS || job == JOB_SUMMER || job == JOB_LORD_KNIGHT2 || job == JOB_PALADIN2 || job == JOB_BABY_KNIGHT2 || job == JOB_BABY_CRUSADER2 || job == JOB_STAR_GLADIATOR2 || (job >= JOB_RUNE_KNIGHT2 && job <= JOB_MECHANIC_T2) || (job >= JOB_BABY_RUNE2 && job <= JOB_BABY_MECHANIC2) - ) // Deny direct transformation into dummy jobs - {clif->message(fd, msg_txt(923)); //"You can not change to this job by command." - return true;} + ) { + clif->message(fd, msg_txt(923)); //"You can not change to this job by command." + return true; + } - if (pcdb_checkid(job)) - { + if (pcdb_checkid(job)) { if (pc->jobchange(sd, job, upper) == 0) clif->message(fd, msg_txt(12)); // Your job has been changed. else { @@ -989,7 +967,6 @@ ACMD(jobchange) *------------------------------------------*/ ACMD(kill) { - nullpo_retr(-1, sd); status_kill(&sd->bl); clif->message(sd->fd, msg_txt(13)); // A pity! You've died. if (fd != sd->fd) @@ -1002,7 +979,6 @@ ACMD(kill) *------------------------------------------*/ ACMD(alive) { - nullpo_retr(-1, sd); if (!status->revive(&sd->bl, 100, 100)) { clif->message(fd, msg_txt(667)); return false; @@ -1017,24 +993,23 @@ ACMD(alive) *------------------------------------------*/ ACMD(kami) { - unsigned long color=0; - nullpo_retr(-1, sd); + unsigned int color=0; memset(atcmd_output, '\0', sizeof(atcmd_output)); - if(*(command + 5) != 'c' && *(command + 5) != 'C') { + if(*(info->command + 4) != 'c' && *(info->command + 4) != 'C') { if (!message || !*message) { clif->message(fd, msg_txt(980)); // Please enter a message (usage: @kami <message>). return false; } sscanf(message, "%199[^\n]", atcmd_output); - if (strstr(command, "l") != NULL) + if (stristr(info->command, "l") != NULL) clif->broadcast(&sd->bl, atcmd_output, strlen(atcmd_output) + 1, BC_DEFAULT, ALL_SAMEMAP); else - intif->broadcast(atcmd_output, strlen(atcmd_output) + 1, (*(command + 5) == 'b' || *(command + 5) == 'B') ? BC_BLUE : BC_YELLOW); + intif->broadcast(atcmd_output, strlen(atcmd_output) + 1, (*(info->command + 4) == 'b' || *(info->command + 4) == 'B') ? BC_BLUE : BC_YELLOW); } else { - if(!message || !*message || (sscanf(message, "%lx %199[^\n]", &color, atcmd_output) < 2)) { + if(!message || !*message || (sscanf(message, "%u %199[^\n]", &color, atcmd_output) < 2)) { clif->message(fd, msg_txt(981)); // Please enter color and message (usage: @kamic <color> <message>). return false; } @@ -1054,7 +1029,6 @@ ACMD(kami) ACMD(heal) { int hp = 0, sp = 0; // [Valaris] thanks to fov - nullpo_retr(-1, sd); sscanf(message, "%d %d", &hp, &sp); @@ -1080,7 +1054,7 @@ ACMD(heal) if ( hp < 0 && sp <= 0 ) { status->damage(NULL, &sd->bl, -hp, -sp, 0, 0); - clif->damage(&sd->bl,&sd->bl, timer->gettick(), 0, 0, -hp, 0, 4, 0); + clif->damage(&sd->bl,&sd->bl, 0, 0, -hp, 0, 4, 0); clif->message(fd, msg_txt(156)); // HP or/and SP modified. return true; } @@ -1091,7 +1065,7 @@ ACMD(heal) status->heal(&sd->bl, hp, 0, 0); else { status->damage(NULL, &sd->bl, -hp, 0, 0, 0); - clif->damage(&sd->bl,&sd->bl, timer->gettick(), 0, 0, -hp, 0, 4, 0); + clif->damage(&sd->bl,&sd->bl, 0, 0, -hp, 0, 4, 0); } } @@ -1108,23 +1082,29 @@ ACMD(heal) /*========================================== * @item command (usage: @item <name/id_of_item> <quantity>) (modified by [Yor] for pet_egg) + * @itembound command (usage: @itembound <name/id_of_item> <quantity> <bound type>) (revised by [Mhalicot]) *------------------------------------------*/ ACMD(item) { char item_name[100]; - int number = 0, item_id, flag = 0; + int number = 0, item_id, flag = 0, bound = 0; struct item item_tmp; struct item_data *item_data; int get_count, i; - nullpo_retr(-1, sd); memset(item_name, '\0', sizeof(item_name)); - - if (!message || !*message || ( - sscanf(message, "\"%99[^\"]\" %d", item_name, &number) < 1 && - sscanf(message, "%99s %d", item_name, &number) < 1 - )) { - clif->message(fd, msg_txt(983)); // Please enter an item name or ID (usage: @item <item name/ID> <quantity>). + + if (!strcmpi(info->command,"itembound") && (!message || !*message || ( + sscanf(message, "\"%99[^\"]\" %d %d", item_name, &number, &bound) < 2 && + sscanf(message, "%99s %d %d", item_name, &number, &bound) < 2 + ))) { + clif->message(fd, msg_txt(295)); // Please enter an item name or ID (usage: @itembound <item name/ID> <quantity> <bound_type>). + return false; + } else if (!message || !*message || ( + sscanf(message, "\"%99[^\"]\" %d", item_name, &number) < 1 && + sscanf(message, "%99s %d", item_name, &number) < 1 )) + { + clif->message(fd, msg_txt(983)); // Please enter an item name or ID (usage: @item <item name/ID> <quantity>). return false; } @@ -1138,11 +1118,40 @@ ACMD(item) return false; } + if(!strcmpi(info->command,"itembound") ) { + if( !(bound >= IBT_MIN && bound <= IBT_MAX) ) { + clif->message(fd, msg_txt(298)); // Invalid bound type + return false; + } + switch( (enum e_item_bound_type)bound ) { + case IBT_CHARACTER: + case IBT_ACCOUNT: + break; /* no restrictions */ + case IBT_PARTY: + if( !sd->status.party_id ) { + clif->message(fd, msg_txt(1498)); //You can't add a party bound item to a character without party! + return false; + } + break; + case IBT_GUILD: + if( !sd->status.guild_id ) { + clif->message(fd, msg_txt(1499)); //You can't add a guild bound item to a character without guild! + return false; + } + break; + } + } + item_id = item_data->nameid; get_count = number; //Check if it's stackable. - if (!itemdb->isstackable2(item_data)) - get_count = 1; + if (!itemdb->isstackable2(item_data)) { + if( bound && (item_data->type == IT_PETEGG || item_data->type == IT_PETARMOR) ) { + clif->message(fd, msg_txt(498)); // Cannot create bounded pet eggs or pet armors. + return false; + } + get_count = 1; + } for (i = 0; i < number; i += get_count) { // if not pet egg @@ -1150,6 +1159,7 @@ ACMD(item) memset(&item_tmp, 0, sizeof(item_tmp)); item_tmp.nameid = item_id; item_tmp.identify = 1; + item_tmp.bound = (unsigned char)bound; if ((flag = pc->additem(sd, &item_tmp, get_count, LOG_TYPE_COMMAND))) clif->additem(sd, 0, 0, flag); @@ -1162,22 +1172,27 @@ ACMD(item) } /*========================================== - * + * @item2 and @itembound2 command (revised by [Mhalicot]) *------------------------------------------*/ ACMD(item2) { struct item item_tmp; struct item_data *item_data; char item_name[100]; - int item_id, number = 0; + int item_id, number = 0, bound = 0; int identify = 0, refine = 0, attr = 0; int c1 = 0, c2 = 0, c3 = 0, c4 = 0; - nullpo_retr(-1, sd); memset(item_name, '\0', sizeof(item_name)); - if (!message || !*message || ( - sscanf(message, "\"%99[^\"]\" %d %d %d %d %d %d %d %d", item_name, &number, &identify, &refine, &attr, &c1, &c2, &c3, &c4) < 9 && + if (!strcmpi(info->command,"itembound2") && (!message || !*message || ( + sscanf(message, "\"%99[^\"]\" %d %d %d %d %d %d %d %d %d", item_name, &number, &identify, &refine, &attr, &c1, &c2, &c3, &c4, &bound) < 10 && + sscanf(message, "%99s %d %d %d %d %d %d %d %d %d", item_name, &number, &identify, &refine, &attr, &c1, &c2, &c3, &c4, &bound) < 10 ))) { + clif->message(fd, msg_txt(296)); // Please enter all parameters (usage: @itembound2 <item name/ID> <quantity> + clif->message(fd, msg_txt(297)); // <identify_flag> <refine> <attribute> <card1> <card2> <card3> <card4> <bound_type>). + return false; + } else if ( !message || !*message || ( + sscanf(message, "\"%99[^\"]\" %d %d %d %d %d %d %d %d", item_name, &number, &identify, &refine, &attr, &c1, &c2, &c3, &c4) < 9 && sscanf(message, "%99s %d %d %d %d %d %d %d %d", item_name, &number, &identify, &refine, &attr, &c1, &c2, &c3, &c4) < 9 )) { clif->message(fd, msg_txt(984)); // Please enter all parameters (usage: @item2 <item name/ID> <quantity> @@ -1187,7 +1202,12 @@ ACMD(item2) if (number <= 0) number = 1; - + + if( !strcmpi(info->command,"itembound2") && !(bound >= IBT_MIN && bound <= IBT_MAX) ) { + clif->message(fd, msg_txt(298)); // Invalid bound type + return false; + } + item_id = 0; if ((item_data = itemdb->search_name(item_name)) != NULL || (item_data = itemdb->exists(atoi(item_name))) != NULL) @@ -1198,9 +1218,14 @@ ACMD(item2) int loop, get_count, i; loop = 1; get_count = number; - if (item_data->type == IT_WEAPON || item_data->type == IT_ARMOR || - item_data->type == IT_PETEGG || item_data->type == IT_PETARMOR) { - loop = number; + if( !strcmpi(info->command,"itembound2") ) + bound = 1; + if( !itemdb->isstackable2(item_data) ) { + if( bound && (item_data->type == IT_PETEGG || item_data->type == IT_PETARMOR) ) { + clif->message(fd, msg_txt(498)); // Cannot create bounded pet eggs or pet armors. + return false; + } + loop = number; get_count = 1; if (item_data->type == IT_PETEGG) { identify = 1; @@ -1220,10 +1245,12 @@ ACMD(item2) item_tmp.identify = identify; item_tmp.refine = refine; item_tmp.attribute = attr; + item_tmp.bound = (unsigned char)bound; item_tmp.card[0] = c1; item_tmp.card[1] = c2; item_tmp.card[2] = c3; item_tmp.card[3] = c4; + if ((flag = pc->additem(sd, &item_tmp, get_count, LOG_TYPE_COMMAND))) clif->additem(sd, 0, 0, flag); } @@ -1244,7 +1271,6 @@ ACMD(item2) ACMD(itemreset) { int i; - nullpo_retr(-1, sd); for (i = 0; i < MAX_INVENTORY; i++) { if (sd->status.inventory[i].amount && sd->status.inventory[i].equip == 0) { @@ -1262,7 +1288,7 @@ ACMD(itemreset) ACMD(baselevelup) { int level=0, i=0, status_point=0; - nullpo_retr(-1, sd); + level = atoi(message); if (!message || !*message || !level) { @@ -1282,6 +1308,7 @@ ACMD(baselevelup) sd->status.status_point += status_point; sd->status.base_level += (unsigned int)level; + status_calc_pc(sd, SCO_FORCE); status_percent_heal(&sd->bl, 100, 100); clif->misceffect(&sd->bl, 0); clif->message(fd, msg_txt(21)); // Base level raised. @@ -1303,13 +1330,13 @@ ACMD(baselevelup) sd->status.status_point -= status_point; sd->status.base_level -= (unsigned int)level; clif->message(fd, msg_txt(22)); // Base level lowered. + status_calc_pc(sd, SCO_FORCE); } sd->status.base_exp = 0; clif->updatestatus(sd, SP_STATUSPOINT); clif->updatestatus(sd, SP_BASELEVEL); clif->updatestatus(sd, SP_BASEEXP); clif->updatestatus(sd, SP_NEXTBASEEXP); - status_calc_pc(sd, 0); pc->baselevelchanged(sd); if(sd->status.party_id) party->send_levelup(sd); @@ -1322,7 +1349,6 @@ ACMD(baselevelup) ACMD(joblevelup) { int level=0; - nullpo_retr(-1, sd); level = atoi(message); @@ -1363,7 +1389,7 @@ ACMD(joblevelup) clif->updatestatus(sd, SP_JOBEXP); clif->updatestatus(sd, SP_NEXTJOBEXP); clif->updatestatus(sd, SP_SKILLPOINT); - status_calc_pc(sd, 0); + status_calc_pc(sd, SCO_FORCE); return true; } @@ -1375,9 +1401,7 @@ ACMD(help) { const char *command_name = NULL; char *default_command = "help"; AtCommandInfo *tinfo = NULL; - - nullpo_retr(-1, sd); - + if (!message || !*message) { command_name = default_command; // If no command_name specified, display help for @help. } else { @@ -1461,7 +1485,6 @@ int atcommand_pvpoff_sub(struct block_list *bl,va_list ap) } ACMD(pvpoff) { - nullpo_retr(-1, sd); if (!map->list[sd->bl.m].flag.pvp) { clif->message(fd, msg_txt(160)); // PvP is already Off. @@ -1499,7 +1522,6 @@ int atcommand_pvpon_sub(struct block_list *bl,va_list ap) } ACMD(pvpon) { - nullpo_retr(-1, sd); if (map->list[sd->bl.m].flag.pvp) { clif->message(fd, msg_txt(161)); // PvP is already On. @@ -1524,7 +1546,6 @@ ACMD(pvpon) { * *------------------------------------------*/ ACMD(gvgoff) { - nullpo_retr(-1, sd); if (!map->list[sd->bl.m].flag.gvg) { clif->message(fd, msg_txt(162)); // GvG is already Off. @@ -1545,7 +1566,6 @@ ACMD(gvgoff) { * *------------------------------------------*/ ACMD(gvgon) { - nullpo_retr(-1, sd); if (map->list[sd->bl.m].flag.gvg) { clif->message(fd, msg_txt(163)); // GvG is already On. @@ -1567,7 +1587,6 @@ ACMD(gvgon) { ACMD(model) { int hair_style = 0, hair_color = 0, cloth_color = 0; - nullpo_retr(-1, sd); memset(atcmd_output, '\0', sizeof(atcmd_output)); @@ -1599,7 +1618,6 @@ ACMD(model) ACMD(dye) { int cloth_color = 0; - nullpo_retr(-1, sd); memset(atcmd_output, '\0', sizeof(atcmd_output)); @@ -1626,7 +1644,6 @@ ACMD(dye) ACMD(hair_style) { int hair_style = 0; - nullpo_retr(-1, sd); memset(atcmd_output, '\0', sizeof(atcmd_output)); @@ -1653,7 +1670,6 @@ ACMD(hair_style) ACMD(hair_color) { int hair_color = 0; - nullpo_retr(-1, sd); memset(atcmd_output, '\0', sizeof(atcmd_output)); @@ -1729,9 +1745,7 @@ ACMD(go) { MAP_MALAYA, 242, 211 }, // 34=Malaya Port { MAP_ECLAGE, 110, 39 }, // 35=Eclage }; - - nullpo_retr(-1, sd); - + memset(map_name, '\0', sizeof(map_name)); memset(atcmd_output, '\0', sizeof(atcmd_output)); @@ -1845,15 +1859,15 @@ ACMD(go) if (town >= 0 && town < ARRAYLENGTH(data)) { m = map->mapname2mapid(data[town].map); - if (m >= 0 && map->list[m].flag.nowarpto && !pc->has_permission(sd, PC_PERM_WARP_ANYWHERE)) { + if (m >= 0 && map->list[m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif->message(fd, msg_txt(247)); return false; } - if (sd->bl.m >= 0 && map->list[sd->bl.m].flag.nowarp && !pc->has_permission(sd, PC_PERM_WARP_ANYWHERE)) { + if (sd->bl.m >= 0 && map->list[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif->message(fd, msg_txt(248)); return false; } - if (pc->setpos(sd, mapindex_name2id(data[town].map), data[town].x, data[town].y, CLR_TELEPORT) == 0) { + if (pc->setpos(sd, mapindex->name2id(data[town].map), data[town].x, data[town].y, CLR_TELEPORT) == 0) { clif->message(fd, msg_txt(0)); // Warped. } else { clif->message(fd, msg_txt(1)); // Map not found. @@ -1881,7 +1895,6 @@ ACMD(monster) int i, k, range; short mx, my; unsigned int size; - nullpo_retr(-1, sd); memset(name, '\0', sizeof(name)); memset(monster, '\0', sizeof(monster)); @@ -1915,12 +1928,7 @@ ACMD(monster) clif->message(fd, msg_txt(40)); // Invalid monster ID or name. return false; } - - if (mob_id == MOBID_EMPERIUM) { - clif->message(fd, msg_txt(83)); // Monster 'Emperium' cannot be spawned. - return false; - } - + if (number <= 0) number = 1; @@ -1931,12 +1939,12 @@ ACMD(monster) if (battle_config.atc_spawn_quantity_limit && number > battle_config.atc_spawn_quantity_limit) number = battle_config.atc_spawn_quantity_limit; - if (strcmp(command+1, "monstersmall") == 0) - size = SZ_MEDIUM; // This is just gorgeous [mkbu95] - else if (strcmp(command+1, "monsterbig") == 0) + if (strcmpi(info->command, "monstersmall") == 0) + size = SZ_SMALL; + else if (strcmpi(info->command, "monsterbig") == 0) size = SZ_BIG; else - size = SZ_SMALL; + size = SZ_MEDIUM; if (battle_config.etc_log) ShowInfo("%s monster='%s' name='%s' id=%d count=%d (%d,%d)\n", command, monster, name, mob_id, number, sd->bl.x, sd->bl.y); @@ -1945,7 +1953,7 @@ ACMD(monster) range = (int)sqrt((float)number) +2; // calculation of an odd number (+ 4 area around) for (i = 0; i < number; i++) { map->search_freecell(&sd->bl, 0, &mx, &my, range, range, 0); - k = mob->once_spawn(sd, sd->bl.m, mx, my, name, mob_id, 1, eventname, size, AI_NONE); + k = mob->once_spawn(sd, sd->bl.m, mx, my, name, mob_id, 1, eventname, size, AI_NONE|(mob_id == MOBID_EMPERIUM?0x200:0x0)); count += (k != 0) ? 1 : 0; } @@ -1988,7 +1996,6 @@ int atkillmonster_sub(struct block_list *bl, va_list ap) ACMD(killmonster) { int map_id, drop_flag; char map_name[MAP_NAME_LENGTH_EXT]; - nullpo_retr(-1, sd); memset(map_name, '\0', sizeof(map_name)); @@ -1999,7 +2006,7 @@ ACMD(killmonster) { map_id = sd->bl.m; } - drop_flag = strcmp(command+1, "killmonster2"); + drop_flag = strcmpi(info->command, "killmonster2"); map->foreachinmap(atcommand->atkillmonster_sub, map_id, BL_MOB, -drop_flag); @@ -2015,7 +2022,6 @@ ACMD(refine) { int i,j, position = 0, refine = 0, current_position, final_refine; int count; - nullpo_retr(-1, sd); memset(atcmd_output, '\0', sizeof(atcmd_output)); @@ -2047,9 +2053,10 @@ ACMD(refine) refine = cap_value(refine, -MAX_REFINE, MAX_REFINE); count = 0; - for (j = 0; j < EQI_MAX-1; j++) { + for (j = 0; j < EQI_MAX; j++) { if ((i = sd->equip_index[j]) < 0) continue; + if(j == EQI_AMMO) continue; /* can't equip ammo */ if(j == EQI_HAND_R && sd->equip_index[EQI_HAND_L] == i) continue; if(j == EQI_HEAD_MID && sd->equip_index[EQI_HEAD_LOW] == i) @@ -2095,7 +2102,6 @@ ACMD(produce) int item_id, attribute = 0, star = 0; struct item_data *item_data; struct item tmp_item; - nullpo_retr(-1, sd); memset(atcmd_output, '\0', sizeof(atcmd_output)); memset(item_name, '\0', sizeof(item_name)); @@ -2151,7 +2157,6 @@ ACMD(produce) ACMD(memo) { int position = 0; - nullpo_retr(-1, sd); memset(atcmd_output, '\0', sizeof(atcmd_output)); @@ -2186,7 +2191,6 @@ ACMD(memo) *------------------------------------------*/ ACMD(gat) { int y; - nullpo_retr(-1, sd); memset(atcmd_output, '\0', sizeof(atcmd_output)); @@ -2211,7 +2215,6 @@ ACMD(gat) { ACMD(displaystatus) { int i, type, flag, tick, val1 = 0, val2 = 0, val3 = 0; - nullpo_retr(-1, sd); if (!message || !*message || (i = sscanf(message, "%d %d %d %d %d %d", &type, &flag, &tick, &val1, &val2, &val3)) < 1) { clif->message(fd, msg_txt(1009)); // Please enter a status type/flag (usage: @displaystatus <status type> <flag> <tick> {<val1> {<val2> {<val3>}}}). @@ -2283,7 +2286,6 @@ ACMD(skillpoint) { int point; unsigned int new_skill_point; - nullpo_retr(-1, sd); if (!message || !*message || (point = atoi(message)) == 0) { clif->message(fd, msg_txt(1011)); // Please enter a number (usage: @skpoint <number of points>). @@ -2331,7 +2333,6 @@ ACMD(skillpoint) ACMD(zeny) { int zeny=0, ret=-1; - nullpo_retr(-1, sd); if (!message || !*message || (zeny = atoi(message)) == 0) { clif->message(fd, msg_txt(1012)); // Please enter an amount (usage: @zeny <amount>). @@ -2359,7 +2360,6 @@ ACMD(param) { const char* param[] = { "str", "agi", "vit", "int", "dex", "luk" }; short* stats[6]; //we don't use direct initialization because it isn't part of the c standard. - nullpo_retr(-1, sd); memset(atcmd_output, '\0', sizeof(atcmd_output)); @@ -2368,7 +2368,7 @@ ACMD(param) { return false; } - ARR_FIND( 0, ARRAYLENGTH(param), i, strcmpi(command+1, param[i]) == 0 ); + ARR_FIND( 0, ARRAYLENGTH(param), i, strcmpi(info->command, param[i]) == 0 ); if( i == ARRAYLENGTH(param) || i > MAX_STATUS_TYPE) { // normally impossible... clif->message(fd, msg_txt(1013)); // Please enter a valid value (usage: @str/@agi/@vit/@int/@dex/@luk <+/-adjustment>). @@ -2399,7 +2399,7 @@ ACMD(param) { *stats[i] = new_value; clif->updatestatus(sd, SP_STR + i); clif->updatestatus(sd, SP_USTR + i); - status_calc_pc(sd, 0); + status_calc_pc(sd, SCO_FORCE); clif->message(fd, msg_txt(42)); // Stat changed. } else { if (value < 0) @@ -2419,7 +2419,6 @@ ACMD(stat_all) { int index, count, value, max, new_value; short* stats[6]; //we don't use direct initialization because it isn't part of the c standard. - nullpo_retr(-1, sd); stats[0] = &sd->status.str; stats[1] = &sd->status.agi; @@ -2457,7 +2456,7 @@ ACMD(stat_all) { } if (count > 0) { // if at least 1 stat modified - status_calc_pc(sd, 0); + status_calc_pc(sd, SCO_FORCE); clif->message(fd, msg_txt(84)); // All stats changed! } else { if (value < 0) @@ -2473,12 +2472,10 @@ ACMD(stat_all) { /*========================================== * *------------------------------------------*/ -ACMD(guildlevelup) -{ +ACMD(guildlevelup) { int level = 0; - short added_level; + int16 added_level; struct guild *guild_info; - nullpo_retr(-1, sd); if (!message || !*message || sscanf(message, "%d", &level) < 1 || level == 0) { clif->message(fd, msg_txt(1014)); // Please enter a valid level (usage: @guildlvup/@guildlvlup <# of levels>). @@ -2489,16 +2486,18 @@ ACMD(guildlevelup) clif->message(fd, msg_txt(43)); // You're not in a guild. return false; } - //if (strcmp(sd->status.name, guild_info->master) != 0) { - // clif->message(fd, msg_txt(44)); // You're not the master of your guild. - // return false; - //} +#if 0 // By enabling this, only the guild leader can use this command + if (strcmp(sd->status.name, guild_info->master) != 0) { + clif->message(fd, msg_txt(44)); // You're not the master of your guild. + return false; + } +#endif // 0 - added_level = (short)level; - if (level > 0 && (level > MAX_GUILDLEVEL || added_level > ((short)MAX_GUILDLEVEL - guild_info->guild_lv))) // fix positiv overflow - added_level = (short)MAX_GUILDLEVEL - guild_info->guild_lv; - else if (level < 0 && (level < -MAX_GUILDLEVEL || added_level < (1 - guild_info->guild_lv))) // fix negativ overflow - added_level = 1 - guild_info->guild_lv; + if (level > INT16_MAX || (level > 0 && level > MAX_GUILDLEVEL - guild_info->guild_lv)) // fix positive overflow + level = MAX_GUILDLEVEL - guild_info->guild_lv; + else if (level < INT16_MIN || (level < 0 && level < 1 - guild_info->guild_lv)) // fix negative overflow + level = 1 - guild_info->guild_lv; + added_level = (int16)level; if (added_level != 0) { intif->guild_change_basicinfo(guild_info->guild_id, GBI_GUILDLV, &added_level, sizeof(added_level)); @@ -2518,7 +2517,6 @@ ACMD(makeegg) { struct item_data *item_data; int id, pet_id; - nullpo_retr(-1, sd); if (!message || !*message) { clif->message(fd, msg_txt(1015)); // Please enter a monster/egg name/ID (usage: @makeegg <pet>). @@ -2556,7 +2554,6 @@ ACMD(makeegg) *------------------------------------------*/ ACMD(hatch) { - nullpo_retr(-1, sd); if (sd->status.pet_id <= 0) clif->sendegg(sd); else { @@ -2574,7 +2571,6 @@ ACMD(petfriendly) { int friendly; struct pet_data *pd; - nullpo_retr(-1, sd); if (!message || !*message || (friendly = atoi(message)) < 0) { clif->message(fd, msg_txt(1016)); // Please enter a valid value (usage: @petfriendly <0-1000>). @@ -2611,7 +2607,6 @@ ACMD(pethungry) { int hungry; struct pet_data *pd; - nullpo_retr(-1, sd); if (!message || !*message || (hungry = atoi(message)) < 0) { clif->message(fd, msg_txt(1017)); // Please enter a valid number (usage: @pethungry <0-100>). @@ -2645,7 +2640,6 @@ ACMD(pethungry) ACMD(petrename) { struct pet_data *pd; - nullpo_retr(-1, sd); if (!sd->status.pet_id || !sd->pd) { clif->message(fd, msg_txt(184)); // Sorry, but you have no pet. return false; @@ -2670,7 +2664,6 @@ ACMD(petrename) ACMD(recall) { struct map_session_data *pl_sd = NULL; - nullpo_retr(-1, sd); if (!message || !*message) { clif->message(fd, msg_txt(1018)); // Please enter a player name (usage: @recall <char name/ID>). @@ -2682,17 +2675,17 @@ ACMD(recall) { return false; } - if ( pc->get_group_level(sd) < pc->get_group_level(pl_sd) ) + if ( pc_get_group_level(sd) < pc_get_group_level(pl_sd) ) { clif->message(fd, msg_txt(81)); // Your GM level doesn't authorize you to preform this action on the specified player. return false; } - if (sd->bl.m >= 0 && map->list[sd->bl.m].flag.nowarpto && !pc->has_permission(sd, PC_PERM_WARP_ANYWHERE)) { + if (sd->bl.m >= 0 && map->list[sd->bl.m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif->message(fd, msg_txt(1019)); // You are not authorized to warp someone to this map. return false; } - if (pl_sd->bl.m >= 0 && map->list[pl_sd->bl.m].flag.nowarp && !pc->has_permission(sd, PC_PERM_WARP_ANYWHERE)) { + if (pl_sd->bl.m >= 0 && map->list[pl_sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif->message(fd, msg_txt(1020)); // You are not authorized to warp this player from their map. return false; } @@ -2712,12 +2705,11 @@ ACMD(recall) { *------------------------------------------*/ ACMD(char_block) { - nullpo_retr(-1, sd); memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); if (!message || !*message || sscanf(message, "%23[^\n]", atcmd_player_name) < 1) { - clif->message(fd, msg_txt(1021)); // Please enter a player name (usage: @charblock/@block <char name>). + clif->message(fd, msg_txt(1021)); // Please enter a player name (usage: @block <char name>). return false; } @@ -2748,13 +2740,12 @@ ACMD(char_ban) int year, month, day, hour, minute, second, value; time_t timestamp; struct tm *tmtime; - nullpo_retr(-1, sd); memset(atcmd_output, '\0', sizeof(atcmd_output)); memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); if (!message || !*message || sscanf(message, "%255s %23[^\n]", atcmd_output, atcmd_player_name) < 2) { - clif->message(fd, msg_txt(1022)); // Please enter ban time and a player name (usage: @charban/@ban/@banish/@charbanish <time> <char name>). + clif->message(fd, msg_txt(1022)); // Please enter ban time and a player name (usage: @ban <time> <char name>). return false; } @@ -2818,7 +2809,7 @@ ACMD(char_ban) return false; } - chrif->char_ask_name(sd->status.account_id, atcmd_player_name, 2, year, month, day, hour, minute, second); // type: 2 - ban + chrif->char_ask_name(sd->status.account_id, atcmd_player_name, !strcmpi(info->command,"charban") ? 6 : 2, year, month, day, hour, minute, second); // type: 2 - ban; 6 - charban clif->message(fd, msg_txt(88)); // Character name sent to char-server to ask it. return true; @@ -2829,12 +2820,11 @@ ACMD(char_ban) *------------------------------------------*/ ACMD(char_unblock) { - nullpo_retr(-1, sd); memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); if (!message || !*message || sscanf(message, "%23[^\n]", atcmd_player_name) < 1) { - clif->message(fd, msg_txt(1024)); // Please enter a player name (usage: @charunblock <char name>). + clif->message(fd, msg_txt(1024)); // Please enter a player name (usage: @unblock <char name>). return false; } @@ -2850,17 +2840,16 @@ ACMD(char_unblock) *------------------------------------------*/ ACMD(char_unban) { - nullpo_retr(-1, sd); memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); if (!message || !*message || sscanf(message, "%23[^\n]", atcmd_player_name) < 1) { - clif->message(fd, msg_txt(1025)); // Please enter a player name (usage: @charunban <char name>). + clif->message(fd, msg_txt(1025)); // Please enter a player name (usage: @unban <char name>). return false; } // send answer to login server via char-server - chrif->char_ask_name(sd->status.account_id, atcmd_player_name, 4, 0, 0, 0, 0, 0, 0); // type: 4 - unban + chrif->char_ask_name(sd->status.account_id, atcmd_player_name, !strcmpi(info->command,"charunban") ? 7 : 4, 0, 0, 0, 0, 0, 0); // type: 4 - unban account; type 7 - unban character clif->message(fd, msg_txt(88)); // Character name sent to char-server to ask it. return true; @@ -2870,7 +2859,6 @@ ACMD(char_unban) * *------------------------------------------*/ ACMD(night) { - nullpo_retr(-1, sd); if (map->night_flag != 1) { pc->map_night_timer(pc->night_timer_tid, 0, 0, 1); @@ -2886,7 +2874,6 @@ ACMD(night) { * *------------------------------------------*/ ACMD(day) { - nullpo_retr(-1, sd); if (map->night_flag != 0) { pc->map_day_timer(pc->day_timer_tid, 0, 0, 1); @@ -2905,13 +2892,11 @@ ACMD(doom) { struct map_session_data* pl_sd; struct s_mapiterator* iter; - - nullpo_retr(-1, sd); - + iter = mapit_getallusers(); for( pl_sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); pl_sd = (TBL_PC*)mapit->next(iter) ) { - if (pl_sd->fd != fd && pc->get_group_level(sd) >= pc->get_group_level(pl_sd)) + if (pl_sd->fd != fd && pc_get_group_level(sd) >= pc_get_group_level(pl_sd)) { status_kill(&pl_sd->bl); clif->specialeffect(&pl_sd->bl,450,AREA); @@ -2932,13 +2917,11 @@ ACMD(doommap) { struct map_session_data* pl_sd; struct s_mapiterator* iter; - - nullpo_retr(-1, sd); - + iter = mapit_getallusers(); for( pl_sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); pl_sd = (TBL_PC*)mapit->next(iter) ) { - if (pl_sd->fd != fd && sd->bl.m == pl_sd->bl.m && pc->get_group_level(sd) >= pc->get_group_level(pl_sd)) + if (pl_sd->fd != fd && sd->bl.m == pl_sd->bl.m && pc_get_group_level(sd) >= pc_get_group_level(pl_sd)) { status_kill(&pl_sd->bl); clif->specialeffect(&pl_sd->bl,450,AREA); @@ -2970,9 +2953,7 @@ ACMD(raise) { struct map_session_data* pl_sd; struct s_mapiterator* iter; - - nullpo_retr(-1, sd); - + iter = mapit_getallusers(); for( pl_sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); pl_sd = (TBL_PC*)mapit->next(iter) ) if( pc_isdead(pl_sd) ) @@ -2991,9 +2972,7 @@ ACMD(raisemap) { struct map_session_data* pl_sd; struct s_mapiterator* iter; - - nullpo_retr(-1, sd); - + iter = mapit_getallusers(); for( pl_sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); pl_sd = (TBL_PC*)mapit->next(iter) ) if (sd->bl.m == pl_sd->bl.m && pc_isdead(pl_sd) ) @@ -3011,7 +2990,6 @@ ACMD(raisemap) ACMD(kick) { struct map_session_data *pl_sd; - nullpo_retr(-1, sd); memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); @@ -3025,7 +3003,7 @@ ACMD(kick) return false; } - if ( pc->get_group_level(sd) < pc->get_group_level(pl_sd) ) + if ( pc_get_group_level(sd) < pc_get_group_level(pl_sd) ) { clif->message(fd, msg_txt(81)); // Your GM level don't authorise you to do this action on this player. return false; @@ -3043,12 +3021,11 @@ ACMD(kickall) { struct map_session_data* pl_sd; struct s_mapiterator* iter; - nullpo_retr(-1, sd); iter = mapit_getallusers(); for( pl_sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); pl_sd = (TBL_PC*)mapit->next(iter) ) { - if (pc->get_group_level(sd) >= pc->get_group_level(pl_sd)) { // you can kick only lower or same gm level + if (pc_get_group_level(sd) >= pc_get_group_level(pl_sd)) { // you can kick only lower or same gm level if (sd->status.account_id != pl_sd->status.account_id) clif->GM_kick(NULL, pl_sd); } @@ -3065,7 +3042,6 @@ ACMD(kickall) *------------------------------------------*/ ACMD(allskill) { - nullpo_retr(-1, sd); pc->allskillup(sd); // all skills sd->status.skill_point = 0; // 0 skill points clif->updatestatus(sd, SP_SKILLPOINT); // update @@ -3080,7 +3056,6 @@ ACMD(allskill) ACMD(questskill) { uint16 skill_id, index; - nullpo_retr(-1, sd); if (!message || !*message || (skill_id = atoi(message)) <= 0) {// also send a list of skills applicable to this command @@ -3123,7 +3098,6 @@ ACMD(questskill) ACMD(lostskill) { uint16 skill_id, index; - nullpo_retr(-1, sd); if (!message || !*message || (skill_id = atoi(message)) <= 0) {// also send a list of skills applicable to this command @@ -3169,14 +3143,13 @@ ACMD(spiritball) { int max_spiritballs; int number; - nullpo_retr(-1, sd); max_spiritballs = min(ARRAYLENGTH(sd->spirit_timer), 0x7FFF); if( !message || !*message || (number = atoi(message)) < 0 || number > max_spiritballs ) { char msg[CHAT_SIZE_MAX]; - safesnprintf(msg, sizeof(msg), msg_txt(1028), max_spiritballs); // Please enter a party name (usage: @party <party_name>). + safesnprintf(msg, sizeof(msg), msg_txt(1028), max_spiritballs); // Please enter an amount (usage: @spiritball <number: 0-%d>). clif->message(fd, msg); return false; } @@ -3196,7 +3169,6 @@ ACMD(spiritball) ACMD(party) { char party_name[NAME_LENGTH]; - nullpo_retr(-1, sd); memset(party_name, '\0', sizeof(party_name)); @@ -3217,7 +3189,6 @@ ACMD(guild) { char guild_name[NAME_LENGTH]; int prev; - nullpo_retr(-1, sd); memset(guild_name, '\0', sizeof(guild_name)); @@ -3236,7 +3207,6 @@ ACMD(guild) ACMD(breakguild) { - nullpo_retr(-1, sd); if (sd->status.guild_id) { // Check if the player has a guild struct guild *g; @@ -3269,7 +3239,6 @@ ACMD(breakguild) * *------------------------------------------*/ ACMD(agitstart) { - nullpo_retr(-1, sd); if (map->agit_flag == 1) { clif->message(fd, msg_txt(73)); // War of Emperium is currently in progress. return false; @@ -3286,7 +3255,6 @@ ACMD(agitstart) { * *------------------------------------------*/ ACMD(agitstart2) { - nullpo_retr(-1, sd); if (map->agit2_flag == 1) { clif->message(fd, msg_txt(404)); // "War of Emperium SE is currently in progress." return false; @@ -3303,7 +3271,6 @@ ACMD(agitstart2) { * *------------------------------------------*/ ACMD(agitend) { - nullpo_retr(-1, sd); if (map->agit_flag == 0) { clif->message(fd, msg_txt(75)); // War of Emperium is currently not in progress. return false; @@ -3320,7 +3287,6 @@ ACMD(agitend) { * *------------------------------------------*/ ACMD(agitend2) { - nullpo_retr(-1, sd); if (map->agit2_flag == 0) { clif->message(fd, msg_txt(406)); // "War of Emperium SE is currently not in progress." return false; @@ -3337,8 +3303,6 @@ ACMD(agitend2) { * @mapexit - shuts down the map server *------------------------------------------*/ ACMD(mapexit) { - nullpo_retr(-1, sd); - map->do_shutdown(); return true; } @@ -3351,7 +3315,6 @@ ACMD(idsearch) char item_name[100]; unsigned int i, match; struct item_data *item_array[MAX_SEARCH]; - nullpo_retr(-1, sd); memset(item_name, '\0', sizeof(item_name)); memset(atcmd_output, '\0', sizeof(atcmd_output)); @@ -3387,11 +3350,10 @@ ACMD(recallall) struct map_session_data* pl_sd; struct s_mapiterator* iter; int count; - nullpo_retr(-1, sd); memset(atcmd_output, '\0', sizeof(atcmd_output)); - if (sd->bl.m >= 0 && map->list[sd->bl.m].flag.nowarpto && !pc->has_permission(sd, PC_PERM_WARP_ANYWHERE)) { + if (sd->bl.m >= 0 && map->list[sd->bl.m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif->message(fd, msg_txt(1032)); // You are not authorized to warp somenone to your current map. return false; } @@ -3399,10 +3361,10 @@ ACMD(recallall) count = 0; iter = mapit_getallusers(); for( pl_sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); pl_sd = (TBL_PC*)mapit->next(iter) ) { - if (sd->status.account_id != pl_sd->status.account_id && pc->get_group_level(sd) >= pc->get_group_level(pl_sd)) { + if (sd->status.account_id != pl_sd->status.account_id && pc_get_group_level(sd) >= pc_get_group_level(pl_sd)) { if (pl_sd->bl.m == sd->bl.m && pl_sd->bl.x == sd->bl.x && pl_sd->bl.y == sd->bl.y) continue; // Don't waste time warping the character to the same place. - if (pl_sd->bl.m >= 0 && map->list[pl_sd->bl.m].flag.nowarp && !pc->has_permission(sd, PC_PERM_WARP_ANYWHERE)) + if (pl_sd->bl.m >= 0 && map->list[pl_sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) count++; else { if (pc_isdead(pl_sd)) { //Wake them up @@ -3434,7 +3396,6 @@ ACMD(guildrecall) int count; char guild_name[NAME_LENGTH]; struct guild *g; - nullpo_retr(-1, sd); memset(guild_name, '\0', sizeof(guild_name)); memset(atcmd_output, '\0', sizeof(atcmd_output)); @@ -3444,7 +3405,7 @@ ACMD(guildrecall) return false; } - if (sd->bl.m >= 0 && map->list[sd->bl.m].flag.nowarpto && !pc->has_permission(sd, PC_PERM_WARP_ANYWHERE)) { + if (sd->bl.m >= 0 && map->list[sd->bl.m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif->message(fd, msg_txt(1032)); // You are not authorized to warp somenone to your current map. return false; } @@ -3462,9 +3423,9 @@ ACMD(guildrecall) for( pl_sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); pl_sd = (TBL_PC*)mapit->next(iter) ) { if (sd->status.account_id != pl_sd->status.account_id && pl_sd->status.guild_id == g->guild_id) { - if (pc->get_group_level(pl_sd) > pc->get_group_level(sd) || (pl_sd->bl.m == sd->bl.m && pl_sd->bl.x == sd->bl.x && pl_sd->bl.y == sd->bl.y)) + if (pc_get_group_level(pl_sd) > pc_get_group_level(sd) || (pl_sd->bl.m == sd->bl.m && pl_sd->bl.x == sd->bl.x && pl_sd->bl.y == sd->bl.y)) continue; // Skip GMs greater than you... or chars already on the cell - if (pl_sd->bl.m >= 0 && map->list[pl_sd->bl.m].flag.nowarp && !pc->has_permission(sd, PC_PERM_WARP_ANYWHERE)) + if (pl_sd->bl.m >= 0 && map->list[pl_sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) count++; else pc->setpos(pl_sd, sd->mapindex, sd->bl.x, sd->bl.y, CLR_RESPAWN); @@ -3492,7 +3453,6 @@ ACMD(partyrecall) char party_name[NAME_LENGTH]; struct party_data *p; int count; - nullpo_retr(-1, sd); memset(party_name, '\0', sizeof(party_name)); memset(atcmd_output, '\0', sizeof(atcmd_output)); @@ -3502,7 +3462,7 @@ ACMD(partyrecall) return false; } - if (sd->bl.m >= 0 && map->list[sd->bl.m].flag.nowarpto && !pc->has_permission(sd, PC_PERM_WARP_ANYWHERE)) { + if (sd->bl.m >= 0 && map->list[sd->bl.m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif->message(fd, msg_txt(1032)); // You are not authorized to warp somenone to your current map. return false; } @@ -3519,9 +3479,9 @@ ACMD(partyrecall) iter = mapit_getallusers(); for( pl_sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); pl_sd = (TBL_PC*)mapit->next(iter) ) { if (sd->status.account_id != pl_sd->status.account_id && pl_sd->status.party_id == p->party.party_id) { - if (pc->get_group_level(pl_sd) > pc->get_group_level(sd) || (pl_sd->bl.m == sd->bl.m && pl_sd->bl.x == sd->bl.x && pl_sd->bl.y == sd->bl.y)) + if (pc_get_group_level(pl_sd) > pc_get_group_level(sd) || (pl_sd->bl.m == sd->bl.m && pl_sd->bl.x == sd->bl.x && pl_sd->bl.y == sd->bl.y)) continue; // Skip GMs greater than you... or chars already on the cell - if (pl_sd->bl.m >= 0 && map->list[pl_sd->bl.m].flag.nowarp && !pc->has_permission(sd, PC_PERM_WARP_ANYWHERE)) + if (pl_sd->bl.m >= 0 && map->list[pl_sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) count++; else pc->setpos(pl_sd, sd->mapindex, sd->bl.x, sd->bl.y, CLR_RESPAWN); @@ -3544,7 +3504,6 @@ ACMD(partyrecall) *------------------------------------------*/ ACMD(reloaditemdb) { - nullpo_retr(-1, sd); itemdb->reload(); clif->message(fd, msg_txt(97)); // Item database has been reloaded. @@ -3555,7 +3514,6 @@ ACMD(reloaditemdb) * *------------------------------------------*/ ACMD(reloadmobdb) { - nullpo_retr(-1, sd); mob->reload(); pet->read_db(); homun->reload(); @@ -3572,7 +3530,6 @@ ACMD(reloadmobdb) { *------------------------------------------*/ ACMD(reloadskilldb) { - nullpo_retr(-1, sd); skill->reload(); homun->reload_skill(); elemental->reload_skilldb(); @@ -3588,22 +3545,22 @@ ACMD(reloadskilldb) ACMD(reloadatcommand) { config_t run_test; - if (conf_read_file(&run_test, "conf/groups.conf")) { + if (libconfig->read_file(&run_test, "conf/groups.conf")) { clif->message(fd, msg_txt(1036)); // Error reading groups.conf, reload failed. return false; } - config_destroy(&run_test); + libconfig->destroy(&run_test); - if (conf_read_file(&run_test, map->ATCOMMAND_CONF_FILENAME)) { + if (libconfig->read_file(&run_test, map->ATCOMMAND_CONF_FILENAME)) { clif->message(fd, msg_txt(1037)); // Error reading atcommand.conf, reload failed. return false; } - config_destroy(&run_test); + libconfig->destroy(&run_test); atcommand->doload(); - pc_groups_reload(); + pcg->reload(); clif->message(fd, msg_txt(254)); return true; } @@ -3680,7 +3637,6 @@ ACMD(reloadscript) { struct s_mapiterator* iter; struct map_session_data* pl_sd; - nullpo_retr(-1, sd); //atcommand_broadcast( fd, sd, "@broadcast", "Server is reloading scripts..." ); //atcommand_broadcast( fd, sd, "@broadcast", "You will feel a bit of lag at this point !" ); @@ -3732,9 +3688,7 @@ ACMD(mapinfo) { int i, m_id, chat_num = 0, list = 0, vend_num = 0; unsigned short m_index; char mapname[24]; - - nullpo_retr(-1, sd); - + memset(atcmd_output, '\0', sizeof(atcmd_output)); memset(mapname, '\0', sizeof(mapname)); memset(direction, '\0', sizeof(direction)); @@ -3757,7 +3711,7 @@ ACMD(mapinfo) { clif->message(fd, msg_txt(1)); // Map not found. return false; } - m_index = mapindex_name2id(mapname); //This one shouldn't fail since the previous seek did not. + m_index = mapindex->name2id(mapname); //This one shouldn't fail since the previous seek did not. clif->message(fd, msg_txt(1039)); // ------ Map Info ------ @@ -3964,7 +3918,6 @@ ACMD(mapinfo) { default: // normally impossible to arrive here clif->message(fd, msg_txt(1118)); // Please enter at least one valid list number (usage: @mapinfo <0-3> <map>). return false; - break; } return true; @@ -3975,8 +3928,6 @@ ACMD(mapinfo) { *------------------------------------------*/ ACMD(mount_peco) { - nullpo_retr(-1, sd); - if (sd->disguise != -1) { clif->message(fd, msg_txt(212)); // Cannot mount while in disguise. return false; @@ -4040,7 +3991,6 @@ ACMD(mount_peco) ACMD(guildspy) { char guild_name[NAME_LENGTH]; struct guild *g; - nullpo_retr(-1, sd); memset(guild_name, '\0', sizeof(guild_name)); memset(atcmd_output, '\0', sizeof(atcmd_output)); @@ -4080,7 +4030,6 @@ ACMD(guildspy) { ACMD(partyspy) { char party_name[NAME_LENGTH]; struct party_data *p; - nullpo_retr(-1, sd); memset(party_name, '\0', sizeof(party_name)); memset(atcmd_output, '\0', sizeof(atcmd_output)); @@ -4121,7 +4070,6 @@ ACMD(partyspy) { ACMD(repairall) { int count, i; - nullpo_retr(-1, sd); count = 0; for (i = 0; i < MAX_INVENTORY; i++) { @@ -4149,7 +4097,6 @@ ACMD(repairall) *------------------------------------------*/ ACMD(nuke) { struct map_session_data *pl_sd; - nullpo_retr(-1, sd); memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); @@ -4159,7 +4106,7 @@ ACMD(nuke) { } if ((pl_sd = map->nick2sd(atcmd_player_name)) != NULL) { - if (pc->get_group_level(sd) >= pc->get_group_level(pl_sd)) { // you can kill only lower or same GM level + if (pc_get_group_level(sd) >= pc_get_group_level(pl_sd)) { // you can kill only lower or same GM level skill->castend_nodamage_id(&pl_sd->bl, &pl_sd->bl, NPC_SELFDESTRUCTION, 99, timer->gettick(), 0); clif->message(fd, msg_txt(109)); // Player has been nuked! } else { @@ -4180,9 +4127,7 @@ ACMD(nuke) { ACMD(tonpc) { char npcname[NAME_LENGTH+1]; struct npc_data *nd; - - nullpo_retr(-1, sd); - + memset(npcname, 0, sizeof(npcname)); if (!message || !*message || sscanf(message, "%23[^\n]", npcname) < 1) { @@ -4209,7 +4154,6 @@ ACMD(tonpc) { ACMD(shownpc) { char NPCname[NAME_LENGTH+1]; - nullpo_retr(-1, sd); memset(NPCname, '\0', sizeof(NPCname)); @@ -4235,7 +4179,6 @@ ACMD(shownpc) ACMD(hidenpc) { char NPCname[NAME_LENGTH+1]; - nullpo_retr(-1, sd); memset(NPCname, '\0', sizeof(NPCname)); @@ -4284,7 +4227,6 @@ ACMD(unloadnpc) { struct npc_data *nd; char NPCname[NAME_LENGTH+1]; - nullpo_retr(-1, sd); memset(NPCname, '\0', sizeof(NPCname)); @@ -4311,10 +4253,9 @@ ACMD(unloadnpc) char* txt_time(unsigned int duration) { int days, hours, minutes, seconds; - char temp[CHAT_SIZE_MAX]; static char temp1[CHAT_SIZE_MAX]; + int tlen = 0; - memset(temp, '\0', sizeof(temp)); memset(temp1, '\0', sizeof(temp1)); days = duration / (60 * 60 * 24); @@ -4325,22 +4266,22 @@ char* txt_time(unsigned int duration) seconds = duration - (60 * minutes); if (days == 1) - sprintf(temp, msg_txt(219), days); // %d day + tlen += sprintf(tlen + temp1, msg_txt(219), days); // %d day else if (days > 1) - sprintf(temp, msg_txt(220), days); // %d days + tlen += sprintf(tlen + temp1, msg_txt(220), days); // %d days if (hours == 1) - sprintf(temp1, msg_txt(221), temp, hours); // %s %d hour + tlen += sprintf(tlen + temp1, msg_txt(221), hours); // %d hour else if (hours > 1) - sprintf(temp1, msg_txt(222), temp, hours); // %s %d hours + tlen += sprintf(tlen + temp1, msg_txt(222), hours); // %d hours if (minutes < 2) - sprintf(temp, msg_txt(223), temp1, minutes); // %s %d minute + tlen += sprintf(tlen + temp1, msg_txt(223), minutes); // %d minute else - sprintf(temp, msg_txt(224), temp1, minutes); // %s %d minutes + tlen += sprintf(tlen + temp1, msg_txt(224), minutes); // %d minutes if (seconds == 1) - sprintf(temp1, msg_txt(225), temp, seconds); // %s and %d second + sprintf(tlen + temp1, msg_txt(225), seconds); // and %d second else if (seconds > 1) - sprintf(temp1, msg_txt(226), temp, seconds); // %s and %d seconds - + sprintf(tlen + temp1, msg_txt(226), seconds); // and %d seconds + return temp1; } @@ -4349,12 +4290,9 @@ char* txt_time(unsigned int duration) * Calculation management of GM modification (@day/@night GM commands) is done *------------------------------------------*/ ACMD(servertime) { - const struct TimerData * timer_data; - const struct TimerData * timer_data2; time_t time_server; // variable for number of seconds (used with time() function) struct tm *datetime; // variable for time in structure ->tm_mday, ->tm_sec, ... char temp[CHAT_SIZE_MAX]; - nullpo_retr(-1, sd); memset(temp, '\0', sizeof(temp)); @@ -4364,51 +4302,40 @@ ACMD(servertime) { strftime(temp, sizeof(temp)-1, msg_txt(230), datetime); // Server time (normal time): %A, %B %d %Y %X. clif->message(fd, temp); - if (battle_config.night_duration == 0 && battle_config.day_duration == 0) { - if (map->night_flag == 0) - clif->message(fd, msg_txt(231)); // Game time: The game is in permanent daylight. - else - clif->message(fd, msg_txt(232)); // Game time: The game is in permanent night. - } else if (battle_config.night_duration == 0) { - if (map->night_flag == 1) { // we start with night - timer_data = timer->get(pc->day_timer_tid); - sprintf(temp, msg_txt(233), txt_time(DIFF_TICK(timer_data->tick,timer->gettick())/1000)); // Game time: The game is actualy in night for %s. - clif->message(fd, temp); - clif->message(fd, msg_txt(234)); // Game time: After, the game will be in permanent daylight. - } else - clif->message(fd, msg_txt(231)); // Game time: The game is in permanent daylight. - } else if (battle_config.day_duration == 0) { - if (map->night_flag == 0) { // we start with day - timer_data = timer->get(pc->night_timer_tid); - sprintf(temp, msg_txt(235), txt_time(DIFF_TICK(timer_data->tick,timer->gettick())/1000)); // Game time: The game is actualy in daylight for %s. - clif->message(fd, temp); - clif->message(fd, msg_txt(236)); // Game time: After, the game will be in permanent night. - } else - clif->message(fd, msg_txt(232)); // Game time: The game is in permanent night. - } else { + if (pc->day_timer_tid != INVALID_TIMER && pc->night_timer_tid != INVALID_TIMER) { + const struct TimerData * timer_data = timer->get(pc->night_timer_tid); + const struct TimerData * timer_data2 = timer->get(pc->day_timer_tid); + if (map->night_flag == 0) { - timer_data = timer->get(pc->night_timer_tid); - timer_data2 = timer->get(pc->day_timer_tid); - sprintf(temp, msg_txt(235), txt_time(DIFF_TICK(timer_data->tick,timer->gettick())/1000)); // Game time: The game is actualy in daylight for %s. + sprintf(temp, msg_txt(235), // Game time: The game is actualy in daylight for %s. + txt_time((unsigned int)(DIFF_TICK(timer_data->tick,timer->gettick())/1000))); clif->message(fd, temp); if (DIFF_TICK(timer_data->tick, timer_data2->tick) > 0) - sprintf(temp, msg_txt(237), txt_time(DIFF_TICK(timer_data->interval,DIFF_TICK(timer_data->tick,timer_data2->tick)) / 1000)); // Game time: After, the game will be in night for %s. + sprintf(temp, msg_txt(237), // Game time: After, the game will be in night for %s. + txt_time((unsigned int)(DIFF_TICK(timer_data->interval,DIFF_TICK(timer_data->tick,timer_data2->tick)) / 1000))); else - sprintf(temp, msg_txt(237), txt_time(DIFF_TICK(timer_data2->tick,timer_data->tick)/1000)); // Game time: After, the game will be in night for %s. + sprintf(temp, msg_txt(237), // Game time: After, the game will be in night for %s. + txt_time((unsigned int)(DIFF_TICK(timer_data2->tick,timer_data->tick)/1000))); clif->message(fd, temp); } else { - timer_data = timer->get(pc->day_timer_tid); - timer_data2 = timer->get(pc->night_timer_tid); - sprintf(temp, msg_txt(233), txt_time(DIFF_TICK(timer_data->tick,timer->gettick()) / 1000)); // Game time: The game is actualy in night for %s. + sprintf(temp, msg_txt(233), // Game time: The game is actualy in night for %s. + txt_time((unsigned int)(DIFF_TICK(timer_data2->tick,timer->gettick()) / 1000))); clif->message(fd, temp); - if (DIFF_TICK(timer_data->tick,timer_data2->tick) > 0) - sprintf(temp, msg_txt(239), txt_time((timer_data->interval - DIFF_TICK(timer_data->tick, timer_data2->tick)) / 1000)); // Game time: After, the game will be in daylight for %s. + if (DIFF_TICK(timer_data2->tick,timer_data->tick) > 0) + sprintf(temp, msg_txt(239), // Game time: After, the game will be in daylight for %s. + txt_time((unsigned int)((timer_data2->interval - DIFF_TICK(timer_data2->tick, timer_data->tick)) / 1000))); else - sprintf(temp, msg_txt(239), txt_time(DIFF_TICK(timer_data2->tick, timer_data->tick) / 1000)); // Game time: After, the game will be in daylight for %s. + sprintf(temp, msg_txt(239), // Game time: After, the game will be in daylight for %s. + txt_time((unsigned int)(DIFF_TICK(timer_data->tick, timer_data2->tick) / 1000))); clif->message(fd, temp); } - sprintf(temp, msg_txt(238), txt_time(timer_data->interval / 1000)); // Game time: A day cycle has a normal duration of %s. + sprintf(temp, msg_txt(238), txt_time(timer_data2->interval / 1000)); // Game time: A day cycle has a normal duration of %s. clif->message(fd, temp); + } else { + if (map->night_flag == 0) + clif->message(fd, msg_txt(231)); // Game time: The game is in permanent daylight. + else + clif->message(fd, msg_txt(232)); // Game time: The game is in permanent night. } return true; @@ -4450,7 +4377,6 @@ ACMD(jail) { struct map_session_data *pl_sd; int x, y; unsigned short m_index; - nullpo_retr(-1, sd); memset(atcmd_player_name, '\0', sizeof(atcmd_player_name)); @@ -4464,7 +4390,7 @@ ACMD(jail) { return false; } - if (pc->get_group_level(sd) < pc->get_group_level(pl_sd)) + if (pc_get_group_level(sd) < pc_get_group_level(pl_sd)) { // you can jail only lower or same GM clif->message(fd, msg_txt(81)); // Your GM level don't authorise you to do this action on this player. return false; @@ -4478,19 +4404,19 @@ ACMD(jail) { switch(rnd() % 2) { //Jail Locations case 0: - m_index = mapindex_name2id(MAP_JAIL); + m_index = mapindex->name2id(MAP_JAIL); x = 24; y = 75; break; default: - m_index = mapindex_name2id(MAP_JAIL); + m_index = mapindex->name2id(MAP_JAIL); x = 49; y = 75; break; } //Duration of INT_MAX to specify infinity. - sc_start4(&pl_sd->bl,SC_JAILED,100,INT_MAX,m_index,x,y,1000); + sc_start4(NULL,&pl_sd->bl,SC_JAILED,100,INT_MAX,m_index,x,y,1000); clif->message(pl_sd->fd, msg_txt(117)); // GM has send you in jails. clif->message(fd, msg_txt(118)); // Player warped in jails. return true; @@ -4515,7 +4441,7 @@ ACMD(unjail) { return false; } - if (pc->get_group_level(sd) < pc->get_group_level(pl_sd)) { // you can jail only lower or same GM + if (pc_get_group_level(sd) < pc_get_group_level(pl_sd)) { // you can jail only lower or same GM clif->message(fd, msg_txt(81)); // Your GM level don't authorise you to do this action on this player. return false; @@ -4528,7 +4454,7 @@ ACMD(unjail) { } //Reset jail time to 1 sec. - sc_start(&pl_sd->bl,SC_JAILED,100,1,1000); + sc_start(NULL,&pl_sd->bl,SC_JAILED,100,1,1000); clif->message(pl_sd->fd, msg_txt(120)); // A GM has discharged you from jail. clif->message(fd, msg_txt(121)); // Player unjailed. return true; @@ -4540,7 +4466,6 @@ ACMD(jailfor) { char * modif_p; int jailtime = 0,x,y; short m_index = 0; - nullpo_retr(-1, sd); if (!message || !*message || sscanf(message, "%255s %23[^\n]",atcmd_output,atcmd_player_name) < 2) { clif->message(fd, msg_txt(400)); //Usage: @jailfor <time> <character name> @@ -4594,7 +4519,7 @@ ACMD(jailfor) { return false; } - if (pc->get_group_level(pl_sd) > pc->get_group_level(sd)) { + if (pc_get_group_level(pl_sd) > pc_get_group_level(sd)) { clif->message(fd, msg_txt(81)); // Your GM level don't authorise you to do this action on this player. return false; } @@ -4631,16 +4556,16 @@ ACMD(jailfor) { switch(rnd()%2) { case 1: //Jail #1 - m_index = mapindex_name2id(MAP_JAIL); + m_index = mapindex->name2id(MAP_JAIL); x = 49; y = 75; break; default: //Default Jail - m_index = mapindex_name2id(MAP_JAIL); + m_index = mapindex->name2id(MAP_JAIL); x = 24; y = 75; break; } - sc_start4(&pl_sd->bl,SC_JAILED,100,jailtime,m_index,x,y,jailtime?60000:1000); //jailtime = 0: Time was reset to 0. Wait 1 second to warp player out (since it's done in status->change_timer). + sc_start4(NULL,&pl_sd->bl,SC_JAILED,100,jailtime,m_index,x,y,jailtime?60000:1000); //jailtime = 0: Time was reset to 0. Wait 1 second to warp player out (since it's done in status->change_timer). return true; } @@ -4650,8 +4575,6 @@ ACMD(jailtime) { int year, month, day, hour, minute; - nullpo_retr(-1, sd); - if (!sd->sc.data[SC_JAILED]) { clif->message(fd, msg_txt(1139)); // You are not in jail. return false; @@ -4682,7 +4605,6 @@ ACMD(jailtime) ACMD(disguise) { int id = 0; - nullpo_retr(-1, sd); if (!message || !*message) { clif->message(fd, msg_txt(1143)); // Please enter a Monster/NPC name/ID (usage: @disguise <name/ID>). @@ -4713,7 +4635,13 @@ ACMD(disguise) clif->message(fd, msg_txt(1144)); // Character cannot be disguised while mounted. return false; } - + + if(sd->sc.data[SC_MONSTER_TRANSFORM]) + { + clif->message(fd, msg_txt(1487)); // Character cannot be disguised while in monster form. + return false; + } + pc->disguise(sd, id); clif->message(fd, msg_txt(122)); // Disguise applied. @@ -4728,7 +4656,6 @@ ACMD(disguiseall) int mob_id=0; struct map_session_data *pl_sd; struct s_mapiterator* iter; - nullpo_retr(-1, sd); if (!message || !*message) { clif->message(fd, msg_txt(1145)); // Please enter a Monster/NPC name/ID (usage: @disguiseall <name/ID>). @@ -4805,7 +4732,6 @@ ACMD(disguiseguild) *------------------------------------------*/ ACMD(undisguise) { - nullpo_retr(-1, sd); if (sd->disguise != -1) { pc->disguise(sd, -1); clif->message(fd, msg_txt(124)); // Undisguise applied. @@ -4823,7 +4749,6 @@ ACMD(undisguise) ACMD(undisguiseall) { struct map_session_data *pl_sd; struct s_mapiterator* iter; - nullpo_retr(-1, sd); iter = mapit_getallusers(); for( pl_sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); pl_sd = (TBL_PC*)mapit->next(iter) ) @@ -4845,7 +4770,6 @@ ACMD(undisguiseguild) struct map_session_data *pl_sd; struct guild *g; int i; - nullpo_retr(-1, sd); memset(guild_name, '\0', sizeof(guild_name)); @@ -4875,7 +4799,7 @@ ACMD(exp) { char output[CHAT_SIZE_MAX]; double nextb, nextj; - nullpo_retr(-1, sd); + memset(output, '\0', sizeof(output)); nextb = pc->nextbaseexp(sd); @@ -4897,7 +4821,6 @@ ACMD(exp) *------------------------------------------*/ ACMD(broadcast) { - nullpo_retr(-1, sd); memset(atcmd_output, '\0', sizeof(atcmd_output)); @@ -4917,8 +4840,6 @@ ACMD(broadcast) *------------------------------------------*/ ACMD(localbroadcast) { - nullpo_retr(-1, sd); - memset(atcmd_output, '\0', sizeof(atcmd_output)); if (!message || !*message) { @@ -4940,7 +4861,6 @@ ACMD(email) { char actual_email[100]; char new_email[100]; - nullpo_retr(-1, sd); memset(actual_email, '\0', sizeof(actual_email)); memset(new_email, '\0', sizeof(new_email)); @@ -4975,7 +4895,6 @@ ACMD(email) ACMD(effect) { int type = 0, flag = 0; - nullpo_retr(-1, sd); if (!message || !*message || sscanf(message, "%d", &type) < 1) { clif->message(fd, msg_txt(1152)); // Please enter an effect number (usage: @effect <effect number>). @@ -4993,7 +4912,6 @@ ACMD(effect) *------------------------------------------*/ ACMD(killer) { - nullpo_retr(-1, sd); sd->state.killer = !sd->state.killer; if(sd->state.killer) @@ -5010,7 +4928,6 @@ ACMD(killer) * enable other people killing you *------------------------------------------*/ ACMD(killable) { - nullpo_retr(-1, sd); sd->state.killable = !sd->state.killable; if(sd->state.killable) @@ -5027,7 +4944,6 @@ ACMD(killable) { * turn skills on for the map *------------------------------------------*/ ACMD(skillon) { - nullpo_retr(-1, sd); map->list[sd->bl.m].flag.noskill = 0; clif->message(fd, msg_txt(244)); return true; @@ -5038,7 +4954,6 @@ ACMD(skillon) { * Turn skills off on the map *------------------------------------------*/ ACMD(skilloff) { - nullpo_retr(-1, sd); map->list[sd->bl.m].flag.noskill = 1; clif->message(fd, msg_txt(243)); return true; @@ -5051,7 +4966,7 @@ ACMD(skilloff) { ACMD(npcmove) { int x = 0, y = 0, m; struct npc_data *nd = 0; - nullpo_retr(-1, sd); + memset(atcmd_player_name, '\0', sizeof atcmd_player_name); if (!message || !*message || sscanf(message, "%d %d %23[^\n]", &x, &y, atcmd_player_name) < 3) { @@ -5090,7 +5005,6 @@ ACMD(addwarp) unsigned short m; struct npc_data* nd; - nullpo_retr(-1, sd); memset(warpname, '\0', sizeof(warpname)); if (!message || !*message || sscanf(message, "%31s %d %d %23[^\n]", mapname, &x, &y, warpname) < 4) { @@ -5098,7 +5012,7 @@ ACMD(addwarp) return false; } - m = mapindex_name2id(mapname); + m = mapindex->name2id(mapname); if( m == 0 ) { sprintf(atcmd_output, msg_txt(1157), mapname); // Unknown map '%s'. @@ -5121,7 +5035,6 @@ ACMD(addwarp) *------------------------------------------*/ ACMD(follow) { struct map_session_data *pl_sd = NULL; - nullpo_retr(-1, sd); if (!message || !*message) { if (sd->followtarget == -1) @@ -5157,7 +5070,7 @@ ACMD(follow) { ACMD(dropall) { int i; - nullpo_retr(-1, sd); + for (i = 0; i < MAX_INVENTORY; i++) { if (sd->status.inventory[i].amount) { if(sd->status.inventory[i].equip != 0) @@ -5175,7 +5088,6 @@ ACMD(dropall) ACMD(storeall) { int i; - nullpo_retr(-1, sd); if (sd->state.storage_flag != 1) { //Open storage. @@ -5201,7 +5113,6 @@ ACMD(storeall) ACMD(clearstorage) { int i, j; - nullpo_retr(-1, sd); if (sd->state.storage_flag == 1) { clif->message(fd, msg_txt(250)); @@ -5223,7 +5134,6 @@ ACMD(cleargstorage) int i, j; struct guild *g; struct guild_storage *guild_storage; - nullpo_retr(-1, sd); g = sd->guild; @@ -5262,7 +5172,6 @@ ACMD(cleargstorage) ACMD(clearcart) { int i; - nullpo_retr(-1, sd); if (pc_iscarton(sd) == 0) { clif->message(fd, msg_txt(1396)); // You do not have a cart to be cleaned. @@ -5291,14 +5200,13 @@ ACMD(clearcart) #define MAX_SKILLID_PARTIAL_RESULTS 5 #define MAX_SKILLID_PARTIAL_RESULTS_LEN 74 /* "skill " (6) + "%d:" (up to 5) + "%s" (up to 30) + " (%s)" (up to 33) */ ACMD(skillid) { - int skillen, idx, i, found = 0; + int idx, i, found = 0; + size_t skillen; DBIterator* iter; DBKey key; DBData *data; char partials[MAX_SKILLID_PARTIAL_RESULTS][MAX_SKILLID_PARTIAL_RESULTS_LEN]; - - nullpo_retr(-1, sd); - + if (!message || !*message) { clif->message(fd, msg_txt(1163)); // Please enter a skill name to look up (usage: @skillid <skill name>). return false; @@ -5342,7 +5250,6 @@ ACMD(useskill) { uint16 skill_id; uint16 skill_lv; char target[100]; - nullpo_retr(-1, sd); if(!message || !*message || sscanf(message, "%hu %hu %23[^\n]", &skill_id, &skill_lv, target) != 3) { clif->message(fd, msg_txt(1165)); // Usage: @useskill <skill ID> <skill level> <target> @@ -5356,7 +5263,7 @@ ACMD(useskill) { return false; } - if ( pc->get_group_level(sd) < pc->get_group_level(pl_sd) ) + if ( pc_get_group_level(sd) < pc_get_group_level(pl_sd) ) { clif->message(fd, msg_txt(81)); // Your GM level don't authorise you to do this action on this player. return false; @@ -5368,11 +5275,13 @@ ACMD(useskill) { else bl = &sd->bl; + pc->delinvincibletimer(sd); + if (skill->get_inf(skill_id)&INF_GROUND_SKILL) unit->skilluse_pos(bl, pl_sd->bl.x, pl_sd->bl.y, skill_id, skill_lv); else unit->skilluse_id(bl, pl_sd->bl.id, skill_id, skill_lv); - + return true; } @@ -5383,10 +5292,9 @@ ACMD(useskill) { *------------------------------------------*/ ACMD(displayskill) { struct status_data *st; - unsigned int tick; + int64 tick; uint16 skill_id; uint16 skill_lv = 1; - nullpo_retr(-1, sd); if (!message || !*message || sscanf(message, "%hu %hu", &skill_id, &skill_lv) < 1) { clif->message(fd, msg_txt(1166)); // Usage: @displayskill <skill ID> {<skill level>} @@ -5410,7 +5318,6 @@ ACMD(skilltree) { int meets, j, c=0; char target[NAME_LENGTH]; struct skill_tree_entry *ent; - nullpo_retr(-1, sd); if(!message || !*message || sscanf(message, "%hu %23[^\r\n]", &skill_id, target) != 2) { clif->message(fd, msg_txt(1167)); // Usage: @skilltree <skill ID> <target> @@ -5432,7 +5339,7 @@ ACMD(skilltree) { if( j == MAX_SKILL_TREE || pc->skill_tree[c][j].id == 0 ) { clif->message(fd, msg_txt(1169)); // The player cannot use that skill. - return true; + return false; } ent = &pc->skill_tree[c][j]; @@ -5480,9 +5387,7 @@ void getring(struct map_session_data* sd) { ACMD(marry) { struct map_session_data *pl_sd = NULL; char player_name[NAME_LENGTH] = ""; - - nullpo_retr(-1, sd); - + if (!message || !*message || sscanf(message, "%23s", player_name) != 1) { clif->message(fd, msg_txt(1172)); // Usage: @marry <char name> return false; @@ -5511,8 +5416,6 @@ ACMD(marry) { *------------------------------------------*/ ACMD(divorce) { - nullpo_retr(-1, sd); - if (pc->divorce(sd) != 0) { sprintf(atcmd_output, msg_txt(1175), sd->status.name); // '%s' is not married. clif->message(fd, atcmd_output); @@ -5555,7 +5458,6 @@ ACMD(changelook) * Turns on/off Autotrade for a specific player *------------------------------------------*/ ACMD(autotrade) { - nullpo_retr(-1, sd); if( map->list[sd->bl.m].flag.autotrade != battle_config.autotrade_mapflag ) { clif->message(fd, msg_txt(1179)); // Autotrade is not allowed on this map. @@ -5575,14 +5477,21 @@ ACMD(autotrade) { sd->state.autotrade = 1; if( battle_config.at_timeout ) { int timeout = atoi(message); - status->change_start(&sd->bl, SC_AUTOTRADE, 10000, 0, 0, 0, 0, ((timeout > 0) ? min(timeout,battle_config.at_timeout) : battle_config.at_timeout) * 60000, 0); + status->change_start(NULL,&sd->bl, SC_AUTOTRADE, 10000, 0, 0, 0, 0, ((timeout > 0) ? min(timeout,battle_config.at_timeout) : battle_config.at_timeout) * 60000, 0); } - + clif->chsys_quit(sd); clif->authfail_fd(sd->fd, 15); + +#ifdef AUTOTRADE_PERSISTENCY + pc->autotrade_prepare(sd); + + return false;/* we fail to not cause it to proceed on is_atcommand */ +#else return true; +#endif } /*========================================== @@ -5592,7 +5501,6 @@ ACMD(autotrade) { ACMD(changegm) { struct guild *g; struct map_session_data *pl_sd; - nullpo_retr(-1, sd); if (sd->status.guild_id == 0 || (g = sd->guild) == NULL || strcmp(g->master,sd->status.name)) { clif->message(fd, msg_txt(1181)); // You need to be a Guild Master to use this command. @@ -5623,7 +5531,6 @@ ACMD(changegm) { * Changes the leader of a party. *------------------------------------------*/ ACMD(changeleader) { - nullpo_retr(-1, sd); if( !message[0] ) { clif->message(fd, msg_txt(1185)); // Usage: @changeleader <party_member_name> @@ -5644,7 +5551,6 @@ ACMD(partyoption) struct party_data *p; int mi, option; char w1[16], w2[16]; - nullpo_retr(-1, sd); if (sd->status.party_id == 0 || (p = party->search(sd->status.party_id)) == NULL) { @@ -5686,7 +5592,7 @@ ACMD(partyoption) ACMD(autoloot) { int rate; - nullpo_retr(-1, sd); + // autoloot command without value if(!message || !*message) { @@ -5732,16 +5638,16 @@ ACMD(autolootitem) } else if (!strcmp(message,"reset")) action = 4; - } - - if (action < 3) // add or remove - { - if ((item_data = itemdb->exists(atoi(message))) == NULL) - item_data = itemdb->search_name(message); - if (!item_data) { - // No items founds in the DB with Id or Name - clif->message(fd, msg_txt(1189)); // Item not found. - return false; + + if (action < 3) // add or remove + { + if ((item_data = itemdb->exists(atoi(message))) == NULL) + item_data = itemdb->search_name(message); + if (!item_data) { + // No items founds in the DB with Id or Name + clif->message(fd, msg_txt(1189)); // Item not found. + return false; + } } } @@ -5807,31 +5713,109 @@ ACMD(autolootitem) } return true; } -/** - * No longer available, keeping here just in case it's back someday. [Ind] - **/ + /*========================================== - * It is made to rain. + * @autoloottype + * Credits: + * chriser,Aleos *------------------------------------------*/ -//ACMD(rain) { -// nullpo_retr(-1, sd); -// if (map->list[sd->bl.m].flag.rain) { -// map->list[sd->bl.m].flag.rain=0; -// clif->weather(sd->bl.m); -// clif->message(fd, msg_txt(1201)); // The rain has stopped. -// } else { -// map->list[sd->bl.m].flag.rain=1; -// clif->weather(sd->bl.m); -// clif->message(fd, msg_txt(1202)); // It has started to rain. -// } -// return true; -//} +ACMD(autoloottype) { + int i; + uint8 action = 3; // 1=add, 2=remove, 3=help+list (default), 4=reset + enum item_types type = -1; + int ITEM_NONE = 0; + + if (message && *message) { + if (message[0] == '+') { + message++; + action = 1; + } else if (message[0] == '-') { + message++; + action = 2; + } else if (strcmp(message,"reset") == 0) { + action = 4; + } + + if (action < 3) { + // add or remove + if (strncmp(message, "healing", 3) == 0) + type = IT_HEALING; + else if (strncmp(message, "usable", 3) == 0) + type = IT_USABLE; + else if (strncmp(message, "etc", 3) == 0) + type = IT_ETC; + else if (strncmp(message, "weapon", 3) == 0) + type = IT_WEAPON; + else if (strncmp(message, "armor", 3) == 0) + type = IT_ARMOR; + else if (strncmp(message, "card", 3) == 0) + type = IT_CARD; + else if (strncmp(message, "petegg", 4) == 0) + type = IT_PETEGG; + else if (strncmp(message, "petarmor", 4) == 0) + type = IT_PETARMOR; + else if (strncmp(message, "ammo", 3) == 0) + type = IT_AMMO; + else { + clif->message(fd, msg_txt(1491)); // Item type not found. + return false; + } + } + } + + switch (action) { + case 1: + if (sd->state.autoloottype&(1<<type)) { + clif->message(fd, msg_txt(1490)); // You're already autolooting this item type. + return false; + } + sd->state.autoloottype |= (1<<type); // Stores the type + sprintf(atcmd_output, msg_txt(1492), itemdb->typename(type)); // Autolooting item type: '%s' + clif->message(fd, atcmd_output); + break; + case 2: + if (!(sd->state.autoloottype&(1<<type))) { + clif->message(fd, msg_txt(1493)); // You're currently not autolooting this item type. + return false; + } + sd->state.autoloottype &= ~(1<<type); + sprintf(atcmd_output, msg_txt(1494), itemdb->typename(type)); // Removed item type: '%s' from your autoloottype list. + clif->message(fd, atcmd_output); + break; + case 3: + clif->message(fd, msg_txt(38)); // Invalid location number, or name. + + { + // attempt to find the text help string + const char *text = atcommand_help_string(info); + if (text) clif->messageln(fd, text); // send the text to the client + } + + if (sd->state.autoloottype == ITEM_NONE) { + clif->message(fd, msg_txt(1495)); // Your autoloottype list is empty. + } else { + clif->message(fd, msg_txt(1496)); // Item types on your autoloottype list: + for(i=0; i < IT_MAX; i++) { + if (sd->state.autoloottype&(1<<i)) { + sprintf(atcmd_output, " '%s'", itemdb->typename(i)); + clif->message(fd, atcmd_output); + } + } + } + break; + case 4: + sd->state.autoloottype = ITEM_NONE; + clif->message(fd, msg_txt(1497)); // Your autoloottype list has been reset. + break; + } + return true; +} /*========================================== * It is made to snow. *------------------------------------------*/ ACMD(snow) { - nullpo_retr(-1, sd); + if (map->list[sd->bl.m].flag.snow) { map->list[sd->bl.m].flag.snow=0; clif->weather(sd->bl.m); @@ -5849,7 +5833,7 @@ ACMD(snow) { * Cherry tree snowstorm is made to fall. (Sakura) *------------------------------------------*/ ACMD(sakura) { - nullpo_retr(-1, sd); + if (map->list[sd->bl.m].flag.sakura) { map->list[sd->bl.m].flag.sakura=0; clif->weather(sd->bl.m); @@ -5866,7 +5850,7 @@ ACMD(sakura) { * Clouds appear. *------------------------------------------*/ ACMD(clouds) { - nullpo_retr(-1, sd); + if (map->list[sd->bl.m].flag.clouds) { map->list[sd->bl.m].flag.clouds=0; clif->weather(sd->bl.m); @@ -5884,7 +5868,7 @@ ACMD(clouds) { * Different type of clouds using effect 516 *------------------------------------------*/ ACMD(clouds2) { - nullpo_retr(-1, sd); + if (map->list[sd->bl.m].flag.clouds2) { map->list[sd->bl.m].flag.clouds2=0; clif->weather(sd->bl.m); @@ -5902,7 +5886,7 @@ ACMD(clouds2) { * Fog hangs over. *------------------------------------------*/ ACMD(fog) { - nullpo_retr(-1, sd); + if (map->list[sd->bl.m].flag.fog) { map->list[sd->bl.m].flag.fog=0; clif->weather(sd->bl.m); @@ -5919,7 +5903,7 @@ ACMD(fog) { * Fallen leaves fall. *------------------------------------------*/ ACMD(leaves) { - nullpo_retr(-1, sd); + if (map->list[sd->bl.m].flag.leaves) { map->list[sd->bl.m].flag.leaves=0; clif->weather(sd->bl.m); @@ -5937,7 +5921,7 @@ ACMD(leaves) { * Fireworks appear. *------------------------------------------*/ ACMD(fireworks) { - nullpo_retr(-1, sd); + if (map->list[sd->bl.m].flag.fireworks) { map->list[sd->bl.m].flag.fireworks=0; clif->weather(sd->bl.m); @@ -5955,11 +5939,7 @@ ACMD(fireworks) { * Clearing Weather Effects by Dexity *------------------------------------------*/ ACMD(clearweather) { - nullpo_retr(-1, sd); - /** - * No longer available, keeping here just in case it's back someday. [Ind] - **/ - //map->list[sd->bl.m].flag.rain=0; + map->list[sd->bl.m].flag.snow=0; map->list[sd->bl.m].flag.sakura=0; map->list[sd->bl.m].flag.clouds=0; @@ -6004,9 +5984,7 @@ ACMD(mobsearch) int mob_id; int number = 0; struct s_mapiterator* it; - - nullpo_retr(-1, sd); - + if (!message || !*message || sscanf(message, "%99[^\n]", mob_name) < 1) { clif->message(fd, msg_txt(1218)); // Please enter a monster name (usage: @mobsearch <monster name>). return false; @@ -6090,11 +6068,11 @@ ACMD(npctalk) { char name[NAME_LENGTH],mes[100],temp[100]; struct npc_data *nd; - bool ifcolor=(*(command + 8) != 'c' && *(command + 8) != 'C')?0:1; - unsigned long color=0; + bool ifcolor=(*(info->command + 7) != 'c' && *(info->command + 7) != 'C')?0:1; + unsigned int color = 0; if (sd->sc.count && //no "chatting" while muted. - (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEP_SLEEP] || + (sd->sc.data[SC_BERSERK] || (sd->sc.data[SC_DEEP_SLEEP] && sd->sc.data[SC_DEEP_SLEEP]->val2) || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT))) return false; @@ -6105,7 +6083,7 @@ ACMD(npctalk) } } else { - if (!message || !*message || sscanf(message, "%lx %23[^,], %99[^\n]", &color, name, mes) < 3) { + if (!message || !*message || sscanf(message, "%u %23[^,], %99[^\n]", &color, name, mes) < 3) { clif->message(fd, msg_txt(1223)); // Please enter the correct parameters (usage: @npctalkc <color> <npc name>, <message>). return false; } @@ -6129,9 +6107,7 @@ ACMD(pettalk) { char mes[100],temp[100]; struct pet_data *pd; - - nullpo_retr(-1, sd); - + if ( battle_config.min_chat_delay ) { if( DIFF_TICK(sd->cantalk_tick, timer->gettick()) > 0 ) return true; @@ -6145,7 +6121,7 @@ ACMD(pettalk) } if (sd->sc.count && //no "chatting" while muted. - (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEP_SLEEP] || + (sd->sc.data[SC_BERSERK] || (sd->sc.data[SC_DEEP_SLEEP] && sd->sc.data[SC_DEEP_SLEEP]->val2) || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT))) return false; @@ -6256,9 +6232,7 @@ ACMD(summon) int mob_id = 0; int duration = 0; struct mob_data *md; - unsigned int tick=timer->gettick(); - - nullpo_retr(-1, sd); + int64 tick=timer->gettick(); if (!message || !*message || sscanf(message, "%23s %d", name, &duration) < 1) { @@ -6279,7 +6253,7 @@ ACMD(summon) return false; } - md = mob->once_spawn_sub(&sd->bl, sd->bl.m, -1, -1, "--ja--", mob_id, "", SZ_SMALL, AI_NONE); + md = mob->once_spawn_sub(&sd->bl, sd->bl.m, -1, -1, "--ja--", mob_id, "", SZ_MEDIUM, AI_NONE); if(!md) return false; @@ -6289,7 +6263,7 @@ ACMD(summon) md->deletetimer=timer->add(tick+(duration*60000),mob->timer_delete,md->bl.id,0); clif->specialeffect(&md->bl,344,AREA); mob->spawn(md); - sc_start4(&md->bl, SC_MODECHANGE, 100, 1, 0, MD_AGGRESSIVE, 0, 60000); + sc_start4(NULL,&md->bl, SC_MODECHANGE, 100, 1, 0, MD_AGGRESSIVE, 0, 60000); clif->skill_poseffect(&sd->bl,AM_CALLHOMUN,1,md->bl.x,md->bl.y,tick); clif->message(fd, msg_txt(39)); // All monster summoned! @@ -6304,7 +6278,6 @@ ACMD(summon) ACMD(adjgroup) { int new_group = 0; - nullpo_retr(-1, sd); if (!message || !*message || sscanf(message, "%d", &new_group) != 1) { clif->message(fd, msg_txt(1226)); // Usage: @adjgroup <group_id> @@ -6327,7 +6300,6 @@ ACMD(adjgroup) *------------------------------------------*/ ACMD(trade) { struct map_session_data *pl_sd = NULL; - nullpo_retr(-1, sd); if (!message || !*message) { clif->message(fd, msg_txt(1230)); // Please enter a player name (usage: @trade <char name>). @@ -6350,7 +6322,6 @@ ACMD(trade) { ACMD(setbattleflag) { char flag[128], value[128]; - nullpo_retr(-1, sd); if (!message || !*message || sscanf(message, "%127s %127s", flag, value) != 2) { clif->message(fd, msg_txt(1231)); // Usage: @setbattleflag <flag> <value> @@ -6372,7 +6343,6 @@ ACMD(setbattleflag) *------------------------------------------*/ ACMD(unmute) { struct map_session_data *pl_sd = NULL; - nullpo_retr(-1, sd); if (!message || !*message) { clif->message(fd, msg_txt(1234)); // Please enter a player name (usage: @unmute <char name>). @@ -6404,7 +6374,6 @@ ACMD(uptime) { unsigned long seconds = 0, day = 24*60*60, hour = 60*60, minute = 60, days = 0, hours = 0, minutes = 0; - nullpo_retr(-1, sd); seconds = timer->get_uptime(); days = seconds/day; @@ -6427,7 +6396,7 @@ ACMD(uptime) ACMD(changesex) { int i; - nullpo_retr(-1, sd); + pc->resetskill(sd,4); // to avoid any problem with equipment and invalid sex, equipment is unequiped. for( i=0; i<EQI_MAX; i++ ) @@ -6442,7 +6411,6 @@ ACMD(changesex) ACMD(mute) { struct map_session_data *pl_sd = NULL; int manner; - nullpo_retr(-1, sd); if (!message || !*message || sscanf(message, "%d %23[^\n]", &manner, atcmd_player_name) < 1) { clif->message(fd, msg_txt(1237)); // Usage: @mute <time> <char name> @@ -6454,7 +6422,7 @@ ACMD(mute) { return false; } - if ( pc->get_group_level(sd) < pc->get_group_level(pl_sd) ) + if ( pc_get_group_level(sd) < pc_get_group_level(pl_sd) ) { clif->message(fd, msg_txt(81)); // Your GM level don't authorise you to do this action on this player. return false; @@ -6465,7 +6433,7 @@ ACMD(mute) { if( pl_sd->status.manner < manner ) { pl_sd->status.manner -= manner; - sc_start(&pl_sd->bl,SC_NOCHAT,100,0,0); + sc_start(NULL,&pl_sd->bl,SC_NOCHAT,100,0,0); } else { pl_sd->status.manner = 0; status_change_end(&pl_sd->bl, SC_NOCHAT, INVALID_TIMER); @@ -6481,7 +6449,6 @@ ACMD(mute) { *------------------------------------------*/ ACMD(refresh) { - nullpo_retr(-1, sd); clif->refresh(sd); return true; } @@ -6490,7 +6457,6 @@ ACMD(refreshall) { struct map_session_data* iter_sd; struct s_mapiterator* iter; - nullpo_retr(-1, sd); iter = mapit_getallusers(); for (iter_sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); iter_sd = (TBL_PC*)mapit->next(iter)) @@ -6506,9 +6472,7 @@ ACMD(refreshall) ACMD(identify) { int i,num; - - nullpo_retr(-1, sd); - + for(i=num=0;i<MAX_INVENTORY;i++){ if(sd->status.inventory[i].nameid > 0 && sd->status.inventory[i].identify!=1){ num++; @@ -6524,7 +6488,7 @@ ACMD(identify) ACMD(misceffect) { int effect = 0; - nullpo_retr(-1, sd); + if (!message || !*message) return false; if (sscanf(message, "%d", &effect) < 1) @@ -6539,7 +6503,6 @@ ACMD(misceffect) { *------------------------------------------*/ ACMD(mail) { - nullpo_ret(sd); mail->openmail(sd); return true; } @@ -6697,9 +6660,7 @@ ACMD(showmobs) int mob_id; int number = 0; struct s_mapiterator* it; - - nullpo_retr(-1, sd); - + if(sscanf(message, "%99[^\n]", mob_name) < 0) return false; @@ -6711,7 +6672,7 @@ ACMD(showmobs) return true; } - if(mob->db(mob_id)->status.mode&MD_BOSS && !pc->has_permission(sd, PC_PERM_SHOW_BOSS)){ // If player group does not have access to boss mobs. + if(mob->db(mob_id)->status.mode&MD_BOSS && !pc_has_permission(sd, PC_PERM_SHOW_BOSS)){ // If player group does not have access to boss mobs. clif->message(fd, msg_txt(1251)); // Can't show boss mobs! return true; } @@ -6755,8 +6716,6 @@ ACMD(homlevel) { TBL_HOM * hd; int level = 0; enum homun_type htype; - - nullpo_retr(-1, sd); if( !message || !*message || ( level = atoi(message) ) < 1 ) { clif->message(fd, msg_txt(1253)); // Please enter a level adjustment (usage: @homlevel <number of levels>). @@ -6801,7 +6760,7 @@ ACMD(homlevel) { hd->homunculus.exp += hd->exp_next; } while( hd->homunculus.level < level && homun->levelup(hd) ); - status_calc_homunculus(hd,0); + status_calc_homunculus(hd,SCO_NONE); status_percent_heal(&hd->bl, 100, 100); clif->specialeffect(&hd->bl,568,AREA); return true; @@ -6812,8 +6771,6 @@ ACMD(homlevel) { *------------------------------------------*/ ACMD(homevolution) { - nullpo_retr(-1, sd); - if ( !homun_alive(sd->hd) ) { clif->message(fd, msg_txt(1254)); // You do not have a homunculus. return false; @@ -6830,7 +6787,6 @@ ACMD(homevolution) ACMD(hommutate) { int homun_id; enum homun_type m_class, m_id; - nullpo_retr(-1, sd); if( !homun_alive(sd->hd) ) { clif->message(fd, msg_txt(1254)); // You do not have a homunculus. @@ -6859,7 +6815,6 @@ ACMD(hommutate) { *------------------------------------------*/ ACMD(makehomun) { int homunid; - nullpo_retr(-1, sd); if (!message || !*message) { clif->message(fd, msg_txt(1256)); // Please enter a homunculus ID (usage: @makehomun <homunculus id>). @@ -6868,8 +6823,10 @@ ACMD(makehomun) { homunid = atoi(message); - if( homunid == -1 && sd->status.hom_id && !homun_alive(sd->hd) ) { - if( !sd->hd->homunculus.vaporize ) + if( homunid == -1 && sd->status.hom_id && !(sd->hd && homun_alive(sd->hd)) ) { + if( !sd->hd ) + homun->call(sd); + else if( sd->hd->homunculus.vaporize ) homun->ressurect(sd, 100, sd->bl.x, sd->bl.y); else homun->call(sd); @@ -6897,9 +6854,7 @@ ACMD(makehomun) { ACMD(homfriendly) { int friendly = 0; - - nullpo_retr(-1, sd); - + if ( !homun_alive(sd->hd) ) { clif->message(fd, msg_txt(1254)); // You do not have a homunculus. return false; @@ -6924,9 +6879,7 @@ ACMD(homfriendly) ACMD(homhungry) { int hungry = 0; - - nullpo_retr(-1, sd); - + if ( !homun_alive(sd->hd) ) { clif->message(fd, msg_txt(1254)); // You do not have a homunculus. return false; @@ -6951,9 +6904,7 @@ ACMD(homhungry) ACMD(homtalk) { char mes[100],temp[100]; - - nullpo_retr(-1, sd); - + if ( battle_config.min_chat_delay ) { if( DIFF_TICK(sd->cantalk_tick, timer->gettick()) > 0 ) return true; @@ -6961,7 +6912,7 @@ ACMD(homtalk) } if (sd->sc.count && //no "chatting" while muted. - (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEP_SLEEP] || + (sd->sc.data[SC_BERSERK] || (sd->sc.data[SC_DEEP_SLEEP] && sd->sc.data[SC_DEEP_SLEEP]->val2) || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT))) return false; @@ -6987,7 +6938,6 @@ ACMD(homtalk) ACMD(hominfo) { struct homun_data *hd; struct status_data *st; - nullpo_retr(-1, sd); if ( !homun_alive(sd->hd) ) { clif->message(fd, msg_txt(1254)); // You do not have a homunculus. @@ -7025,9 +6975,7 @@ ACMD(homstats) struct s_homunculus_db *db; struct s_homunculus *hom; int lv, min, max, evo; - - nullpo_retr(-1, sd); - + if ( !homun_alive(sd->hd) ) { clif->message(fd, msg_txt(1254)); // You do not have a homunculus. return false; @@ -7089,7 +7037,6 @@ ACMD(homstats) } ACMD(homshuffle) { - nullpo_retr(-1, sd); if(!sd->hd) return false; // nothing to do @@ -7268,7 +7215,7 @@ ACMD(version) { * @mutearea by MouseJstr *------------------------------------------*/ int atcommand_mutearea_sub(struct block_list *bl,va_list ap) -{ +{ // As it is being used [ACMD(mutearea)] there's no need to be a bool, but if there's need to reuse it, it's better to be this way int time, id; struct map_session_data *pl_sd = (struct map_session_data *)bl; @@ -7278,19 +7225,18 @@ int atcommand_mutearea_sub(struct block_list *bl,va_list ap) id = va_arg(ap, int); time = va_arg(ap, int); - if (id != bl->id && !pc->get_group_level(pl_sd)) { + if (id != bl->id && !pc_get_group_level(pl_sd)) { pl_sd->status.manner -= time; if (pl_sd->status.manner < 0) - sc_start(&pl_sd->bl,SC_NOCHAT,100,0,0); + sc_start(NULL,&pl_sd->bl,SC_NOCHAT,100,0,0); else status_change_end(&pl_sd->bl, SC_NOCHAT, INVALID_TIMER); } - return 0; + return 1; } ACMD(mutearea) { int time; - nullpo_ret(sd); if (!message || !*message) { clif->message(fd, msg_txt(1297)); // Please enter a time in minutes (usage: @mutearea/@stfu <time in minutes>). @@ -7311,7 +7257,6 @@ ACMD(rates) { char buf[CHAT_SIZE_MAX]; - nullpo_ret(sd); memset(buf, '\0', sizeof(buf)); snprintf(buf, CHAT_SIZE_MAX, msg_txt(1298), // Experience rates: Base %.2fx / Job %.2fx @@ -7337,13 +7282,12 @@ ACMD(rates) ACMD(me) { char tempmes[CHAT_SIZE_MAX]; - nullpo_retr(-1, sd); memset(tempmes, '\0', sizeof(tempmes)); memset(atcmd_output, '\0', sizeof(atcmd_output)); if (sd->sc.count && //no "chatting" while muted. - (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEP_SLEEP] || + (sd->sc.data[SC_BERSERK] || (sd->sc.data[SC_DEEP_SLEEP] && sd->sc.data[SC_DEEP_SLEEP]->val2) || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT))) return false; @@ -7366,17 +7310,16 @@ ACMD(me) ACMD(size) { int size = 0; - nullpo_retr(-1, sd); - size = cap_value(atoi(message),SZ_SMALL,SZ_BIG); + size = cap_value(atoi(message),SZ_MEDIUM,SZ_BIG); if(sd->state.size) { - sd->state.size = SZ_SMALL; + sd->state.size = SZ_MEDIUM; pc->setpos(sd, sd->mapindex, sd->bl.x, sd->bl.y, CLR_TELEPORT); } sd->state.size = size; - if( size == SZ_MEDIUM ) + if( size == SZ_SMALL ) clif->specialeffect(&sd->bl,420,AREA); else if( size == SZ_BIG ) clif->specialeffect(&sd->bl,422,AREA); @@ -7398,12 +7341,12 @@ ACMD(sizeall) for( pl_sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); pl_sd = (TBL_PC*)mapit->next(iter) ) { if( pl_sd->state.size != size ) { if( pl_sd->state.size ) { - pl_sd->state.size = SZ_SMALL; + pl_sd->state.size = SZ_MEDIUM; pc->setpos(pl_sd, pl_sd->mapindex, pl_sd->bl.x, pl_sd->bl.y, CLR_TELEPORT); } pl_sd->state.size = size; - if( size == SZ_MEDIUM ) + if( size == SZ_SMALL ) clif->specialeffect(&pl_sd->bl,420,AREA); else if( size == SZ_BIG ) clif->specialeffect(&pl_sd->bl,422,AREA); @@ -7421,7 +7364,6 @@ ACMD(sizeguild) char guild_name[NAME_LENGTH]; struct map_session_data *pl_sd; struct guild *g; - nullpo_retr(-1, sd); memset(guild_name, '\0', sizeof(guild_name)); @@ -7435,17 +7377,17 @@ ACMD(sizeguild) return false; } - size = cap_value(size,SZ_SMALL,SZ_BIG); + size = cap_value(size,SZ_MEDIUM,SZ_BIG); for( i = 0; i < g->max_member; i++ ) { if( (pl_sd = g->member[i].sd) && pl_sd->state.size != size ) { if( pl_sd->state.size ) { - pl_sd->state.size = SZ_SMALL; + pl_sd->state.size = SZ_MEDIUM; pc->setpos(pl_sd, pl_sd->mapindex, pl_sd->bl.x, pl_sd->bl.y, CLR_TELEPORT); } pl_sd->state.size = size; - if( size == SZ_MEDIUM ) + if( size == SZ_SMALL ) clif->specialeffect(&pl_sd->bl,420,AREA); else if( size == SZ_BIG ) clif->specialeffect(&pl_sd->bl,422,AREA); @@ -7460,9 +7402,7 @@ ACMD(sizeguild) * @monsterignore * => Makes monsters ignore you. [Valaris] *------------------------------------------*/ -ACMD(monsterignore) -{ - nullpo_retr(-1, sd); +ACMD(monsterignore) { if (!sd->state.monster_ignore) { sd->state.monster_ignore = 1; @@ -7478,9 +7418,7 @@ ACMD(monsterignore) * @fakename * => Gives your character a fake name. [Valaris] *------------------------------------------*/ -ACMD(fakename) -{ - nullpo_retr(-1, sd); +ACMD(fakename){ if( !message || !*message ) { @@ -7525,7 +7463,7 @@ ACMD(mapflag) { char flag_name[100]; short flag=0,i; - nullpo_retr(-1, sd); + memset(flag_name, '\0', sizeof(flag_name)); if (!message || !*message || (sscanf(message, "%99s %hd", flag_name, &flag) < 1)) { @@ -7543,7 +7481,7 @@ ACMD(mapflag) { CHECKFLAG(nojobexp); CHECKFLAG(nomobloot); CHECKFLAG(nomvploot); CHECKFLAG(nightenabled); CHECKFLAG(nodrop); CHECKFLAG(novending); CHECKFLAG(loadevent); CHECKFLAG(nochat); CHECKFLAG(partylock); CHECKFLAG(guildlock); CHECKFLAG(src4instance); - CHECKFLAG(notomb); + CHECKFLAG(notomb); CHECKFLAG(nocashshop); clif->message(sd->fd," "); clif->message(sd->fd,msg_txt(1312)); // Usage: "@mapflag monster_noteleport 1" (0=Off | 1=On) clif->message(sd->fd,msg_txt(1313)); // Type "@mapflag available" to list the available mapflags. @@ -7580,7 +7518,7 @@ ACMD(mapflag) { SETFLAG(nojobexp); SETFLAG(nomobloot); SETFLAG(nomvploot); SETFLAG(nightenabled); SETFLAG(nodrop); SETFLAG(novending); SETFLAG(loadevent); SETFLAG(nochat); SETFLAG(partylock); SETFLAG(guildlock); SETFLAG(src4instance); - SETFLAG(notomb); + SETFLAG(notomb); SETFLAG(nocashshop); clif->message(sd->fd,msg_txt(1314)); // Invalid flag name or flag. clif->message(sd->fd,msg_txt(1312)); // Usage: "@mapflag monster_noteleport 1" (0=Off | 1=On) @@ -7592,7 +7530,7 @@ ACMD(mapflag) { clif->message(sd->fd,"nozenypenalty, notrade, noskill, nowarp, nowarpto, noicewall, snow, clouds, clouds2,"); clif->message(sd->fd,"fog, fireworks, sakura, leaves, nobaseexp, nojobexp, nomobloot,"); clif->message(sd->fd,"nomvploot, nightenabled, nodrop, novending, loadevent, nochat, partylock,"); - clif->message(sd->fd,"guildlock, src4instance, notomb"); + clif->message(sd->fd,"guildlock, src4instance, notomb, nocashshop"); #undef CHECKFLAG #undef SETFLAG @@ -7655,10 +7593,11 @@ ACMD(invite) { unsigned int did = sd->duel_group; struct map_session_data *target_sd = map->nick2sd((char *)message); - if(did == 0) { + if(did == 0) + { // "Duel: @invite without @duel." clif->message(fd, msg_txt(350)); - return true; + return false; } if(duel->list[did].max_players_limit > 0 && @@ -7666,26 +7605,27 @@ ACMD(invite) { // "Duel: Limit of players is reached." clif->message(fd, msg_txt(351)); - return true; + return false; } if(target_sd == NULL) { // "Duel: Player not found." clif->message(fd, msg_txt(352)); - return true; + return false; } if(target_sd->duel_group > 0 || target_sd->duel_invite > 0) { // "Duel: Player already in duel." clif->message(fd, msg_txt(353)); - return true; + return false; } if(battle_config.duel_only_on_same_map && target_sd->bl.m != sd->bl.m) { + // "Duel: You can't invite %s because he/she isn't on the same map." sprintf(atcmd_output, msg_txt(364), message); clif->message(fd, atcmd_output); - return true; + return false; } duel->invite(did, sd, target_sd); @@ -7705,7 +7645,7 @@ ACMD(duel) { if(sd->duel_invite > 0) { // "Duel: @duel without @reject." clif->message(fd, msg_txt(355)); - return true; + return false; } if(!duel->checktime(sd)) { @@ -7713,14 +7653,14 @@ ACMD(duel) { // "Duel: You can take part in duel only one time per %d minutes." sprintf(output, msg_txt(356), battle_config.duel_time_interval); clif->message(fd, output); - return true; + return false; } if( message[0] ) { if(sscanf(message, "%d", &maxpl) >= 1) { if(maxpl < 2 || maxpl > 65535) { clif->message(fd, msg_txt(357)); // "Duel: Invalid value." - return true; + return false; } duel->create(sd, maxpl); } else { @@ -7731,7 +7671,7 @@ ACMD(duel) { if((newduel = duel->create(sd, 2)) != -1) { if(target_sd->duel_group > 0 || target_sd->duel_invite > 0) { clif->message(fd, msg_txt(353)); // "Duel: Player already in duel." - return true; + return false; } duel->invite(newduel, sd, target_sd); clif->message(fd, msg_txt(354)); // "Duel: Invitation has been sent." @@ -7739,7 +7679,7 @@ ACMD(duel) { } else { // "Duel: Player not found." clif->message(fd, msg_txt(352)); - return true; + return false; } } } else @@ -7753,7 +7693,7 @@ ACMD(leave) { if(sd->duel_group <= 0) { // "Duel: @leave without @duel." clif->message(fd, msg_txt(358)); - return true; + return false; } duel->leave(sd->duel_group, sd); @@ -7767,20 +7707,20 @@ ACMD(accept) { // "Duel: You can take part in duel only one time per %d minutes." sprintf(output, msg_txt(356), battle_config.duel_time_interval); clif->message(fd, output); - return true; + return false; } if(sd->duel_invite <= 0) { // "Duel: @accept without invititation." clif->message(fd, msg_txt(360)); - return true; + return false; } if( duel->list[sd->duel_invite].max_players_limit > 0 && duel->list[sd->duel_invite].members_count >= duel->list[sd->duel_invite].max_players_limit ) { // "Duel: Limit of players is reached." clif->message(fd, msg_txt(351)); - return true; + return false; } duel->accept(sd->duel_invite, sd); @@ -7793,7 +7733,7 @@ ACMD(reject) { if(sd->duel_invite <= 0) { // "Duel: @reject without invititation." clif->message(fd, msg_txt(362)); - return true; + return false; } duel->reject(sd->duel_invite, sd); @@ -7810,43 +7750,45 @@ ACMD(cash) char output[128]; int value; int ret=0; - nullpo_retr(-1, sd); if( !message || !*message || (value = atoi(message)) == 0 ) { clif->message(fd, msg_txt(1322)); // Please enter an amount. return false; } - if( !strcmpi(command+1,"cash") ) - { + if( !strcmpi(info->command,"cash") ) { if( value > 0 ) { if( (ret=pc->getcash(sd, value, 0)) >= 0){ - sprintf(output, msg_txt(505), ret, sd->cashPoints); - clif->disp_onlyself(sd, output, strlen(output)); - } - else clif->message(fd, msg_txt(149)); // Unable to decrease the number/value. + // If this option is set, the message is already sent by pc function + if( !battle_config.cashshop_show_points ){ + sprintf(output, msg_txt(505), ret, sd->cashPoints); + clif_disp_onlyself(sd, output, strlen(output)); + } + } else + clif->message(fd, msg_txt(149)); // Unable to decrease the number/value. } else { if( (ret=pc->paycash(sd, -value, 0)) >= 0){ sprintf(output, msg_txt(410), ret, sd->cashPoints); - clif->disp_onlyself(sd, output, strlen(output)); - } - else clif->message(fd, msg_txt(41)); // Unable to decrease the number/value. + clif_disp_onlyself(sd, output, strlen(output)); + } else + clif->message(fd, msg_txt(41)); // Unable to decrease the number/value. } - } - else - { // @points + } else { // @points if( value > 0 ) { - if( (ret=pc->getcash(sd, 0, value)) >= 0){ - sprintf(output, msg_txt(506), ret, sd->kafraPoints); - clif->disp_onlyself(sd, output, strlen(output)); - } - else clif->message(fd, msg_txt(149)); // Unable to decrease the number/value. + if( (ret=pc->getcash(sd, 0, value)) >= 0) { + // If this option is set, the message is already sent by pc function + if( !battle_config.cashshop_show_points ){ + sprintf(output, msg_txt(506), ret, sd->kafraPoints); + clif_disp_onlyself(sd, output, strlen(output)); + } + } else + clif->message(fd, msg_txt(149)); // Unable to decrease the number/value. } else { if( (ret=pc->paycash(sd, -value, -value)) >= 0){ sprintf(output, msg_txt(411), ret, sd->kafraPoints); - clif->disp_onlyself(sd, output, strlen(output)); - } - else clif->message(fd, msg_txt(41)); // Unable to decrease the number/value. + clif_disp_onlyself(sd, output, strlen(output)); + } else + clif->message(fd, msg_txt(41)); // Unable to decrease the number/value. } } @@ -7860,32 +7802,33 @@ ACMD(clone) { if (!message || !*message) { clif->message(sd->fd,msg_txt(1323)); // You must enter a player name or ID. - return true; + return false; } if((pl_sd=map->nick2sd((char *)message)) == NULL && (pl_sd=map->charid2sd(atoi(message))) == NULL) { clif->message(fd, msg_txt(3)); // Character not found. - return true; + return false; } - if(pc->get_group_level(pl_sd) > pc->get_group_level(sd)) { + if(pc_get_group_level(pl_sd) > pc_get_group_level(sd)) { clif->message(fd, msg_txt(126)); // Cannot clone a player of higher GM level than yourself. - return true; + return false; } - if (strcmpi(command+1, "clone") == 0) + if (strcmpi(info->command, "clone") == 0) flag = 1; - else if (strcmpi(command+1, "slaveclone") == 0) { + else if (strcmpi(info->command, "slaveclone") == 0) { flag = 2; if(pc_isdead(sd)){ + //"Unable to spawn slave clone." clif->message(fd, msg_txt(129+flag*2)); - return true; + return false; } master = sd->bl.id; if (battle_config.atc_slave_clone_limit && mob->countslave(&sd->bl) >= battle_config.atc_slave_clone_limit) { clif->message(fd, msg_txt(127)); // You've reached your slave clones limit. - return true; + return false; } } @@ -7904,7 +7847,7 @@ ACMD(clone) { return true; } clif->message(fd, msg_txt(129+flag*2)); // Unable to spawn evil clone. Unable to spawn clone. Unable to spawn slave clone. - return true; + return false; } /*===================================== @@ -7937,7 +7880,7 @@ ACMD(request) sprintf(atcmd_output, msg_txt(278), message); // (@request): %s intif->wis_message_to_gm(sd->status.name, PC_PERM_RECEIVE_REQUESTS, atcmd_output); - clif->disp_onlyself(sd, atcmd_output, strlen(atcmd_output)); + clif_disp_onlyself(sd, atcmd_output, strlen(atcmd_output)); clif->message(sd->fd,msg_txt(279)); // @request sent. return true; } @@ -7956,9 +7899,12 @@ ACMD(feelreset) /*========================================== * AUCTION SYSTEM *------------------------------------------*/ -ACMD(auction) -{ - nullpo_ret(sd); +ACMD(auction) { + + if( !battle_config.feature_auction ) { + clif->colormes(sd->fd,COLOR_RED,msg_txt(1484)); + return false; + } clif->auction_openwindow(sd); @@ -7970,8 +7916,6 @@ ACMD(auction) *------------------------------------------*/ ACMD(ksprotection) { - nullpo_retr(-1,sd); - if( sd->state.noks ) { sd->state.noks = 0; clif->message(fd, msg_txt(1325)); // [ K.S Protection Inactive ] @@ -8002,7 +7946,6 @@ ACMD(ksprotection) * Map Kill Steal Protection Setting *------------------------------------------*/ ACMD(allowks) { - nullpo_retr(-1,sd); if( map->list[sd->bl.m].flag.allowks ) { map->list[sd->bl.m].flag.allowks = 0; @@ -8014,9 +7957,7 @@ ACMD(allowks) { return true; } -ACMD(resetstat) -{ - nullpo_retr(-1, sd); +ACMD(resetstat) { pc->resetstate(sd); sprintf(atcmd_output, msg_txt(207), sd->status.name); @@ -8024,9 +7965,7 @@ ACMD(resetstat) return true; } -ACMD(resetskill) -{ - nullpo_retr(-1,sd); +ACMD(resetskill) { pc->resetskill(sd,1); sprintf(atcmd_output, msg_txt(206), sd->status.name); @@ -8046,18 +7985,16 @@ ACMD(itemlist) const struct item* items; int size; StringBuf buf; - - nullpo_retr(-1, sd); - - if( strcmp(command+1, "storagelist") == 0 ) { + + if( strcmpi(info->command, "storagelist") == 0 ) { location = "storage"; items = sd->status.storage.items; size = MAX_STORAGE; - } else if( strcmp(command+1, "cartlist") == 0 ) { + } else if( strcmpi(info->command, "cartlist") == 0 ) { location = "cart"; items = sd->status.cart; size = MAX_CART; - } else if( strcmp(command+1, "itemlist") == 0 ) { + } else if( strcmpi(info->command, "itemlist") == 0 ) { location = "inventory"; items = sd->status.inventory; size = MAX_INVENTORY; @@ -8248,14 +8185,11 @@ ACMD(stats) return true; } -ACMD(delitem) -{ +ACMD(delitem) { char item_name[100]; int nameid, amount = 0, total, idx; struct item_data* id; - - nullpo_retr(-1, sd); - + if( !message || !*message || ( sscanf(message, "\"%99[^\"]\" %d", item_name, &amount) < 2 && sscanf(message, "%99s %d", item_name, &amount) < 2 ) || amount < 1 ) { clif->message(fd, msg_txt(1355)); // Please enter an item name/ID, a quantity, and a player name (usage: #delitem <player> <item_name_or_ID> <quantity>). @@ -8314,17 +8248,15 @@ ACMD(delitem) /*========================================== * Custom Fonts *------------------------------------------*/ -ACMD(font) -{ +ACMD(font) { int font_id; - nullpo_retr(-1,sd); font_id = atoi(message); if( font_id == 0 ) { - if( sd->user_font ) + if( sd->status.font ) { - sd->user_font = 0; + sd->status.font = 0; clif->message(fd, msg_txt(1356)); // Returning to normal font. clif->font(sd); } @@ -8336,9 +8268,9 @@ ACMD(font) } else if( font_id < 0 || font_id > 9 ) clif->message(fd, msg_txt(1359)); // Invalid font. Use a value from 0 to 9. - else if( font_id != sd->user_font ) + else if( font_id != sd->status.font ) { - sd->user_font = font_id; + sd->status.font = font_id; clif->font(sd); clif->message(fd, msg_txt(1360)); // Font changed. } @@ -8365,15 +8297,15 @@ void atcommand_commands_sub(struct map_session_data* sd, const int fd, AtCommand clif->message(fd, msg_txt(273)); // "Commands available:" for (cmd = dbi_first(iter); dbi_exists(iter); cmd = dbi_next(iter)) { - unsigned int slen = 0; + size_t slen; switch( type ) { case COMMAND_CHARCOMMAND: - if( cmd->char_groups[pc_group_get_idx(sd->group)] == 0 ) + if( cmd->char_groups[pcg->get_idx(sd->group)] == 0 ) continue; break; case COMMAND_ATCOMMAND: - if( cmd->at_groups[pc_group_get_idx(sd->group)] == 0 ) + if( cmd->at_groups[pcg->get_idx(sd->group)] == 0 ) continue; break; default: @@ -8434,7 +8366,7 @@ ACMD(mount2) { clif->message(sd->fd,msg_txt(1362)); // NOTICE: If you crash with mount your LUA is outdated. if( !(sd->sc.data[SC_ALL_RIDING]) ) { clif->message(sd->fd,msg_txt(1363)); // You have mounted. - sc_start(&sd->bl,SC_ALL_RIDING,100,0,-1); + sc_start(NULL,&sd->bl,SC_ALL_RIDING,100,0,-1); } else { clif->message(sd->fd,msg_txt(1364)); // You have released your mount. status_change_end(&sd->bl, SC_ALL_RIDING, INVALID_TIMER); @@ -8454,7 +8386,7 @@ ACMD(accinfo) { //remove const type safestrncpy(query, message, NAME_LENGTH); - intif->request_accinfo( sd->fd, sd->bl.id, pc->get_group_level(sd), query ); + intif->request_accinfo( sd->fd, sd->bl.id, pc_get_group_level(sd), query ); return true; } @@ -8463,8 +8395,9 @@ ACMD(accinfo) { ACMD(set) { char reg[32], val[128]; struct script_data* data; - int toset = 0, len; + int toset = 0; bool is_str = false; + size_t len; if( !message || !*message || (toset = sscanf(message, "%31s %128[^\n]s", reg, val)) < 1 ) { clif->message(fd, msg_txt(1367)); // Usage: @set <variable name> <value> @@ -8514,12 +8447,12 @@ ACMD(set) { break; case '#': if( reg[1] == '#' ) - data->u.str = pc_readaccountreg2str(sd, reg);// global + data->u.str = pc_readaccountreg2str(sd, script->add_str(reg));// global else - data->u.str = pc_readaccountregstr(sd, reg);// local + data->u.str = pc_readaccountregstr(sd, script->add_str(reg));// local break; default: - data->u.str = pc_readglobalreg_str(sd, reg); + data->u.str = pc_readglobalreg_str(sd, script->add_str(reg)); break; } @@ -8543,12 +8476,12 @@ ACMD(set) { break; case '#': if( reg[1] == '#' ) - data->u.num = pc_readaccountreg2(sd, reg);// global + data->u.num = pc_readaccountreg2(sd, script->add_str(reg));// global else - data->u.num = pc_readaccountreg(sd, reg);// local + data->u.num = pc_readaccountreg(sd, script->add_str(reg));// local break; default: - data->u.num = pc_readglobalreg(sd, reg); + data->u.num = pc_readglobalreg(sd, script->add_str(reg)); break; } @@ -8582,8 +8515,8 @@ ACMD(reloadquestdb) { return true; } ACMD(addperm) { - int perm_size = ARRAYLENGTH(pc_g_permission_name); - bool add = (strcmpi(command+1, "addperm") == 0) ? true : false; + int perm_size = pcg->permission_count; + bool add = (strcmpi(info->command, "addperm") == 0) ? true : false; int i; if( !message || !*message ) { @@ -8591,37 +8524,37 @@ ACMD(addperm) { clif->message(fd, atcmd_output); clif->message(fd, msg_txt(1379)); // -- Permission List for( i = 0; i < perm_size; i++ ) { - sprintf(atcmd_output,"- %s",pc_g_permission_name[i].name); + sprintf(atcmd_output,"- %s",pcg->permissions[i].name); clif->message(fd, atcmd_output); } return false; } - ARR_FIND(0, perm_size, i, strcmpi(pc_g_permission_name[i].name, message) == 0); + ARR_FIND(0, perm_size, i, strcmpi(pcg->permissions[i].name, message) == 0); if( i == perm_size ) { sprintf(atcmd_output,msg_txt(1380),message); // '%s' is not a known permission. clif->message(fd, atcmd_output); clif->message(fd, msg_txt(1379)); // -- Permission List for( i = 0; i < perm_size; i++ ) { - sprintf(atcmd_output,"- %s",pc_g_permission_name[i].name); + sprintf(atcmd_output,"- %s",pcg->permissions[i].name); clif->message(fd, atcmd_output); } return false; } - if( add && (sd->extra_temp_permissions&pc_g_permission_name[i].permission) ) { - sprintf(atcmd_output, msg_txt(1381),sd->status.name,pc_g_permission_name[i].name); // User '%s' already possesses the '%s' permission. + if( add && (sd->extra_temp_permissions&pcg->permissions[i].permission) ) { + sprintf(atcmd_output, msg_txt(1381),sd->status.name,pcg->permissions[i].name); // User '%s' already possesses the '%s' permission. clif->message(fd, atcmd_output); return false; - } else if ( !add && !(sd->extra_temp_permissions&pc_g_permission_name[i].permission) ) { - sprintf(atcmd_output, msg_txt(1382),sd->status.name,pc_g_permission_name[i].name); // User '%s' doesn't possess the '%s' permission. + } else if ( !add && !(sd->extra_temp_permissions&pcg->permissions[i].permission) ) { + sprintf(atcmd_output, msg_txt(1382),sd->status.name,pcg->permissions[i].name); // User '%s' doesn't possess the '%s' permission. clif->message(fd, atcmd_output); sprintf(atcmd_output,msg_txt(1383),sd->status.name); // -- User '%s' Permissions clif->message(fd, atcmd_output); for( i = 0; i < perm_size; i++ ) { - if( sd->extra_temp_permissions&pc_g_permission_name[i].permission ) { - sprintf(atcmd_output,"- %s",pc_g_permission_name[i].name); + if( sd->extra_temp_permissions&pcg->permissions[i].permission ) { + sprintf(atcmd_output,"- %s",pcg->permissions[i].name); clif->message(fd, atcmd_output); } } @@ -8630,9 +8563,9 @@ ACMD(addperm) { } if( add ) - sd->extra_temp_permissions |= pc_g_permission_name[i].permission; + sd->extra_temp_permissions |= pcg->permissions[i].permission; else - sd->extra_temp_permissions &=~ pc_g_permission_name[i].permission; + sd->extra_temp_permissions &=~ pcg->permissions[i].permission; sprintf(atcmd_output, msg_txt(1384),sd->status.name); // User '%s' permissions updated successfully. The changes are temporary. @@ -8656,10 +8589,11 @@ ACMD(unloadnpcfile) { return true; } ACMD(cart) { -#define MC_CART_MDFY(x,idx) \ -sd->status.skill[idx].id = x?MC_PUSHCART:0; \ -sd->status.skill[idx].lv = x?1:0; \ -sd->status.skill[idx].flag = x?1:0; +#define MC_CART_MDFY(x,idx) do { \ + sd->status.skill[idx].id = (x)?MC_PUSHCART:0; \ + sd->status.skill[idx].lv = (x)?1:0; \ + sd->status.skill[idx].flag = (x)?1:0; \ +} while(0) int val = atoi(message); bool need_skill = pc->checkskill(sd, MC_PUSHCART) ? false : true; @@ -8698,7 +8632,7 @@ sd->status.skill[idx].flag = x?1:0; } /* [Ind/Hercules] */ ACMD(join) { - struct hChSysCh *channel; + struct hChSysCh *channel = NULL; char name[HCHSYS_NAME_LENGTH], pass[HCHSYS_NAME_LENGTH]; if( !message || !*message || sscanf(message, "%s %s", name, pass) < 1 ) { @@ -8709,26 +8643,34 @@ ACMD(join) { if( hChSys.local && strcmpi(name + 1, hChSys.local_name) == 0 ) { if( !map->list[sd->bl.m].channel ) { clif->chsys_mjoin(sd); - return true; + if( map->list[sd->bl.m].channel ) /* mjoin might have refused, map has chatting capabilities disabled */ + return true; } else channel = map->list[sd->bl.m].channel; } else if( hChSys.ally && sd->status.guild_id && strcmpi(name + 1, hChSys.ally_name) == 0 ) { struct guild *g = sd->guild; if( !g ) return false;/* unlikely, but we wont let it crash anyway. */ - channel = (struct hChSysCh *)g->channel; + channel = g->channel; } else if( !( channel = strdb_get(clif->channel_db, name + 1) ) ) { sprintf(atcmd_output, msg_txt(1400),name,command); // Unknown Channel '%s' (usage: %s <#channel_name>) clif->message(fd, atcmd_output); return false; } + if( !channel ) { + sprintf(atcmd_output, msg_txt(1400),name,command); // Unknown Channel '%s' (usage: %s <#channel_name>) + clif->message(fd, atcmd_output); + return false; + } + + if( idb_exists(channel->users, sd->status.char_id) ) { sprintf(atcmd_output, msg_txt(1475),name); // You're already in the '%s' channel clif->message(fd, atcmd_output); return false; } if( channel->pass[0] != '\0' && strcmp(channel->pass,pass) != 0 ) { - if( pc->has_permission(sd, PC_PERM_HCHSYS_ADMIN) ) { + if( pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN) ) { sd->stealth = true; } else { sprintf(atcmd_output, msg_txt(1401),name,command); // '%s' Channel is password protected (usage: %s <#channel_name> <password>) @@ -8752,8 +8694,8 @@ ACMD(join) { int i; for (i = 0; i < MAX_GUILDALLIANCE; i++) { if( g->alliance[i].opposition == 0 && g->alliance[i].guild_id && (sg = guild->search(g->alliance[i].guild_id) ) ) { - if( !(((struct hChSysCh*)sg->channel)->banned && idb_exists(((struct hChSysCh*)sg->channel)->banned, sd->status.account_id))) { - clif->chsys_join((struct hChSysCh *)sg->channel,sd); + if( !(sg->channel->banned && idb_exists(sg->channel->banned, sd->status.account_id))) { + clif->chsys_join(sg->channel,sd); } } } @@ -8816,16 +8758,16 @@ static inline void atcmd_channel_help(int fd, const char *command, bool can_crea /* [Ind/Hercules] */ ACMD(channel) { struct hChSysCh *channel; - char key[HCHSYS_NAME_LENGTH], sub1[HCHSYS_NAME_LENGTH], sub2[HCHSYS_NAME_LENGTH], sub3[HCHSYS_NAME_LENGTH]; + char subcmd[HCHSYS_NAME_LENGTH], sub1[HCHSYS_NAME_LENGTH], sub2[HCHSYS_NAME_LENGTH], sub3[HCHSYS_NAME_LENGTH]; unsigned char k = 0; sub1[0] = sub2[0] = sub3[0] = '\0'; - if( !message || !*message || sscanf(message, "%s %s %s %s", key, sub1, sub2, sub3) < 1 ) { - atcmd_channel_help(fd,command,( hChSys.allow_user_channel_creation || pc->has_permission(sd, PC_PERM_HCHSYS_ADMIN) )); + if( !message || !*message || sscanf(message, "%s %s %s %s", subcmd, sub1, sub2, sub3) < 1 ) { + atcmd_channel_help(fd,command,( hChSys.allow_user_channel_creation || pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN) )); return true; } - if( strcmpi(key,"create") == 0 && ( hChSys.allow_user_channel_creation || pc->has_permission(sd, PC_PERM_HCHSYS_ADMIN) ) ) { + if( strcmpi(subcmd,"create") == 0 && ( hChSys.allow_user_channel_creation || pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN) ) ) { if( sub1[0] != '#' ) { clif->message(fd, msg_txt(1405));// Channel name must start with a '#' return false; @@ -8857,7 +8799,7 @@ ACMD(channel) { clif->chsys_join(channel,sd); - } else if ( strcmpi(key,"list") == 0 ) { + } else if ( strcmpi(subcmd,"list") == 0 ) { if( sub1[0] != '\0' && strcmpi(sub1,"colors") == 0 ) { char mout[40]; for( k = 0; k < hChSys.colors_count; k++ ) { @@ -8874,7 +8816,7 @@ ACMD(channel) { } } else { DBIterator *iter = db_iterator(clif->channel_db); - bool show_all = pc->has_permission(sd, PC_PERM_HCHSYS_ADMIN) ? true : false; + bool show_all = pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN) ? true : false; clif->message(fd, msg_txt(1410)); // -- Public Channels if( hChSys.local ) { sprintf(atcmd_output, msg_txt(1409), hChSys.local_name, map->list[sd->bl.m].channel ? db_size(map->list[sd->bl.m].channel->users) : 0);// - #%s ( %d users ) @@ -8883,7 +8825,7 @@ ACMD(channel) { if( hChSys.ally && sd->status.guild_id ) { struct guild *g = sd->guild; if( !g ) { dbi_destroy(iter); return false; } - sprintf(atcmd_output, msg_txt(1409), hChSys.ally_name, db_size(((struct hChSysCh *)g->channel)->users));// - #%s ( %d users ) + sprintf(atcmd_output, msg_txt(1409), hChSys.ally_name, db_size(g->channel->users));// - #%s ( %d users ) clif->message(fd, atcmd_output); } for(channel = dbi_first(iter); dbi_exists(iter); channel = dbi_next(iter)) { @@ -8894,7 +8836,7 @@ ACMD(channel) { } dbi_destroy(iter); } - } else if ( strcmpi(key,"setcolor") == 0 ) { + } else if ( strcmpi(subcmd,"setcolor") == 0 ) { if( sub1[0] != '#' ) { clif->message(fd, msg_txt(1405));// Channel name must start with a '#' @@ -8907,7 +8849,7 @@ ACMD(channel) { return false; } - if( channel->owner != sd->status.char_id && !pc->has_permission(sd, PC_PERM_HCHSYS_ADMIN) ) { + if( channel->owner != sd->status.char_id && !pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN) ) { sprintf(atcmd_output, msg_txt(1412), sub1);// You're not the owner of channel '%s' clif->message(fd, atcmd_output); return false; @@ -8925,7 +8867,7 @@ ACMD(channel) { channel->color = k; sprintf(atcmd_output, msg_txt(1413),sub1,hChSys.colors_name[k]);// '%s' channel color updated to '%s' clif->message(fd, atcmd_output); - } else if ( strcmpi(key,"leave") == 0 ) { + } else if ( strcmpi(subcmd,"leave") == 0 ) { if( sub1[0] != '#' ) { clif->message(fd, msg_txt(1405));// Channel name must start with a '#' @@ -8953,7 +8895,7 @@ ACMD(channel) { clif->chsys_left(sd->channels[k],sd); sprintf(atcmd_output, msg_txt(1426),sub1); // You've left the '%s' channel clif->message(fd, atcmd_output); - } else if ( strcmpi(key,"bindto") == 0 ) { + } else if ( strcmpi(subcmd,"bindto") == 0 ) { if( sub1[0] != '#' ) { clif->message(fd, msg_txt(1405));// Channel name must start with a '#' @@ -8973,7 +8915,7 @@ ACMD(channel) { sd->gcbind = sd->channels[k]; sprintf(atcmd_output, msg_txt(1431),sub1); // Your global chat is now binded to the '%s' channel clif->message(fd, atcmd_output); - } else if ( strcmpi(key,"unbind") == 0 ) { + } else if ( strcmpi(subcmd,"unbind") == 0 ) { if( sd->gcbind == NULL ) { clif->message(fd, msg_txt(1432));// Your global chat is not binded to any channel @@ -8984,7 +8926,7 @@ ACMD(channel) { clif->message(fd, atcmd_output); sd->gcbind = NULL; - } else if ( strcmpi(key,"ban") == 0 ) { + } else if ( strcmpi(subcmd,"ban") == 0 ) { struct map_session_data *pl_sd = NULL; struct hChSysBanEntry *entry = NULL; @@ -8999,13 +8941,13 @@ ACMD(channel) { return false; } - if( channel->owner != sd->status.char_id && !pc->has_permission(sd, PC_PERM_HCHSYS_ADMIN) ) { + if( channel->owner != sd->status.char_id && !pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN) ) { sprintf(atcmd_output, msg_txt(1412), sub1);// You're not the owner of channel '%s' clif->message(fd, atcmd_output); return false; } - if (!message || !*message || sscanf(message, "%s %s %24[^\n]", key, sub1, sub2) < 1) { + if (!message || !*message || sscanf(message, "%s %s %24[^\n]", subcmd, sub1, sub2) < 1) { sprintf(atcmd_output, msg_txt(1434), sub2);// Player '%s' was not found clif->message(fd, atcmd_output); return false; @@ -9017,7 +8959,7 @@ ACMD(channel) { return false; } - if( pc->has_permission(pl_sd, PC_PERM_HCHSYS_ADMIN) ) { + if( pc_has_permission(pl_sd, PC_PERM_HCHSYS_ADMIN) ) { clif->message(fd, msg_txt(1464)); // Ban failed, not possible to ban this user. return false; } @@ -9041,7 +8983,7 @@ ACMD(channel) { sprintf(atcmd_output, msg_txt(1437),pl_sd->status.name,sub1); // Player '%s' has now been banned from '%s' channel clif->message(fd, atcmd_output); - } else if ( strcmpi(key,"unban") == 0 ) { + } else if ( strcmpi(subcmd,"unban") == 0 ) { struct map_session_data *pl_sd = NULL; if( sub1[0] != '#' ) { @@ -9055,7 +8997,7 @@ ACMD(channel) { return false; } - if( channel->owner != sd->status.char_id && !pc->has_permission(sd, PC_PERM_HCHSYS_ADMIN) ) { + if( channel->owner != sd->status.char_id && !pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN) ) { sprintf(atcmd_output, msg_txt(1412), sub1);// You're not the owner of channel '%s' clif->message(fd, atcmd_output); return false; @@ -9088,7 +9030,7 @@ ACMD(channel) { sprintf(atcmd_output, msg_txt(1441),pl_sd->status.name,sub1); // Player '%s' has now been unbanned from the '%s' channel clif->message(fd, atcmd_output); - } else if ( strcmpi(key,"unbanall") == 0 ) { + } else if ( strcmpi(subcmd,"unbanall") == 0 ) { if( sub1[0] != '#' ) { clif->message(fd, msg_txt(1405));// Channel name must start with a '#' return false; @@ -9100,7 +9042,7 @@ ACMD(channel) { return false; } - if( channel->owner != sd->status.char_id && !pc->has_permission(sd, PC_PERM_HCHSYS_ADMIN) ) { + if( channel->owner != sd->status.char_id && !pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN) ) { sprintf(atcmd_output, msg_txt(1412), sub1);// You're not the owner of channel '%s' clif->message(fd, atcmd_output); return false; @@ -9117,11 +9059,11 @@ ACMD(channel) { sprintf(atcmd_output, msg_txt(1442),sub1); // Removed all bans from '%s' channel clif->message(fd, atcmd_output); - } else if ( strcmpi(key,"banlist") == 0 ) { + } else if ( strcmpi(subcmd,"banlist") == 0 ) { DBIterator *iter = NULL; DBKey key; DBData *data; - bool isA = pc->has_permission(sd, PC_PERM_HCHSYS_ADMIN)?true:false; + bool isA = pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN)?true:false; if( sub1[0] != '#' ) { clif->message(fd, msg_txt(1405));// Channel name must start with a '#' return false; @@ -9162,7 +9104,7 @@ ACMD(channel) { dbi_destroy(iter); - } else if ( strcmpi(key,"setopt") == 0 ) { + } else if ( strcmpi(subcmd,"setopt") == 0 ) { const char* opt_str[3] = { "None", "JoinAnnounce", @@ -9180,7 +9122,7 @@ ACMD(channel) { return false; } - if( channel->owner != sd->status.char_id && !pc->has_permission(sd, PC_PERM_HCHSYS_ADMIN) ) { + if( channel->owner != sd->status.char_id && !pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN) ) { sprintf(atcmd_output, msg_txt(1412), sub1);// You're not the owner of channel '%s' clif->message(fd, atcmd_output); return false; @@ -9271,7 +9213,7 @@ ACMD(channel) { } } else { - atcmd_channel_help(fd,command,( hChSys.allow_user_channel_creation || pc->has_permission(sd, PC_PERM_HCHSYS_ADMIN) )); + atcmd_channel_help(fd,command,( hChSys.allow_user_channel_creation || pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN) )); } return true; @@ -9341,17 +9283,28 @@ ACMD(searchstore){ return true; } ACMD(costume){ - const char* names[4] = { + const char* names[] = { "Wedding", "Xmas", "Summer", "Hanbok", +#if PACKETVER >= 20131218 + "Oktoberfest", +#endif + }; + const int name2id[] = { + SC_WEDDING, + SC_XMAS, + SC_SUMMER, + SC_HANBOK, +#if PACKETVER >= 20131218 + SC_OKTOBERFEST, +#endif }; - const int name2id[4] = { SC_WEDDING, SC_XMAS, SC_SUMMER, SC_HANBOK }; - unsigned short k = 0; + unsigned short k = 0, len = ARRAYLENGTH(names); if( !message || !*message ) { - for( k = 0; k < 4; k++ ) { + for( k = 0; k < len; k++ ) { if( sd->sc.data[name2id[k]] ) { sprintf(atcmd_output,msg_txt(1473),names[k]);//Costume '%s' removed. clif->message(sd->fd,atcmd_output); @@ -9361,14 +9314,14 @@ ACMD(costume){ } clif->message(sd->fd,msg_txt(1472)); - for( k = 0; k < 4; k++ ) { + for( k = 0; k < len; k++ ) { sprintf(atcmd_output,msg_txt(1471),names[k]);//-- %s clif->message(sd->fd,atcmd_output); } return false; } - for( k = 0; k < 4; k++ ) { + for( k = 0; k < len; k++ ) { if( sd->sc.data[name2id[k]] ) { sprintf(atcmd_output,msg_txt(1470),names[k]);// You're already with a '%s' costume, type '@costume' to remove it. clif->message(sd->fd,atcmd_output); @@ -9376,17 +9329,17 @@ ACMD(costume){ } } - for( k = 0; k < 4; k++ ) { + for( k = 0; k < len; k++ ) { if( strcmpi(message,names[k]) == 0 ) break; } - if( k == 4 ) { + if( k == len ) { sprintf(atcmd_output,msg_txt(1469),message);// '%s' is not a known costume clif->message(sd->fd,atcmd_output); return false; } - sc_start(&sd->bl, name2id[k], 100, 0, -1); + sc_start(NULL,&sd->bl, name2id[k], 100, 0, -1); return true; } @@ -9441,6 +9394,8 @@ void atcommand_basecommands(void) { ACMD_DEF(heal), ACMD_DEF(item), ACMD_DEF(item2), + ACMD_DEF2("itembound", item), + ACMD_DEF2("itembound2", item2), ACMD_DEF(itemreset), ACMD_DEF(clearstorage), ACMD_DEF(cleargstorage), @@ -9517,7 +9472,9 @@ void atcommand_basecommands(void) { ACMD_DEF2("allstats", stat_all), ACMD_DEF2("block", char_block), ACMD_DEF2("ban", char_ban), + ACMD_DEF2("charban", char_ban),/* char-specific ban time */ ACMD_DEF2("unblock", char_unblock), + ACMD_DEF2("charunban", char_unban),/* char-specific ban time */ ACMD_DEF2("unban", char_unban), ACMD_DEF2("mount", mount_peco), ACMD_DEF(guildspy), @@ -9588,6 +9545,7 @@ void atcommand_basecommands(void) { ACMD_DEF(changelook), ACMD_DEF(autoloot), ACMD_DEF2("alootid", autolootitem), + ACMD_DEF(autoloottype), ACMD_DEF(mobinfo), ACMD_DEF(exp), ACMD_DEF(version), @@ -9668,23 +9626,41 @@ void atcommand_basecommands(void) { ACMD_DEF(costume), ACMD_DEF(skdebug), }; - AtCommandInfo* cmd; int i; for( i = 0; i < ARRAYLENGTH(atcommand_base); i++ ) { - if(atcommand->exists(atcommand_base[i].command)) { // Should not happen if atcommand_base[] array is OK + if(!atcommand->add(atcommand_base[i].command,atcommand_base[i].func,false)) { // Should not happen if atcommand_base[] array is OK ShowDebug("atcommand_basecommands: duplicate ACMD_DEF for '%s'.\n", atcommand_base[i].command); continue; } - CREATE(cmd, AtCommandInfo, 1); - safestrncpy(cmd->command, atcommand_base[i].command, sizeof(cmd->command)); - cmd->func = atcommand_base[i].func; - cmd->help = NULL;/* start as null dear */ - cmd->log = true; - strdb_put(atcommand->db, cmd->command, cmd); } + + /* @commands from plugins */ + HPM_map_atcommands(); + return; } +#undef ACMD_DEF +#undef ACMD_DEF2 + +bool atcommand_add(char *name,AtCommandFunc func, bool replace) { + AtCommandInfo* cmd; + + if( (cmd = atcommand->exists(name)) ) { //caller will handle/display on false + if( !replace ) + return false; + } else { + CREATE(cmd, AtCommandInfo, 1); + strdb_put(atcommand->db, name, cmd); + } + + safestrncpy(cmd->command, name, sizeof(cmd->command)); + cmd->func = func; + cmd->help = NULL; + cmd->log = true; + + return true; +} /*========================================== * Command lookup functions @@ -9779,9 +9755,14 @@ void atcommand_get_suggestions(struct map_session_data* sd, const char *name, bo dbi_destroy(alias_iter); } -/// Executes an at-command. -bool is_atcommand(const int fd, struct map_session_data* sd, const char* message, int type) -{ +/** + * Executes an at-command + * @param fd fd associated to the invoking character + * @param sd sd associated to the invoking character + * @param message atcommand arguments + * @param player_invoked true if the command was invoked by a player, false if invoked by the server (bypassing any restrictions) + */ +bool atcommand_exec(const int fd, struct map_session_data *sd, const char *message, bool player_invoked) { char charname[NAME_LENGTH], params[100]; char charname2[NAME_LENGTH], params2[100]; char command[100]; @@ -9811,11 +9792,9 @@ bool is_atcommand(const int fd, struct map_session_data* sd, const char* message if ( *message != atcommand->at_symbol && *message != atcommand->char_symbol ) return false; - // type value 0 = server invoked: bypass restrictions - // 1 = player invoked - if ( type == 1) { + if (player_invoked) { //Commands are disabled on maps flagged as 'nocommand' - if ( map->list[sd->bl.m].nocommand && pc->get_group_level(sd) < map->list[sd->bl.m].nocommand ) { + if ( map->list[sd->bl.m].nocommand && pc_get_group_level(sd) < map->list[sd->bl.m].nocommand ) { clif->message(fd, msg_txt(143)); return false; } @@ -9850,10 +9829,10 @@ bool is_atcommand(const int fd, struct map_session_data* sd, const char* message break; } - if( !pc->get_group_level(sd) ) { + if( !pc_get_group_level(sd) ) { if( x >= 1 || y >= 1 ) { /* we have command */ info = atcommand->get_info_byname(atcommand->check_alias(command + 1)); - if( !info || info->char_groups[pc_group_get_idx(sd->group)] == 0 ) /* if we can't use or doesn't exist: don't even display the command failed message */ + if( !info || info->char_groups[pcg->get_idx(sd->group)] == 0 ) /* if we can't use or doesn't exist: don't even display the command failed message */ return false; } else return false;/* display as normal message */ @@ -9864,13 +9843,16 @@ bool is_atcommand(const int fd, struct map_session_data* sd, const char* message return true; } while(0); } - else if (*message == atcommand->at_symbol) { + else /*if (*message == atcommand->at_symbol)*/ { //atcmd_msg is constructed above differently for charcommands //it's copied from message if not a charcommand so it can //pass through the rest of the code compatible with both symbols sprintf(atcmd_msg, "%s", message); } + if( battle_config.idletime_criteria & BCIDLE_ATCOMMAND ) + sd->idletime = sockt->last_tick; + //Clearing these to be used once more. memset(command, '\0', sizeof(command)); memset(params, '\0', sizeof(params)); @@ -9880,7 +9862,7 @@ bool is_atcommand(const int fd, struct map_session_data* sd, const char* message params[0] = '\0'; // @commands (script based) - if(type == 1 && atcommand->binding_count > 0) { + if(player_invoked && atcommand->binding_count > 0) { struct atcmd_binding_data * binding; // Get atcommand binding @@ -9890,8 +9872,8 @@ bool is_atcommand(const int fd, struct map_session_data* sd, const char* message if( binding != NULL && binding->npc_event[0] && ( - (*atcmd_msg == atcommand->at_symbol && pc->get_group_level(sd) >= binding->group_lv) - || (*atcmd_msg == atcommand->char_symbol && pc->get_group_level(sd) >= binding->group_lv_char) + (*atcmd_msg == atcommand->at_symbol && pc_get_group_level(sd) >= binding->group_lv) + || (*atcmd_msg == atcommand->char_symbol && pc_get_group_level(sd) >= binding->group_lv_char) ) ) { // Check if self or character invoking; if self == character invoked, then self invoke. @@ -9918,7 +9900,7 @@ bool is_atcommand(const int fd, struct map_session_data* sd, const char* message //Grab the command information and check for the proper GM level required to use it or if the command exists info = atcommand->get_info_byname(atcommand->check_alias(command + 1)); if (info == NULL) { - if( pc->get_group_level(sd) ) { // TODO: remove or replace with proper permission + if( pc_get_group_level(sd) ) { // TODO: remove or replace with proper permission sprintf(output, msg_txt(153), command); // "%s is Unknown Command." clif->message(fd, output); atcommand->get_suggestions(sd, command + 1, *message == atcommand->at_symbol); @@ -9927,20 +9909,19 @@ bool is_atcommand(const int fd, struct map_session_data* sd, const char* message return false; } - // type == 1 : player invoked - if (type == 1) { + if (player_invoked) { int i; - if ((*command == atcommand->at_symbol && info->at_groups[pc_group_get_idx(sd->group)] == 0) || - (*command == atcommand->char_symbol && info->char_groups[pc_group_get_idx(sd->group)] == 0) ) { + if ((*command == atcommand->at_symbol && info->at_groups[pcg->get_idx(sd->group)] == 0) || + (*command == atcommand->char_symbol && info->char_groups[pcg->get_idx(sd->group)] == 0) ) { return false; } - if( pc_isdead(sd) && pc->has_permission(sd,PC_PERM_DISABLE_CMD_DEAD) ) { + if( pc_isdead(sd) && pc_has_permission(sd,PC_PERM_DISABLE_CMD_DEAD) ) { clif->message(fd, msg_txt(1393)); // You can't use commands while dead return true; } for(i = 0; i < map->list[sd->bl.m].zone->disabled_commands_count; i++) { if( info->func == map->list[sd->bl.m].zone->disabled_commands[i]->cmd ) { - if( pc->get_group_level(sd) < map->list[sd->bl.m].zone->disabled_commands[i]->group_lv ) { + if( pc_get_group_level(sd) < map->list[sd->bl.m].zone->disabled_commands[i]->group_lv ) { clif->colormes(sd->fd,COLOR_RED,"This command is disabled in this area"); return true; } else @@ -9981,11 +9962,11 @@ void atcommand_config_read(const char* config_filename) { const char *symbol = NULL; int num_aliases = 0; - if (conf_read_file(&atcommand_config, config_filename)) + if (libconfig->read_file(&atcommand_config, config_filename)) return; // Command symbols - if (config_lookup_string(&atcommand_config, "atcommand_symbol", &symbol)) { + if (libconfig->lookup_string(&atcommand_config, "atcommand_symbol", &symbol)) { if (ISPRINT(*symbol) && // no control characters *symbol != '/' && // symbol of client commands *symbol != '%' && // symbol of party chat @@ -9994,7 +9975,7 @@ void atcommand_config_read(const char* config_filename) { atcommand->at_symbol = *symbol; } - if (config_lookup_string(&atcommand_config, "charcommand_symbol", &symbol)) { + if (libconfig->lookup_string(&atcommand_config, "charcommand_symbol", &symbol)) { if (ISPRINT(*symbol) && // no control characters *symbol != '/' && // symbol of client commands *symbol != '%' && // symbol of party chat @@ -10004,10 +9985,10 @@ void atcommand_config_read(const char* config_filename) { } // Command aliases - aliases = config_lookup(&atcommand_config, "aliases"); + aliases = libconfig->lookup(&atcommand_config, "aliases"); if (aliases != NULL) { int i = 0; - int count = config_setting_length(aliases); + int count = libconfig->setting_length(aliases); for (i = 0; i < count; ++i) { config_setting_t *command; @@ -10015,7 +9996,7 @@ void atcommand_config_read(const char* config_filename) { int j = 0, alias_count = 0; AtCommandInfo *commandinfo = NULL; - command = config_setting_get_elem(aliases, i); + command = libconfig->setting_get_elem(aliases, i); if (config_setting_type(command) != CONFIG_TYPE_ARRAY) continue; commandname = config_setting_name(command); @@ -10023,9 +10004,9 @@ void atcommand_config_read(const char* config_filename) { ShowConfigWarning(command, "atcommand_config_read: can not set alias for non-existent command %s", commandname); continue; } - alias_count = config_setting_length(command); + alias_count = libconfig->setting_length(command); for (j = 0; j < alias_count; ++j) { - const char *alias = config_setting_get_string_elem(command, j); + const char *alias = libconfig->setting_get_string_elem(command, j); if (alias != NULL) { AliasInfo *alias_info; if (strdb_exists(atcommand->alias_db, alias)) { @@ -10042,17 +10023,17 @@ void atcommand_config_read(const char* config_filename) { } } - nolog = config_lookup(&atcommand_config, "nolog"); + nolog = libconfig->lookup(&atcommand_config, "nolog"); if (nolog != NULL) { int i = 0; - int count = config_setting_length(nolog); + int count = libconfig->setting_length(nolog); for (i = 0; i < count; ++i) { config_setting_t *command; const char *commandname = NULL; AtCommandInfo *commandinfo = NULL; - command = config_setting_get_elem(nolog, i); + command = libconfig->setting_get_elem(nolog, i); commandname = config_setting_name(command); if ( !( commandinfo = atcommand_exists(commandname) ) ) { ShowConfigWarning(command, "atcommand_config_read: can not disable logging for non-existent command %s", commandname); @@ -10064,9 +10045,9 @@ void atcommand_config_read(const char* config_filename) { // Commands help // We only check if all commands exist - help = config_lookup(&atcommand_config, "help"); + help = libconfig->lookup(&atcommand_config, "help"); if (help != NULL) { - int count = config_setting_length(help); + int count = libconfig->setting_length(help); int i; for (i = 0; i < count; ++i) { @@ -10074,14 +10055,14 @@ void atcommand_config_read(const char* config_filename) { const char *commandname; AtCommandInfo *commandinfo = NULL; - command = config_setting_get_elem(help, i); + command = libconfig->setting_get_elem(help, i); commandname = config_setting_name(command); if ( !( commandinfo = atcommand_exists(commandname) ) ) ShowConfigWarning(command, "atcommand_config_read: command %s does not exist", commandname); else { if( commandinfo->help == NULL ) { - const char *str = config_setting_get_string(command); - int len = strlen(str); + const char *str = libconfig->setting_get_string(command); + size_t len = strlen(str); commandinfo->help = aMalloc( len * sizeof(char) ); safestrncpy(commandinfo->help, str, len); } @@ -10091,7 +10072,7 @@ void atcommand_config_read(const char* config_filename) { ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' command aliases in '"CL_WHITE"%s"CL_RESET"'.\n", num_aliases, config_filename); - config_destroy(&atcommand_config); + libconfig->destroy(&atcommand_config); return; } @@ -10129,13 +10110,13 @@ void atcommand_db_load_groups(GroupSettings **groups, config_setting_t **command continue; } - idx = pc_group_get_idx(group); + idx = pcg->get_idx(group); if (idx < 0 || idx >= sz) { ShowError("atcommand_db_load_groups: index (%d) out of bounds [0,%d]\n", idx, sz - 1); continue; } - if (pc_group_has_permission(group, PC_PERM_USE_ALL_COMMANDS)) { + if (pcg->has_permission(group, PC_PERM_USE_ALL_COMMANDS)) { atcmd->at_groups[idx] = atcmd->char_groups[idx] = 1; continue; } @@ -10173,8 +10154,8 @@ bool atcommand_can_use(struct map_session_data *sd, const char *command) { if (info == NULL) return false; - if ((*command == atcommand->at_symbol && info->at_groups[pc_group_get_idx(sd->group)] != 0) || - (*command == atcommand->char_symbol && info->char_groups[pc_group_get_idx(sd->group)] != 0) ) { + if ((*command == atcommand->at_symbol && info->at_groups[pcg->get_idx(sd->group)] != 0) || + (*command == atcommand->char_symbol && info->char_groups[pcg->get_idx(sd->group)] != 0) ) { return true; } @@ -10186,38 +10167,22 @@ bool atcommand_can_use2(struct map_session_data *sd, const char *command, AtComm if (info == NULL) return false; - if ((type == COMMAND_ATCOMMAND && info->at_groups[pc_group_get_idx(sd->group)] != 0) || - (type == COMMAND_CHARCOMMAND && info->char_groups[pc_group_get_idx(sd->group)] != 0) ) { + if ((type == COMMAND_ATCOMMAND && info->at_groups[pcg->get_idx(sd->group)] != 0) || + (type == COMMAND_CHARCOMMAND && info->char_groups[pcg->get_idx(sd->group)] != 0) ) { return true; } return false; } bool atcommand_hp_add(char *name, AtCommandFunc func) { - AtCommandInfo* cmd; - + /* if commands are added after group permissions are thrown in, they end up with no permissions */ + /* so we restrict commands to be linked in during boot */ if( runflag == MAPSERVER_ST_RUNNING ) { ShowDebug("atcommand_hp_add: Commands can't be added after server is ready, skipping '%s'...\n",name); return false; } - if( atcommand->db == NULL ) - atcommand->db = stridb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, ATCOMMAND_LENGTH); - - if( atcommand->exists(name) ) { - ShowDebug("atcommand_hp_add: duplicate command '%s', skipping...\n", name); - return false; - } - - CREATE(cmd, AtCommandInfo, 1); - - safestrncpy(cmd->command, name, sizeof(cmd->command)); - cmd->func = func; - cmd->help = NULL;/* start as null dear */ - cmd->log = true; - - strdb_put(atcommand->db, cmd->command, cmd); - return true; + return HPM_map_add_atcommand(name,func); } /** @@ -10254,7 +10219,10 @@ void atcommand_doload(void) { atcommand->config_read(map->ATCOMMAND_CONF_FILENAME); } -void do_init_atcommand(void) { +void do_init_atcommand(bool minimal) { + if (minimal) + return; + atcommand->at_symbol = '@'; atcommand->char_symbol = '#'; atcommand->binding_count = 0; @@ -10277,7 +10245,7 @@ void atcommand_defaults(void) { atcommand->init = do_init_atcommand; atcommand->final = do_final_atcommand; - atcommand->parse = is_atcommand; + atcommand->exec = atcommand_exec; atcommand->create = atcommand_hp_add; atcommand->can_use = atcommand_can_use; atcommand->can_use2 = atcommand_can_use2; @@ -10303,4 +10271,6 @@ void atcommand_defaults(void) { atcommand->cmd_db_clear_sub = atcommand_db_clear_sub; atcommand->doload = atcommand_doload; atcommand->base_commands = atcommand_basecommands; + atcommand->add = atcommand_add; + atcommand->msg = atcommand_msg; } diff --git a/src/map/atcommand.h b/src/map/atcommand.h index 603abc0cc..39f7cc2b2 100644 --- a/src/map/atcommand.h +++ b/src/map/atcommand.h @@ -2,8 +2,8 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _ATCOMMAND_H_ -#define _ATCOMMAND_H_ +#ifndef _MAP_ATCOMMAND_H_ +#define _MAP_ATCOMMAND_H_ #include "../common/conf.h" #include "../common/db.h" @@ -21,7 +21,7 @@ struct block_list; **/ #define ATCOMMAND_LENGTH 50 #define MAX_MSG 1500 - +#define msg_txt(idx) atcommand->msg(idx) /** * Enumerations **/ @@ -77,16 +77,16 @@ struct atcommand_interface { /* */ char* msg_table[MAX_MSG]; // Server messages (0-499 reserved for GM commands, 500-999 reserved for others) /* */ - void (*init) (void); + void (*init) (bool minimal); void (*final) (void); /* */ - bool (*parse) (const int fd, struct map_session_data* sd, const char* message, int type); + bool (*exec) (const int fd, struct map_session_data *sd, const char *message, bool player_invoked); bool (*create) (char *name, AtCommandFunc func); bool (*can_use) (struct map_session_data *sd, const char *command); bool (*can_use2) (struct map_session_data *sd, const char *command, AtCommandType type); void (*load_groups) (GroupSettings **groups, config_setting_t **commands_, size_t sz); AtCommandInfo* (*exists) (const char* name); - int (*msg_read) (const char* cfgName); + bool (*msg_read) (const char* cfgName); void (*final_msg) (void); /* atcommand binding */ struct atcmd_binding_data* (*get_bind_byname) (const char* name); @@ -110,17 +110,15 @@ struct atcommand_interface { int (*cmd_db_clear_sub) (DBKey key, DBData *data, va_list args); void (*doload) (void); void (*base_commands) (void); + bool (*add) (char *name, AtCommandFunc func, bool replace); + const char* (*msg) (int msg_number); }; struct atcommand_interface *atcommand; -/* will remain outside for a while, we have plans for this little fellow */ -const char* msg_txt(int msg_number); - void atcommand_defaults(void); /* stay here */ #define ACMD(x) static bool atcommand_ ## x (const int fd, struct map_session_data* sd, const char* command, const char* message, struct AtCommandInfo *info) -#define ACMD_A(x) atcommand_ ## x -#endif /* _ATCOMMAND_H_ */ +#endif /* _MAP_ATCOMMAND_H_ */ diff --git a/src/map/battle.c b/src/map/battle.c index 928d14c22..e9e17708c 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -12,6 +12,7 @@ #include "../common/socket.h" #include "../common/strlib.h" #include "../common/utils.h" +#include "../common/HPM.h" #include "map.h" #include "path.h" @@ -196,7 +197,7 @@ struct block_list* battle_getenemyarea(struct block_list *src, int x, int y, int return bl_list[rnd()%c]; } -int battle_delay_damage_sub(int tid, unsigned int tick, int id, intptr_t data) { +int battle_delay_damage_sub(int tid, int64 tick, int id, intptr_t data) { struct delay_damage *dat = (struct delay_damage *)data; if ( dat ) { @@ -206,7 +207,7 @@ int battle_delay_damage_sub(int tid, unsigned int tick, int id, intptr_t data) { if( !target || status->isdead(target) ) {/* nothing we can do */ if( dat->src_type == BL_PC && ( src = map->id2bl(dat->src_id) ) && --((TBL_PC*)src)->delayed_damage == 0 && ((TBL_PC*)src)->state.hold_recalc ) { ((TBL_PC*)src)->state.hold_recalc = 0; - status_calc_pc(((TBL_PC*)src),0); + status_calc_pc(((TBL_PC*)src),SCO_FORCE); } ers_free(battle->delay_damage_ers, dat); return 0; @@ -237,14 +238,14 @@ int battle_delay_damage_sub(int tid, unsigned int tick, int id, intptr_t data) { if( src && src->type == BL_PC && --((TBL_PC*)src)->delayed_damage == 0 && ((TBL_PC*)src)->state.hold_recalc ) { ((TBL_PC*)src)->state.hold_recalc = 0; - status_calc_pc(((TBL_PC*)src),0); + status_calc_pc(((TBL_PC*)src),SCO_FORCE); } } ers_free(battle->delay_damage_ers, dat); return 0; } -int battle_delay_damage (unsigned int tick, int amotion, struct block_list *src, struct block_list *target, int attack_type, uint16 skill_id, uint16 skill_lv, int64 damage, enum damage_lv dmg_lv, int ddelay, bool additional_effects) { +int battle_delay_damage(int64 tick, int amotion, struct block_list *src, struct block_list *target, int attack_type, uint16 skill_id, uint16 skill_lv, int64 damage, enum damage_lv dmg_lv, int ddelay, bool additional_effects) { struct delay_damage *dat; struct status_change *sc; nullpo_ret(src); @@ -335,11 +336,11 @@ int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 d if( atk_elem == ELE_FIRE && battle->get_current_skill(target) == GN_WALLOFTHORN ) { struct skill_unit *su = (struct skill_unit*)target; struct skill_unit_group *sg; - struct block_list *src; + struct block_list *sgsrc; if( !su || !su->alive || (sg = su->group) == NULL || sg->val3 == -1 - || (src = map->id2bl(sg->src_id)) == NULL || status->isdead(src) + || (sgsrc = map->id2bl(sg->src_id)) == NULL || status->isdead(sgsrc) ) return 0; @@ -347,9 +348,9 @@ int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 d int x,y; x = sg->val3 >> 16; y = sg->val3 & 0xffff; - skill->unitsetting(src,su->group->skill_id,su->group->skill_lv,x,y,1); + skill->unitsetting(sgsrc,su->group->skill_id,su->group->skill_lv,x,y,1); sg->val3 = -1; - sg->limit = DIFF_TICK(timer->gettick(),sg->tick)+300; + sg->limit = DIFF_TICK32(timer->gettick(),sg->tick)+300; } } } @@ -365,8 +366,6 @@ int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 d } if( tsc->data[SC_THORNS_TRAP]) status_change_end(target, SC_THORNS_TRAP, INVALID_TIMER); - if( tsc->data[SC_FIRE_CLOAK_OPTION]) - damage -= damage * tsc->data[SC_FIRE_CLOAK_OPTION]->val2 / 100; if( tsc->data[SC_COLD] && target->type != BL_MOB) status_change_end(target, SC_COLD, INVALID_TIMER); if( tsc->data[SC_EARTH_INSIGNIA]) damage += damage/2; @@ -376,7 +375,7 @@ int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 d if( tsc->data[SC_ORATIO]) ratio += tsc->data[SC_ORATIO]->val1 * 2; break; case ELE_POISON: - if( tsc->data[SC_VENOMIMPRESS]) ratio += tsc->data[SC_VENOMIMPRESS]->val2; + if( tsc->data[SC_VENOMIMPRESS] && atk_elem == ELE_POISON ) ratio += tsc->data[SC_VENOMIMPRESS]->val2; break; case ELE_WIND: if( tsc->data[SC_COLD] && target->type != BL_MOB) damage += damage/2; @@ -408,7 +407,10 @@ int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 d if( t < 5 && atk_elem == t ) damage -= damage * ( tsd->charm[t] * 3 ) / 100;// -3% custom value } - return damage*ratio/100; + if( ratio < 100 ) + return damage - (damage * (100 - ratio) / 100); + else + return damage + (damage * (ratio - 100) / 100); } int64 battle_calc_weapon_damage(struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, struct weapon_atk *watk, int nk, bool n_ele, short s_ele, short s_ele_, int size, int type, int flag, int flag2){ // [malufett] #ifdef RENEWAL @@ -442,8 +444,8 @@ int64 battle_calc_weapon_damage(struct block_list *src, struct block_list *bl, u eatk += 200; #ifdef RENEWAL_EDP if( sc->data[SC_EDP] && skill_id != AS_GRIMTOOTH && skill_id != AS_VENOMKNIFE && skill_id != ASC_BREAKER ){ - eatk = eatk * sc->data[SC_EDP]->val4 / 100; - damage += damage * sc->data[SC_EDP]->val3 / 100; + eatk = eatk * (sc->data[SC_EDP]->val4 / 100 - 1); + damage = damage * (sc->data[SC_EDP]->val4 / 100); } #endif } @@ -607,7 +609,7 @@ int64 battle_addmastery(struct map_session_data *sd,struct block_list *target,in if( (skill_lv = pc->checkskill(sd,NC_RESEARCHFE)) > 0 && (st->def_ele == ELE_FIRE || st->def_ele == ELE_EARTH) ) damage += (skill_lv * 10); if( pc_ismadogear(sd) ) - damage += 20 + 20 * pc->checkskill(sd, NC_MADOLICENCE); + damage += 15 * pc->checkskill(sd, NC_MADOLICENCE); #ifdef RENEWAL if( (skill_lv = pc->checkskill(sd,BS_WEAPONRESEARCH)) > 0 ) damage += (skill_lv * 2); @@ -761,18 +763,18 @@ int64 battle_calc_masteryfix(struct block_list *src, struct block_list *target, if(sc->data[SC_IMPOSITIO]) damage += sc->data[SC_IMPOSITIO]->val2; if(sc->data[SC_DRUMBATTLE]){ - if(tstatus->size == SZ_SMALL) + if(tstatus->size == SZ_MEDIUM) damage += sc->data[SC_DRUMBATTLE]->val2; - else if(tstatus->size == SZ_MEDIUM) + else if(tstatus->size == SZ_SMALL) damage += 10 * sc->data[SC_DRUMBATTLE]->val1; //else no bonus for large target } if(sc->data[SC_GS_MADNESSCANCEL]) damage += 100; if(sc->data[SC_GS_GATLINGFEVER]){ - if(tstatus->size == SZ_SMALL) + if(tstatus->size == SZ_MEDIUM) damage += 10 * sc->data[SC_GS_GATLINGFEVER]->val1; - else if(tstatus->size == SZ_MEDIUM) + else if(tstatus->size == SZ_SMALL) damage += -5 * sc->data[SC_GS_GATLINGFEVER]->val1; else damage += sc->data[SC_GS_GATLINGFEVER]->val1; @@ -784,6 +786,8 @@ int64 battle_calc_masteryfix(struct block_list *src, struct block_list *target, // general skill masteries #ifdef RENEWAL + if( div < 0 ) // div fix + div = 1; if( skill_id == MO_FINGEROFFENSIVE )//The finger offensive spheres on moment of attack do count. [Skotlex] damage += div * sd->spiritball_old * 3; else @@ -845,8 +849,12 @@ int64 battle_calc_elefix(struct block_list *src, struct block_list *target, uint damage=battle->attr_fix(src, target, damage, s_ele, tstatus->def_ele, tstatus->ele_lv); if( skill_id == MC_CARTREVOLUTION ) //Cart Revolution applies the element fix once more with neutral element damage = battle->attr_fix(src,target,damage,ELE_NEUTRAL,tstatus->def_ele, tstatus->ele_lv); + if( skill_id == NC_ARMSCANNON ) + damage = battle->attr_fix(src,target,damage,ELE_NEUTRAL,tstatus->def_ele, tstatus->ele_lv); + if( skill_id == GN_CARTCANNON ) + damage = battle->attr_fix(src,target,damage,ELE_NEUTRAL,tstatus->def_ele, tstatus->ele_lv); if( skill_id == GS_GROUNDDRIFT ) //Additional 50*lv Neutral damage. - damage += battle_attr_fix(src,target,50*skill_lv,ELE_NEUTRAL,tstatus->def_ele, tstatus->ele_lv); + damage += battle->attr_fix(src,target,50*skill_lv,ELE_NEUTRAL,tstatus->def_ele, tstatus->ele_lv); } } @@ -944,11 +952,13 @@ int64 battle_calc_cardfix(int attack_type, struct block_list *src, struct block_ break; } } +#ifndef RENEWAL //It was discovered that ranged defense also counts vs magic! [Skotlex] if ( wflag&BF_SHORT ) cardfix = cardfix * ( 100 - tsd->bonus.near_attack_def_rate ) / 100; else cardfix = cardfix * ( 100 - tsd->bonus.long_attack_def_rate ) / 100; +#endif cardfix = cardfix * ( 100 - tsd->bonus.magic_def_rate ) / 100; @@ -1358,6 +1368,22 @@ int64 battle_calc_defense(int attack_type, struct block_list *src, struct block_ return damage; } +// Minstrel/Wanderer number check for chorus skills. +int battle_calc_chorusbonus(struct map_session_data *sd) { + int members = 0; + + if (!sd || !sd->status.party_id) + return 0; + + members = party->foreachsamemap(party->sub_count_chorus, sd, 0); + + if (members < 3) + return 0; // Bonus remains 0 unless 3 or more Minstrel's/Wanderer's are in the party. + if (members > 7) + return 5; // Maximum effect possiable from 7 or more Minstrel's/Wanderer's + return members - 2; // Effect bonus from additional Minstrel's/Wanderer's if not above the max possible +} + int battle_calc_skillratio(int attack_type, struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int skillratio, int flag){ int i; struct status_change *sc, *tsc; @@ -1494,25 +1520,24 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block * Arch Bishop **/ case AB_JUDEX: - skillratio += 180 + 20 * skill_lv; - if (skill_lv > 4) skillratio += 20; + skillratio = 300 + 20 * skill_lv; RE_LVL_DMOD(100); break; case AB_ADORAMUS: - skillratio += 400 + 100 * skill_lv; + skillratio = 500 + 100 * skill_lv; RE_LVL_DMOD(100); break; case AB_DUPLELIGHT_MAGIC: - skillratio += 100 + 20 * skill_lv; + skillratio = 200 + 20 * skill_lv; break; /** * Warlock **/ - case WL_SOULEXPANSION: // MATK [{( Skill Level + 4 ) x 100 ) + ( Caster?s INT )} x ( Caster?s Base Level / 100 )] % - skillratio += 300 + 100 * skill_lv + status_get_int(src); + case WL_SOULEXPANSION: // MATK [{( Skill Level + 4 ) x 100 ) + ( Caster's INT )} x ( Caster's Base Level / 100 )] % + skillratio = 100 * (skill_lv + 4) + st->int_; RE_LVL_DMOD(100); break; - case WL_FROSTMISTY: // MATK [{( Skill Level x 100 ) + 200 } x ( Caster?s Base Level / 100 )] % + case WL_FROSTMISTY: // MATK [{( Skill Level x 100 ) + 200 } x ( Caster's Base Level / 100 )] % skillratio += 100 + 100 * skill_lv; RE_LVL_DMOD(100); break; @@ -1560,7 +1585,7 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block c = 0; memset (p_sd, 0, sizeof(p_sd)); party->foreachsamemap(skill->check_condition_char_sub, sd, 3, &sd->bl, &c, &p_sd, skill_id); - c = ( c > 1 ? rand()%c : 0 ); + c = ( c > 1 ? rnd()%c : 0 ); if( (psd = map->id2sd(p_sd[c])) && pc->checkskill(psd,WL_COMET) > 0 ){ skillratio = skill_lv * 400; //MATK [{( Skill Level x 400 ) x ( Caster's Base Level / 120 )} + 2500 ] % @@ -1577,7 +1602,7 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block skillratio += 100 * flag; break; case WL_EARTHSTRAIN: - skillratio += 1900 + 100 * skill_lv; + skillratio = 2000 + 100 * skill_lv; RE_LVL_DMOD(100); break; case WL_TETRAVORTEX_FIRE: @@ -1590,7 +1615,7 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block case WL_SUMMON_ATK_WATER: case WL_SUMMON_ATK_WIND: case WL_SUMMON_ATK_GROUND: - skillratio = skill_lv * (status->get_lv(src) + ( sd ? sd->status.job_level : 50 ));// This is close to official, but lacking a little info to finalize. [Rytech] + skillratio = (1 + skill_lv) / 2 * (status->get_lv(src) + (sd ? sd->status.job_level : 50)); RE_LVL_DMOD(100); break; case LG_RAYOFGENESIS: @@ -1601,82 +1626,68 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block bandingBonus = 200 * (sd ? skill->check_pc_partner(sd,skill_id,&lv,skill->get_splash(skill_id,skill_lv),0) : 1); skillratio = ((300 * skill_lv) + bandingBonus) * (sd ? sd->status.job_level : 1) / 25; } - break; - case LG_SHIELDSPELL:// [(Casters Base Level x 4) + (Shield MDEF x 100) + (Casters INT x 2)] % - if( sd ) { - skillratio = status->get_lv(src) * 4 + sd->bonus.shieldmdef * 100 + status_get_int(src) * 2; - } else - skillratio += 1900; //2000% break; - case WM_METALICSOUND: - skillratio += 120 * skill_lv + 60 * ( sd? pc->checkskill(sd, WM_LESSON) : 10 ) - 100; + case LG_SHIELDSPELL: + if ( sd && skill_lv == 2 ) // [(Casters Base Level x 4) + (Shield MDEF x 100) + (Casters INT x 2)] % + skillratio = 4 * status->get_lv(src) + 100 * sd->bonus.shieldmdef + 2 * st->int_; + else + skillratio = 0; break; - /*case WM_SEVERE_RAINSTORM: - skillratio += 50 * skill_lv; + case WM_METALICSOUND: + skillratio = 120 * skill_lv + 60 * ( sd? pc->checkskill(sd, WM_LESSON) : 10 ); + RE_LVL_DMOD(100); break; - - WM_SEVERE_RAINSTORM just set a unit place, - refer to WM_SEVERE_RAINSTORM_MELEE to set the formula. - */ case WM_REVERBERATION_MAGIC: - // MATK [{(Skill Level x 100) + 100} x Casters Base Level / 100] % - skillratio += 100 * (sd ? pc->checkskill(sd, WM_REVERBERATION) : 1); + skillratio = 100 * skill_lv + 100; RE_LVL_DMOD(100); break; case SO_FIREWALK: - skillratio = 300; + skillratio = 60 * skill_lv; RE_LVL_DMOD(100); if( sc && sc->data[SC_HEATER_OPTION] ) - skillratio += sc->data[SC_HEATER_OPTION]->val3; + skillratio += sc->data[SC_HEATER_OPTION]->val3 / 2; break; case SO_ELECTRICWALK: - skillratio = 300; + skillratio = 60 * skill_lv; RE_LVL_DMOD(100); if( sc && sc->data[SC_BLAST_OPTION] ) - skillratio += sd ? sd->status.job_level / 2 : 0; + skillratio += sc->data[SC_BLAST_OPTION]->val2 / 2; break; case SO_EARTHGRAVE: - skillratio = ( 200 * ( sd ? pc->checkskill(sd, SA_SEISMICWEAPON) : 10 ) + status_get_int(src) * skill_lv ); + skillratio = st->int_ * skill_lv + 200 * (sd ? pc->checkskill(sd,SA_SEISMICWEAPON) : 1); RE_LVL_DMOD(100); if( sc && sc->data[SC_CURSED_SOIL_OPTION] ) - skillratio += sc->data[SC_CURSED_SOIL_OPTION]->val2; + skillratio += sc->data[SC_CURSED_SOIL_OPTION]->val3 * 5; break; case SO_DIAMONDDUST: - skillratio = ( 200 * ( sd ? pc->checkskill(sd, SA_FROSTWEAPON) : 10 ) + status_get_int(src) * skill_lv ); - RE_LVL_DMOD(100); + skillratio = (st->int_ * skill_lv + 200 * (sd ? pc->checkskill(sd, SA_FROSTWEAPON) : 1)) * status->get_lv(src) / 100; if( sc && sc->data[SC_COOLER_OPTION] ) - skillratio += sc->data[SC_COOLER_OPTION]->val3; + skillratio += sc->data[SC_COOLER_OPTION]->val3 * 5; break; case SO_POISON_BUSTER: - skillratio += 1100 + 300 * skill_lv; + skillratio += 900 + 300 * skill_lv; + RE_LVL_DMOD(100); if( sc && sc->data[SC_CURSED_SOIL_OPTION] ) - skillratio += sc->data[SC_CURSED_SOIL_OPTION]->val2; + skillratio += sc->data[SC_CURSED_SOIL_OPTION]->val3 * 5; break; case SO_PSYCHIC_WAVE: - skillratio += -100 + skill_lv * 70 + (status_get_int(src) * 3); + skillratio = 70 * skill_lv + 3 * st->int_; RE_LVL_DMOD(100); - if( sc ){ - if( sc->data[SC_HEATER_OPTION] ) - skillratio += sc->data[SC_HEATER_OPTION]->val3; - else if(sc->data[SC_COOLER_OPTION] ) - skillratio += sc->data[SC_COOLER_OPTION]->val3; - else if(sc->data[SC_BLAST_OPTION] ) - skillratio += sc->data[SC_BLAST_OPTION]->val2; - else if(sc->data[SC_CURSED_SOIL_OPTION] ) - skillratio += sc->data[SC_CURSED_SOIL_OPTION]->val3; - } + if( sc && ( sc->data[SC_HEATER_OPTION] || sc->data[SC_COOLER_OPTION] + || sc->data[SC_BLAST_OPTION] || sc->data[SC_CURSED_SOIL_OPTION] ) ) + skillratio += skillratio * 20 / 100; break; - case SO_VARETYR_SPEAR: //MATK [{( Endow Tornado skill level x 50 ) + ( Caster INT x Varetyr Spear Skill level )} x Caster Base Level / 100 ] % + case SO_VARETYR_SPEAR: skillratio = status_get_int(src) * skill_lv + ( sd ? pc->checkskill(sd, SA_LIGHTNINGLOADER) * 50 : 0 ); RE_LVL_DMOD(100); if( sc && sc->data[SC_BLAST_OPTION] ) - skillratio += sd ? sd->status.job_level * 5 : 0; + skillratio += sc->data[SC_BLAST_OPTION]->val2 * 5; break; case SO_CLOUD_KILL: - skillratio += -100 + skill_lv * 40; + skillratio = 40 * skill_lv; RE_LVL_DMOD(100); if( sc && sc->data[SC_CURSED_SOIL_OPTION] ) - skillratio += sc->data[SC_CURSED_SOIL_OPTION]->val2; + skillratio += sc->data[SC_CURSED_SOIL_OPTION]->val3; break; case GN_DEMONIC_FIRE: if( skill_lv > 20) @@ -2067,7 +2078,7 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block skillratio += ((skill_lv-1)%5+1) * 100; break; case RK_SONICWAVE: - skillratio += -100 + 100 * (skill_lv + 5); + skillratio = (skill_lv + 5) * 100; skillratio = skillratio * (100 + (status->get_lv(src)-100) / 2) / 100; break; case RK_HUNDREDSPEAR: @@ -2081,20 +2092,20 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block } break; case RK_WINDCUTTER: - skillratio += -100 + 50 * (skill_lv + 2); + skillratio = (skill_lv + 2) * 50; RE_LVL_DMOD(100); break; case RK_IGNITIONBREAK: - i = distance_bl(src,target); - if( i < 2 ) - skillratio += 300 * skill_lv; - else if( i < 4 ) - skillratio += 250 * skill_lv; - else - skillratio += 200 * skill_lv; - skillratio = (skillratio - 100) * (100 + (status->get_lv(src)-100)) / 100; - if( st->rhw.ele == ELE_FIRE ) - skillratio += 100 * skill_lv; + i = distance_bl(src,target); + if( i < 2 ) + skillratio = 300 * skill_lv; + else if( i < 4 ) + skillratio = 250 * skill_lv; + else + skillratio = 200 * skill_lv; + skillratio = skillratio * status->get_lv(src) / 100; + if( st->rhw.ele == ELE_FIRE ) + skillratio += 100 * skill_lv; break; case RK_CRUSHSTRIKE: if( sd ) @@ -2106,10 +2117,10 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block } break; case RK_STORMBLAST: - skillratio += -100 + 100 *(sd ? pc->checkskill(sd,RK_RUNEMASTERY) : 1) + status_get_int(src) / 8; + skillratio = ((sd ? pc->checkskill(sd,RK_RUNEMASTERY) : 1) + status_get_int(src) / 8) * 100; break; case RK_PHANTOMTHRUST: - skillratio += -100 + 50 * skill_lv + 10 * ( sd ? pc->checkskill(sd,KN_SPEARMASTERY) : 10); + skillratio = 50 * skill_lv + 10 * (sd ? pc->checkskill(sd,KN_SPEARMASTERY) : 10); RE_LVL_DMOD(150); break; /** @@ -2128,7 +2139,7 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block RE_LVL_DMOD(120); break; case GC_ROLLINGCUTTER: - skillratio += -50 + 50 * skill_lv; + skillratio = 50 + 50 * skill_lv; RE_LVL_DMOD(100); break; case GC_CROSSRIPPERSLASHER: @@ -2161,127 +2172,142 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block skillratio += 100 + 100 * skill_lv; break; case RA_WUGDASH:// ATK 300% - skillratio += 200; + skillratio = 300; + if( sc && sc->data[SC_DANCE_WITH_WUG] ) + skillratio += 10 * sc->data[SC_DANCE_WITH_WUG]->val1 * (2 + battle->calc_chorusbonus(sd)); break; case RA_WUGSTRIKE: - skillratio += -100 + 200 * skill_lv; + skillratio = 200 * skill_lv; + if( sc && sc->data[SC_DANCE_WITH_WUG] ) + skillratio += 10 * sc->data[SC_DANCE_WITH_WUG]->val1 * (2 + battle->calc_chorusbonus(sd)); break; case RA_WUGBITE: skillratio += 300 + 200 * skill_lv; if ( skill_lv == 5 ) skillratio += 100; break; case RA_SENSITIVEKEEN: - skillratio += 50 * skill_lv; + skillratio = 150 * skill_lv; break; /** * Mechanic **/ case NC_BOOSTKNUCKLE: - skillratio += 100 + 100 * skill_lv + status_get_dex(src); - RE_LVL_DMOD(100); + skillratio = skill_lv * 100 + 200 + st->dex; + RE_LVL_DMOD(120); break; case NC_PILEBUNKER: - skillratio += 200 + 100 * skill_lv + status_get_str(src); + skillratio = skill_lv*100 + 300 + status_get_str(src); RE_LVL_DMOD(100); break; case NC_VULCANARM: - skillratio += -100 + 70 * skill_lv + status_get_dex(src); + skillratio = 70 * skill_lv + status_get_dex(src); RE_LVL_DMOD(100); break; case NC_FLAMELAUNCHER: case NC_COLDSLOWER: - skillratio += 200 + 300 * skill_lv; + skillratio += 200 + 100 * skill_lv + status_get_str(src); RE_LVL_DMOD(100); break; case NC_ARMSCANNON: switch( tst->size ) { - case SZ_SMALL: skillratio += 100 + 500 * skill_lv; break;// Small - case SZ_MEDIUM: skillratio += 100 + 400 * skill_lv; break;// Medium - case SZ_BIG: skillratio += 100 + 300 * skill_lv; break;// Large + case SZ_MEDIUM: skillratio = 300 + 350 * skill_lv; break; // Medium + case SZ_SMALL: skillratio = 300 + 400 * skill_lv; break; // Small + case SZ_BIG: skillratio = 300 + 300 * skill_lv; break; // Large } - RE_LVL_DMOD(100); - //NOTE: Their's some other factors that affects damage, but not sure how exactly. Will recheck one day. [Rytech] + RE_LVL_DMOD(120); break; case NC_AXEBOOMERANG: - skillratio += 60 + 40 * skill_lv; + skillratio = 250 + 50 * skill_lv; if( sd ) { short index = sd->equip_index[EQI_HAND_R]; if( index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_WEAPON ) - skillratio += sd->inventory_data[index]->weight / 10;// Weight is divided by 10 since 10 weight in coding make 1 whole actural weight. [Rytech] + skillratio += sd->inventory_data[index]->weight / 10; } RE_LVL_DMOD(100); break; case NC_POWERSWING: - skillratio += 80 + 20 * skill_lv + status_get_str(src) + status_get_dex(src); - RE_LVL_DMOD(100); + skillratio = 300 + 100*skill_lv + ( status_get_str(src)+status_get_dex(src) ) * status->get_lv(src) / 100; break; case NC_AXETORNADO: - skillratio += 100 + 100 * skill_lv + status_get_vit(src); + skillratio = 200 + 100 * skill_lv + st->vit; RE_LVL_DMOD(100); + if( st->rhw.ele == ELE_WIND ) + skillratio = skillratio * 125 / 100; + if ( distance_bl(src, target) > 2 ) // Will deal 75% damage outside of 5x5 area. + skillratio = skillratio * 75 / 100; break; case SC_FATALMENACE: - skillratio += 100 * skill_lv; + skillratio = 100 * (skill_lv+1) * status->get_lv(src) / 100; break; case SC_TRIANGLESHOT: - skillratio += 270 + 30 * skill_lv; + skillratio = ( 300 + (skill_lv-1) * status_get_agi(src)/2 ) * status->get_lv(src) / 120; break; case SC_FEINTBOMB: - skillratio += 100 + 100 * skill_lv; + skillratio = (skill_lv+1) * (st->dex/2) * (sd?sd->status.job_level:50)/10 * status->get_lv(src) / 120; break; - case LG_CANNONSPEAR:// Stimated formula. Still need confirm it. - skillratio += -100 + (50 + status_get_str(src)) * skill_lv; + case LG_CANNONSPEAR: + skillratio = (50 + st->str) * skill_lv; RE_LVL_DMOD(100); break; case LG_BANISHINGPOINT: - skillratio += -100 + ((50 * skill_lv) + (30 * ((sd)?pc->checkskill(sd,SM_BASH):1))); + skillratio = 50 * skill_lv + 30 * (sd ? pc->checkskill(sd,SM_BASH) : 10); RE_LVL_DMOD(100); break; case LG_SHIELDPRESS: - skillratio += 60 + 43 * skill_lv; + skillratio = 150 * skill_lv + st->str; + if( sd ) { + short index = sd->equip_index[EQI_HAND_L]; + if( index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_ARMOR ) + skillratio += sd->inventory_data[index]->weight / 10; + } RE_LVL_DMOD(100); break; case LG_PINPOINTATTACK: - skillratio += -100 + ((100 * skill_lv) + (10 * status_get_agi(src)) ); - RE_LVL_DMOD(100); + skillratio = 100 * skill_lv + 5 * st->agi; + RE_LVL_DMOD(120); break; case LG_RAGEBURST: - if( sd && sd->spiritball_old ) - skillratio += -100 + (sd->spiritball_old * 200); - else - skillratio += -100 + 15 * 200; + if( sc ){ + skillratio += -100 + (status_get_max_hp(src) - status_get_hp(src)) / 100 + sc->fv_counter * 200; + clif->millenniumshield(src, (sc->fv_counter = 0)); + } RE_LVL_DMOD(100); break; - case LG_SHIELDSPELL:// [(Casters Base Level x 4) + (Shield DEF x 10) + (Casters VIT x 2)] % - if( sd ) { + case LG_SHIELDSPELL: + if ( sd && skill_lv == 1 ) { struct item_data *shield_data = sd->inventory_data[sd->equip_index[EQI_HAND_L]]; - skillratio += -100 + status->get_lv(src) * 4 + status_get_vit(src) * 2; if( shield_data ) - skillratio += shield_data->def * 10; - } else - skillratio += 2400; //2500% + skillratio = 4 * status->get_lv(src) + 10 * shield_data->def + 2 * st->vit; + } + else + skillratio = 0; // Prevents ATK damage from being done on LV 2 usage since LV 2 us MATK. [Rytech] break; case LG_MOONSLASHER: - skillratio += -100 + (120 * skill_lv + ((sd) ? pc->checkskill(sd,LG_OVERBRAND) : 5) * 80); + skillratio = 120 * skill_lv + 80 * (sd ? pc->checkskill(sd,LG_OVERBRAND) : 5); RE_LVL_DMOD(100); break; case LG_OVERBRAND: - skillratio += -100 + 400 * skill_lv + (pc->checkskill(sd,CR_SPEARQUICKEN) * 30); - RE_LVL_DMOD(100); + skillratio += -100 + 50 * (((sd) ? pc->checkskill(sd,CR_SPEARQUICKEN) : 1) + 8 * skill_lv); + RE_LVL_DMOD(150); break; case LG_OVERBRAND_BRANDISH: - skillratio += -100 + 300 * skill_lv + (2 * (status_get_str(src) + status_get_dex(src)) / 3); - RE_LVL_DMOD(100); + skillratio += -100 + 300 * skill_lv + status_get_str(src) + status_get_dex(src); + RE_LVL_DMOD(150); break; case LG_OVERBRAND_PLUSATK: - skillratio += -100 + 150 * skill_lv; + skillratio += -100 + 100 * skill_lv; RE_LVL_DMOD(100); break; case LG_RAYOFGENESIS: - skillratio += 200 + 300 * skill_lv; + skillratio = 300 + 300 * skill_lv; RE_LVL_DMOD(100); break; case LG_EARTHDRIVE: - skillratio = (skillratio + 100) * skill_lv; + if( sd ) { + short index = sd->equip_index[EQI_HAND_L]; + if( index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_ARMOR ) + skillratio = (1 + skill_lv) * sd->inventory_data[index]->weight / 10; + } RE_LVL_DMOD(100); break; case LG_HESPERUSLIT: @@ -2327,15 +2353,17 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block break; case SR_RAMPAGEBLASTER: skillratio += 20 * skill_lv * (sd?sd->spiritball_old:5) - 100; - if( sc && sc->data[SC_EXPLOSIONSPIRITS] ){ + if( sc && sc->data[SC_EXPLOSIONSPIRITS] ) { skillratio += sc->data[SC_EXPLOSIONSPIRITS]->val1 * 20; RE_LVL_DMOD(120); - }else + } else { RE_LVL_DMOD(150); + } break; case SR_KNUCKLEARROW: - if( flag&4 ){ // ATK [(Skill Level x 150) + (1000 x Target current weight / Maximum weight) + (Target Base Level x 5) x (Caster Base Level / 150)] % - skillratio += -100 + 150 * skill_lv + status->get_lv(target) * 5 * (status->get_lv(src) / 100) ; + if ( flag&4 || map->list[src->m].flag.gvg_castle || tst->mode&MD_BOSS ) { + // ATK [(Skill Level x 150) + (1000 x Target current weight / Maximum weight) + (Target Base Level x 5) x (Caster Base Level / 150)] % + skillratio = 150 * skill_lv + status->get_lv(target) * 5 * (status->get_lv(src) / 100) ; if( tsd && tsd->weight ) skillratio += 100 * (tsd->weight / tsd->max_weight); }else // ATK [(Skill Level x 100 + 500) x Caster Base Level / 100] % @@ -2343,7 +2371,7 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block RE_LVL_DMOD(100); break; case SR_WINDMILL: // ATK [(Caster Base Level + Caster DEX) x Caster Base Level / 100] % - skillratio += -100 + status->get_lv(src) + status_get_dex(src); + skillratio = status->get_lv(src) + status_get_dex(src); RE_LVL_DMOD(100); break; case SR_GATEOFHELL: @@ -2369,66 +2397,69 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block RE_LVL_DMOD(100); break; case WM_REVERBERATION_MELEE: - // ATK [{(Skill Level x 100) + 300} x Caster Base Level / 100] - skillratio += 200 + 100 * pc->checkskill(sd, WM_REVERBERATION); + skillratio += 200 + 100 * skill_lv; RE_LVL_DMOD(100); break; case WM_SEVERE_RAINSTORM_MELEE: - //ATK [{(Caster DEX + AGI) x (Skill Level / 5)} x Caster Base Level / 100] % - skillratio += -100 + (status_get_dex(src) + status_get_agi(src)) * (skill_lv * 2); + skillratio = (st->agi + st->dex) * skill_lv / 5; RE_LVL_DMOD(100); - skillratio /= 10; break; case WM_GREAT_ECHO: - skillratio += 800 + 100 * skill_lv; - if( sd ) { // Still need official value [pakpil] - uint16 lv = skill_lv; - skillratio += 100 * skill->check_pc_partner(sd,skill_id,&lv,skill->get_splash(skill_id,skill_lv),0); - } - break; - case WM_SOUND_OF_DESTRUCTION: - skillratio += 400; + { + int chorusbonus = battle->calc_chorusbonus(sd); + skillratio += 300 + 200 * skill_lv; + //Chorus bonus dont count the first 2 Minstrel's/Wanderer's and only increases when their's 3 or more. [Rytech] + if (chorusbonus >= 1 && chorusbonus <= 5) + skillratio += 100<<(chorusbonus-1); // 1->100; 2->200; 3->400; 4->800; 5->1600 + RE_LVL_DMOD(100); + } break; case GN_CART_TORNADO: - // ATK [( Skill Level x 50 ) + ( Cart Weight / ( 150 - Caster Base STR ))] + ( Cart Remodeling Skill Level x 50 )] % - skillratio += -100 + 50 * skill_lv; - if( sd && sd->cart_weight) - skillratio += sd->cart_weight/10 / max(150-status_get_str(src),1) + pc->checkskill(sd, GN_REMODELING_CART) * 50; + { + int strbonus = st->str; // FIXME Supposed to take only base STR, but current code wont allow that. So well just take STR for now. [Rytech] + if ( strbonus > 130 ) // Max base stat limit on official is 130. So well allow no higher then 125 STR here. This limit prevents + strbonus = 130; // the division from going any lower then 30 so the server wont divide by 0 if someone has 150 STR. + skillratio = 50 * skill_lv + (sd ? sd->cart_weight : battle_config.max_cart_weight) / 10 / (150 - strbonus) + 50 * (sd ? pc->checkskill(sd, GN_REMODELING_CART) : 5); + } break; case GN_CARTCANNON: - // ATK [{( Cart Remodeling Skill Level x 50 ) x ( INT / 40 )} + ( Cart Cannon Skill Level x 60 )] % - skillratio += -100 + 60 * skill_lv; - if( sd ) skillratio += pc->checkskill(sd, GN_REMODELING_CART) * 50 * (status_get_int(src) / 40); + skillratio = 50 * (sd ? pc->checkskill(sd, GN_REMODELING_CART) : 5) * (st->int_ / 40) + 60 * skill_lv; break; case GN_SPORE_EXPLOSION: - skillratio += 200 + 100 * skill_lv; - break; + skillratio = 100 * skill_lv + (200 + st->int_) * status->get_lv(src) / 100; case GN_CRAZYWEED_ATK: skillratio += 400 + 100 * skill_lv; break; case GN_SLINGITEM_RANGEMELEEATK: if( sd ) { switch( sd->itemid ) { - case 13260: // Apple Bomob - case 13261: // Coconut Bomb - case 13262: // Melon Bomb - case 13263: // Pinapple Bomb - skillratio += 400; // Unconfirded + case ITEMID_APPLE_BOMB: + skillratio = st->str + st->dex + 300; + break; + case ITEMID_MELON_BOMB: + skillratio = st->str + st->dex + 500; break; - case 13264: // Banana Bomb 2000% - skillratio += 1900; + case ITEMID_COCONUT_BOMB: + case ITEMID_PINEAPPLE_BOMB: + case ITEMID_BANANA_BOMB: + skillratio = st->str + st->dex + 800; + break; + case ITEMID_BLACK_LUMP: + skillratio = (st->str + st->agi + st->dex) / 3; // Black Lump + break; + case ITEMID_BLACK_HARD_LUMP: + skillratio = (st->str + st->agi + st->dex) / 2; // Hard Black Lump + break; + case ITEMID_VERY_HARD_LUMP: + skillratio = st->str + st->agi + st->dex; // Extremely Hard Black Lump break; - case 13265: skillratio -= 75; break; // Black Lump 25% - case 13266: skillratio -= 25; break; // Hard Black Lump 75% - case 13267: skillratio += 100; break; // Extremely Hard Black Lump 200% } - } else - skillratio += 300; // Bombs + } break; case SO_VARETYR_SPEAR://ATK [{( Striking Level x 50 ) + ( Varetyr Spear Skill Level x 50 )} x Caster Base Level / 100 ] % skillratio += -100 + 50 * skill_lv + ( sd ? pc->checkskill(sd, SO_STRIKING) * 50 : 0 ); if( sc && sc->data[SC_BLAST_OPTION] ) - skillratio += sd ? sd->status.job_level * 5 : 0; + skillratio += (sd ? sd->status.job_level * 5 : 0); break; // Physical Elemantal Spirits Attack Skills case EL_CIRCLE_OF_FIRE: @@ -2491,17 +2522,19 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block } //Skill damage modifiers that stack linearly if(sc && skill_id != PA_SACRIFICE){ +#ifdef RENEWAL_EDP if( sc->data[SC_EDP] ){ if( skill_id == AS_SONICBLOW || skill_id == GC_COUNTERSLASH || skill_id == GC_CROSSIMPACT ) skillratio >>= 1; } +#endif if(sc->data[SC_OVERTHRUST]) skillratio += sc->data[SC_OVERTHRUST]->val3; if(sc->data[SC_OVERTHRUSTMAX]) skillratio += sc->data[SC_OVERTHRUSTMAX]->val2; - if(sc->data[SC_BERSERK] || sc->data[SC_SATURDAY_NIGHT_FEVER]) + if(sc->data[SC_BERSERK]) #ifndef RENEWAL skillratio += 100; #else @@ -2526,7 +2559,7 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block *------------------------------------------*/ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damage *d,int64 damage,uint16 skill_id,uint16 skill_lv) { struct map_session_data *sd = NULL; - struct status_change *sc; + struct status_change *sc, *tsc; struct status_change_entry *sce; int div_ = d->div_, flag = d->flag; @@ -2536,9 +2569,6 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam return 0; if( battle_config.ksprotection && mob->ksprotected(src, bl) ) return 0; - if( map->getcell(bl->m, bl->x, bl->y, CELL_CHKMAELSTROM) && skill->get_type(skill_id) != BF_MISC - && skill->get_casttype(skill_id) == CAST_GROUND ) - return 0; if (bl->type == BL_PC) { sd=(struct map_session_data *)bl; //Special no damage states @@ -2555,6 +2585,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam } sc = status->get_sc(bl); + tsc = status->get_sc(src); if( sc && sc->data[SC_INVINCIBLE] && !sc->data[SC_INVINCIBLEOFF] ) return 1; @@ -2595,30 +2626,38 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam if( sc->data[SC_SAFETYWALL] && (flag&(BF_SHORT|BF_MAGIC))==BF_SHORT ) { struct skill_unit_group* group = skill->id2group(sc->data[SC_SAFETYWALL]->val3); - uint16 skill_id = sc->data[SC_SAFETYWALL]->val2; + uint16 src_skill_id = sc->data[SC_SAFETYWALL]->val2; if (group) { - if(skill_id == MH_STEINWAND){ - if (--group->val2<=0) - skill->del_unitgroup(group,ALC_MARK); - d->dmg_lv = ATK_BLOCK; - return 0; + d->dmg_lv = ATK_BLOCK; + if(src_skill_id == MH_STEINWAND){ + if (--group->val2<=0) + skill->del_unitgroup(group,ALC_MARK); + if( (group->val3 - damage) > 0 ) + group->val3 -= (int)cap_value(damage, INT_MIN, INT_MAX); + else + skill->del_unitgroup(group,ALC_MARK); + return 0; + } + if( skill_id == SO_ELEMENTAL_SHIELD ) { + if ( ( group->val2 - damage) > 0 ) { + group->val2 -= (int)cap_value(damage,INT_MIN,INT_MAX); + } else + skill->del_unitgroup(group,ALC_MARK); + return 0; } /** * in RE, SW possesses a lifetime equal to 3 times the caster's health **/ #ifdef RENEWAL - d->dmg_lv = ATK_BLOCK; if ( ( group->val2 - damage) > 0 ) { group->val2 -= (int)cap_value(damage,INT_MIN,INT_MAX); } else skill->del_unitgroup(group,ALC_MARK); - return 0; #else if (--group->val2<=0) skill->del_unitgroup(group,ALC_MARK); - d->dmg_lv = ATK_BLOCK; - return 0; #endif + return 0; } status_change_end(bl, SC_SAFETYWALL, INVALID_TIMER); } @@ -2627,11 +2666,26 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam d->dmg_lv = ATK_BLOCK; return 0; } + if( sc->data[SC_NEUTRALBARRIER] && (flag&(BF_MAGIC|BF_LONG)) == BF_LONG && skill_id != CR_ACIDDEMONSTRATION ) { + d->dmg_lv = ATK_BLOCK; + return 0; + } + if( sc->data[SC__MAELSTROM] && (flag&BF_MAGIC) && skill_id && (skill->get_inf(skill_id)&INF_GROUND_SKILL) ) { + // {(Maelstrom Skill LevelxAbsorbed Skill Level)+(Caster's Job/5)}/2 + int sp = (sc->data[SC__MAELSTROM]->val1 * skill_lv + sd->status.job_level / 5) / 2; + status->heal(bl, 0, sp, 3); + d->dmg_lv = ATK_BLOCK; + return 0; + } if( sc->data[SC_WEAPONBLOCKING] && flag&(BF_SHORT|BF_WEAPON) && rnd()%100 < sc->data[SC_WEAPONBLOCKING]->val2 ) { clif->skill_nodamage(bl,src,GC_WEAPONBLOCKING,1,1); d->dmg_lv = ATK_BLOCK; - sc_start2(bl,SC_COMBOATTACK,100,GC_WEAPONBLOCKING,src->id,2000); + sc_start2(src,bl,SC_COMBOATTACK,100,GC_WEAPONBLOCKING,src->id,2000); + return 0; + } + if( sc->data[SC_HOVERING] && skill_id && (skill->get_inf(skill_id)&INF_GROUND_SKILL || skill_id == SR_WINDMILL) ) { + d->dmg_lv = ATK_BLOCK; return 0; } if( (sce=sc->data[SC_AUTOGUARD]) && flag&BF_WEAPON && !(skill->get_nk(skill_id)&NK_NO_CARDFIX_ATK) && rnd()%100 < sce->val2 ) @@ -2649,6 +2703,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam if(sc->data[SC_CR_SHRINK] && rnd()%100<5*sce->val1) skill->blown(bl,src,skill->get_blewcount(CR_SHRINK,1),-1,0); + d->dmg_lv = ATK_MISS; return 0; } @@ -2656,12 +2711,11 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam clif->skill_nodamage(bl, bl, RK_MILLENNIUMSHIELD, 1, 1); sce->val3 -= (int)cap_value(damage,INT_MIN,INT_MAX); // absorb damage d->dmg_lv = ATK_BLOCK; - sc_start(bl,SC_STUN,15,0,skill->get_time2(RK_MILLENNIUMSHIELD,sce->val1)); // There is a chance to be stuned when one shield is broken. + sc_start(src,bl,SC_STUN,15,0,skill->get_time2(RK_MILLENNIUMSHIELD,sce->val1)); // There is a chance to be stuned when one shield is broken. if( sce->val3 <= 0 ) { // Shield Down sce->val2--; if( sce->val2 > 0 ) { - if( sd ) - clif->millenniumshield(sd,sce->val2); + clif->millenniumshield(bl,sce->val2); sce->val3 = 1000; // Next Shield } else status_change_end(bl,SC_MILLENNIUMSHIELD,INVALID_TIMER); // All shields down @@ -2682,21 +2736,16 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam if (sd && pc_issit(sd)) pc->setstand(sd); //Stand it to dodge. clif->skill_nodamage(bl,bl,TK_DODGE,1,1); if (!sc->data[SC_COMBOATTACK]) - sc_start4(bl, SC_COMBOATTACK, 100, TK_JUMPKICK, src->id, 1, 0, 2000); + sc_start4(src, bl, SC_COMBOATTACK, 100, TK_JUMPKICK, src->id, 1, 0, 2000); return 0; } - if(sc->data[SC_HERMODE] && flag&BF_MAGIC) + if((sc->data[SC_HERMODE] || sc->data[SC_HOVERING]) && flag&BF_MAGIC) return 0; if(sc->data[SC_NJ_TATAMIGAESHI] && (flag&(BF_MAGIC|BF_LONG)) == BF_LONG) return 0; - if( sc->data[SC_NEUTRALBARRIER] && (flag&(BF_MAGIC|BF_LONG)) == (BF_MAGIC|BF_LONG) ) { - d->dmg_lv = ATK_MISS; - return 0; - } - if((sce=sc->data[SC_KAUPE]) && rnd()%100 < sce->val2) { //Kaupe blocks damage (skill or otherwise) from players, mobs, homuns, mercenaries. clif->specialeffect(bl, 462, AREA); @@ -2804,7 +2853,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam (flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON)) damage -= damage * 20 / 100; - if(sc->data[SC_FOGWALL] && skill_id != RK_DRAGONBREATH && skill_id != RK_DRAGONBREATH_WATER) { + if(sc->data[SC_FOGWALL]) { if(flag&BF_SKILL) //25% reduction damage -= damage * 25 / 100; else if ((flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON)) @@ -2832,11 +2881,13 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam sce->val3&flag && sce->val4&flag) damage -= damage * sc->data[SC_ARMOR]->val2 / 100; + if( sc->data[SC_ENERGYCOAT] && (skill_id == GN_HELLS_PLANT_ATK || #ifdef RENEWAL - if(sc->data[SC_ENERGYCOAT] && (flag&BF_WEAPON || flag&BF_MAGIC) && skill_id != WS_CARTTERMINATION) + ((flag&BF_WEAPON || flag&BF_MAGIC) && skill_id != WS_CARTTERMINATION) #else - if(sc->data[SC_ENERGYCOAT] && (flag&BF_WEAPON && skill_id != WS_CARTTERMINATION)) + (flag&BF_WEAPON && skill_id != WS_CARTTERMINATION) #endif + ) ) { struct status_data *sstatus = status->get_status_data(bl); int per = 100*sstatus->sp / sstatus->max_sp -1; //100% should be counted as the 80~99% interval @@ -2857,6 +2908,9 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam skill->castend_damage_id(bl,src,MH_MAGMA_FLOW,sce->val1,timer->gettick(),0); } + if( sc->data[SC_DARKCROW] && (flag&(BF_SHORT|BF_MAGIC)) == BF_SHORT ) + damage += damage * sc->data[SC_DARKCROW]->val2 / 100; + if( (sce = sc->data[SC_STONEHARDSKIN]) && flag&(BF_SHORT|BF_WEAPON) && damage > 0 ) { sce->val2 -= (int)cap_value(damage,INT_MIN,INT_MAX); if( src->type == BL_PC ) { @@ -2867,7 +2921,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam skill->break_equip(src, EQP_WEAPON, 3000, BCT_SELF); // 30% chance to reduce monster's ATK by 25% for 10 seconds. if( src->type == BL_MOB ) - sc_start(src, SC_NOEQUIPWEAPON, 30, 0, skill->get_time2(RK_STONEHARDSKIN, sce->val1)); + sc_start(bl,src, SC_NOEQUIPWEAPON, 30, 0, skill->get_time2(RK_STONEHARDSKIN, sce->val1)); if( sce->val2 <= 0 ) status_change_end(bl, SC_STONEHARDSKIN, INVALID_TIMER); } @@ -2927,36 +2981,17 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam rnd()%100 < sce->val3) status->heal(src, damage*sce->val4/100, 0, 3); - if( sd && (sce = sc->data[SC_FORCEOFVANGUARD]) && flag&BF_WEAPON && rnd()%100 < sce->val2 ) - pc->addspiritball(sd,skill->get_time(LG_FORCEOFVANGUARD,sce->val1),sce->val3); + if( (sce = sc->data[SC_FORCEOFVANGUARD]) && flag&BF_WEAPON + && rnd()%100 < sce->val2 && sc->fv_counter <= sce->val3 ) + clif->millenniumshield(bl, sc->fv_counter++); + if (sc->data[SC_STYLE_CHANGE] && rnd()%2) { TBL_HOM *hd = BL_CAST(BL_HOM,bl); if (hd) homun->addspiritball(hd, 10); //add a sphere } - if( sc->data[SC__DEADLYINFECT] && damage > 0 && rnd()%100 < 65 + 5 * sc->data[SC__DEADLYINFECT]->val1 ) + if( sc->data[SC__DEADLYINFECT] && flag&BF_SHORT && damage > 0 && rnd()%100 < 30 + 10 * sc->data[SC__DEADLYINFECT]->val1 && !is_boss(src) ) status->change_spread(bl, src); // Deadly infect attacked side - - if( sc && sc->data[SC__SHADOWFORM] ) { - struct block_list *s_bl = map->id2bl(sc->data[SC__SHADOWFORM]->val2); - if( !s_bl || s_bl->m != bl->m ) { // If the shadow form target is not present remove the sc. - status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER); - } else if( status->isdead(s_bl) || !battle->check_target(src,s_bl,BCT_ENEMY)) { // If the shadow form target is dead or not your enemy remove the sc in both. - status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER); - if( s_bl->type == BL_PC ) - ((TBL_PC*)s_bl)->shadowform_id = 0; - } else { - if( (--sc->data[SC__SHADOWFORM]->val3) < 0 ) { // If you have exceded max hits supported, remove the sc in both. - status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER); - if( s_bl->type == BL_PC ) - ((TBL_PC*)s_bl)->shadowform_id = 0; - } else { - status->damage(bl, s_bl, damage, 0, clif->damage(s_bl, s_bl, timer->gettick(), 500, 500, damage, -1, 0, 0), 0); - return ATK_NONE; - } - } - } - } //SC effects from caster side. @@ -2986,10 +3021,19 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam break; } } - if( sc->data[SC_POISONINGWEAPON] && skill_id != GC_VENOMPRESSURE && (flag&BF_WEAPON) && damage > 0 && rnd()%100 < sc->data[SC_POISONINGWEAPON]->val3 ) - sc_start(bl,sc->data[SC_POISONINGWEAPON]->val2,100,sc->data[SC_POISONINGWEAPON]->val1,skill->get_time2(GC_POISONINGWEAPON, 1)); - if( sc->data[SC__DEADLYINFECT] && damage > 0 && rnd()%100 < 65 + 5 * sc->data[SC__DEADLYINFECT]->val1 ) + if( tsc->data[SC_POISONINGWEAPON] ) { + short rate = 100; + struct status_data *tstatus = status->get_status_data(bl); + if ( !(flag&BF_SKILL) && (flag&BF_WEAPON) && damage > 0 && rnd()%100 < tsc->data[SC_POISONINGWEAPON]->val3 ) { + if ( tsc->data[SC_POISONINGWEAPON]->val1 == 9 ) // Oblivion Curse gives a 2nd success chance after the 1st one passes which is reduceable. [Rytech] + rate = 100 - tstatus->int_ * 4 / 5; + sc_start(src,bl,tsc->data[SC_POISONINGWEAPON]->val2,rate,tsc->data[SC_POISONINGWEAPON]->val1,skill->get_time2(GC_POISONINGWEAPON,1) - (tstatus->vit + tstatus->luk) / 2 * 1000); + } + } + if( sc->data[SC__DEADLYINFECT] && flag&BF_SHORT && damage > 0 && rnd()%100 < 30 + 10 * sc->data[SC__DEADLYINFECT]->val1 && !is_boss(src) ) status->change_spread(src, bl); + if (sc->data[SC_SHIELDSPELL_REF] && sc->data[SC_SHIELDSPELL_REF]->val1 == 1 && damage > 0) + skill->break_equip(bl,EQP_ARMOR,10000,BCT_ENEMY ); if (sc->data[SC_STYLE_CHANGE] && rnd()%2) { TBL_HOM *hd = BL_CAST(BL_HOM,bl); if (hd) homun->addspiritball(hd, 10); @@ -3117,6 +3161,7 @@ int64 battle_calc_gvg_damage(struct block_list *src,struct block_list *bl,int64 case HW_GRAVITATION: case NJ_ZENYNAGE: case KO_MUCHANAGE: + case NC_SELFDESTRUCTION: break; default: /* Uncomment if you want god-mode Emperiums at 100 defense. [Kisuka] @@ -3205,7 +3250,7 @@ int battle_blewcount_bonus(struct map_session_data *sd, uint16 skill_id) { return 0; } //For quick div adjustment. -#define damage_div_fix(dmg, div) { if (div > 1) (dmg)*=div; else if (div < 0) (div)*=-1; } +#define damage_div_fix(dmg, div) do { if ((div) > 1) (dmg)*=(div); else if ((div) < 0) (div)*=-1; } while(0) /*========================================== * battle_calc_magic_attack [DracoRPG] *------------------------------------------*/ @@ -3227,11 +3272,9 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list memset(&ad,0,sizeof(ad)); memset(&flag,0,sizeof(flag)); - if(src==NULL || target==NULL) - { - nullpo_info(NLP_MARK); - return ad; - } + nullpo_retr(ad, src); + nullpo_retr(ad, target); + //Initial Values ad.damage = 1; ad.div_=skill->get_num(skill_id,skill_lv); @@ -3279,11 +3322,8 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list //Skill Range Criteria ad.flag |= battle->range_type(src, target, skill_id, skill_lv); flag.infdef=(tstatus->mode&MD_PLANT?1:0); - if( target->type == BL_SKILL){ - TBL_SKILL *su = (TBL_SKILL*)target; - if( su->group && (su->group->skill_id == WM_REVERBERATION || su->group->skill_id == WM_POEMOFNETHERWORLD) ) - flag.infdef = 1; - } + if( !flag.infdef && target->type == BL_SKILL && ((TBL_SKILL*)target)->group->unit_id == UNT_REVERBERATION ) + flag.infdef = 1; // Reberberation takes 1 damage switch(skill_id) { case MG_FIREWALL: @@ -3321,22 +3361,24 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list ad.damage = 0; //reinitialize.. #endif //MATK_RATE scales the damage. 100 = no change. 50 is halved, 200 is doubled, etc -#define MATK_RATE( a ) { ad.damage= ad.damage*(a)/100; } +#define MATK_RATE( a ) ( ad.damage= ad.damage*(a)/100 ) //Adds dmg%. 100 = +100% (double) damage. 10 = +10% damage -#define MATK_ADDRATE( a ) { ad.damage+= ad.damage*(a)/100; } +#define MATK_ADDRATE( a ) ( ad.damage+= ad.damage*(a)/100 ) //Adds an absolute value to damage. 100 = +100 damage -#define MATK_ADD( a ) { ad.damage+= a; } +#define MATK_ADD( a ) ( ad.damage+= (a) ) switch (skill_id) { //Calc base damage according to skill case AL_HEAL: case PR_BENEDICTIO: case PR_SANCTUARY: + ad.damage = skill->calc_heal(src, target, skill_id, skill_lv, false); + break; /** * Arch Bishop **/ case AB_HIGHNESSHEAL: - ad.damage = skill->calc_heal(src, target, skill_id, skill_lv, false); + ad.damage = skill->calc_heal(src, target, AL_HEAL, 10, false) * ( 17 + 3 * skill_lv ) / 10; break; case PR_ASPERSIO: ad.damage = 40; @@ -3351,7 +3393,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list ad.damage = tstatus->hp; else { #ifdef RENEWAL - MATK_ADD(status->get_matk(src, 2)); + MATK_ADD(status->get_matk(src, 2)); #else ad.damage = status->get_lv(src) + sstatus->int_ + skill_lv * 10; #endif @@ -3365,9 +3407,9 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list **/ case AB_RENOVATIO: //Damage calculation from iRO wiki. [Jobbie] - ad.damage = (int)((15 * status->get_lv(src)) + (1.5 * sstatus->int_)); + ad.damage = status->get_lv(src) * 10 + sstatus->int_; break; - default: { + default: { MATK_ADD( status->get_matk(src, 2) ); if (nk&NK_SPLASHSPLIT) { // Divide MATK in case of multiple targets skill @@ -3379,14 +3421,14 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list if (sc){ if( sc->data[SC_TELEKINESIS_INTENSE] && s_ele == ELE_GHOST ) - skillratio += sc->data[SC_TELEKINESIS_INTENSE]->val3; + ad.damage += sc->data[SC_TELEKINESIS_INTENSE]->val3; } switch(skill_id){ case MG_FIREBOLT: case MG_COLDBOLT: case MG_LIGHTNINGBOLT: if ( sc && sc->data[SC_SPELLFIST] && mflag&BF_SHORT ) { - skillratio += (sc->data[SC_SPELLFIST]->val4 * 100) + (sc->data[SC_SPELLFIST]->val2 * 100) - 100;// val4 = used bolt level, val2 = used spellfist level. [Rytech] + skillratio = sc->data[SC_SPELLFIST]->val2 * 50 + sc->data[SC_SPELLFIST]->val4 * 100;// val4 = used bolt level, val2 = used spellfist level. [Rytech] ad.div_ = 1;// ad mods, to make it work similar to regular hits [Xazax] ad.flag = BF_WEAPON|BF_SHORT; ad.type = 0; @@ -3426,11 +3468,36 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list ad.damage = battle->calc_cardfix(BF_MAGIC, src, target, nk, s_ele, 0, ad.damage, 0, ad.flag); #endif if(sd) { + uint16 rskill;/* redirect skill */ //Damage bonuses if ((i = pc->skillatk_bonus(sd, skill_id))) ad.damage += ad.damage*i/100; - - if( (i = battle->adjust_skill_damage(src->m,skill_id)) ) + switch(skill_id){ + case WL_CHAINLIGHTNING_ATK: + rskill = WL_CHAINLIGHTNING; + break; + case AB_DUPLELIGHT_MAGIC: + rskill = AB_DUPLELIGHT; + break; + case WL_TETRAVORTEX_FIRE: + case WL_TETRAVORTEX_WATER: + case WL_TETRAVORTEX_WIND: + case WL_TETRAVORTEX_GROUND: + rskill = WL_TETRAVORTEX; + break; + case WL_SUMMON_ATK_FIRE: + case WL_SUMMON_ATK_WIND: + case WL_SUMMON_ATK_WATER: + case WL_SUMMON_ATK_GROUND: + rskill = WL_RELEASE; + break; + case WM_REVERBERATION_MAGIC: + rskill = WM_REVERBERATION; + break; + default: + rskill = skill_id; + } + if( (i = battle->adjust_skill_damage(src->m,rskill)) ) MATK_RATE(i); //Ignore Defense? @@ -3515,6 +3582,9 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list } return ad; +#undef MATK_RATE +#undef MATK_ADDRATE +#undef MATK_ADD } /*========================================== @@ -3536,10 +3606,8 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list * memset(&md,0,sizeof(md)); - if( src == NULL || target == NULL ){ - nullpo_info(NLP_MARK); - return md; - } + nullpo_retr(md, src); + nullpo_retr(md, target); //Some initial values md.amotion=skill->get_inf(skill_id)&INF_GROUND_SKILL?0:sstatus->amotion; @@ -3657,12 +3725,12 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list * md.damage = 7 * md.damage / 20; }*/ }else{ - float vitfactor = 0.0f, temp; + float vitfactor = 0.0f, ftemp; if( (vitfactor=(status_get_vit(target)-120.0f)) > 0) vitfactor = (vitfactor * (matk + atk) / 10) / status_get_vit(target); - temp = max(0, vitfactor) + (targetVit * (matk + atk)) / 10; - md.damage = (int64)(temp * 70 * skill_lv / 100); + ftemp = max(0, vitfactor) + (targetVit * (matk + atk)) / 10; + md.damage = (int64)(ftemp * 70 * skill_lv / 100); } md.damage -= totaldef; } @@ -3730,7 +3798,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list * case RK_DRAGONBREATH_WATER: md.damage = ((status_get_hp(src) / 50) + (status_get_max_sp(src) / 4)) * skill_lv; RE_LVL_MDMOD(150); - if (sd) md.damage = md.damage * (100 + 5 * (pc->checkskill(sd,RK_DRAGONTRAINING) - 1)) / 100; + if (sd) md.damage = md.damage * (95 + 5 * pc->checkskill(sd,RK_DRAGONTRAINING)) / 100; md.flag |= BF_LONG|BF_WEAPON; break; /** @@ -3752,6 +3820,10 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list * md.damage = md.damage * 200 / (skill_id == RA_CLUSTERBOMB?50:100); break; + case WM_SOUND_OF_DESTRUCTION: + md.damage = 1000 * skill_lv + sstatus->int_ * (sd ? pc->checkskill(sd,WM_LESSON) : 10); + md.damage += md.damage * 10 * battle->calc_chorusbonus(sd) / 100; + break; /** * Mechanic **/ @@ -3774,8 +3846,8 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list * md.damage = 100 + 200 * skill_lv + sstatus->int_; break; case GN_HELLS_PLANT_ATK: - //[{( Hell Plant Skill Level x Casters Base Level ) x 10 } + {( Casters INT x 7 ) / 2 } x { 18 + ( Casters Job Level / 4 )] x ( 5 / ( 10 - Summon Flora Skill Level )) - md.damage = ( skill_lv * status->get_lv(src) * 10 ) + ( sstatus->int_ * 7 / 2 ) * ( 18 + (sd?sd->status.job_level:0) / 4 ) * ( 5 / (10 - (sd?pc->checkskill(sd,AM_CANNIBALIZE):0)) ); + md.damage = skill_lv * status->get_lv(src) * 10 + sstatus->int_ * 7 / 2 * (18 + (sd ? sd->status.job_level : 0) / 4) * (5 / (10 - (sd ? pc->checkskill(sd, AM_CANNIBALIZE) : 0))); + md.damage = md.damage*(1000 + tstatus->mdef) / (1000 + tstatus->mdef * 10) - tstatus->mdef2; break; case KO_HAPPOKUNAI: { @@ -3865,10 +3937,18 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list * } #endif md.damage = battle->calc_cardfix(BF_MISC, src, target, nk, s_ele, 0, md.damage, 0, md.flag); - - if (sd && (i = pc->skillatk_bonus(sd, skill_id))) - md.damage += md.damage*i/100; - + if(skill_id){ + uint16 rskill;/* redirect skill id */ + switch(skill_id){ + case GN_HELLS_PLANT_ATK: + rskill = GN_HELLS_PLANT; + break; + default: + rskill = skill_id; + } + if (sd && (i = pc->skillatk_bonus(sd, rskill))) + md.damage += md.damage*i/100; + } if( (i = battle->adjust_skill_damage(src->m,skill_id)) ) md.damage = md.damage * i / 100; @@ -3887,10 +3967,6 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list * default: md.damage = 1; } - }else if( target->type == BL_SKILL ){ - TBL_SKILL *su = (TBL_SKILL*)target; - if( su->group && (su->group->skill_id == WM_REVERBERATION || su->group->skill_id == WM_POEMOFNETHERWORLD) ) - md.damage = 1; } if(!(nk&NK_NO_ELEFIX)) @@ -3962,11 +4038,9 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list memset(&wd,0,sizeof(wd)); memset(&flag,0,sizeof(flag)); - if(src==NULL || target==NULL) - { - nullpo_info(NLP_MARK); - return wd; - } + nullpo_retr(wd, src); + nullpo_retr(wd, target); + //Initial flag flag.rh=1; flag.weapon=1; @@ -3975,11 +4049,8 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list && skill_id != HT_FREEZINGTRAP #endif ?1:0); - if( target->type == BL_SKILL){ - TBL_SKILL *su = (TBL_SKILL*)target; - if( su->group && (su->group->skill_id == WM_REVERBERATION || su->group->skill_id == WM_POEMOFNETHERWORLD) ) - flag.infdef = 1; - } + if( !flag.infdef && target->type == BL_SKILL && ((TBL_SKILL*)target)->group->unit_id == UNT_REVERBERATION ) + flag.infdef = 1; // Reberberation takes 1 damage //Initial Values wd.type=0; //Normal attack @@ -4163,7 +4234,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list } else if(sc && sc->data[SC_FEARBREEZE] && sd->weapontype1==W_BOW && (i = sd->equip_index[EQI_AMMO]) >= 0 && sd->inventory_data[i] && sd->status.inventory[i].amount > 1){ - int chance = rand()%100; + int chance = rnd()%100; wd.type = 0x08; switch(sc->data[SC_FEARBREEZE]->val1){ case 5: @@ -4347,6 +4418,12 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list case GC_VENOMPRESSURE: hitrate += 10 + 4 * skill_lv; break; + case SC_FATALMENACE: + hitrate -= 35 - 5 * skill_lv; + break; + case LG_BANISHINGPOINT: + hitrate += 3 * skill_lv; + break; } if( sd ) { @@ -4375,19 +4452,19 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list //Assuming that 99% of the cases we will not need to check for the flag.rh... we don't. //ATK_RATE scales the damage. 100 = no change. 50 is halved, 200 is doubled, etc -#define ATK_RATE( a ) { wd.damage= wd.damage*(a)/100 ; if(flag.lh) wd.damage2= wd.damage2*(a)/100; } -#define ATK_RATE2( a , b ) { wd.damage= wd.damage*(a)/100 ; if(flag.lh) wd.damage2= wd.damage2*(b)/100; } -#define ATK_RATER(a){ wd.damage = wd.damage*(a)/100;} -#define ATK_RATEL(a){ wd.damage2 = wd.damage2*(a)/100;} +#define ATK_RATE( a ) do { int64 temp__ = (a); wd.damage= wd.damage*temp__/100 ; if(flag.lh) wd.damage2= wd.damage2*temp__/100; } while(0) +#define ATK_RATE2( a , b ) do { wd.damage= wd.damage*(a)/100 ; if(flag.lh) wd.damage2= wd.damage2*(b)/100; } while(0) +#define ATK_RATER(a) ( wd.damage = wd.damage*(a)/100 ) +#define ATK_RATEL(a) ( wd.damage2 = wd.damage2*(a)/100 ) //Adds dmg%. 100 = +100% (double) damage. 10 = +10% damage -#define ATK_ADDRATE( a ) { wd.damage+= wd.damage*(a)/100 ; if(flag.lh) wd.damage2+= wd.damage2*(a)/100; } -#define ATK_ADDRATE2( a , b ) { wd.damage+= wd.damage*(a)/100 ; if(flag.lh) wd.damage2+= wd.damage2*(b)/100; } +#define ATK_ADDRATE( a ) do { int64 temp__ = (a); wd.damage+= wd.damage*temp__/100; if(flag.lh) wd.damage2+= wd.damage2*temp__/100; } while(0) +#define ATK_ADDRATE2( a , b ) do { wd.damage+= wd.damage*(a)/100 ; if(flag.lh) wd.damage2+= wd.damage2*(b)/100; } while(0) //Adds an absolute value to damage. 100 = +100 damage -#define ATK_ADD( a ) { wd.damage+= a; if (flag.lh) wd.damage2+= a; } -#define ATK_ADD2( a , b ) { wd.damage+= a; if (flag.lh) wd.damage2+= b; } +#define ATK_ADD( a ) do { int64 temp__ = (a); wd.damage += temp__; if (flag.lh) wd.damage2 += temp__; } while(0) +#define ATK_ADD2( a , b ) do { wd.damage += (a); if (flag.lh) wd.damage2 += (b); } while(0) #ifdef RENEWAL -#define GET_NORMAL_ATTACK( f ) { wd.damage = battle->calc_base_damage(src, target, skill_id, skill_lv, nk, n_ele, s_ele, s_ele_, EQI_HAND_R, f, wd.flag); } -#define GET_NORMAL_ATTACK2( f ) { wd.damage2 = battle->calc_base_damage(src, target, skill_id, skill_lv, nk, n_ele, s_ele, s_ele_, EQI_HAND_L, f, wd.flag); } +#define GET_NORMAL_ATTACK( f ) ( wd.damage = battle->calc_base_damage(src, target, skill_id, skill_lv, nk, n_ele, s_ele, s_ele_, EQI_HAND_R, (f), wd.flag) ) +#define GET_NORMAL_ATTACK2( f ) ( wd.damage2 = battle->calc_base_damage(src, target, skill_id, skill_lv, nk, n_ele, s_ele, s_ele_, EQI_HAND_L, (f), wd.flag) ) #endif switch (skill_id) { //Calc base damage according to skill @@ -4454,10 +4531,10 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list i*=i; ATK_ADD(i); //Add str bonus. switch (tstatus->size) { //Size-fix. Is this modified by weapon perfection? - case SZ_SMALL: //Small: 125% + case SZ_MEDIUM: //Medium: 125% ATK_RATE(125); break; - //case SZ_MEDIUM: //Medium: 100% + //case SZ_SMALL: //Medium: 100% case SZ_BIG: //Large: 75% ATK_RATE(75); break; @@ -4466,16 +4543,14 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list #endif case CR_SHIELDBOOMERANG: case PA_SHIELDCHAIN: - case LG_SHIELDPRESS: - case LG_EARTHDRIVE: wd.damage = sstatus->batk; if (sd) { + int damagevalue = 0; short index = sd->equip_index[EQI_HAND_L]; - if (index >= 0 && - sd->inventory_data[index] && - sd->inventory_data[index]->type == IT_ARMOR) - ATK_ADD(sd->inventory_data[index]->weight/10); + if( index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_ARMOR ) + damagevalue = sd->inventory_data[index]->weight/10; + ATK_ADD(damagevalue); } else ATK_ADD(sstatus->rhw.atk2); //Else use Atk2 break; @@ -4534,6 +4609,8 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list ATK_ADDRATE(sd->bonus.atk_rate); if(flag.cri && sd->bonus.crit_atk_rate) ATK_ADDRATE(sd->bonus.crit_atk_rate); + if(flag.cri && sc && sc->data[SC_MTF_CRIDAMAGE]) + ATK_ADDRATE(25);// temporary it should be 'bonus.crit_atk_rate' #ifndef RENEWAL if(sd->status.party_id && (temp=pc->checkskill(sd,TK_POWER)) > 0){ @@ -4546,16 +4623,21 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list } //End default case } //End switch(skill_id) - if( sc && skill_id != PA_SACRIFICE ){ - if( sc->data[SC_UNLIMIT] && wd.flag&BF_LONG ) - ATK_ADD( 50 * sc->data[SC_UNLIMIT]->val1 ); + if( sc && skill_id != PA_SACRIFICE && sc->data[SC_UNLIMIT] && (wd.flag&(BF_LONG|BF_MAGIC)) == BF_LONG) { + switch(skill_id) { + case RA_WUGDASH: + case RA_WUGSTRIKE: + case RA_WUGBITE: + break; + default: + ATK_ADD( 50 * sc->data[SC_UNLIMIT]->val1 ); + } } - if( tsc && skill_id != PA_SACRIFICE ){ - if( tsc->data[SC_DARKCROW] && wd.flag&BF_SHORT ) - ATK_ADD( 30 * tsc->data[SC_DARKCROW]->val1 ); + if ( sc && !skill_id && sc->data[SC_EXEEDBREAK] ) { + ATK_ADDRATE(sc->data[SC_EXEEDBREAK]->val1); + status_change_end(src, SC_EXEEDBREAK, INVALID_TIMER); } - #ifdef RENEWAL if( sd && skill_id == NJ_KUNAI ){ flag.tdef = 1; @@ -4572,7 +4654,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list short index = sd?sd->equip_index[EQI_HAND_R]:0; GET_NORMAL_ATTACK( (sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|(sc && sc->data[SC_WEAPONPERFECT]?8:0) ); wd.damage = wd.damage * 70 / 100; - n_ele = true; + //n_ele = true; // FIXME: This is has no effect if it's after GET_NORMAL_ATTACK (was this intended, or was it supposed to be put above?) if (sd && index >= 0 && sd->inventory_data[index] && @@ -4580,7 +4662,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list ATK_ADD(sd->inventory_data[index]->weight * 7 / 100); switch (tstatus->size) { - case SZ_SMALL: //Small: 115% + case SZ_MEDIUM: //Medium: 115% ATK_RATE(115); break; case SZ_BIG: //Large: 85% @@ -4628,12 +4710,40 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list case GC_COUNTERSLASH: ATK_ADD( status_get_agi(src) * 2 + (sd?sd->status.job_level:0) * 4 ); break; - case SR_TIGERCANNON: // (Tiger Cannon skill level x 240) + (Target Base Level x 40) + case RA_WUGDASH: + if( sc && sc->data[SC_DANCE_WITH_WUG] ) + ATK_ADD(2 * sc->data[SC_DANCE_WITH_WUG]->val1 * (2 + battle->calc_chorusbonus(sd))); + break; + case SR_TIGERCANNON: ATK_ADD( skill_lv * 240 + status->get_lv(target) * 40 ); if( sc && sc->data[SC_COMBOATTACK] - && sc->data[SC_COMBOATTACK]->val1 == SR_FALLENEMPIRE ) // (Tiger Cannon skill level x 500) + (Target Base Level x 40) + && sc->data[SC_COMBOATTACK]->val1 == SR_FALLENEMPIRE ) ATK_ADD( skill_lv * 500 + status->get_lv(target) * 40 ); break; + case RA_WUGSTRIKE: + case RA_WUGBITE: + if(sd) + ATK_ADD(30*pc->checkskill(sd, RA_TOOTHOFWUG)); + if( sc && sc->data[SC_DANCE_WITH_WUG] ) + ATK_ADD(2 * sc->data[SC_DANCE_WITH_WUG]->val1 * (2 + battle->calc_chorusbonus(sd))); + break; + case LG_SHIELDPRESS: + if( sd ) { + int damagevalue = 0; + short index = sd->equip_index[EQI_HAND_L]; + if( index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_ARMOR ) + damagevalue = sstatus->vit * sd->status.inventory[index].refine; + ATK_ADD(damagevalue); + } + break; + case SR_GATEOFHELL: + ATK_ADD (sstatus->max_hp - status_get_hp(src)); + if(sc && sc->data[SC_COMBOATTACK] && sc->data[SC_COMBOATTACK]->val1 == SR_FALLENEMPIRE) { + ATK_ADD( (sstatus->max_sp * (1 + skill_lv * 2 / 10)) + 40 * status->get_lv(src) ); + } else { + ATK_ADD( (sstatus->sp * (1 + skill_lv * 2 / 10)) + 10 * status->get_lv(src) ); + } + break; case SR_FALLENEMPIRE:// [(Target Size value + Skill Level - 1) x Caster STR] + [(Target current weight x Caster DEX / 120)] ATK_ADD( ((tstatus->size+1)*2 + skill_lv - 1) * sstatus->str); if( tsd && tsd->weight ){ @@ -4662,12 +4772,6 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list if( sc->data[SC_TRUESIGHT] ) ATK_ADDRATE(2*sc->data[SC_TRUESIGHT]->val1); #endif - if( sc->data[SC_GLOOMYDAY_SK] && - ( skill_id == LK_SPIRALPIERCE || skill_id == KN_BRANDISHSPEAR || - skill_id == CR_SHIELDBOOMERANG || skill_id == PA_SHIELDCHAIN || - skill_id == LG_SHIELDPRESS || skill_id == RK_HUNDREDSPEAR || - skill_id == CR_SHIELDCHARGE ) ) - ATK_ADDRATE(sc->data[SC_GLOOMYDAY_SK]->val2); #ifndef RENEWAL_EDP if( sc->data[SC_EDP] ){ @@ -4702,25 +4806,53 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list sc->data[SC_SOULLINK]->val2 == SL_CRUSADER) ATK_ADDRATE(100); break; - case NC_AXETORNADO: - if( (sstatus->rhw.ele) == ELE_WIND || (sstatus->lhw.ele) == ELE_WIND ) - ATK_ADDRATE(50); - break; } - - if( (i = battle->adjust_skill_damage(src->m,skill_id)) ) - ATK_RATE(i); - #ifdef RENEWAL - if( skill_id && (wd.damage+wd.damage2) ){ - RE_SKILL_REDUCTION(); + if( skill_id ){ + uint16 rskill;/* redirect skill id */ + switch(skill_id){ + case AB_DUPLELIGHT_MELEE: + rskill = AB_DUPLELIGHT; + break; + case LG_OVERBRAND_BRANDISH: + case LG_OVERBRAND_PLUSATK: + rskill = LG_OVERBRAND; + break; + case WM_SEVERE_RAINSTORM_MELEE: + rskill = WM_SEVERE_RAINSTORM; + break; + case WM_REVERBERATION_MELEE: + rskill = WM_REVERBERATION; + break; + case GN_CRAZYWEED_ATK: + rskill = GN_CRAZYWEED; + break; + case GN_SLINGITEM_RANGEMELEEATK: + rskill = GN_SLINGITEM; + break; + case RL_R_TRIP_PLUSATK: + rskill = RL_R_TRIP; + break; + case RL_B_FLICKER_ATK: + rskill = RL_FLICKER; + break; + case RL_GLITTERING_GREED_ATK: + rskill = RL_GLITTERING_GREED; + break; + default: + rskill = skill_id; + } + if( (i = battle->adjust_skill_damage(src->m,rskill)) ) + ATK_RATE(i); } - #endif + if( sd ) { if (skill_id && (i = pc->skillatk_bonus(sd, skill_id))) ATK_ADDRATE(i); #ifdef RENEWAL if( wd.flag&BF_LONG ) ATK_ADDRATE(sd->bonus.long_attack_atk_rate); + if( sc && sc->data[SC_MTF_RANGEATK] ) + ATK_ADDRATE(25);// temporary it should be 'bonus.long_attack_atk_rate' #endif if( (i=pc->checkskill(sd,AB_EUCHARISTICA)) > 0 && (tstatus->race == RC_DEMON || tstatus->def_ele == ELE_DARK) ) @@ -4975,6 +5107,19 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list if(!flag.lh && wd.damage2) wd.damage2=0; + if( sc && sc->data[SC_GLOOMYDAY] ) { + switch( skill_id ) { + case KN_BRANDISHSPEAR: + case LK_SPIRALPIERCE: + case CR_SHIELDCHARGE: + case CR_SHIELDBOOMERANG: + case PA_SHIELDCHAIN: + case RK_HUNDREDSPEAR: + case LG_SHIELDPRESS: + wd.damage += wd.damage * sc->data[SC_GLOOMYDAY]->val2 / 100; + } + } + if( sc ) { //SG_FUSION hp penalty [Komurka] if (sc->data[SC_FUSION]) { @@ -4997,55 +5142,11 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list wd.damage += md.damage; break; } - case SR_GATEOFHELL: - ATK_ADD (sstatus->max_hp - status_get_hp(src)); - if(sc && sc->data[SC_COMBOATTACK] && sc->data[SC_COMBOATTACK]->val1 == SR_FALLENEMPIRE){ - ATK_ADD ( (sstatus->max_sp * (1 + skill_lv * 2 / 10)) + 40 * status->get_lv(src) ); - }else{ - ATK_ADD ( (sstatus->sp * (1 + skill_lv * 2 / 10)) + 10 * status->get_lv(src) ); - } - break; } - if( wd.damage + wd.damage2 ) - { //There is a total damage value - int64 damage = wd.damage + wd.damage2, rdamage = 0; - int rdelay = 0; - - if( src != target && - (!skill_id || skill_id || - ( src->type == BL_SKILL && ( skill_id == SG_SUN_WARM || skill_id == SG_MOON_WARM || skill_id == SG_STAR_WARM ) )) ){ - - rdamage = battle->calc_return_damage(target, src, &damage, wd.flag, 0, &rdelay); - - if( tsc && tsc->count ) { - if( tsc && tsc->data[SC_DEATHBOUND] ){ - wd.damage = damage; - wd.damage2 = 0; - status_change_end(target,SC_DEATHBOUND,INVALID_TIMER); - } - } - if( rdamage > 0 ) { - if( tsc && tsc->data[SC_LG_REFLECTDAMAGE] ) { - if( src != target ) {// Don't reflect your own damage (Grand Cross) - bool change = false; - if( sd && !sd->state.autocast ) - change = true; - if( change ) - sd->state.autocast = 1; - map->foreachinshootrange(battle->damage_area,target,skill->get_splash(LG_REFLECTDAMAGE,1),BL_CHAR,timer->gettick(),target,wd.amotion,sstatus->dmotion,rdamage,tstatus->race); - if( change ) - sd->state.autocast = 0; - } - } else { - //Use Reflect Shield to signal this kind of skill trigger. [Skotlex] - if( tsd && src != target ) - battle->drain(tsd, src, rdamage, rdamage, sstatus->race, is_boss(src)); - battle->delay_damage(timer->gettick(), wd.amotion,target,src,0,CR_REFLECTSHIELD,0,rdamage,ATK_DEF,rdelay,true); - skill->additional_effect(target, src, CR_REFLECTSHIELD, 1, BF_WEAPON|BF_SHORT|BF_NORMAL,ATK_DEF,timer->gettick()); - } - } - } + if( wd.damage + wd.damage2 ) { //There is a total damage value + int64 damage = wd.damage + wd.damage2; + if(!wd.damage2) { wd.damage = battle->calc_damage(src,target,&wd,wd.damage,skill_id,skill_lv); if( map_flag_gvg2(target->m) ) @@ -5076,6 +5177,25 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list wd.damage-=wd.damage2; #endif } + + if( src != target ) { // Don't reflect your own damage (Grand Cross) + + if( wd.dmg_lv == ATK_MISS || wd.dmg_lv == ATK_BLOCK ) { + int64 prev1 = wd.damage, prev2 = wd.damage2; + + wd.damage = damage; + wd.damage2 = 0; + + battle->reflect_damage(target, src, &wd, skill_id); + + wd.damage = prev1; + wd.damage2 = prev2; + + } else + battle->reflect_damage(target, src, &wd, skill_id); + + } + } //Reject Sword bugreport:4493 by Daegaladh if(wd.damage && tsc && tsc->data[SC_SWORDREJECT] && @@ -5086,8 +5206,8 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list )) && rnd()%100 < tsc->data[SC_SWORDREJECT]->val2 ) { - ATK_RATER(50) - status_fix_damage(target,src,wd.damage,clif->damage(target,src,timer->gettick(),0,0,wd.damage,0,0,0)); + ATK_RATER(50); + status_fix_damage(target,src,wd.damage,clif->damage(target,src,0,0,wd.damage,0,0,0)); clif->skill_nodamage(target,target,ST_REJECTSWORD,tsc->data[SC_SWORDREJECT]->val1,1); if( --(tsc->data[SC_SWORDREJECT]->val3) <= 0 ) status_change_end(target, SC_SWORDREJECT, INVALID_TIMER); @@ -5148,90 +5268,191 @@ struct Damage battle_calc_attack(int attack_type,struct block_list *bl,struct bl d.dmg_lv = ATK_DEF; return d; } - -//Calculates BF_WEAPON returned damage. -int64 battle_calc_return_damage(struct block_list* bl, struct block_list *src, int64 *dmg, int flag, uint16 skill_id, int *delay){ - int64 rdamage = 0, damage = *dmg, trdamage = 0; - struct map_session_data* sd; - struct status_change* sc; +//Performs reflect damage (magic (maya) is performed over skill.c). +void battle_reflect_damage(struct block_list *target, struct block_list *src, struct Damage *wd,uint16 skill_id) { + int64 damage = wd->damage + wd->damage2, rdamage = 0, trdamage = 0; + struct map_session_data *sd, *tsd; + struct status_change *sc; + struct status_change *ssc; + int64 tick = timer->gettick(); + int delay = 50, rdelay = 0; #ifdef RENEWAL int max_reflect_damage; - max_reflect_damage = max(status_get_max_hp(bl), status_get_max_hp(bl) * status->get_lv(bl) / 100); + max_reflect_damage = max(status_get_max_hp(target), status_get_max_hp(target) * status->get_lv(target) / 100); #endif - sd = BL_CAST(BL_PC, bl); - sc = status->get_sc(bl); + + sd = BL_CAST(BL_PC, src); + + tsd = BL_CAST(BL_PC, target); + sc = status->get_sc(target); #ifdef RENEWAL -#define NORMALIZE_RDAMAGE(d){ trdamage += rdamage = max(1, min(max_reflect_damage, d)); } +#define NORMALIZE_RDAMAGE(d) ( trdamage += rdamage = max(1, min(max_reflect_damage, (d))) ) #else -#define NORMALIZE_RDAMAGE(d){ trdamage += rdamage = max(1, d); } +#define NORMALIZE_RDAMAGE(d) ( trdamage += rdamage = max(1, (d)) ) #endif - if( sc && sc->data[SC_CRESCENTELBOW] && !is_boss(src) && rnd()%100 < sc->data[SC_CRESCENTELBOW]->val2 ){ - //ATK [{(Target HP / 100) x Skill Level} x Caster Base Level / 125] % + [Received damage x {1 + (Skill Level x 0.2)}] - int ratio = (status_get_hp(src) / 100) * sc->data[SC_CRESCENTELBOW]->val1 * status->get_lv(bl) / 125; - if (ratio > 5000) ratio = 5000; // Maximum of 5000% ATK - rdamage = rdamage * ratio / 100 + (*dmg) * (10 + sc->data[SC_CRESCENTELBOW]->val1 * 20 / 10) / 10; - skill->blown(bl, src, skill->get_blewcount(SR_CRESCENTELBOW_AUTOSPELL, sc->data[SC_CRESCENTELBOW]->val1), unit->getdir(src), 0); - clif->skill_damage(bl, src, timer->gettick(), status_get_amotion(src), 0, rdamage, - 1, SR_CRESCENTELBOW_AUTOSPELL, sc->data[SC_CRESCENTELBOW]->val1, 6); // This is how official does - clif->damage(src, bl, timer->gettick(), status_get_amotion(src)+1000, 0, rdamage/10, 1, 0, 0); - status->damage(src, bl, status->damage(bl, src, rdamage, 0, 0, 1)/10, 0, 0, 1); - status_change_end(bl, SC_CRESCENTELBOW, INVALID_TIMER); - return 0; // Just put here to minimize redundancy - } - if( flag & BF_SHORT) {//Bounces back part of the damage. - if ( sd && sd->bonus.short_weapon_damage_return ){ - NORMALIZE_RDAMAGE(damage * sd->bonus.short_weapon_damage_return / 100); - *delay = clif->damage(src, src, timer->gettick(), status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4, 0); - } - if( sc && sc->count ) { - if( sc->data[SC_REFLECTSHIELD] && skill_id != WS_CARTTERMINATION ){ - NORMALIZE_RDAMAGE(damage * sc->data[SC_REFLECTSHIELD]->val2 / 100); - *delay = clif->skill_damage(src, src, timer->gettick(), status_get_amotion(src), status_get_dmotion(src), rdamage, 1, CR_REFLECTSHIELD, 1, 4); - } - if( sc->data[SC_LG_REFLECTDAMAGE] && rand()%100 < (30 + 10*sc->data[SC_LG_REFLECTDAMAGE]->val1) ) { - if( skill_id != HT_LANDMINE && skill_id != HT_CLAYMORETRAP - && skill_id != RA_CLUSTERBOMB && (skill_id <= RA_VERDURETRAP || skill_id > RA_ICEBOUNDTRAP) && skill_id != MA_LANDMINE ){ - NORMALIZE_RDAMAGE((*dmg) * sc->data[SC_LG_REFLECTDAMAGE]->val2 / 100); - *delay = clif->damage(src, src, timer->gettick(), status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4, 0); + if( sc && !sc->count ) + sc = NULL; + + if( sc ) { + + if( sc->data[SC_CRESCENTELBOW] && !is_boss(src) && rnd()%100 < sc->data[SC_CRESCENTELBOW]->val2 ){ + //ATK [{(Target HP / 100) x Skill Level} x Caster Base Level / 125] % + [Received damage x {1 + (Skill Level x 0.2)}] + int ratio = (status_get_hp(src) / 100) * sc->data[SC_CRESCENTELBOW]->val1 * status->get_lv(target) / 125; + if (ratio > 5000) ratio = 5000; // Maximum of 5000% ATK + rdamage = rdamage * ratio / 100 + (damage) * (10 + sc->data[SC_CRESCENTELBOW]->val1 * 20 / 10) / 10; + skill->blown(target, src, skill->get_blewcount(SR_CRESCENTELBOW_AUTOSPELL, sc->data[SC_CRESCENTELBOW]->val1), unit->getdir(src), 0); + clif->skill_damage(target, src, tick, status_get_amotion(src), 0, rdamage, + 1, SR_CRESCENTELBOW_AUTOSPELL, sc->data[SC_CRESCENTELBOW]->val1, 6); // This is how official does + clif->delay_damage(tick + delay, src, target,status_get_amotion(src)+1000,0, rdamage/10, 1, 0); + status->damage(src, target, status->damage(target, src, rdamage, 0, 0, 1)/10, 0, 0, 1); + status_change_end(target, SC_CRESCENTELBOW, INVALID_TIMER); + /* shouldn't this trigger skill->additional_effect? */ + return; // Just put here to minimize redundancy + } + + if( wd->flag & BF_SHORT ) { + if( !is_boss(src) ) { + if( sc->data[SC_DEATHBOUND] && skill_id != WS_CARTTERMINATION ) { + uint8 dir = map->calc_dir(target,src->x,src->y), + t_dir = unit->getdir(target); + + if( !map->check_dir(dir,t_dir) ) { + int64 rd1 = damage * sc->data[SC_DEATHBOUND]->val2 / 100; // Amplify damage. + + trdamage += rdamage = rd1 - (damage = rd1 * 30 / 100); // not normalized as intended. + rdelay = clif->skill_damage(src, target, tick, status_get_amotion(src), status_get_dmotion(src), -3000, 1, RK_DEATHBOUND, sc->data[SC_DEATHBOUND]->val1, 6); + skill->blown(target, src, skill->get_blewcount(RK_DEATHBOUND, sc->data[SC_DEATHBOUND]->val1), unit->getdir(src), 0); + + if( tsd ) /* is this right? rdamage as both left and right? */ + battle->drain(tsd, src, rdamage, rdamage, status_get_race(src), 0); + battle->delay_damage(tick, wd->amotion,target,src,0,CR_REFLECTSHIELD,0,rdamage,ATK_DEF,rdelay,true); + + delay += 100;/* gradual increase so the numbers don't clip in the client */ + } + wd->damage = wd->damage + wd->damage2; + wd->damage2 = 0; + status_change_end(target,SC_DEATHBOUND,INVALID_TIMER); } } - if( sc->data[SC_DEATHBOUND] && skill_id != WS_CARTTERMINATION && !is_boss(src) ) { - uint8 dir = map->calc_dir(bl,src->x,src->y), - t_dir = unit->getdir(bl); - - if( !map->check_dir(dir,t_dir) ) { - int64 rd1 = damage * sc->data[SC_DEATHBOUND]->val2 / 100; // Amplify damage. - trdamage += rdamage = rd1 - (*dmg = rd1 * 30 / 100); // not normalized as intended. - clif->skill_damage(src, bl, timer->gettick(), status_get_amotion(src), 0, -3000, 1, RK_DEATHBOUND, sc->data[SC_DEATHBOUND]->val1, 6); - skill->blown(bl, src, skill->get_blewcount(RK_DEATHBOUND, sc->data[SC_DEATHBOUND]->val1), unit->getdir(src), 0); - if( skill_id ) - status_change_end(bl, SC_DEATHBOUND, INVALID_TIMER); - *delay = clif->damage(src, src, timer->gettick(), status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4, 0); + } + + if( sc->data[SC_KYOMU] ){ + // Nullify reflecting ability of the conditions onwards + return; + } + + } + + if( wd->flag & BF_SHORT ) { + if ( tsd && tsd->bonus.short_weapon_damage_return ) { + NORMALIZE_RDAMAGE(damage * tsd->bonus.short_weapon_damage_return / 100); + + rdelay = clif->delay_damage(tick+delay,src, src, status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4); + + /* is this right? rdamage as both left and right? */ + battle->drain(tsd, src, rdamage, rdamage, status_get_race(src), 0); + battle->delay_damage(tick, wd->amotion,target,src,0,CR_REFLECTSHIELD,0,rdamage,ATK_DEF,rdelay,true); + + delay += 100;/* gradual increase so the numbers don't clip in the client */ + } + + if( wd->dmg_lv >= ATK_BLOCK ) {/* yes block still applies, somehow gravity thinks it makes sense. */ + if( sc ) { + if( sc->data[SC_REFLECTSHIELD] && skill_id != WS_CARTTERMINATION ) { + NORMALIZE_RDAMAGE(damage * sc->data[SC_REFLECTSHIELD]->val2 / 100); + +#ifndef RENEWAL + rdelay = clif->delay_damage(tick+delay,src, src, status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4); +#else + rdelay = clif->skill_damage(src, src, tick, delay, status_get_dmotion(src), rdamage, 1, CR_REFLECTSHIELD, 1, 4); +#endif + /* is this right? rdamage as both left and right? */ + if( tsd ) + battle->drain(tsd, src, rdamage, rdamage, status_get_race(src), 0); + battle->delay_damage(tick, wd->amotion,target,src,0,CR_REFLECTSHIELD,0,rdamage,ATK_DEF,rdelay,true); + + delay += 100;/* gradual increase so the numbers don't clip in the client */ + } + if( sc->data[SC_LG_REFLECTDAMAGE] && rand()%100 < (30 + 10*sc->data[SC_LG_REFLECTDAMAGE]->val1) ) { + bool change = false; + + NORMALIZE_RDAMAGE(damage * sc->data[SC_LG_REFLECTDAMAGE]->val2 / 100); + + trdamage -= rdamage;/* wont count towards total */ + + if( sd && !sd->state.autocast ) { + change = true; + sd->state.autocast = 1; + } + + map->foreachinshootrange(battle->damage_area,target,skill->get_splash(LG_REFLECTDAMAGE,1),BL_CHAR,tick,target,delay,wd->dmotion,rdamage,status_get_race(target)); + + if( change ) + sd->state.autocast = 0; + + delay += 150;/* gradual increase so the numbers don't clip in the client */ + + if( (--sc->data[SC_LG_REFLECTDAMAGE]->val3) <= 0 ) + status_change_end(target, SC_LG_REFLECTDAMAGE, INVALID_TIMER); + } + if( sc->data[SC_SHIELDSPELL_DEF] && sc->data[SC_SHIELDSPELL_DEF]->val1 == 2 ){ + NORMALIZE_RDAMAGE(damage * sc->data[SC_SHIELDSPELL_DEF]->val2 / 100); + + rdelay = clif->delay_damage(tick+delay,src, src, status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4); + + /* is this right? rdamage as both left and right? */ + if( tsd ) + battle->drain(tsd, src, rdamage, rdamage, status_get_race(src), 0); + battle->delay_damage(tick, wd->amotion,target,src,0,CR_REFLECTSHIELD,0,rdamage,ATK_DEF,rdelay,true); + + delay += 100;/* gradual increase so the numbers don't clip in the client */ } } - if( sc->data[SC_SHIELDSPELL_DEF] && sc->data[SC_SHIELDSPELL_DEF]->val1 == 2 && !is_boss(src) ){ - NORMALIZE_RDAMAGE(damage * sc->data[SC_SHIELDSPELL_DEF]->val2 / 100); - *delay = clif->damage(src, src, timer->gettick(), status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4, 0); + if( ( ssc = status->get_sc(src) ) ) { + if( ssc->data[SC_INSPIRATION] ) { + NORMALIZE_RDAMAGE(damage / 100); + + rdelay = clif->delay_damage(tick+delay,target, target, status_get_amotion(target), status_get_dmotion(target), rdamage, 1, 4); + + /* is this right? rdamage as both left and right? */ + if( sd ) + battle->drain(sd, target, rdamage, rdamage, status_get_race(target), 0); + battle->delay_damage(tick, wd->amotion,src,target,0,CR_REFLECTSHIELD,0,rdamage,ATK_DEF,rdelay,true); + + delay += 100;/* gradual increase so the numbers don't clip in the client */ + } } } - } else { - if (sd && sd->bonus.long_weapon_damage_return){ - NORMALIZE_RDAMAGE(damage * sd->bonus.long_weapon_damage_return / 100); - *delay = clif->damage(src, src, timer->gettick(), status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4, 0); + } else {/* long */ + if ( tsd && tsd->bonus.long_weapon_damage_return ) { + NORMALIZE_RDAMAGE(damage * tsd->bonus.long_weapon_damage_return / 100); + + rdelay = clif->delay_damage(tick+delay,src, src, status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4); + + /* is this right? rdamage as both left and right? */ + battle->drain(tsd, src, rdamage, rdamage, status_get_race(src), 0); + battle->delay_damage(tick, wd->amotion,target,src,0,CR_REFLECTSHIELD,0,rdamage,ATK_DEF,rdelay,true); + + delay += 100;/* gradual increase so the numbers don't clip in the client */ } } - - if( !(sc && sc->data[SC_DEATHBOUND]) ){ - if( sc && sc->data[SC_KYOMU] ) // Nullify reflecting ability - return 0; + +#ifdef __clang_analyzer__ + // Tell Clang's static analyzer that we want to += it even the value is currently unused (it'd be used if we added new checks) + (void)delay; +#endif // __clang_analyzer + + /* something caused reflect */ + if( trdamage ) { + skill->additional_effect(target, src, CR_REFLECTSHIELD, 1, BF_WEAPON|BF_SHORT|BF_NORMAL,ATK_DEF,tick); } - return max(0, trdamage); + return; +#undef NORMALIZE_RDAMAGE } - void battle_drain(TBL_PC *sd, struct block_list *tbl, int64 rdamage, int64 ldamage, int race, int boss) { struct weapon_data *wd; @@ -5284,14 +5505,14 @@ void battle_drain(TBL_PC *sd, struct block_list *tbl, int64 rdamage, int64 ldama status_zap(tbl, rhp, rsp); } // Deals the same damage to targets in area. [pakpil] -int battle_damage_area( struct block_list *bl, va_list ap) { - unsigned int tick; +int battle_damage_area(struct block_list *bl, va_list ap) { + int64 tick; int amotion, dmotion, damage; struct block_list *src; nullpo_ret(bl); - tick=va_arg(ap, unsigned int); + tick = va_arg(ap, int64); src=va_arg(ap,struct block_list *); amotion=va_arg(ap,int); dmotion=va_arg(ap,int); @@ -5306,7 +5527,7 @@ int battle_damage_area( struct block_list *bl, va_list ap) { battle->delay_damage(tick, amotion,src,bl,0,CR_REFLECTSHIELD,0,damage,ATK_DEF,0,true); else status_fix_damage(src,bl,damage,0); - clif->damage(bl,bl,tick,amotion,dmotion,damage,1,ATK_BLOCK,0); + clif->damage(bl,bl,amotion,dmotion,damage,1,ATK_BLOCK,0); if( !(src && src->type == BL_PC && ((TBL_PC*)src)->state.autocast) ) skill->additional_effect(src, bl, CR_REFLECTSHIELD, 1, BF_WEAPON|BF_SHORT|BF_NORMAL,ATK_DEF,tick); map->freeblock_unlock(); @@ -5317,7 +5538,7 @@ int battle_damage_area( struct block_list *bl, va_list ap) { /*========================================== * Do a basic physical attack (call trough unit_attack_timer) *------------------------------------------*/ -enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* target, unsigned int tick, int flag) { +enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* target, int64 tick, int flag) { struct map_session_data *sd = NULL, *tsd = NULL; struct status_data *sstatus, *tstatus; struct status_change *sc, *tsc; @@ -5395,7 +5616,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t if(dist <= 0 || (!map->check_dir(dir,t_dir) && dist <= tstatus->rhw.range+1)) { uint16 skill_lv = tsc->data[SC_AUTOCOUNTER]->val1; clif->skillcastcancel(target); //Remove the casting bar. [Skotlex] - clif->damage(src, target, tick, sstatus->amotion, 1, 0, 1, 0, 0); //Display MISS. + clif->damage(src, target, sstatus->amotion, 1, 0, 1, 0, 0); //Display MISS. status_change_end(target, SC_AUTOCOUNTER, INVALID_TIMER); skill->attack(BF_WEAPON,target,target,src,KN_AUTOCOUNTER,skill_lv,tick,0); return ATK_BLOCK; @@ -5407,11 +5628,11 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t uint16 skill_lv = tsc->data[SC_BLADESTOP_WAIT]->val1; int duration = skill->get_time2(MO_BLADESTOP,skill_lv); status_change_end(target, SC_BLADESTOP_WAIT, INVALID_TIMER); - if(sc_start4(src, SC_BLADESTOP, 100, sd?pc->checkskill(sd, MO_BLADESTOP):5, 0, 0, target->id, duration)) { + if(sc_start4(target, src, SC_BLADESTOP, 100, sd?pc->checkskill(sd, MO_BLADESTOP):5, 0, 0, target->id, duration)) { //Target locked. - clif->damage(src, target, tick, sstatus->amotion, 1, 0, 1, 0, 0); //Display MISS. + clif->damage(src, target, sstatus->amotion, 1, 0, 1, 0, 0); //Display MISS. clif->bladestop(target, src->id, 1); - sc_start4(target, SC_BLADESTOP, 100, skill_lv, 0, 0, src->id, duration); + sc_start4(target, target, SC_BLADESTOP, 100, skill_lv, 0, 0, src->id, duration); return ATK_BLOCK; } } @@ -5472,6 +5693,9 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t return ATK_DEF; return ATK_MISS; } + if( tsc && tsc->data[SC_MTF_MLEATKED] && rnd()%100 < 20 ) + clif->skill_nodamage(target, target, SM_ENDURE, 5, + sc_start(target,target, SC_ENDURE, 100, 5, skill->get_time(SM_ENDURE, 5))); } if(tsc && tsc->data[SC_KAAHI] && tsc->data[SC_KAAHI]->val4 == INVALID_TIMER && tstatus->hp < tstatus->max_hp) @@ -5480,10 +5704,6 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t wd = battle->calc_attack(BF_WEAPON, src, target, 0, 0, flag); if( sc && sc->count ) { - if (sc->data[SC_EXEEDBREAK]) { - ATK_RATER(sc->data[SC_EXEEDBREAK]->val1) - status_change_end(src, SC_EXEEDBREAK, INVALID_TIMER); - } if( sc->data[SC_SPELLFIST] ) { if( --(sc->data[SC_SPELLFIST]->val1) >= 0 ){ struct Damage ad = battle->calc_attack(BF_MAGIC,src,target,sc->data[SC_SPELLFIST]->val3,sc->data[SC_SPELLFIST]->val4,flag|BF_SHORT); @@ -5513,7 +5733,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t } } - wd.dmotion = clif->damage(src, target, tick, wd.amotion, wd.dmotion, wd.damage, wd.div_ , wd.type, wd.damage2); + wd.dmotion = clif->damage(src, target, wd.amotion, wd.dmotion, wd.damage, wd.div_ , wd.type, wd.damage2); if (sd && sd->bonus.splash_range > 0 && damage > 0) skill->castend_damage_id(src, target, 0, 1, tick, 0); @@ -5524,7 +5744,13 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t } map->freeblock_lock(); - battle->delay_damage(tick, wd.amotion, src, target, wd.flag, 0, 0, damage, wd.dmg_lv, wd.dmotion, true); + if( skill->check_shadowform(target, damage, wd.div_) ){ + if( !status->isdead(target) ) + skill->additional_effect(src, target, 0, 0, wd.flag, wd.dmg_lv, tick); + if( wd.dmg_lv > ATK_BLOCK) + skill->counter_additional_effect(src, target, 0, 0, wd.flag,tick); + }else + battle->delay_damage(tick, wd.amotion, src, target, wd.flag, 0, 0, damage, wd.dmg_lv, wd.dmotion, true); if( tsc ) { if( tsc->data[SC_DEVOTION] ) { struct status_change_entry *sce = tsc->data[SC_DEVOTION]; @@ -5535,7 +5761,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t (d_bl->type == BL_PC && ((TBL_PC*)d_bl)->devotion[sce->val2] == target->id) ) && check_distance_bl(target, d_bl, sce->val3) ) { - clif->damage(d_bl, d_bl, timer->gettick(), 0, 0, damage, 0, 0, 0); + clif->damage(d_bl, d_bl, 0, 0, damage, 0, 0, 0); status_fix_damage(NULL, d_bl, damage, 0); } else @@ -5549,10 +5775,10 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t } else if( tsc->data[SC_WATER_SCREEN_OPTION] && tsc->data[SC_WATER_SCREEN_OPTION]->val1 ) { struct block_list *e_bl = map->id2bl(tsc->data[SC_WATER_SCREEN_OPTION]->val1); if( e_bl && !status->isdead(e_bl) ) { - clif->damage(e_bl,e_bl,tick,wd.amotion,wd.dmotion,damage,wd.div_,wd.type,wd.damage2); + clif->damage(e_bl,e_bl,wd.amotion,wd.dmotion,damage,wd.div_,wd.type,wd.damage2); status->damage(target,e_bl,damage,0,0,0); // Just show damage in target. - clif->damage(src, target, tick, wd.amotion, wd.dmotion, damage, wd.div_, wd.type, wd.damage2 ); + clif->damage(src, target, wd.amotion, wd.dmotion, damage, wd.div_, wd.type, wd.damage2 ); map->freeblock_unlock(); return ATK_NONE; } @@ -5677,22 +5903,32 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t map->freeblock_unlock(); return wd.dmg_lv; } - -int battle_check_undead(int race,int element) +#undef ATK_RATE +#undef ATK_RATE2 +#undef ATK_RATER +#undef ATK_RATEL +#undef ATK_ADDRATE +#undef ATK_ADDRATE2 +#undef ATK_ADD +#undef ATK_ADD2 +#undef GET_NORMAL_ATTACK +#undef GET_NORMAL_ATTACK2 + +bool battle_check_undead(int race,int element) { if(battle_config.undead_detect_type == 0) { if(element == ELE_UNDEAD) - return 1; + return true; } else if(battle_config.undead_detect_type == 1) { if(race == RC_UNDEAD) - return 1; + return true; } else { if(element == ELE_UNDEAD || race == RC_UNDEAD) - return 1; + return true; } - return 0; + return false; } //Returns the upmost level master starting with the given object @@ -5752,6 +5988,10 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f m = target->m; + if (flag&BCT_ENEMY && ( map->getcell(m,src->x,src->y,CELL_CHKBASILICA) || map->getcell(m,target->x,target->y,CELL_CHKBASILICA) ) ) { + return -1; + } + //t_bl/s_bl hold the 'master' of the attack, while src/target are the actual //objects involved. if( (t_bl = battle->get_master(target)) == NULL ) @@ -5763,11 +6003,11 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f if ( s_bl->type == BL_PC ) { switch( t_bl->type ) { case BL_MOB: // Source => PC, Target => MOB - if (pc->has_permission((TBL_PC*)s_bl, PC_PERM_DISABLE_PVM) ) + if (pc_has_permission((TBL_PC*)s_bl, PC_PERM_DISABLE_PVM) ) return 0; break; case BL_PC: - if (pc->has_permission((TBL_PC*)s_bl, PC_PERM_DISABLE_PVP)) + if (pc_has_permission((TBL_PC*)s_bl, PC_PERM_DISABLE_PVP)) return 0; break; default:/* anything else goes */ @@ -5817,12 +6057,9 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f case MS_MAGNUM: case RA_DETONATOR: case RA_SENSITIVEKEEN: - case GN_CRAZYWEED_ATK: case RK_STORMBLAST: - case RK_PHANTOMTHRUST: case SR_RAMPAGEBLASTER: case NC_COLDSLOWER: - case NC_SELFDESTRUCTION: #ifdef RENEWAL case KN_BOWLINGBASH: case KN_SPEARSTAB: @@ -5844,14 +6081,10 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f strip_enemy = 0; break; default: - if(su->group->skill_id == WM_REVERBERATION || su->group->skill_id == WM_POEMOFNETHERWORLD){ - state |= BCT_ENEMY; - strip_enemy = 0; - }else - return 0; + return 0; } } else if (su->group->skill_id==WZ_ICEWALL || - su->group->skill_id == GN_WALLOFTHORN) { + su->group->skill_id == GN_WALLOFTHORN) { state |= BCT_ENEMY; strip_enemy = 0; } else //Excepting traps and icewall, you should not be able to target skills. @@ -6003,9 +6236,11 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f } if( flag&(BCT_PARTY|BCT_ENEMY) ) { int s_party = status->get_party_id(s_bl); + int s_guild = status->get_guild_id(s_bl); + if( s_party && s_party == status->get_party_id(t_bl) && !(map->list[m].flag.pvp && map->list[m].flag.pvp_noparty) - && !(map_flag_gvg(m) && map->list[m].flag.gvg_noparty) + && !(map_flag_gvg(m) && map->list[m].flag.gvg_noparty && !( s_guild && s_guild == status->get_guild_id(t_bl) )) && (!map->list[m].flag.battleground || sbg_id == tbg_id) ) state |= BCT_PARTY; else @@ -6393,7 +6628,7 @@ static const struct _battle_data { { "duel_time_interval", &battle_config.duel_time_interval, 60, 0, INT_MAX, }, { "duel_only_on_same_map", &battle_config.duel_only_on_same_map, 0, 0, 1, }, { "skip_teleport_lv1_menu", &battle_config.skip_teleport_lv1_menu, 0, 0, 1, }, - { "mob_max_skilllvl", &battle_config.mob_max_skilllvl, 100, 1, INT_MAX, }, + { "mob_max_skilllvl", &battle_config.mob_max_skilllvl, 100, 1, INT_MAX, }, { "allow_skill_without_day", &battle_config.allow_skill_without_day, 0, 0, 1, }, { "allow_es_magic_player", &battle_config.allow_es_magic_pc, 0, 0, 1, }, { "skill_caster_check", &battle_config.skill_caster_check, 1, 0, 1, }, @@ -6445,6 +6680,7 @@ static const struct _battle_data { { "cashshop_show_points", &battle_config.cashshop_show_points, 0, 0, 1, }, { "mail_show_status", &battle_config.mail_show_status, 0, 0, 2, }, { "client_limit_unit_lv", &battle_config.client_limit_unit_lv, 0, 0, BL_ALL, }, + { "client_emblem_max_blank_percent", &battle_config.client_emblem_max_blank_percent, 100, 0, 100, }, // BattleGround Settings { "bg_update_interval", &battle_config.bg_update_interval, 1000, 100, INT_MAX, }, { "bg_flee_penalty", &battle_config.bg_flee_penalty, 20, 0, INT_MAX, }, @@ -6461,19 +6697,25 @@ static const struct _battle_data { { "atcommand_mobinfo_type", &battle_config.atcommand_mobinfo_type, 0, 0, 1 }, { "homunculus_max_level", &battle_config.hom_max_level, 99, 0, MAX_LEVEL, }, { "homunculus_S_max_level", &battle_config.hom_S_max_level, 150, 0, MAX_LEVEL, }, - { "mob_size_influence", &battle_config.mob_size_influence, 0, 0, 1, }, + { "mob_size_influence", &battle_config.mob_size_influence, 0, 0, 1, }, /** * Hercules **/ { "skill_trap_type", &battle_config.skill_trap_type, 0, 0, 1, }, { "item_restricted_consumption_type", &battle_config.item_restricted_consumption_type,1, 0, 1, }, - { "max_walk_path", &battle_config.max_walk_path, 17, 1, MAX_WALKPATH, }, - { "item_enabled_npc", &battle_config.item_enabled_npc, 1, 0, 1, }, - { "gm_ignore_warpable_area", &battle_config.gm_ignore_warpable_area, 0, 2, 100, }, - { "packet_obfuscation", &battle_config.packet_obfuscation, 1, 0, 3, }, - { "client_accept_chatdori", &battle_config.client_accept_chatdori, 0, 0, INT_MAX, }, - { "snovice_call_type", &battle_config.snovice_call_type, 0, 0, 1, }, - { "guild_notice_changemap", &battle_config.guild_notice_changemap, 2, 0, 2, }, + { "max_walk_path", &battle_config.max_walk_path, 17, 1, MAX_WALKPATH, }, + { "item_enabled_npc", &battle_config.item_enabled_npc, 1, 0, 1, }, + { "gm_ignore_warpable_area", &battle_config.gm_ignore_warpable_area, 0, 2, 100, }, + { "packet_obfuscation", &battle_config.packet_obfuscation, 1, 0, 3, }, + { "client_accept_chatdori", &battle_config.client_accept_chatdori, 0, 0, INT_MAX, }, + { "snovice_call_type", &battle_config.snovice_call_type, 0, 0, 1, }, + { "guild_notice_changemap", &battle_config.guild_notice_changemap, 2, 0, 2, }, + { "feature.banking", &battle_config.feature_banking, 1, 0, 1, }, + { "feature.auction", &battle_config.feature_auction, 0, 0, 2, }, + { "idletime_criteria", &battle_config.idletime_criteria, 0x25, 1, INT_MAX, }, + + { "mon_trans_disable_in_gvg", &battle_config.mon_trans_disable_in_gvg, 0, 0, 1, }, + { "case_sensitive_aegisnames", &battle_config.case_sensitive_aegisnames, 1, 0, 1, }, }; #ifndef STATS_OPT_OUT /** @@ -6618,7 +6860,7 @@ void Hercules_report(char* date, char *time_c) { #undef BFLAG_LENGTH } -static int Hercules_report_timer(int tid, unsigned int tick, int id, intptr_t data) { +static int Hercules_report_timer(int tid, int64 tick, int id, intptr_t data) { if( chrif->isconnected() ) {/* char server relays it, so it must be online. */ Hercules_report(__DATE__,__TIME__); } @@ -6632,8 +6874,11 @@ int battle_set_value(const char* w1, const char* w2) int i; ARR_FIND(0, ARRAYLENGTH(battle_data), i, strcmpi(w1, battle_data[i].str) == 0); - if (i == ARRAYLENGTH(battle_data)) + if (i == ARRAYLENGTH(battle_data)) { + if( HPM->parseConf(w1,w2,HPCT_BATTLE) ) /* if plugin-owned, succeed */ + return 1; return 0; // not found + } if (val < battle_data[i].min || val > battle_data[i].max) { @@ -6695,6 +6940,22 @@ void battle_adjust_conf(void) { battle_config.feature_search_stores = 0; } #endif + +#if PACKETVER < 20130724 + if( battle_config.feature_banking ) { + ShowWarning("conf/battle/feature.conf banking is enabled but it requires PACKETVER 2013-07-24 or newer, disabling...\n"); + battle_config.feature_banking = 0; + } +#endif + +#if PACKETVER > 20120000 && PACKETVER < 20130515 /* exact date (when it started) not known */ + if( battle_config.feature_auction == 1 ) { + ShowWarning("conf/battle/feature.conf:feature.auction is enabled but it is not stable on PACKETVER "EXPAND_AND_QUOTE(PACKETVER)", disabling...\n"); + ShowWarning("conf/battle/feature.conf:feature.auction change value to '2' to silence this warning and maintain it enabled\n"); + battle_config.feature_auction = 0; + } +#endif + #ifndef CELL_NOSTACK if (battle_config.cell_stack_limit != 1) @@ -6744,9 +7005,12 @@ int battle_config_read(const char* cfgName) return 0; } -void do_init_battle(void) { +void do_init_battle(bool minimal) { + if (minimal) + return; + battle->delay_damage_ers = ers_new(sizeof(struct delay_damage),"battle.c::delay_damage_ers",ERS_OPT_CLEAR); - timer->add_func_list(battle_delay_damage_sub, "battle_delay_damage_sub"); + timer->add_func_list(battle->delay_damage_sub, "battle_delay_damage_sub"); #ifndef STATS_OPT_OUT timer->add_func_list(Hercules_report_timer, "Hercules_report_timer"); @@ -6779,12 +7043,13 @@ void battle_defaults(void) { battle->calc_weapon_attack = battle_calc_weapon_attack; battle->delay_damage = battle_delay_damage; battle->drain = battle_drain; - battle->calc_return_damage = battle_calc_return_damage; + battle->reflect_damage = battle_reflect_damage; battle->attr_ratio = battle_attr_ratio; battle->attr_fix = battle_attr_fix; battle->calc_cardfix = battle_calc_cardfix; battle->calc_elefix = battle_calc_elefix; battle->calc_masteryfix = battle_calc_masteryfix; + battle->calc_chorusbonus = battle_calc_chorusbonus; battle->calc_skillratio = battle_calc_skillratio; battle->calc_sizefix = battle_calc_sizefix; battle->calc_weapon_damage = battle_calc_weapon_damage; diff --git a/src/map/battle.h b/src/map/battle.h index 6d5d5f186..b57476cb4 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -2,8 +2,8 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _BATTLE_H_ -#define _BATTLE_H_ +#ifndef _MAP_BATTLE_H_ +#define _MAP_BATTLE_H_ #include "../common/cbasetypes.h" #include "map.h" //ELE_MAX @@ -21,14 +21,14 @@ struct status_data; /** * Defines **/ -#define MIN_HAIR_STYLE battle_config.min_hair_style -#define MAX_HAIR_STYLE battle_config.max_hair_style -#define MIN_HAIR_COLOR battle_config.min_hair_color -#define MAX_HAIR_COLOR battle_config.max_hair_color -#define MIN_CLOTH_COLOR battle_config.min_cloth_color -#define MAX_CLOTH_COLOR battle_config.max_cloth_color +#define MIN_HAIR_STYLE (battle_config.min_hair_style) +#define MAX_HAIR_STYLE (battle_config.max_hair_style) +#define MIN_HAIR_COLOR (battle_config.min_hair_color) +#define MAX_HAIR_COLOR (battle_config.max_hair_color) +#define MIN_CLOTH_COLOR (battle_config.min_cloth_color) +#define MAX_CLOTH_COLOR (battle_config.max_cloth_color) -#define is_boss(bl) (status_get_mode(bl)&MD_BOSS) // Can refine later [Aru] +#define is_boss(bl) (status_get_mode(bl)&MD_BOSS) // Can refine later [Aru] /** * Enumerations @@ -426,6 +426,7 @@ struct Battle_Config { int cashshop_show_points; int mail_show_status; int client_limit_unit_lv; + int client_emblem_max_blank_percent; int hom_max_level; int hom_S_max_level; @@ -443,7 +444,7 @@ struct Battle_Config { int mvp_tomb_enabled; int atcommand_suggestions_enabled; - int min_npc_vendchat_distance; + int min_npc_vendchat_distance; int atcommand_mobinfo_type; int mob_size_influence; // Enable modifications on earned experience, drop rates and monster status depending on monster size. [mkbu95] @@ -454,15 +455,35 @@ struct Battle_Config { int max_walk_path; int item_enabled_npc; int packet_obfuscation; - + int idletime_criteria; int gm_ignore_warpable_area; int client_accept_chatdori; // [Ai4rei/Mirei] int snovice_call_type; int guild_notice_changemap; + int feature_banking; + int feature_auction; + + int mon_trans_disable_in_gvg; + + int case_sensitive_aegisnames; } battle_config; +/* criteria for battle_config.idletime_critera */ +enum e_battle_config_idletime { + BCIDLE_WALK = 0x001, + BCIDLE_USESKILLTOID = 0x002, + BCIDLE_USESKILLTOPOS = 0x004, + BCIDLE_USEITEM = 0x008, + BCIDLE_ATTACK = 0x010, + BCIDLE_CHAT = 0x020, + BCIDLE_SIT = 0x040, + BCIDLE_EMOTION = 0x080, + BCIDLE_DROPITEM = 0x100, + BCIDLE_ATCOMMAND = 0x200, +}; + // Dammage delayed info struct delay_damage { int src_id; @@ -488,7 +509,7 @@ struct battle_interface { int attr_fix_table[4][ELE_MAX][ELE_MAX]; struct eri *delay_damage_ers; //For battle delay damage structures. /* init */ - void (*init) (void); + void (*init) (bool minimal); /* final */ void (*final) (void); /* damage calculation */ @@ -500,15 +521,15 @@ struct battle_interface { /* battlegrounds final damage calculation */ int64 (*calc_bg_damage) (struct block_list *src, struct block_list *bl, int64 damage, int div_, uint16 skill_id, uint16 skill_lv, int flag); /* normal weapon attack */ - enum damage_lv (*weapon_attack) (struct block_list *bl, struct block_list *target, unsigned int tick, int flag); + enum damage_lv (*weapon_attack) (struct block_list *bl, struct block_list *target, int64 tick, int flag); /* calculate weapon attack */ struct Damage (*calc_weapon_attack) (struct block_list *src,struct block_list *target,uint16 skill_id,uint16 skill_lv,int wflag); /* delays damage or skills by a timer */ - int (*delay_damage) (unsigned int tick, int amotion, struct block_list *src, struct block_list *target, int attack_type, uint16 skill_id, uint16 skill_lv, int64 damage, enum damage_lv dmg_lv, int ddelay, bool additional_effects); + int (*delay_damage) (int64 tick, int amotion, struct block_list *src, struct block_list *target, int attack_type, uint16 skill_id, uint16 skill_lv, int64 damage, enum damage_lv dmg_lv, int ddelay, bool additional_effects); /* drain damage */ void (*drain) (struct map_session_data *sd, struct block_list *tbl, int64 rdamage, int64 ldamage, int race, int boss); - /* damage return/reflect */ - int64 (*calc_return_damage) (struct block_list *bl, struct block_list *src, int64 *, int flag, uint16 skill_id, int *rdelay); + /* damage reflect */ + void (*reflect_damage) (struct block_list *target, struct block_list *src, struct Damage *wd,uint16 skill_id); /* attribute rate */ int (*attr_ratio) (int atk_elem, int def_type, int def_lv); /* applies attribute modifiers */ @@ -519,6 +540,8 @@ struct battle_interface { int64 (*calc_elefix) (struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int64 damage, int nk, int n_ele, int s_ele, int s_ele_, bool left, int flag); /* applies mastery modifiers */ int64 (*calc_masteryfix) (struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int64 damage, int div, bool left, bool weapon); + /* calculates chorus bonus */ + int (*calc_chorusbonus) (struct map_session_data *sd); /* applies skill modifiers */ int (*calc_skillratio) (int attack_type, struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int skillratio, int flag); /* applies size modifiers */ @@ -538,7 +561,7 @@ struct battle_interface { /* the current skill being processed/casted by this unit */ int (*get_current_skill) (struct block_list *bl); /* is either this race or element enough to be considered undead? */ - int (*check_undead) (int race,int element); + bool (*check_undead) (int race,int element); /* check if src and target are part of flag (e.g. enemies or allies) */ int (*check_target) (struct block_list *src, struct block_list *target,int flag); /* is src and bl within range? */ @@ -548,7 +571,7 @@ struct battle_interface { int (*get_targeted_sub) (struct block_list *bl, va_list ap); int (*get_enemy_sub) (struct block_list *bl, va_list ap); int (*get_enemy_area_sub) (struct block_list *bl, va_list ap); - int (*delay_damage_sub) (int tid, unsigned int tick, int id, intptr_t data); + int (*delay_damage_sub) (int tid, int64 tick, int id, intptr_t data); int (*blewcount_bonus) (struct map_session_data *sd, uint16 skill_id); /* skill range criteria */ int (*range_type) (struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv); @@ -569,10 +592,10 @@ struct battle_interface { /* picks a random enemy within the specified range */ struct block_list* (*get_enemy_area) (struct block_list *src, int x, int y, int range, int type, int ignore_id); /* damages area, originally for royal guard's reflect damage */ - int (*damage_area) ( struct block_list *bl, va_list ap); + int (*damage_area) (struct block_list *bl, va_list ap); }; struct battle_interface *battle; void battle_defaults(void); -#endif /* _BATTLE_H_ */ +#endif /* _MAP_BATTLE_H_ */ diff --git a/src/map/battleground.c b/src/map/battleground.c index e7fe4085b..65f475124 100644 --- a/src/map/battleground.c +++ b/src/map/battleground.c @@ -42,12 +42,12 @@ struct map_session_data* bg_getavailablesd(struct battleground_data *bgd) { } /// Deletes BG Team from db -int bg_team_delete(int bg_id) { +bool bg_team_delete(int bg_id) { int i; struct map_session_data *sd; struct battleground_data *bgd = bg->team_search(bg_id); - if( bgd == NULL ) return 0; + if( bgd == NULL ) return false; for( i = 0; i < MAX_BG_MEMBERS; i++ ) { if( (sd = bgd->members[i].sd) == NULL ) continue; @@ -56,35 +56,34 @@ int bg_team_delete(int bg_id) { sd->bg_id = 0; } idb_remove(bg->team_db, bg_id); - return 1; + return true; } /// Warps a Team -int bg_team_warp(int bg_id, unsigned short mapindex, short x, short y) { +bool bg_team_warp(int bg_id, unsigned short map_index, short x, short y) { int i; struct battleground_data *bgd = bg->team_search(bg_id); - if( bgd == NULL ) return 0; + if( bgd == NULL ) return false; for( i = 0; i < MAX_BG_MEMBERS; i++ ) - if( bgd->members[i].sd != NULL ) pc->setpos(bgd->members[i].sd, mapindex, x, y, CLR_TELEPORT); - return 1; + if( bgd->members[i].sd != NULL ) pc->setpos(bgd->members[i].sd, map_index, x, y, CLR_TELEPORT); + return true; } -int bg_send_dot_remove(struct map_session_data *sd) { +void bg_send_dot_remove(struct map_session_data *sd) { if( sd && sd->bg_id ) clif->bg_xy_remove(sd); - return 0; } /// Player joins team -int bg_team_join(int bg_id, struct map_session_data *sd) { +bool bg_team_join(int bg_id, struct map_session_data *sd) { int i; struct battleground_data *bgd = bg->team_search(bg_id); struct map_session_data *pl_sd; - if( bgd == NULL || sd == NULL || sd->bg_id ) return 0; + if( bgd == NULL || sd == NULL || sd->bg_id ) return false; ARR_FIND(0, MAX_BG_MEMBERS, i, bgd->members[i].sd == NULL); - if( i == MAX_BG_MEMBERS ) return 0; // No free slots + if( i == MAX_BG_MEMBERS ) return false; // No free slots sd->bg_id = bg_id; bgd->members[i].sd = sd; @@ -110,7 +109,7 @@ int bg_team_join(int bg_id, struct map_session_data *sd) { clif->bg_hp(sd); clif->bg_xy(sd); - return 1; + return true; } /// Single Player leaves team @@ -156,26 +155,26 @@ int bg_team_leave(struct map_session_data *sd, int flag) { } /// Respawn after killed -int bg_member_respawn(struct map_session_data *sd) { +bool bg_member_respawn(struct map_session_data *sd) { struct battleground_data *bgd; if( sd == NULL || !pc_isdead(sd) || !sd->bg_id || (bgd = bg->team_search(sd->bg_id)) == NULL ) - return 0; + return false; if( bgd->mapindex == 0 ) - return 0; // Respawn not handled by Core + return false; // Respawn not handled by Core pc->setpos(sd, bgd->mapindex, bgd->x, bgd->y, CLR_OUTSIGHT); status->revive(&sd->bl, 1, 100); - return 1; // Warped + return true; // Warped } -int bg_create(unsigned short mapindex, short rx, short ry, const char *ev, const char *dev) { +int bg_create(unsigned short map_index, short rx, short ry, const char *ev, const char *dev) { struct battleground_data *bgd; bg->team_counter++; CREATE(bgd, struct battleground_data, 1); bgd->bg_id = bg->team_counter; bgd->count = 0; - bgd->mapindex = mapindex; + bgd->mapindex = map_index; bgd->x = rx; bgd->y = ry; safestrncpy(bgd->logout_event, ev, sizeof(bgd->logout_event)); @@ -219,14 +218,14 @@ int bg_team_get_id(struct block_list *bl) { return 0; } -int bg_send_message(struct map_session_data *sd, const char *mes, int len) { +bool bg_send_message(struct map_session_data *sd, const char *mes, int len) { struct battleground_data *bgd; nullpo_ret(sd); if( sd->bg_id == 0 || (bgd = bg->team_search(sd->bg_id)) == NULL ) - return 0; + return false; // Couldn't send message clif->bg_message(bgd, sd->bl.id, sd->status.name, mes, len); - return 0; + return true; } /** @@ -249,7 +248,7 @@ int bg_send_xy_timer_sub(DBKey key, DBData *data, va_list ap) { return 0; } -int bg_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data) { +int bg_send_xy_timer(int tid, int64 tick, int id, intptr_t data) { bg->team_db->foreach(bg->team_db, bg->send_xy_timer_sub, tick); return 0; } @@ -258,34 +257,34 @@ void bg_config_read(void) { config_setting_t *data = NULL; const char *config_filename = "conf/battlegrounds.conf"; // FIXME hardcoded name - if (conf_read_file(&bg_conf, config_filename)) + if (libconfig->read_file(&bg_conf, config_filename)) return; - data = config_lookup(&bg_conf, "battlegrounds"); + data = libconfig->lookup(&bg_conf, "battlegrounds"); if (data != NULL) { - config_setting_t *settings = config_setting_get_elem(data, 0); + config_setting_t *settings = libconfig->setting_get_elem(data, 0); config_setting_t *arenas; const char *delay_var; int i, arena_count = 0, offline = 0; - if( !config_setting_lookup_string(settings, "global_delay_var", &delay_var) ) + if( !libconfig->setting_lookup_string(settings, "global_delay_var", &delay_var) ) delay_var = "BG_Delay_Tick"; safestrncpy(bg->gdelay_var, delay_var, BG_DELAY_VAR_LENGTH); - config_setting_lookup_int(settings, "maximum_afk_seconds", &bg->mafksec); + libconfig->setting_lookup_int(settings, "maximum_afk_seconds", &bg->mafksec); - config_setting_lookup_bool(settings, "feature_off", &offline); + libconfig->setting_lookup_bool(settings, "feature_off", &offline); if( offline == 0 ) bg->queue_on = true; - if( (arenas = config_setting_get_member(settings, "arenas")) != NULL ) { - arena_count = config_setting_length(arenas); + if( (arenas = libconfig->setting_get_member(settings, "arenas")) != NULL ) { + arena_count = libconfig->setting_length(arenas); CREATE( bg->arena, struct bg_arena *, arena_count ); for(i = 0; i < arena_count; i++) { - config_setting_t *arena = config_setting_get_elem(arenas, i); + config_setting_t *arena = libconfig->setting_get_elem(arenas, i); config_setting_t *reward; const char *aName, *aEvent, *aDelayVar; int minLevel = 0, maxLevel = 0; @@ -296,18 +295,18 @@ void bg_config_read(void) { bg->arena[i] = NULL; - if( !config_setting_lookup_string(arena, "name", &aName) ) { + if( !libconfig->setting_lookup_string(arena, "name", &aName) ) { ShowError("bg_config_read: failed to find 'name' for arena #%d\n",i); continue; } - if( !config_setting_lookup_string(arena, "event", &aEvent) ) { + if( !libconfig->setting_lookup_string(arena, "event", &aEvent) ) { ShowError("bg_config_read: failed to find 'event' for arena #%d\n",i); continue; } - config_setting_lookup_int(arena, "minLevel", &minLevel); - config_setting_lookup_int(arena, "maxLevel", &maxLevel); + libconfig->setting_lookup_int(arena, "minLevel", &minLevel); + libconfig->setting_lookup_int(arena, "maxLevel", &maxLevel); if( minLevel < 0 ) { ShowWarning("bg_config_read: invalid %d value for arena '%s' minLevel\n",minLevel,aName); @@ -318,14 +317,14 @@ void bg_config_read(void) { maxLevel = MAX_LEVEL; } - if( !(reward = config_setting_get_member(arena, "reward")) ) { + if( !(reward = libconfig->setting_get_member(arena, "reward")) ) { ShowError("bg_config_read: failed to find 'reward' for arena '%s'/#%d\n",aName,i); continue; } - config_setting_lookup_int(reward, "win", &prizeWin); - config_setting_lookup_int(reward, "loss", &prizeLoss); - config_setting_lookup_int(reward, "draw", &prizeDraw); + libconfig->setting_lookup_int(reward, "win", &prizeWin); + libconfig->setting_lookup_int(reward, "loss", &prizeLoss); + libconfig->setting_lookup_int(reward, "draw", &prizeDraw); if( prizeWin < 0 ) { ShowWarning("bg_config_read: invalid %d value for arena '%s' reward:win\n",prizeWin,aName); @@ -340,9 +339,9 @@ void bg_config_read(void) { prizeDraw = 0; } - config_setting_lookup_int(arena, "minPlayers", &minPlayers); - config_setting_lookup_int(arena, "maxPlayers", &maxPlayers); - config_setting_lookup_int(arena, "minTeamPlayers", &minTeamPlayers); + libconfig->setting_lookup_int(arena, "minPlayers", &minPlayers); + libconfig->setting_lookup_int(arena, "maxPlayers", &maxPlayers); + libconfig->setting_lookup_int(arena, "minTeamPlayers", &minTeamPlayers); if( minPlayers < 0 ) { ShowWarning("bg_config_read: invalid %d value for arena '%s' minPlayers\n",minPlayers,aName); @@ -357,20 +356,20 @@ void bg_config_read(void) { minTeamPlayers = 0; } - if( !config_setting_lookup_string(arena, "delay_var", &aDelayVar) ) { + if( !libconfig->setting_lookup_string(arena, "delay_var", &aDelayVar) ) { ShowError("bg_config_read: failed to find 'delay_var' for arena '%s'/#%d\n",aName,i); continue; } - config_setting_lookup_int(arena, "maxDuration", &maxDuration); + libconfig->setting_lookup_int(arena, "maxDuration", &maxDuration); if( maxDuration < 0 ) { ShowWarning("bg_config_read: invalid %d value for arena '%s' maxDuration\n",maxDuration,aName); maxDuration = 30; } - config_setting_lookup_int(arena, "fillDuration", &fillup_duration); - config_setting_lookup_int(arena, "pGameDuration", &pregame_duration); + libconfig->setting_lookup_int(arena, "fillDuration", &fillup_duration); + libconfig->setting_lookup_int(arena, "pGameDuration", &pregame_duration); if( fillup_duration < 20 ) { ShowWarning("bg_config_read: invalid %d value for arena '%s' fillDuration, minimum has to be 20, defaulting to 20.\n",fillup_duration,aName); @@ -409,7 +408,7 @@ void bg_config_read(void) { bg->arenas = arena_count; } - config_destroy(&bg_conf); + libconfig->destroy(&bg_conf); } } struct bg_arena *bg_name2arena (char *name) { @@ -496,7 +495,7 @@ void bg_match_over(struct bg_arena *arena, bool canceled) { if( canceled ) clif->colormes(sd->fd,COLOR_RED,"BG Match Cancelled: not enough players"); else { - pc_setglobalreg(sd, arena->delay_var, (unsigned int)time(NULL)); + pc_setglobalreg(sd, script->add_str(arena->delay_var), (unsigned int)time(NULL)); } } } @@ -520,13 +519,43 @@ void bg_begin(struct bg_arena *arena) { bg->queue_pc_cleanup(sd); } } + /* TODO/FIXME? I *think* it should check what kind of queue the player used, then check if his party/guild + * (his team) still meet the join criteria (sort of what bg->can_queue does) + */ if( count < arena->min_players ) { bg->match_over(arena,true); } else { arena->ongoing = true; - mapreg->setreg(script->add_str("$@bg_queue_id"),arena->queue_id);/* TODO: make this a arena-independant var? or just .@? */ + /* TODO: make this a arena-independant var? or just .@? */ + mapreg->setreg(script->add_str("$@bg_queue_id"),arena->queue_id); mapreg->setregstr(script->add_str("$@bg_delay_var$"),bg->gdelay_var); + + count = 0; + for( i = 0; i < queue->size; i++ ) { + struct map_session_data * sd = NULL; + + if( queue->item[i] > 0 && ( sd = map->id2sd(queue->item[i]) ) ) { + if( sd->bg_queue.ready == 1 ) { + + mapreg->setreg(reference_uid(script->add_str("$@bg_member"), count), sd->status.account_id); + + mapreg->setreg(reference_uid(script->add_str("$@bg_member_group"), count), + sd->bg_queue.type == BGQT_GUILD ? sd->status.guild_id : + sd->bg_queue.type == BGQT_PARTY ? sd->status.party_id : + 0 + ); + mapreg->setreg(reference_uid(script->add_str("$@bg_member_type"), count), + sd->bg_queue.type == BGQT_GUILD ? 1 : + sd->bg_queue.type == BGQT_PARTY ? 2 : + 0 + ); + count++; + } + } + } + mapreg->setreg(script->add_str("$@bg_member_size"),count); + npc->event_do(arena->npc_event); /* we split evenly? */ /* but if a party of say 10 joins, it cant be split evenly unless by luck there are 10 soloers in the queue besides them */ @@ -534,7 +563,7 @@ void bg_begin(struct bg_arena *arena) { /* currently running only on solo mode so we do it evenly */ } } -int bg_begin_timer(int tid, unsigned int tick, int id, intptr_t data) { +int bg_begin_timer(int tid, int64 tick, int id, intptr_t data) { bg->begin(bg->arena[id]); bg->arena[id]->begin_timer = INVALID_TIMER; return 0; @@ -553,7 +582,7 @@ void bg_queue_pregame(struct bg_arena *arena) { } arena->begin_timer = timer->add( timer->gettick() + (arena->pregame_duration*1000), bg->begin_timer, arena->id, 0 ); } -int bg_fillup_timer(int tid, unsigned int tick, int id, intptr_t data) { +int bg_fillup_timer(int tid, int64 tick, int id, intptr_t data) { bg->queue_pregame(bg->arena[id]); bg->arena[id]->fillup_timer = INVALID_TIMER; return 0; @@ -663,7 +692,7 @@ enum BATTLEGROUNDS_QUEUE_ACK bg_canqueue(struct map_session_data *sd, struct bg_ tsec = (unsigned int)time(NULL); - if ( ( tick = pc_readglobalreg(sd, bg->gdelay_var) ) && tsec < tick ) { + if ( ( tick = pc_readglobalreg(sd, script->add_str(bg->gdelay_var)) ) && tsec < tick ) { char response[100]; if( (tick-tsec) > 60 ) sprintf(response, "You are a deserter! Wait %d minute(s) before you can apply again",(tick-tsec)/60); @@ -673,7 +702,7 @@ enum BATTLEGROUNDS_QUEUE_ACK bg_canqueue(struct map_session_data *sd, struct bg_ return BGQA_FAIL_DESERTER; } - if ( ( tick = pc_readglobalreg(sd, arena->delay_var) ) && tsec < tick ) { + if ( ( tick = pc_readglobalreg(sd, script->add_str(arena->delay_var)) ) && tsec < tick ) { char response[100]; if( (tick-tsec) > 60 ) sprintf(response, "You can't reapply to this arena so fast. Apply to the different arena or wait %d minute(s)",(tick-tsec)/60); @@ -685,12 +714,7 @@ enum BATTLEGROUNDS_QUEUE_ACK bg_canqueue(struct map_session_data *sd, struct bg_ if( sd->bg_queue.arena != NULL ) return BGQA_DUPLICATE_REQUEST; - - if( type != BGQT_INDIVIDUAL ) {/* until we get the damn balancing correct */ - clif->colormes(sd->fd,COLOR_RED,"Queueing is only currently enabled only for Solo Mode"); - return BGQA_FAIL_TEAM_COUNT; - } - + switch(type) { case BGQT_GUILD: if( !sd->guild || !sd->state.gmaster_flag ) @@ -757,7 +781,10 @@ enum BATTLEGROUNDS_QUEUE_ACK bg_canqueue(struct map_session_data *sd, struct bg_ return BGQA_SUCCESS; } -void do_init_battleground(void) { +void do_init_battleground(bool minimal) { + if (minimal) + return; + bg->team_db = idb_alloc(DB_OPT_RELEASE_DATA); timer->add_func_list(bg->send_xy_timer, "bg_send_xy_timer"); timer->add_interval(timer->gettick() + battle_config.bg_update_interval, bg->send_xy_timer, 0, 0, battle_config.bg_update_interval); diff --git a/src/map/battleground.h b/src/map/battleground.h index 1c224e1c2..ed7347566 100644 --- a/src/map/battleground.h +++ b/src/map/battleground.h @@ -2,8 +2,8 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _BATTLEGROUND_H_ -#define _BATTLEGROUND_H_ +#ifndef _MAP_BATTLEGROUND_H_ +#define _MAP_BATTLEGROUND_H_ #include "../common/mmo.h" // struct party #include "clif.h" @@ -19,10 +19,11 @@ * Enumerations **/ enum bg_queue_types { - BGQT_INVALID, - BGQT_INDIVIDUAL, - BGQT_PARTY, - BGQT_GUILD + BGQT_INVALID = 0x0, + BGQT_INDIVIDUAL = 0x1, + BGQT_PARTY = 0x2, + /* yup no 0x3 */ + BGQT_GUILD = 0x4, }; struct battleground_member_data { @@ -75,7 +76,7 @@ struct battleground_interface { DBMap *team_db; // int bg_id -> struct battleground_data* unsigned int team_counter; // Next bg_id /* */ - void (*init) (void); + void (*init) (bool minimal); void (*final) (void); /* */ struct bg_arena *(*name2arena) (char *name); @@ -84,25 +85,25 @@ struct battleground_interface { int (*id2pos) (int queue_id, int account_id); void (*queue_pc_cleanup) (struct map_session_data *sd); void (*begin) (struct bg_arena *arena); - int (*begin_timer) (int tid, unsigned int tick, int id, intptr_t data); + int (*begin_timer) (int tid, int64 tick, int id, intptr_t data); void (*queue_pregame) (struct bg_arena *arena); - int (*fillup_timer) (int tid, unsigned int tick, int id, intptr_t data); + int (*fillup_timer) (int tid, int64 tick, int id, intptr_t data); void (*queue_ready_ack) (struct bg_arena *arena, struct map_session_data *sd, bool response); void (*match_over) (struct bg_arena *arena, bool canceled); void (*queue_check) (struct bg_arena *arena); struct battleground_data* (*team_search) (int bg_id); struct map_session_data* (*getavailablesd) (struct battleground_data *bgd); - int (*team_delete) (int bg_id); - int (*team_warp) (int bg_id, unsigned short mapindex, short x, short y); - int (*send_dot_remove) (struct map_session_data *sd); - int (*team_join) (int bg_id, struct map_session_data *sd); + bool (*team_delete) (int bg_id); + bool (*team_warp) (int bg_id, unsigned short map_index, short x, short y); + void (*send_dot_remove) (struct map_session_data *sd); + bool (*team_join) (int bg_id, struct map_session_data *sd); int (*team_leave) (struct map_session_data *sd, int flag); - int (*member_respawn) (struct map_session_data *sd); - int (*create) (unsigned short mapindex, short rx, short ry, const char *ev, const char *dev); + bool (*member_respawn) (struct map_session_data *sd); + int (*create) (unsigned short map_index, short rx, short ry, const char *ev, const char *dev); int (*team_get_id) (struct block_list *bl); - int (*send_message) (struct map_session_data *sd, const char *mes, int len); + bool (*send_message) (struct map_session_data *sd, const char *mes, int len); int (*send_xy_timer_sub) (DBKey key, DBData *data, va_list ap); - int (*send_xy_timer) (int tid, unsigned int tick, int id, intptr_t data); + int (*send_xy_timer) (int tid, int64 tick, int id, intptr_t data); /* */ void (*config_read) (void); }; @@ -111,4 +112,4 @@ struct battleground_interface *bg; void battleground_defaults(void); -#endif /* _BATTLEGROUND_H_ */ +#endif /* _MAP_BATTLEGROUND_H_ */ diff --git a/src/map/buyingstore.c b/src/map/buyingstore.c index 2a9e6a88e..2a15e66fc 100644 --- a/src/map/buyingstore.c +++ b/src/map/buyingstore.c @@ -76,7 +76,7 @@ void buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned cha return; } - if( !pc->can_give_items(sd) ) + if( !pc_can_give_items(sd) ) {// custom: GM is not allowed to buy (give zeny) sd->buyingstore.slots = 0; clif->message(sd->fd, msg_txt(246)); @@ -123,7 +123,7 @@ void buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned cha break; } - if( !id->flag.buyingstore || !itemdb->cantrade_sub(id, pc->get_group_level(sd), pc->get_group_level(sd)) || ( idx = pc->search_inventory(sd, nameid) ) == -1 ) + if( !id->flag.buyingstore || !itemdb->cantrade_sub(id, pc_get_group_level(sd), pc_get_group_level(sd)) || ( idx = pc->search_inventory(sd, nameid) ) == -1 ) {// restrictions: allowed, no character-bound items and at least one must be owned break; } @@ -197,7 +197,7 @@ void buyingstore_open(struct map_session_data* sd, int account_id) return; } - if( !pc->can_give_items(sd) ) + if( !pc_can_give_items(sd) ) {// custom: GM is not allowed to sell clif->message(sd->fd, msg_txt(246)); return; @@ -235,7 +235,7 @@ void buyingstore_trade(struct map_session_data* sd, int account_id, unsigned int return; } - if( !pc->can_give_items(sd) ) + if( !pc_can_give_items(sd) ) {// custom: GM is not allowed to sell clif->message(sd->fd, msg_txt(246)); clif->buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, 0); @@ -290,8 +290,8 @@ void buyingstore_trade(struct map_session_data* sd, int account_id, unsigned int return; } - if( sd->status.inventory[index].expire_time || !itemdb_cantrade(&sd->status.inventory[index], pc->get_group_level(sd), pc->get_group_level(pl_sd)) || memcmp(sd->status.inventory[index].card, buyingstore->blankslots, sizeof(buyingstore->blankslots)) ) - {// non-tradable item + if( sd->status.inventory[index].expire_time || (sd->status.inventory[index].bound && !pc_can_give_bound_items(sd)) || !itemdb_cantrade(&sd->status.inventory[index], pc_get_group_level(sd), pc_get_group_level(pl_sd)) || memcmp(sd->status.inventory[index].card, buyingstore->blankslots, sizeof(buyingstore->blankslots)) ) + {// non-tradable item clif->buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, nameid); return; } diff --git a/src/map/buyingstore.h b/src/map/buyingstore.h index b0db40661..5141a1013 100644 --- a/src/map/buyingstore.h +++ b/src/map/buyingstore.h @@ -2,8 +2,8 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _BUYINGSTORE_H_ -#define _BUYINGSTORE_H_ +#ifndef _MAP_BUYINGSTORE_H_ +#define _MAP_BUYINGSTORE_H_ /** * Declarations @@ -70,4 +70,4 @@ struct buyingstore_interface *buyingstore; void buyingstore_defaults (void); -#endif // _BUYINGSTORE_H_ +#endif // _MAP_BUYINGSTORE_H_ diff --git a/src/map/chat.c b/src/map/chat.c index 187d40337..549904ca6 100644 --- a/src/map/chat.c +++ b/src/map/chat.c @@ -54,11 +54,11 @@ struct chat_data* chat_createchat(struct block_list* bl, const char* title, cons if( cd->bl.id == 0 ) { aFree(cd); - cd = NULL; + return NULL; } map->addiddb(&cd->bl); - + if( bl->type != BL_NPC ) cd->kick_list = idb_alloc(DB_OPT_BASE); @@ -68,26 +68,26 @@ struct chat_data* chat_createchat(struct block_list* bl, const char* title, cons /*========================================== * player chatroom creation *------------------------------------------*/ -int chat_createpcchat(struct map_session_data* sd, const char* title, const char* pass, int limit, bool pub) { +bool chat_createpcchat(struct map_session_data* sd, const char* title, const char* pass, int limit, bool pub) { struct chat_data* cd; nullpo_ret(sd); if( sd->chatID ) - return 0; //Prevent people abusing the chat system by creating multiple chats, as pointed out by End of Exam. [Skotlex] + return false; //Prevent people abusing the chat system by creating multiple chats, as pointed out by End of Exam. [Skotlex] if( sd->state.vending || sd->state.buyingstore ) {// not chat, when you already have a store open - return 0; + return false; } if( map->list[sd->bl.m].flag.nochat ) { clif->message(sd->fd, msg_txt(281)); - return 0; //Can't create chatrooms on this map. + return false; //Can't create chatrooms on this map. } if( map->getcell(sd->bl.m,sd->bl.x,sd->bl.y,CELL_CHKNOCHAT) ) { - clif->message (sd->fd, msg_txt(665)); - return 0; + clif->message (sd->fd, msg_txt(665)); // "Can't create chat rooms in this area." + return false; } pc_stop_walking(sd,1); @@ -100,16 +100,17 @@ int chat_createpcchat(struct map_session_data* sd, const char* title, const char pc_stop_attack(sd); clif->createchat(sd,0); clif->dispchat(cd,0); - } else - clif->createchat(sd,1); + return true; + } + clif->createchat(sd,1); // 1 = Room limit exceeded - return 0; + return false; } /*========================================== * join an existing chatroom *------------------------------------------*/ -int chat_joinchat(struct map_session_data* sd, int chatid, const char* pass) { +bool chat_joinchat(struct map_session_data* sd, int chatid, const char* pass) { struct chat_data* cd; nullpo_ret(sd); @@ -117,33 +118,33 @@ int chat_joinchat(struct map_session_data* sd, int chatid, const char* pass) { if( cd == NULL || cd->bl.type != BL_CHAT || cd->bl.m != sd->bl.m || sd->state.vending || sd->state.buyingstore || sd->chatID || ((cd->owner->type == BL_NPC) ? cd->users+1 : cd->users) >= cd->limit ) { - clif->joinchatfail(sd,0); - return 0; + clif->joinchatfail(sd,0); // room full + return false; } - if( !cd->pub && strncmp(pass, cd->pass, sizeof(cd->pass)) != 0 && !pc->has_permission(sd, PC_PERM_JOIN_ALL_CHAT) ) + if( !cd->pub && strncmp(pass, cd->pass, sizeof(cd->pass)) != 0 && !pc_has_permission(sd, PC_PERM_JOIN_ALL_CHAT) ) { - clif->joinchatfail(sd,1); - return 0; + clif->joinchatfail(sd,1); // wrong password + return false; } if( sd->status.base_level < cd->minLvl || sd->status.base_level > cd->maxLvl ) { if(sd->status.base_level < cd->minLvl) - clif->joinchatfail(sd,5); + clif->joinchatfail(sd,5); // too low level else - clif->joinchatfail(sd,6); + clif->joinchatfail(sd,6); // too high level - return 0; + return false; } if( sd->status.zeny < cd->zeny ) { - clif->joinchatfail(sd,4); - return 0; + clif->joinchatfail(sd,4); // not enough zeny + return false; } if( cd->owner->type != BL_NPC && idb_exists(cd->kick_list,sd->status.char_id) ) { - clif->joinchatfail(sd,2);//You have been kicked out of the room. - return 0; + clif->joinchatfail(sd,2); // You have been kicked out of the room. + return false; } pc_stop_walking(sd,1); @@ -158,31 +159,36 @@ int chat_joinchat(struct map_session_data* sd, int chatid, const char* pass) { chat->trigger_event(cd); //Event - return 0; + return true; } /*========================================== - * leave a chatroom + * Leave a chatroom + * Return + * 0: User not found in chatroom/Missing data + * 1: Success + * 2: Chat room deleted (chat room empty) + * 3: Owner changed (Owner left and a new one as assigned) *------------------------------------------*/ int chat_leavechat(struct map_session_data* sd, bool kicked) { struct chat_data* cd; int i; int leavechar; - nullpo_retr(1, sd); + nullpo_retr(0, sd); cd = (struct chat_data*)map->id2bl(sd->chatID); if( cd == NULL ) { pc_setchatid(sd, 0); - return 1; + return 0; } ARR_FIND( 0, cd->users, i, cd->usersd[i] == sd ); if ( i == cd->users ) { // Not found in the chatroom? pc_setchatid(sd, 0); - return -1; + return 0; } clif->leavechat(cd, sd, kicked); @@ -210,7 +216,7 @@ int chat_leavechat(struct map_session_data* sd, bool kicked) { if (group != NULL) skill->unit_onplace(su, &sd->bl, group->tick); - return 1; + return 2; } if( leavechar == 0 && cd->owner->type == BL_PC ) { @@ -226,29 +232,33 @@ int chat_leavechat(struct map_session_data* sd, bool kicked) { map->addblock( &cd->bl ); clif->dispchat(cd,0); - } else - clif->dispchat(cd,0); // refresh chatroom + return 3; // Owner changed + } + clif->dispchat(cd,0); // refresh chatroom - return 0; + return 1; } /*========================================== - * change a chatroom's owner + * Change a chatroom's owner + * Return + * 0: User not found/Missing data + * 1: Success *------------------------------------------*/ -int chat_changechatowner(struct map_session_data* sd, const char* nextownername) { +bool chat_changechatowner(struct map_session_data* sd, const char* nextownername) { struct chat_data* cd; struct map_session_data* tmpsd; int i; - nullpo_retr(1, sd); + nullpo_ret(sd); cd = (struct chat_data*)map->id2bl(sd->chatID); if( cd == NULL || (struct block_list*) sd != cd->owner ) - return 1; + return false; ARR_FIND( 1, cd->users, i, strncmp(cd->usersd[i]->status.name, nextownername, NAME_LENGTH) == 0 ); if( i == cd->users ) - return -1; // name not found + return false; // name not found // erase temporarily clif->clearchat(cd,0); @@ -271,20 +281,23 @@ int chat_changechatowner(struct map_session_data* sd, const char* nextownername) // and display again clif->dispchat(cd,0); - return 0; + return true; } /*========================================== - * change a chatroom's status (title, etc) + * Change a chatroom's status (title, etc) + * Return + * 0: Missing data + * 1: Success *------------------------------------------*/ -int chat_changechatstatus(struct map_session_data* sd, const char* title, const char* pass, int limit, bool pub) { +bool chat_changechatstatus(struct map_session_data* sd, const char* title, const char* pass, int limit, bool pub) { struct chat_data* cd; - nullpo_retr(1, sd); + nullpo_ret(sd); cd = (struct chat_data*)map->id2bl(sd->chatID); if( cd==NULL || (struct block_list *)sd != cd->owner ) - return 1; + return false; safestrncpy(cd->title, title, CHATROOM_TITLE_SIZE); safestrncpy(cd->pass, pass, CHATROOM_PASS_SIZE); @@ -294,50 +307,55 @@ int chat_changechatstatus(struct map_session_data* sd, const char* title, const clif->changechatstatus(cd); clif->dispchat(cd,0); - return 0; + return true; } /*========================================== - * kick an user from a chatroom + * Kick an user from a chatroom + * Return: + * 0: User cannot be kicked (is gm)/Missing data + * 1: Success *------------------------------------------*/ -int chat_kickchat(struct map_session_data* sd, const char* kickusername) { +bool chat_kickchat(struct map_session_data* sd, const char* kickusername) { struct chat_data* cd; int i; - nullpo_retr(1, sd); + nullpo_ret(sd); cd = (struct chat_data *)map->id2bl(sd->chatID); if( cd==NULL || (struct block_list *)sd != cd->owner ) - return -1; + return false; ARR_FIND( 0, cd->users, i, strncmp(cd->usersd[i]->status.name, kickusername, NAME_LENGTH) == 0 ); - if( i == cd->users ) - return -1; + if( i == cd->users ) // User not found + return false; - if (pc->has_permission(cd->usersd[i], PC_PERM_NO_CHAT_KICK)) - return 0; //gm kick protection [Valaris] + if (pc_has_permission(cd->usersd[i], PC_PERM_NO_CHAT_KICK)) + return false; //gm kick protection [Valaris] - idb_put(cd->kick_list,cd->usersd[i]->status.char_id,(void*)1); + idb_iput(cd->kick_list,cd->usersd[i]->status.char_id,1); chat->leave(cd->usersd[i],1); - return 0; + return true; } -/// Creates a chat room for the npc. -int chat_createnpcchat(struct npc_data* nd, const char* title, int limit, bool pub, int trigger, const char* ev, int zeny, int minLvl, int maxLvl) +/*========================================== + * Creates a chat room for the npc + *------------------------------------------*/ +bool chat_createnpcchat(struct npc_data* nd, const char* title, int limit, bool pub, int trigger, const char* ev, int zeny, int minLvl, int maxLvl) { struct chat_data* cd; nullpo_ret(nd); if( nd->chat_id ) { ShowError("chat_createnpcchat: npc '%s' already has a chatroom, cannot create new one!\n", nd->exname); - return 0; + return false; } if( zeny > MAX_ZENY || maxLvl > MAX_LEVEL ) { ShowError("chat_createnpcchat: npc '%s' has a required lvl or amount of zeny over the max limit!\n", nd->exname); - return 0; + return false; } cd = chat->create(&nd->bl, title, "", limit, pub, trigger, ev, zeny, minLvl, maxLvl); @@ -345,19 +363,25 @@ int chat_createnpcchat(struct npc_data* nd, const char* title, int limit, bool p if( cd ) { nd->chat_id = cd->bl.id; clif->dispchat(cd,0); + return true; } - return 0; + return false; } -/// Removes the chatroom from the npc. -int chat_deletenpcchat(struct npc_data* nd) { +/*========================================== + * Removes the chatroom from the npc. + * Return: + * 0: Missing data + * 1: Success + *------------------------------------------*/ +bool chat_deletenpcchat(struct npc_data* nd) { struct chat_data *cd; nullpo_ret(nd); cd = (struct chat_data*)map->id2bl(nd->chat_id); if( cd == NULL ) - return 0; + return false; chat->npc_kick_all(cd); clif->clearchat(cd, 0); @@ -366,50 +390,56 @@ int chat_deletenpcchat(struct npc_data* nd) { map->freeblock(&cd->bl); nd->chat_id = 0; - return 0; + return true; } /*========================================== * Trigger npc event when we enter the chatroom + * Return + * 0: Couldn't trigger / Missing data + * 1: Success *------------------------------------------*/ -int chat_triggerevent(struct chat_data *cd) +bool chat_triggerevent(struct chat_data *cd) { nullpo_ret(cd); if( cd->users >= cd->trigger && cd->npc_event[0] ) + { npc->event_do(cd->npc_event); - return 0; + return true; + } + return false; } /// Enables the event of the chat room. /// At most, 127 users are needed to trigger the event. -int chat_enableevent(struct chat_data* cd) +bool chat_enableevent(struct chat_data* cd) { nullpo_ret(cd); cd->trigger &= 0x7f; chat->trigger_event(cd); - return 0; + return true; } /// Disables the event of the chat room -int chat_disableevent(struct chat_data* cd) +bool chat_disableevent(struct chat_data* cd) { nullpo_ret(cd); cd->trigger |= 0x80; - return 0; + return true; } /// Kicks all the users from the chat room. -int chat_npckickall(struct chat_data* cd) +bool chat_npckickall(struct chat_data* cd) { nullpo_ret(cd); while( cd->users > 0 ) chat->leave(cd->usersd[cd->users-1],0); - return 0; + return true; } /*===================================== diff --git a/src/map/chat.h b/src/map/chat.h index 695e59b6e..71e5a11ec 100644 --- a/src/map/chat.h +++ b/src/map/chat.h @@ -2,8 +2,8 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _CHAT_H_ -#define _CHAT_H_ +#ifndef _MAP_CHAT_H_ +#define _MAP_CHAT_H_ #include "map.h" // struct block_list, CHATROOM_TITLE_SIZE @@ -36,18 +36,18 @@ struct chat_data { struct chat_interface { /* funcs */ - int (*create_pc_chat) (struct map_session_data* sd, const char* title, const char* pass, int limit, bool pub); - int (*join) (struct map_session_data* sd, int chatid, const char* pass); + bool (*create_pc_chat) (struct map_session_data* sd, const char* title, const char* pass, int limit, bool pub); + bool (*join) (struct map_session_data* sd, int chatid, const char* pass); int (*leave) (struct map_session_data* sd, bool kicked); - int (*change_owner) (struct map_session_data* sd, const char* nextownername); - int (*change_status) (struct map_session_data* sd, const char* title, const char* pass, int limit, bool pub); - int (*kick) (struct map_session_data* sd, const char* kickusername); - int (*create_npc_chat) (struct npc_data* nd, const char* title, int limit, bool pub, int trigger, const char* ev, int zeny, int minLvl, int maxLvl); - int (*delete_npc_chat) (struct npc_data* nd); - int (*enable_event) (struct chat_data* cd); - int (*disable_event) (struct chat_data* cd); - int (*npc_kick_all) (struct chat_data* cd); - int (*trigger_event) (struct chat_data *cd); + bool (*change_owner) (struct map_session_data* sd, const char* nextownername); + bool (*change_status) (struct map_session_data* sd, const char* title, const char* pass, int limit, bool pub); + bool (*kick) (struct map_session_data* sd, const char* kickusername); + bool (*create_npc_chat) (struct npc_data* nd, const char* title, int limit, bool pub, int trigger, const char* ev, int zeny, int minLvl, int maxLvl); + bool (*delete_npc_chat) (struct npc_data* nd); + bool (*enable_event) (struct chat_data* cd); + bool (*disable_event) (struct chat_data* cd); + bool (*npc_kick_all) (struct chat_data* cd); + bool (*trigger_event) (struct chat_data *cd); struct chat_data* (*create) (struct block_list* bl, const char* title, const char* pass, int limit, bool pub, int trigger, const char* ev, int zeny, int minLvl, int maxLvl); }; @@ -55,4 +55,4 @@ struct chat_interface *chat; void chat_defaults(void); -#endif /* _CHAT_H_ */ +#endif /* _MAP_CHAT_H_ */ diff --git a/src/map/chrif.c b/src/map/chrif.c index 01af69fbf..301c8ec66 100644 --- a/src/map/chrif.c +++ b/src/map/chrif.c @@ -88,7 +88,7 @@ struct chrif_interface chrif_s; //2b27: Incoming, chrif_authfail -> 'client authentication failed' //This define should spare writing the check in every function. [Skotlex] -#define chrif_check(a) { if(!chrif->isconnected()) return a; } +#define chrif_check(a) do { if(!chrif->isconnected()) return a; } while(0) /// Resets all the data. void chrif_reset(void) { @@ -119,18 +119,23 @@ struct auth_node* chrif_auth_check(int account_id, int char_id, enum sd_state st bool chrif_auth_delete(int account_id, int char_id, enum sd_state state) { struct auth_node *node; - + if ( (node = chrif->auth_check(account_id, char_id, state) ) ) { int fd = node->sd ? node->sd->fd : node->fd; if ( session[fd] && session[fd]->session_data == node->sd ) session[fd]->session_data = NULL; - if ( node->char_dat ) - aFree(node->char_dat); - - if ( node->sd ) + if ( node->sd ) { + + if( node->sd->var_db ) + node->sd->var_db->destroy(node->sd->var_db,script->reg_destroy); + + if( node->sd->array_db ) + node->sd->array_db->destroy(node->sd->array_db,script->array_free_db); + aFree(node->sd); + } ers_free(chrif->auth_db_ers, node); idb_remove(chrif->auth_db,account_id); @@ -211,20 +216,19 @@ void chrif_checkdefaultlogin(void) { } // sets char-server's ip address -int chrif_setip(const char* ip) { +bool chrif_setip(const char* ip) { char ip_str[16]; if ( !( chrif->ip = host2ip(ip) ) ) { ShowWarning("Failed to Resolve Char Server Address! (%s)\n", ip); - - return 0; + return false; } safestrncpy(chrif->ip_str, ip, sizeof(chrif->ip_str)); ShowInfo("Char Server IP Address : '"CL_WHITE"%s"CL_RESET"' -> '"CL_WHITE"%s"CL_RESET"'.\n", ip, ip2str(chrif->ip, ip_str)); - return 1; + return true; } // sets char-server's port number @@ -242,8 +246,8 @@ int chrif_isconnected(void) { * Flag = 1: Character is quitting * Flag = 2: Character is changing map-servers *------------------------------------------*/ -int chrif_save(struct map_session_data *sd, int flag) { - nullpo_retr(-1, sd); +bool chrif_save(struct map_session_data *sd, int flag) { + nullpo_ret(sd); pc->makesavestatus(sd); @@ -255,7 +259,7 @@ int chrif_save(struct map_session_data *sd, int flag) { ShowError("chrif_save: Failed to set up player %d:%d for proper quitting!\n", sd->status.account_id, sd->status.char_id); } - chrif_check(-1); //Character is saved on reconnect. + chrif_check(false); //Character is saved on reconnect. //For data sync if (sd->state.storage_flag == 2) @@ -265,12 +269,8 @@ int chrif_save(struct map_session_data *sd, int flag) { sd->state.storage_flag = 0; //Force close it. //Saving of registry values. - if (sd->state.reg_dirty&4) - intif->saveregistry(sd, 3); //Save char regs - if (sd->state.reg_dirty&2) - intif->saveregistry(sd, 2); //Save account regs - if (sd->state.reg_dirty&1) - intif->saveregistry(sd, 1); //Save account2 regs + if (sd->vars_dirty) + intif->saveregistry(sd); WFIFOHEAD(chrif->fd, sizeof(sd->status) + 13); WFIFOW(chrif->fd,0) = 0x2b01; @@ -292,11 +292,11 @@ int chrif_save(struct map_session_data *sd, int flag) { if( sd->save_quest ) intif->quest_save(sd); - return 0; + return true; } // connects to char-server (plaintext) -int chrif_connect(int fd) { +void chrif_connect(int fd) { ShowStatus("Logging in to char server...\n", chrif->fd); WFIFOHEAD(fd,60); WFIFOW(fd,0) = 0x2af8; @@ -306,12 +306,10 @@ int chrif_connect(int fd) { WFIFOL(fd,54) = htonl(clif->map_ip); WFIFOW(fd,58) = htons(clif->map_port); WFIFOSET(fd,60); - - return 0; } // sends maps to char-server -int chrif_sendmap(int fd) { +void chrif_sendmap(int fd) { int i; ShowStatus("Sending maps to char server...\n"); @@ -323,12 +321,10 @@ int chrif_sendmap(int fd) { WFIFOW(fd,4+i*4) = map_id2index(i); WFIFOW(fd,2) = 4 + i * 4; WFIFOSET(fd,WFIFOW(fd,2)); - - return 0; } // receive maps from some other map-server (relayed via char-server) -int chrif_recvmap(int fd) { +void chrif_recvmap(int fd) { int i, j; uint32 ip = ntohl(RFIFOL(fd,4)); uint16 port = ntohs(RFIFOW(fd,8)); @@ -341,12 +337,10 @@ int chrif_recvmap(int fd) { ShowStatus("Received maps from %d.%d.%d.%d:%d (%d maps)\n", CONVIP(ip), port, j); chrif->other_mapserver_count++; - - return 0; } // remove specified maps (used when some other map-server disconnects) -int chrif_removemap(int fd) { +void chrif_removemap(int fd) { int i, j; uint32 ip = RFIFOL(fd,4); uint16 port = RFIFOW(fd,8); @@ -358,8 +352,6 @@ int chrif_removemap(int fd) { if(battle_config.etc_log) ShowStatus("remove map of server %d.%d.%d.%d:%d (%d maps)\n", CONVIP(ip), port, j); - - return 0; } // received after a character has been "final saved" on the char-server @@ -369,15 +361,15 @@ void chrif_save_ack(int fd) { } // request to move a character between mapservers -int chrif_changemapserver(struct map_session_data* sd, uint32 ip, uint16 port) { - nullpo_retr(-1, sd); +bool chrif_changemapserver(struct map_session_data* sd, uint32 ip, uint16 port) { + nullpo_ret(sd); if (chrif->other_mapserver_count < 1) {//No other map servers are online! clif->authfail_fd(sd->fd, 0); - return -1; + return false; } - chrif_check(-1); + chrif_check(false); WFIFOHEAD(chrif->fd,35); WFIFOW(chrif->fd, 0) = 0x2b05; @@ -395,19 +387,19 @@ int chrif_changemapserver(struct map_session_data* sd, uint32 ip, uint16 port) { WFIFOL(chrif->fd,35) = sd->group_id; WFIFOSET(chrif->fd,39); - return 0; + return true; } /// map-server change request acknowledgement (positive or negative) /// R 2b06 <account_id>.L <login_id1>.L <login_id2>.L <char_id>.L <map_index>.W <x>.W <y>.W <ip>.L <port>.W -int chrif_changemapserverack(int account_id, int login_id1, int login_id2, int char_id, short map_index, short x, short y, uint32 ip, uint16 port) { +bool chrif_changemapserverack(int account_id, int login_id1, int login_id2, int char_id, short map_index, short x, short y, uint32 ip, uint16 port) { struct auth_node *node; if ( !( node = chrif->auth_check(account_id, char_id, ST_MAPCHANGE) ) ) - return -1; + return false; if ( !login_id1 ) { - ShowError("map server change failed.\n"); + ShowError("chrif_changemapserverack: map server change failed.\n"); clif->authfail_fd(node->fd, 0); } else clif->changemapserver(node->sd, map_index, x, y, ntohl(ip), ntohs(port)); @@ -415,13 +407,13 @@ int chrif_changemapserverack(int account_id, int login_id1, int login_id2, int c //Player has been saved already, remove him from memory. [Skotlex] chrif->auth_delete(account_id, char_id, ST_MAPCHANGE); - return 0; + return (!login_id1)?false:true; // Is this the best approach here? } /*========================================== * *------------------------------------------*/ -int chrif_connectack(int fd) { +void chrif_connectack(int fd) { static bool char_init_done = false; if (RFIFOB(fd,2)) { @@ -442,10 +434,8 @@ int chrif_connectack(int fd) { guild->castle_map_init(); } - socket_datasync(fd, true); + sockt->datasync(fd, true); chrif->skillid2idx(fd); - - return 0; } /** @@ -456,9 +446,9 @@ int chrif_reconnect(DBKey key, DBData *data, va_list ap) { switch (node->state) { case ST_LOGIN: - if ( node->sd && node->char_dat == NULL ) {//Since there is no way to request the char auth, make it fail. + if ( node->sd ) {//Since there is no way to request the char auth, make it fail. pc->authfail(node->sd); - chrif->char_offline(node->sd); + chrif_char_offline(node->sd); chrif->auth_delete(node->account_id, node->char_id, ST_LOGIN); } break; @@ -475,7 +465,6 @@ int chrif_reconnect(DBKey key, DBData *data, va_list ap) { chrif->changemapserver(sd, ip, port); else //too much lag/timeout is the closest explanation for this error. clif->authfail_fd(sd->fd, 3); - break; } } @@ -486,6 +475,7 @@ int chrif_reconnect(DBKey key, DBData *data, va_list ap) { /// Called when all the connection steps are completed. void chrif_on_ready(void) { + static bool once = false; ShowStatus("Map Server is now online.\n"); chrif->state = 2; @@ -503,13 +493,20 @@ void chrif_on_ready(void) { //Re-save any guild castles that were modified in the disconnection time. guild->castle_reconnect(-1, 0, 0); + + if( !once ) { +#ifdef AUTOTRADE_PERSISTENCY + pc->autotrade_load(); +#endif + once = true; + } } /*========================================== * *------------------------------------------*/ -int chrif_sendmapack(int fd) { +void chrif_sendmapack(int fd) { if (RFIFOB(fd,2)) { ShowFatalError("chrif : send map list to char server failed %d\n", RFIFOB(fd,2)); @@ -519,17 +516,15 @@ int chrif_sendmapack(int fd) { memcpy(map->wisp_server_name, RFIFOP(fd,3), NAME_LENGTH); chrif->on_ready(); - - return 0; } /*========================================== * Request sc_data from charserver [Skotlex] *------------------------------------------*/ -int chrif_scdata_request(int account_id, int char_id) { +bool chrif_scdata_request(int account_id, int char_id) { #ifdef ENABLE_SC_SAVING - chrif_check(-1); + chrif_check(false); WFIFOHEAD(chrif->fd,10); WFIFOW(chrif->fd,0) = 0x2afc; @@ -538,28 +533,29 @@ int chrif_scdata_request(int account_id, int char_id) { WFIFOSET(chrif->fd,10); #endif - return 0; + return true; } /*========================================== * Request auth confirmation *------------------------------------------*/ -void chrif_authreq(struct map_session_data *sd) { +void chrif_authreq(struct map_session_data *sd, bool hstandalone) { struct auth_node *node= chrif->search(sd->bl.id); - + if( node != NULL || !chrif->isconnected() ) { set_eof(sd->fd); return; } - WFIFOHEAD(chrif->fd,19); + WFIFOHEAD(chrif->fd,20); WFIFOW(chrif->fd,0) = 0x2b26; WFIFOL(chrif->fd,2) = sd->status.account_id; WFIFOL(chrif->fd,6) = sd->status.char_id; WFIFOL(chrif->fd,10) = sd->login_id1; WFIFOB(chrif->fd,14) = sd->status.sex; WFIFOL(chrif->fd,15) = htonl(session[sd->fd]->client_addr); - WFIFOSET(chrif->fd,19); + WFIFOB(chrif->fd,19) = hstandalone ? 1 : 0; + WFIFOSET(chrif->fd,20); chrif->sd_to_auth(sd, ST_LOGIN); } @@ -594,7 +590,7 @@ void chrif_authok(int fd) { //Causes problems if the currently connected player tries to quit or this data belongs to an already connected player which is trying to re-auth. if ( ( sd = map->id2sd(account_id) ) != NULL ) return; - + if ( ( node = chrif->search(account_id) ) == NULL ) return; // should not happen @@ -613,7 +609,6 @@ void chrif_authok(int fd) { sd = node->sd; if( runflag == MAPSERVER_ST_RUNNING && - node->char_dat == NULL && node->account_id == account_id && node->char_id == char_id && node->login_id1 == login_id1 ) @@ -624,7 +619,7 @@ void chrif_authok(int fd) { pc->authfail(sd); } - chrif->char_offline(sd); //Set him offline, the char server likely has it set as online already. + chrif_char_offline(sd); //Set him offline, the char server likely has it set as online already. chrif->auth_delete(account_id, char_id, ST_LOGIN); } @@ -682,22 +677,22 @@ int auth_db_cleanup_sub(DBKey key, DBData *data, va_list ap) { return 0; } -int auth_db_cleanup(int tid, unsigned int tick, int id, intptr_t data) { +int auth_db_cleanup(int tid, int64 tick, int id, intptr_t data) { chrif_check(0); chrif->auth_db->foreach(chrif->auth_db, chrif->auth_db_cleanup_sub); return 0; } /*========================================== - * + * Request char selection *------------------------------------------*/ -int chrif_charselectreq(struct map_session_data* sd, uint32 s_ip) { - nullpo_retr(-1, sd); +bool chrif_charselectreq(struct map_session_data* sd, uint32 s_ip) { + nullpo_ret(sd); - if( !sd || !sd->bl.id || !sd->login_id1 ) - return -1; + if( !sd->bl.id || !sd->login_id1 ) + return false; - chrif_check(-1); + chrif_check(false); WFIFOHEAD(chrif->fd,18); WFIFOW(chrif->fd, 0) = 0x2b02; @@ -707,36 +702,36 @@ int chrif_charselectreq(struct map_session_data* sd, uint32 s_ip) { WFIFOL(chrif->fd,14) = htonl(s_ip); WFIFOSET(chrif->fd,18); - return 0; + return true; } /*========================================== * Search Char trough id on char serv *------------------------------------------*/ -int chrif_searchcharid(int char_id) { +bool chrif_searchcharid(int char_id) { if( !char_id ) - return -1; + return false; - chrif_check(-1); + chrif_check(false); WFIFOHEAD(chrif->fd,6); WFIFOW(chrif->fd,0) = 0x2b08; WFIFOL(chrif->fd,2) = char_id; WFIFOSET(chrif->fd,6); - return 0; + return true; } /*========================================== * Change Email *------------------------------------------*/ -int chrif_changeemail(int id, const char *actual_email, const char *new_email) { +bool chrif_changeemail(int id, const char *actual_email, const char *new_email) { if (battle_config.etc_log) ShowInfo("chrif_changeemail: account: %d, actual_email: '%s', new_email: '%s'.\n", id, actual_email, new_email); - chrif_check(-1); + chrif_check(false); WFIFOHEAD(chrif->fd,86); WFIFOW(chrif->fd,0) = 0x2b0c; @@ -745,18 +740,18 @@ int chrif_changeemail(int id, const char *actual_email, const char *new_email) { memcpy(WFIFOP(chrif->fd,46), new_email, 40); WFIFOSET(chrif->fd,86); - return 0; + return true; } /*========================================== * S 2b0e <accid>.l <name>.24B <type>.w { <year>.w <month>.w <day>.w <hour>.w <minute>.w <second>.w } * Send an account modification request to the login server (via char server). * type of operation: - * 1: block, 2: ban, 3: unblock, 4: unban, 5: changesex (use next function for 5) + * 1: block, 2: ban, 3: unblock, 4: unban, 5: changesex (use next function for 5), 6: charban *------------------------------------------*/ -int chrif_char_ask_name(int acc, const char* character_name, unsigned short operation_type, int year, int month, int day, int hour, int minute, int second) { +bool chrif_char_ask_name(int acc, const char* character_name, unsigned short operation_type, int year, int month, int day, int hour, int minute, int second) { - chrif_check(-1); + chrif_check(false); WFIFOHEAD(chrif->fd,44); WFIFOW(chrif->fd,0) = 0x2b0e; @@ -764,7 +759,7 @@ int chrif_char_ask_name(int acc, const char* character_name, unsigned short oper safestrncpy((char*)WFIFOP(chrif->fd,6), character_name, NAME_LENGTH); WFIFOW(chrif->fd,30) = operation_type; - if ( operation_type == 2 ) { + if ( operation_type == 2 || operation_type == 6 ) { WFIFOW(chrif->fd,32) = year; WFIFOW(chrif->fd,34) = month; WFIFOW(chrif->fd,36) = day; @@ -774,11 +769,11 @@ int chrif_char_ask_name(int acc, const char* character_name, unsigned short oper } WFIFOSET(chrif->fd,44); - return 0; + return true; } -int chrif_changesex(struct map_session_data *sd) { - chrif_check(-1); +bool chrif_changesex(struct map_session_data *sd) { + chrif_check(false); WFIFOHEAD(chrif->fd,44); WFIFOW(chrif->fd,0) = 0x2b0e; @@ -793,39 +788,44 @@ int chrif_changesex(struct map_session_data *sd) { clif->authfail_fd(sd->fd, 15); else map->quit(sd); - return 0; + return true; } /*========================================== * R 2b0f <accid>.l <name>.24B <type>.w <answer>.w * Processing a reply to chrif->char_ask_name() (request to modify an account). * type of operation: - * 1: block, 2: ban, 3: unblock, 4: unban, 5: changesex + * 1: block, 2: ban, 3: unblock, 4: unban, 5: changesex, 6: charban, 7: charunban * type of answer: * 0: login-server request done * 1: player not found * 2: gm level too low * 3: login-server offline *------------------------------------------*/ -void chrif_char_ask_name_answer(int acc, const char* player_name, uint16 type, uint16 answer) { +bool chrif_char_ask_name_answer(int acc, const char* player_name, uint16 type, uint16 answer) { struct map_session_data* sd; char action[25]; char output[256]; + bool charsrv = ( type == 6 || type == 7 ) ? true : false; sd = map->id2sd(acc); if( acc < 0 || sd == NULL ) { ShowError("chrif_char_ask_name_answer failed - player not online.\n"); - return; + return false; } + /* re-use previous msg_txt */ + if( type == 6 ) type = 2; + if( type == 7 ) type = 4; + if( type > 0 && type <= 5 ) snprintf(action,25,"%s",msg_txt(427+type)); //block|ban|unblock|unban|change the sex of else snprintf(action,25,"???"); switch( answer ) { - case 0 : sprintf(output, msg_txt(424), action, NAME_LENGTH, player_name); break; + case 0 : sprintf(output, msg_txt(charsrv?434:424), action, NAME_LENGTH, player_name); break; case 1 : sprintf(output, msg_txt(425), NAME_LENGTH, player_name); break; case 2 : sprintf(output, msg_txt(426), action, NAME_LENGTH, player_name); break; case 3 : sprintf(output, msg_txt(427), action, NAME_LENGTH, player_name); break; @@ -833,12 +833,13 @@ void chrif_char_ask_name_answer(int acc, const char* player_name, uint16 type, u } clif->message(sd->fd, output); + return true; } /*========================================== * Request char server to change sex of char (modified by Yor) *------------------------------------------*/ -int chrif_changedsex(int fd) { +void chrif_changedsex(int fd) { int acc, sex; struct map_session_data *sd; @@ -851,7 +852,7 @@ int chrif_changedsex(int fd) { sd = map->id2sd(acc); if ( sd ) { //Normally there should not be a char logged on right now! if ( sd->status.sex == sex ) - return 0; //Do nothing? Likely safe. + return; //Do nothing? Likely safe. sd->status.sex = !sd->status.sex; // reset skill of some job @@ -890,13 +891,12 @@ int chrif_changedsex(int fd) { set_eof(sd->fd); // forced to disconnect for the change map->quit(sd); // Remove leftovers (e.g. autotrading) [Paradox924X] } - return 0; } /*========================================== * Request Char Server to Divorce Players *------------------------------------------*/ -int chrif_divorce(int partner_id1, int partner_id2) { - chrif_check(-1); +bool chrif_divorce(int partner_id1, int partner_id2) { + chrif_check(false); WFIFOHEAD(chrif->fd,10); WFIFOW(chrif->fd,0) = 0x2b11; @@ -904,19 +904,19 @@ int chrif_divorce(int partner_id1, int partner_id2) { WFIFOL(chrif->fd,6) = partner_id2; WFIFOSET(chrif->fd,10); - return 0; + return true; } /*========================================== * Divorce players * only used if 'partner_id' is offline *------------------------------------------*/ -int chrif_divorceack(int char_id, int partner_id) { +bool chrif_divorceack(int char_id, int partner_id) { struct map_session_data* sd; int i; if( !char_id || !partner_id ) - return 0; + return false; if( ( sd = map->charid2sd(char_id) ) != NULL && sd->status.partner_id == partner_id ) { sd->status.partner_id = 0; @@ -932,12 +932,12 @@ int chrif_divorceack(int char_id, int partner_id) { pc->delitem(sd, i, 1, 0, 0, LOG_TYPE_OTHER); } - return 0; + return true; } /*========================================== * Removes Baby from parents *------------------------------------------*/ -int chrif_deadopt(int father_id, int mother_id, int child_id) { +void chrif_deadopt(int father_id, int mother_id, int child_id) { struct map_session_data* sd; int idx = skill->get_index(WE_CALLBABY); @@ -957,30 +957,29 @@ int chrif_deadopt(int father_id, int mother_id, int child_id) { clif->deleteskill(sd,WE_CALLBABY); } - return 0; } /*========================================== - * Disconnection of a player (account has been banned of has a status, from login-server) by [Yor] + * Disconnection of a player (account or char has been banned of has a status, from login or char server) by [Yor] *------------------------------------------*/ -int chrif_accountban(int fd) { - int acc; +void chrif_idbanned(int fd) { + int id; struct map_session_data *sd; - acc = RFIFOL(fd,2); + id = RFIFOL(fd,2); if ( battle_config.etc_log ) - ShowNotice("chrif_accountban %d.\n", acc); + ShowNotice("chrif_idbanned %d.\n", id); - sd = map->id2sd(acc); + sd = ( RFIFOB(fd,6) == 2 ) ? map->charid2sd(id) : map->id2sd(id); - if ( acc < 0 || sd == NULL ) { - ShowError("chrif_accountban failed - player not online.\n"); - return 0; + if ( id < 0 || sd == NULL ) { + /* player not online or unknown id, either way no error is necessary (since if you try to ban a offline char it still works) */ + return; } sd->login_id1++; // change identify, because if player come back in char within the 5 seconds, he can change its characters - if (RFIFOB(fd,6) == 0) { // 0: change of statut, 1: ban + if (RFIFOB(fd,6) == 0) { // 0: change of statut int ret_status = RFIFOL(fd,7); // status or final date of a banishment if(0<ret_status && ret_status<=9) clif->message(sd->fd, msg_txt(411+ret_status)); @@ -988,18 +987,24 @@ int chrif_accountban(int fd) { clif->message(sd->fd, msg_txt(421)); else clif->message(sd->fd, msg_txt(420)); //"Your account has not more authorised." - } else if (RFIFOB(fd,6) == 1) { // 0: change of statut, 1: ban + } else if (RFIFOB(fd,6) == 1) { // 1: ban time_t timestamp; char tmpstr[2048]; timestamp = (time_t)RFIFOL(fd,7); // status or final date of a banishment strcpy(tmpstr, msg_txt(423)); //"Your account has been banished until " strftime(tmpstr + strlen(tmpstr), 24, "%d-%m-%Y %H:%M:%S", localtime(×tamp)); clif->message(sd->fd, tmpstr); + } else if (RFIFOB(fd,6) == 2) { // 2: change of status for character + time_t timestamp; + char tmpstr[2048]; + timestamp = (time_t)RFIFOL(fd,7); // status or final date of a banishment + strcpy(tmpstr, msg_txt(433)); //"This character has been banned until " + strftime(tmpstr + strlen(tmpstr), 24, "%d-%m-%Y %H:%M:%S", localtime(×tamp)); + clif->message(sd->fd, tmpstr); } set_eof(sd->fd); // forced to disconnect for the change map->quit(sd); // Remove leftovers (e.g. autotrading) [Paradox924X] - return 0; } //Disconnect the player out of the game, simple packet @@ -1062,17 +1067,17 @@ int chrif_updatefamelist(struct map_session_data* sd) { return 0; } -int chrif_buildfamelist(void) { - chrif_check(-1); +bool chrif_buildfamelist(void) { + chrif_check(false); WFIFOHEAD(chrif->fd,2); WFIFOW(chrif->fd,0) = 0x2b1a; WFIFOSET(chrif->fd,2); - return 0; + return true; } -int chrif_recvfamelist(int fd) { +void chrif_recvfamelist(int fd) { int num, size; int total = 0, len = 8; @@ -1108,8 +1113,6 @@ int chrif_recvfamelist(int fd) { total += num; ShowInfo("Received Fame List of '"CL_WHITE"%d"CL_RESET"' characters.\n", total); - - return 0; } /// fame ranking update confirmation @@ -1135,16 +1138,16 @@ int chrif_updatefamelist_ack(int fd) { return 1; } -int chrif_save_scdata(struct map_session_data *sd) { //parses the sc_data of the player and sends it to the char-server for saving. [Skotlex] +bool chrif_save_scdata(struct map_session_data *sd) { //parses the sc_data of the player and sends it to the char-server for saving. [Skotlex] #ifdef ENABLE_SC_SAVING int i, count=0; - unsigned int tick; + int64 tick; struct status_change_data data; struct status_change *sc = &sd->sc; const struct TimerData *td; - chrif_check(-1); + chrif_check(false); tick = timer->gettick(); WFIFOHEAD(chrif->fd, 14 + SC_MAX*sizeof(struct status_change_data)); @@ -1159,7 +1162,7 @@ int chrif_save_scdata(struct map_session_data *sd) { //parses the sc_data of the td = timer->get(sc->data[i]->timer); if (td == NULL || td->func != status->change_timer || DIFF_TICK(td->tick,tick) < 0) continue; - data.tick = DIFF_TICK(td->tick,tick); //Duration that is left before ending. + data.tick = DIFF_TICK32(td->tick,tick); //Duration that is left before ending. } else data.tick = -1; //Infinite duration data.type = i; @@ -1173,18 +1176,18 @@ int chrif_save_scdata(struct map_session_data *sd) { //parses the sc_data of the } if (count == 0) - return 0; //Nothing to save. + return true; //Nothing to save. | Everything was as successful as if there was something to save. WFIFOW(chrif->fd,12) = count; WFIFOW(chrif->fd,2) = 14 +count*sizeof(struct status_change_data); //Total packet size WFIFOSET(chrif->fd,WFIFOW(chrif->fd,2)); #endif - return 0; + return true; } //Retrieve and load sc_data for a player. [Skotlex] -int chrif_load_scdata(int fd) { +bool chrif_load_scdata(int fd) { #ifdef ENABLE_SC_SAVING struct map_session_data *sd; @@ -1198,31 +1201,33 @@ int chrif_load_scdata(int fd) { if ( !sd ) { ShowError("chrif_load_scdata: Player of AID %d not found!\n", aid); - return -1; + return false; } if ( sd->status.char_id != cid ) { ShowError("chrif_load_scdata: Receiving data for account %d, char id does not matches (%d != %d)!\n", aid, sd->status.char_id, cid); - return -1; + return false; } count = RFIFOW(fd,12); //sc_count for (i = 0; i < count; i++) { data = (struct status_change_data*)RFIFOP(fd,14 + i*sizeof(struct status_change_data)); - status->change_start(&sd->bl, (sc_type)data->type, 10000, data->val1, data->val2, data->val3, data->val4, data->tick, 15); + status->change_start(NULL, &sd->bl, (sc_type)data->type, 10000, data->val1, data->val2, data->val3, data->val4, data->tick, 15); } + + pc->scdata_received(sd); #endif - return 0; + return true; } /*========================================== * Send rates to char server [Wizputer] * S 2b16 <base rate>.L <job rate>.L <drop rate>.L *------------------------------------------*/ -int chrif_ragsrvinfo(int base_rate, int job_rate, int drop_rate) { - chrif_check(-1); +bool chrif_ragsrvinfo(int base_rate, int job_rate, int drop_rate) { + chrif_check(false); WFIFOHEAD(chrif->fd,14); WFIFOW(chrif->fd,0) = 0x2b16; @@ -1231,26 +1236,15 @@ int chrif_ragsrvinfo(int base_rate, int job_rate, int drop_rate) { WFIFOL(chrif->fd,10) = drop_rate; WFIFOSET(chrif->fd,14); - return 0; + return true; } /*========================================= * Tell char-server charcter disconnected [Wizputer] *-----------------------------------------*/ -int chrif_char_offline(struct map_session_data *sd) { - chrif_check(-1); - - WFIFOHEAD(chrif->fd,10); - WFIFOW(chrif->fd,0) = 0x2b17; - WFIFOL(chrif->fd,2) = sd->status.char_id; - WFIFOL(chrif->fd,6) = sd->status.account_id; - WFIFOSET(chrif->fd,10); - - return 0; -} -int chrif_char_offline_nsd(int account_id, int char_id) { - chrif_check(-1); +bool chrif_char_offline_nsd(int account_id, int char_id) { + chrif_check(false); WFIFOHEAD(chrif->fd,10); WFIFOW(chrif->fd,0) = 0x2b17; @@ -1258,41 +1252,40 @@ int chrif_char_offline_nsd(int account_id, int char_id) { WFIFOL(chrif->fd,6) = account_id; WFIFOSET(chrif->fd,10); - return 0; + return true; } /*========================================= * Tell char-server to reset all chars offline [Wizputer] *-----------------------------------------*/ -int chrif_flush_fifo(void) { - chrif_check(-1); +bool chrif_flush(void) { + chrif_check(false); set_nonblocking(chrif->fd, 0); flush_fifos(); set_nonblocking(chrif->fd, 1); - return 0; + return true; } /*========================================= * Tell char-server to reset all chars offline [Wizputer] *-----------------------------------------*/ -int chrif_char_reset_offline(void) { - chrif_check(-1); +bool chrif_char_reset_offline(void) { + chrif_check(false); WFIFOHEAD(chrif->fd,2); WFIFOW(chrif->fd,0) = 0x2b18; WFIFOSET(chrif->fd,2); - return 0; + return true; } /*========================================= * Tell char-server charcter is online [Wizputer] *-----------------------------------------*/ - -int chrif_char_online(struct map_session_data *sd) { - chrif_check(-1); +bool chrif_char_online(struct map_session_data *sd) { + chrif_check(false); WFIFOHEAD(chrif->fd,10); WFIFOW(chrif->fd,0) = 0x2b19; @@ -1300,10 +1293,9 @@ int chrif_char_online(struct map_session_data *sd) { WFIFOL(chrif->fd,6) = sd->status.account_id; WFIFOSET(chrif->fd,10); - return 0; + return true; } - /// Called when the connection to Char Server is disconnected. void chrif_on_disconnect(void) { if( chrif->connected != 1 ) @@ -1352,6 +1344,9 @@ void chrif_skillid2idx(int fd) { if( fd == 0 ) fd = chrif->fd; + if( !session_isValid(fd) ) + return; + WFIFOHEAD(fd,4 + (MAX_SKILL * 4)); WFIFOW(fd,0) = 0x2b0b; for(i = 0; i < MAX_SKILL; i++) { @@ -1384,7 +1379,7 @@ int chrif_parse(int fd) { chrif->on_disconnect(); return 0; } else if ( session[fd]->flag.ping ) {/* we've reached stall time */ - if( DIFF_TICK(last_tick, session[fd]->rdata_tick) > (stall_time * 2) ) {/* we can't wait any longer */ + if( DIFF_TICK(sockt->last_tick, session[fd]->rdata_tick) > (sockt->stall_time * 2) ) {/* we can't wait any longer */ set_eof(fd); return 0; } else if( session[fd]->flag.ping != 2 ) { /* we haven't sent ping out yet */ @@ -1435,11 +1430,11 @@ int chrif_parse(int fd) { case 0x2b04: chrif->recvmap(fd); break; case 0x2b06: chrif->changemapserverack(RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOL(fd,14), RFIFOW(fd,18), RFIFOW(fd,20), RFIFOW(fd,22), RFIFOL(fd,24), RFIFOW(fd,28)); break; case 0x2b09: map->addnickdb(RFIFOL(fd,2), (char*)RFIFOP(fd,6)); break; - case 0x2b0a: socket_datasync(fd, false); break; + case 0x2b0a: sockt->datasync(fd, false); break; case 0x2b0d: chrif->changedsex(fd); break; case 0x2b0f: chrif->char_ask_name_answer(RFIFOL(fd,2), (char*)RFIFOP(fd,6), RFIFOW(fd,30), RFIFOW(fd,32)); break; case 0x2b12: chrif->divorceack(RFIFOL(fd,2), RFIFOL(fd,6)); break; - case 0x2b14: chrif->accountban(fd); break; + case 0x2b14: chrif->idbanned(fd); break; case 0x2b1b: chrif->recvfamelist(fd); break; case 0x2b1d: chrif->load_scdata(fd); break; case 0x2b1e: chrif->update_ip(fd); break; @@ -1462,7 +1457,7 @@ int chrif_parse(int fd) { return 0; } -int send_usercount_tochar(int tid, unsigned int tick, int id, intptr_t data) { +int send_usercount_tochar(int tid, int64 tick, int id, intptr_t data) { chrif_check(-1); WFIFOHEAD(chrif->fd,4); @@ -1476,12 +1471,12 @@ int send_usercount_tochar(int tid, unsigned int tick, int id, intptr_t data) { * timerFunction * Send to char the number of client connected to map *------------------------------------------*/ -int send_users_tochar(void) { +bool send_users_tochar(void) { int users = 0, i = 0; struct map_session_data* sd; struct s_mapiterator* iter; - chrif_check(-1); + chrif_check(false); users = map->usercount(); @@ -1502,14 +1497,14 @@ int send_users_tochar(void) { WFIFOW(chrif->fd,4) = users; WFIFOSET(chrif->fd, 6+8*users); - return 0; + return true; } /*========================================== * timerFunction - * Chk the connection to char server, (if it down) + * Check the connection to char server, (if it down) *------------------------------------------*/ -int check_connect_char_server(int tid, unsigned int tick, int id, intptr_t data) { +int check_connect_char_server(int tid, int64 tick, int id, intptr_t data) { static int displayed = 0; if ( chrif->fd <= 0 || session[chrif->fd] == NULL ) { if ( !displayed ) { @@ -1543,9 +1538,9 @@ int check_connect_char_server(int tid, unsigned int tick, int id, intptr_t data) /*========================================== * Asks char server to remove friend_id from the friend list of char_id *------------------------------------------*/ -int chrif_removefriend(int char_id, int friend_id) { +bool chrif_removefriend(int char_id, int friend_id) { - chrif_check(-1); + chrif_check(false); WFIFOHEAD(chrif->fd,10); WFIFOW(chrif->fd,0) = 0x2b07; @@ -1553,7 +1548,7 @@ int chrif_removefriend(int char_id, int friend_id) { WFIFOL(chrif->fd,6) = friend_id; WFIFOSET(chrif->fd,10); - return 0; + return true; } void chrif_send_report(char* buf, int len) { @@ -1573,26 +1568,74 @@ void chrif_send_report(char* buf, int len) { } /** + * Sends a single scdata for saving into char server, meant to ensure integrity of durationless conditions + **/ +void chrif_save_scdata_single(int account_id, int char_id, short type, struct status_change_entry *sce) { + + if( !chrif->isconnected() ) + return; + + WFIFOHEAD(chrif->fd, 28); + + WFIFOW(chrif->fd, 0) = 0x2740; + WFIFOL(chrif->fd, 2) = account_id; + WFIFOL(chrif->fd, 6) = char_id; + WFIFOW(chrif->fd, 10) = type; + WFIFOL(chrif->fd, 12) = sce->val1; + WFIFOL(chrif->fd, 16) = sce->val2; + WFIFOL(chrif->fd, 20) = sce->val3; + WFIFOL(chrif->fd, 24) = sce->val4; + + WFIFOSET(chrif->fd, 28); + +} +/** + * Sends a single scdata deletion request into char server, meant to ensure integrity of durationless conditions + **/ +void chrif_del_scdata_single(int account_id, int char_id, short type) { + + if( !chrif->isconnected() ) { + ShowError("MAYDAY! failed to delete status %d from CID:%d/AID:%d\n",type,char_id,account_id); + return; + } + + + WFIFOHEAD(chrif->fd, 12); + + WFIFOW(chrif->fd, 0) = 0x2741; + WFIFOL(chrif->fd, 2) = account_id; + WFIFOL(chrif->fd, 6) = char_id; + WFIFOW(chrif->fd, 10) = type; + + WFIFOSET(chrif->fd, 12); + +} + +/** ` * @see DBApply */ int auth_db_final(DBKey key, DBData *data, va_list ap) { struct auth_node *node = DB->data2ptr(data); - if (node->char_dat) - aFree(node->char_dat); - - if (node->sd) + if (node->sd) { + + if( node->sd->var_db ) + node->sd->var_db->destroy(node->sd->var_db,script->reg_destroy); + + if( node->sd->array_db ) + node->sd->array_db->destroy(node->sd->array_db,script->array_free_db); + aFree(node->sd); - + } ers_free(chrif->auth_db_ers, node); - + return 0; } /*========================================== * Destructor *------------------------------------------*/ -int do_final_chrif(void) { +void do_final_chrif(void) { if( chrif->fd != -1 ) { do_close(chrif->fd); @@ -1602,15 +1645,15 @@ int do_final_chrif(void) { chrif->auth_db->destroy(chrif->auth_db, chrif->auth_db_final); ers_destroy(chrif->auth_db_ers); - - return 0; } /*========================================== * *------------------------------------------*/ -int do_init_chrif(void) { - +void do_init_chrif(bool minimal) { + if (minimal) + return; + chrif->auth_db = idb_alloc(DB_OPT_BASE); chrif->auth_db_ers = ers_new(sizeof(struct auth_node),"chrif.c::auth_db_ers",ERS_OPT_NONE); @@ -1626,8 +1669,6 @@ int do_init_chrif(void) { // send the user count every 10 seconds, to hide the charserver's online counting problem timer->add_interval(timer->gettick() + 1000, chrif->send_usercount_tochar, 0, 0, UPDATE_INTERVAL); - - return 0; } @@ -1698,7 +1739,6 @@ void chrif_defaults(void) { chrif->buildfamelist = chrif_buildfamelist; chrif->save_scdata = chrif_save_scdata; chrif->ragsrvinfo = chrif_ragsrvinfo; - chrif->char_offline = chrif_char_offline; chrif->char_offline_nsd = chrif_char_offline_nsd; chrif->char_reset_offline = chrif_char_reset_offline; chrif->send_users_tochar = send_users_tochar; @@ -1710,7 +1750,7 @@ void chrif_defaults(void) { chrif->removefriend = chrif_removefriend; chrif->send_report = chrif_send_report; - chrif->flush_fifo = chrif_flush_fifo; + chrif->flush = chrif_flush; chrif->skillid2idx = chrif_skillid2idx; chrif->sd_to_auth = chrif_sd_to_auth; @@ -1732,13 +1772,13 @@ void chrif_defaults(void) { chrif->changemapserverack = chrif_changemapserverack; chrif->changedsex = chrif_changedsex; chrif->divorceack = chrif_divorceack; - chrif->accountban = chrif_accountban; + chrif->idbanned = chrif_idbanned; chrif->recvfamelist = chrif_recvfamelist; chrif->load_scdata = chrif_load_scdata; chrif->update_ip = chrif_update_ip; chrif->disconnectplayer = chrif_disconnectplayer; chrif->removemap = chrif_removemap; - chrif->updatefamelist_ack = chrif->updatefamelist_ack; + chrif->updatefamelist_ack = chrif_updatefamelist_ack; chrif->keepalive = chrif_keepalive; chrif->keepalive_ack = chrif_keepalive_ack; chrif->deadopt = chrif_deadopt; @@ -1746,4 +1786,6 @@ void chrif_defaults(void) { chrif->on_ready = chrif_on_ready; chrif->on_disconnect = chrif_on_disconnect; chrif->parse = chrif_parse; + chrif->save_scdata_single = chrif_save_scdata_single; + chrif->del_scdata_single = chrif_del_scdata_single; } diff --git a/src/map/chrif.h b/src/map/chrif.h index 0617a6702..25e955604 100644 --- a/src/map/chrif.h +++ b/src/map/chrif.h @@ -2,13 +2,15 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _CHRIF_H_ -#define _CHRIF_H_ +#ifndef _MAP_CHRIF_H_ +#define _MAP_CHRIF_H_ #include "../common/cbasetypes.h" #include <time.h> #include "map.h" //TBL_stuff +struct status_change_entry; + /** * Defines **/ @@ -30,11 +32,10 @@ enum sd_state { ST_LOGIN, ST_LOGOUT, ST_MAPCHANGE }; struct auth_node { int account_id, char_id; int login_id1, login_id2, sex, fd; - time_t expiration_time; // # of seconds 1/1/1970 (timestamp): Validity limit of the account (0 = unlimited) - struct map_session_data *sd; //Data from logged on char. - struct mmo_charstatus *char_dat; //Data from char server. - unsigned int node_created; //timestamp for node timeouts - enum sd_state state; //To track whether player was login in/out or changing maps. + time_t expiration_time; // # of seconds 1/1/1970 (timestamp): Validity limit of the account (0 = unlimited) + struct map_session_data *sd; //Data from logged on char. + int64 node_created; //timestamp for node timeouts + enum sd_state state; //To track whether player was login in/out or changing maps. }; /*===================================== @@ -62,13 +63,13 @@ struct chrif_interface { char userid[NAME_LENGTH], passwd[NAME_LENGTH]; int state; /* */ - int (*final) (void); - int (*init) (void); + void (*init) (bool minimal); + void (*final) (void); /* funcs */ void (*setuserid) (char* id); void (*setpasswd) (char* pwd); void (*checkdefaultlogin) (void); - int (*setip) (const char* ip); + bool (*setip) (const char* ip); void (*setport) (uint16 port); int (*isconnected) (void); @@ -79,72 +80,76 @@ struct chrif_interface { bool (*auth_delete) (int account_id, int char_id, enum sd_state state); bool (*auth_finished) (struct map_session_data* sd); - void (*authreq) (struct map_session_data* sd); + void (*authreq) (struct map_session_data* sd, bool hstandalone); void (*authok) (int fd); - int (*scdata_request) (int account_id, int char_id); - int (*save) (struct map_session_data* sd, int flag); - int (*charselectreq) (struct map_session_data* sd, uint32 s_ip); - int (*changemapserver) (struct map_session_data* sd, uint32 ip, uint16 port); + bool (*scdata_request) (int account_id, int char_id); + bool (*save) (struct map_session_data* sd, int flag); + bool (*charselectreq) (struct map_session_data* sd, uint32 s_ip); + bool (*changemapserver) (struct map_session_data* sd, uint32 ip, uint16 port); - int (*searchcharid) (int char_id); - int (*changeemail) (int id, const char *actual_email, const char *new_email); - int (*char_ask_name) (int acc, const char* character_name, unsigned short operation_type, int year, int month, int day, int hour, int minute, int second); + bool (*searchcharid) (int char_id); + bool (*changeemail) (int id, const char *actual_email, const char *new_email); + bool (*char_ask_name) (int acc, const char* character_name, unsigned short operation_type, int year, int month, int day, int hour, int minute, int second); int (*updatefamelist) (struct map_session_data *sd); - int (*buildfamelist) (void); - int (*save_scdata) (struct map_session_data *sd); - int (*ragsrvinfo) (int base_rate,int job_rate, int drop_rate); - int (*char_offline) (struct map_session_data *sd); - int (*char_offline_nsd) (int account_id, int char_id); - int (*char_reset_offline) (void); - int (*send_users_tochar) (void); - int (*char_online) (struct map_session_data *sd); - int (*changesex) (struct map_session_data *sd); + bool (*buildfamelist) (void); + bool (*save_scdata) (struct map_session_data *sd); + bool (*ragsrvinfo) (int base_rate,int job_rate, int drop_rate); + //int (*char_offline) (struct map_session_data *sd); + bool (*char_offline_nsd) (int account_id, int char_id); + bool (*char_reset_offline) (void); + bool (*send_users_tochar) (void); + bool (*char_online) (struct map_session_data *sd); + bool (*changesex) (struct map_session_data *sd); //int (*chardisconnect) (struct map_session_data *sd); // FIXME: Commented out in clif.c, function does not exist - int (*divorce) (int partner_id1, int partner_id2); + bool (*divorce) (int partner_id1, int partner_id2); - int (*removefriend) (int char_id, int friend_id); + bool (*removefriend) (int char_id, int friend_id); void (*send_report) (char* buf, int len); - int (*flush_fifo) (void); + bool (*flush) (void); void (*skillid2idx) (int fd); bool (*sd_to_auth) (TBL_PC* sd, enum sd_state state); - int (*check_connect_char_server) (int tid, unsigned int tick, int id, intptr_t data); + int (*check_connect_char_server) (int tid, int64 tick, int id, intptr_t data); bool (*auth_logout) (TBL_PC* sd, enum sd_state state); void (*save_ack) (int fd); int (*reconnect) (DBKey key, DBData *data, va_list ap); int (*auth_db_cleanup_sub) (DBKey key, DBData *data, va_list ap); - void (*char_ask_name_answer) (int acc, const char* player_name, uint16 type, uint16 answer); + bool (*char_ask_name_answer) (int acc, const char* player_name, uint16 type, uint16 answer); int (*auth_db_final) (DBKey key, DBData *data, va_list ap); - int (*send_usercount_tochar) (int tid, unsigned int tick, int id, intptr_t data); - int (*auth_db_cleanup) (int tid, unsigned int tick, int id, intptr_t data); + int (*send_usercount_tochar) (int tid, int64 tick, int id, intptr_t data); + int (*auth_db_cleanup) (int tid, int64 tick, int id, intptr_t data); - int (*connect) (int fd); - int (*connectack) (int fd); - int (*sendmap) (int fd); - int (*sendmapack) (int fd); - int (*recvmap) (int fd); - int (*changemapserverack) (int account_id, int login_id1, int login_id2, int char_id, short map_index, short x, short y, uint32 ip, uint16 port); - int (*changedsex) (int fd); - int (*divorceack) (int char_id, int partner_id); - int (*accountban) (int fd); - int (*recvfamelist) (int fd); - int (*load_scdata) (int fd); + void (*connect) (int fd); + void (*connectack) (int fd); + void (*sendmap) (int fd); + void (*sendmapack) (int fd); + void (*recvmap) (int fd); + bool (*changemapserverack) (int account_id, int login_id1, int login_id2, int char_id, short map_index, short x, short y, uint32 ip, uint16 port); + void (*changedsex) (int fd); + bool (*divorceack) (int char_id, int partner_id); + void (*idbanned) (int fd); + void (*recvfamelist) (int fd); + bool (*load_scdata) (int fd); void (*update_ip) (int fd); int (*disconnectplayer) (int fd); - int (*removemap) (int fd); + void (*removemap) (int fd); int (*updatefamelist_ack) (int fd); void (*keepalive)(int fd); void (*keepalive_ack) (int fd); - int (*deadopt) (int father_id, int mother_id, int child_id); + void (*deadopt) (int father_id, int mother_id, int child_id); void (*authfail) (int fd); void (*on_ready) (void); void (*on_disconnect) (void); int (*parse) (int fd); + void (*save_scdata_single) (int account_id, int char_id, short type, struct status_change_entry *sce); + void (*del_scdata_single) (int account_id, int char_id, short type); }; struct chrif_interface *chrif; void chrif_defaults(void); +// There's no need for another function when a simple macro can do exactly the same effect +#define chrif_char_offline(x) chrif->char_offline_nsd((x)->status.account_id,(x)->status.char_id) -#endif /* _CHRIF_H_ */ +#endif /* _MAP_CHRIF_H_ */ diff --git a/src/map/clif.c b/src/map/clif.c index 9b2f76c0e..a3541cab9 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -45,7 +45,6 @@ #include "clif.h" #include "mail.h" #include "quest.h" -#include "packets_struct.h" #include "irc-bot.h" #include <stdio.h> @@ -56,15 +55,24 @@ struct clif_interface clif_s; +/* re-usable */ +static struct packet_itemlist_normal itemlist_normal; +static struct packet_itemlist_equip itemlist_equip; +static struct packet_storelist_normal storelist_normal; +static struct packet_storelist_equip storelist_equip; +static struct packet_viewequip_ack viewequip_list; +static struct packet_npc_market_result_ack npcmarket_result; +static struct packet_npc_market_open npcmarket_open; //#define DUMP_UNKNOWN_PACKET //#define DUMP_INVALID_PACKET //Converts item type in case of pet eggs. static inline int itemtype(int type) { - switch( type ){ + switch( type ) { #if PACKETVER >= 20080827 case IT_WEAPON: return IT_ARMOR; case IT_ARMOR: + case IT_PETARMOR: #endif case IT_PETEGG: return IT_WEAPON; default: return type; @@ -177,27 +185,28 @@ static inline unsigned int mes_len_check(char* mes, unsigned int len, unsigned i /*========================================== * Ip setting of map-server *------------------------------------------*/ -int clif_setip(const char* ip) { +bool clif_setip(const char* ip) { char ip_str[16]; clif->map_ip = host2ip(ip); - if (!clif->map_ip) { + if ( !clif->map_ip ) { ShowWarning("Failed to Resolve Map Server Address! (%s)\n", ip); - return 0; + return false; } safestrncpy(clif->map_ip_str, ip, sizeof(clif->map_ip_str)); ShowInfo("Map Server IP Address : '"CL_WHITE"%s"CL_RESET"' -> '"CL_WHITE"%s"CL_RESET"'.\n", ip, ip2str(clif->map_ip, ip_str)); - return 1; + return true; } -void clif_setbindip(const char* ip) { +bool clif_setbindip(const char* ip) { clif->bind_ip = host2ip(ip); - if (clif->bind_ip) { + if ( clif->bind_ip ) { char ip_str[16]; ShowInfo("Map Server Bind IP Address : '"CL_WHITE"%s"CL_RESET"' -> '"CL_WHITE"%s"CL_RESET"'.\n", ip, ip2str(clif->bind_ip, ip_str)); - } else { - ShowWarning("Failed to Resolve Map Server Address! (%s)\n", ip); + return true; } + ShowWarning("Failed to Resolve Map Server Address! (%s)\n", ip); + return false; } /*========================================== @@ -224,18 +233,21 @@ uint16 clif_getport(void) { return clif->map_port; } - +/*========================================== + * Updates server ip resolution and returns it + *------------------------------------------*/ uint32 clif_refresh_ip(void) { uint32 new_ip; - + new_ip = host2ip(clif->map_ip_str); - if (new_ip && new_ip != clif->map_ip) { + if ( new_ip && new_ip != clif->map_ip ) { clif->map_ip = new_ip; ShowInfo("Updating IP resolution of [%s].\n", clif->map_ip_str); return clif->map_ip; } return 0; } + #if PACKETVER >= 20071106 static inline unsigned char clif_bl_type(struct block_list *bl) { switch (bl->type) { @@ -313,6 +325,10 @@ int clif_send_sub(struct block_list *bl, va_list ap) { #endif } + /* unless visible, hold it here */ + if( clif->ally_only && !sd->sc.data[SC_CLAIRVOYANCE] && !sd->special_state.intravision && battle->check_target( src_bl, &sd->bl, BCT_ENEMY ) > 0 ) + return 0; + WFIFOHEAD(fd, len); if (WFIFOP(fd,0) == buf) { ShowError("WARNING: Invalid use of clif->send function\n"); @@ -334,7 +350,7 @@ int clif_send_sub(struct block_list *bl, va_list ap) { * Packet Delegation (called on all packets that require data to be sent to more than one client) * functions that are sent solely to one use whose ID it posses use WFIFOSET *------------------------------------------*/ -int clif_send(const void* buf, int len, struct block_list* bl, enum send_target type) { +bool clif_send(const void* buf, int len, struct block_list* bl, enum send_target type) { int i; struct map_session_data *sd, *tsd; struct party_data *p = NULL; @@ -565,25 +581,25 @@ int clif_send(const void* buf, int len, struct block_list* bl, enum send_target case BG_QUEUE: if( sd && sd->bg_queue.arena ) { struct hQueue *queue = &script->hq[sd->bg_queue.arena->queue_id]; - + for( i = 0; i < queue->size; i++ ) { - struct map_session_data * sd = NULL; - - if( queue->item[i] > 0 && ( sd = map->id2sd(queue->item[i]) ) ) { - WFIFOHEAD(sd->fd,len); - memcpy(WFIFOP(sd->fd,0), buf, len); - WFIFOSET(sd->fd,len); + struct map_session_data *qsd = NULL; + + if( queue->item[i] > 0 && ( qsd = map->id2sd(queue->item[i]) ) ) { + WFIFOHEAD(qsd->fd,len); + memcpy(WFIFOP(qsd->fd,0), buf, len); + WFIFOSET(qsd->fd,len); } } } break; - + default: ShowError("clif_send: Unrecognized type %d\n",type); - return -1; + return false; } - return 0; + return true; } /// Notifies the client, that it's connection attempt was accepted. @@ -592,16 +608,16 @@ int clif_send(const void* buf, int len, struct block_list* bl, enum send_target void clif_authok(struct map_session_data *sd) { struct packet_authok p; - + p.PacketType = authokType; - p.startTime = timer->gettick(); + p.startTime = (unsigned int)timer->gettick(); WBUFPOS(&p.PosDir[0],0,sd->bl.x,sd->bl.y,sd->ud.dir); /* do the stupid client math */ p.xSize = p.ySize = 5; /* not-used */ #if PACKETVER >= 20080102 - p.font = sd->user_font; // FIXME: Font is currently not saved. + p.font = sd->status.font; #endif - + clif->send(&p,sizeof(p),&sd->bl,SELF); } @@ -626,7 +642,7 @@ void clif_authrefuse(int fd, uint8 error_code) /// Notifies the client of a ban or forced disconnect (SC_NOTIFY_BAN). /// 0081 <error code>.B /// error code: -/// 0 = BAN_UNFAIR +/// 0 = BAN_UNFAIR -> "disconnected from server" -> MsgStringTable[3] /// 1 = server closed -> MsgStringTable[4] /// 2 = ID already logged in -> MsgStringTable[5] /// 3 = timeout/too much lag -> MsgStringTable[241] @@ -699,20 +715,20 @@ void clif_dropflooritem(struct flooritem_data* fitem) { if (fitem->item_data.nameid <= 0) return; - + p.PacketType = dropflooritemType; p.ITAID = fitem->bl.id; p.ITID = ((view = itemdb_viewid(fitem->item_data.nameid)) > 0) ? view : fitem->item_data.nameid; #if PACKETVER >= 20130000 /* not sure date */ p.type = itemtype(itemdb_type(fitem->item_data.nameid)); #endif - p.IsIdentified = fitem->item_data.identify; + p.IsIdentified = fitem->item_data.identify ? 1 : 0; p.xPos = fitem->bl.x; p.yPos = fitem->bl.y; p.subX = fitem->subx; p.subY = fitem->suby; p.count = fitem->item_data.amount; - + clif->send(&p, sizeof(p), &fitem->bl, AREA); } @@ -786,22 +802,23 @@ void clif_clearunit_area(struct block_list* bl, clr_type type) /// Used to make monsters with player-sprites disappear after dying /// like normal monsters, because the client does not remove those /// automatically. -int clif_clearunit_delayed_sub(int tid, unsigned int tick, int id, intptr_t data) { +int clif_clearunit_delayed_sub(int tid, int64 tick, int id, intptr_t data) { struct block_list *bl = (struct block_list *)data; clif->clearunit_area(bl, (clr_type) id); ers_free(clif->delay_clearunit_ers,bl); return 0; } -void clif_clearunit_delayed(struct block_list* bl, clr_type type, unsigned int tick) -{ + +void clif_clearunit_delayed(struct block_list* bl, clr_type type, int64 tick) { struct block_list *tbl = ers_alloc(clif->delay_clearunit_ers, struct block_list); memcpy (tbl, bl, sizeof (struct block_list)); timer->add(tick, clif->clearunit_delayed_sub, (int)type, (intptr_t)tbl); } +/// Gets weapon view info from sd's inventory_data and points (*rhand,*lhand) void clif_get_weapon_view(struct map_session_data* sd, unsigned short *rhand, unsigned short *lhand) { - if(sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER|OPTION_HANBOK)) { + if(sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER|OPTION_HANBOK|OPTION_OKTOBERFEST)) { *rhand = *lhand = 0; return; } @@ -868,9 +885,9 @@ void clif_set_unit_idle2(struct block_list* bl, struct map_session_data *tsd, en struct view_data* vd = status->get_viewdata(bl); struct packet_idle_unit2 p; int g_id = status->get_guild_id(bl); - + sd = BL_CAST(BL_PC, bl); - + p.PacketType = idle_unit2Type; #if PACKETVER >= 20071106 p.objecttype = clif_bl_type(bl); @@ -899,13 +916,13 @@ void clif_set_unit_idle2(struct block_list* bl, struct map_session_data *tsd, en p.GEmblemVer = status->get_emblem_id(bl); p.honor = (sd) ? sd->status.manner : 0; p.virtue = (sc) ? sc->opt3 : 0; - p.isPKModeON = (sd) ? sd->status.karma : 0; + p.isPKModeON = (sd && sd->status.karma) ? 1 : 0; p.sex = vd->sex; WBUFPOS(&p.PosDir[0],0,bl->x,bl->y,unit->getdir(bl)); p.xSize = p.ySize = (sd) ? 5 : 0; p.state = vd->dead_sit; p.clevel = clif_setlevel(bl); - + clif->send(&p,sizeof(p),tsd?&tsd->bl:bl,target); #else return; @@ -920,6 +937,8 @@ void clif_set_unit_idle(struct block_list* bl, struct map_session_data *tsd, enu struct view_data* vd = status->get_viewdata(bl); struct packet_idle_unit p; int g_id = status->get_guild_id(bl); + + nullpo_retv(bl); #if PACKETVER < 20091103 if( !pcdb_checkid(vd->class_) ) { @@ -927,9 +946,9 @@ void clif_set_unit_idle(struct block_list* bl, struct map_session_data *tsd, enu return; } #endif - + sd = BL_CAST(BL_PC, bl); - + p.PacketType = idle_unitType; #if PACKETVER >= 20091103 p.PacketLength = sizeof(p); @@ -964,16 +983,16 @@ void clif_set_unit_idle(struct block_list* bl, struct map_session_data *tsd, enu p.GEmblemVer = status->get_emblem_id(bl); p.honor = (sd) ? sd->status.manner : 0; p.virtue = (sc) ? sc->opt3 : 0; - p.isPKModeON = (sd) ? sd->status.karma : 0; + p.isPKModeON = (sd && sd->status.karma) ? 1 : 0; p.sex = vd->sex; WBUFPOS(&p.PosDir[0],0,bl->x,bl->y,unit->getdir(bl)); p.xSize = p.ySize = (sd) ? 5 : 0; p.state = vd->dead_sit; p.clevel = clif_setlevel(bl); #if PACKETVER >= 20080102 - p.font = (sd) ? sd->user_font : 0; + p.font = (sd) ? sd->status.font : 0; #endif -#if PACKETVER >= 20140000 //actual 20120221 +#if PACKETVER >= 20150000 //actual 20120221 if( bl->type == BL_MOB ) { p.maxHP = status_get_max_hp(bl); p.HP = status_get_hp(bl); @@ -984,7 +1003,7 @@ void clif_set_unit_idle(struct block_list* bl, struct map_session_data *tsd, enu p.isBoss = 0; } #endif - + clif->send(&p,sizeof(p),tsd?&tsd->bl:bl,target); if( disguised(bl) ) { @@ -996,7 +1015,7 @@ void clif_set_unit_idle(struct block_list* bl, struct map_session_data *tsd, enu #endif clif->send(&p,sizeof(p),bl,SELF); } - + } /* for 'packetver < 20091103' 0x7c non-pc-looking unit handling */ void clif_spawn_unit2(struct block_list* bl, enum send_target target) { @@ -1006,9 +1025,9 @@ void clif_spawn_unit2(struct block_list* bl, enum send_target target) { struct view_data* vd = status->get_viewdata(bl); struct packet_spawn_unit2 p; int g_id = status->get_guild_id(bl); - + sd = BL_CAST(BL_PC, bl); - + p.PacketType = spawn_unit2Type; #if PACKETVER >= 20071106 p.objecttype = clif_bl_type(bl); @@ -1033,7 +1052,7 @@ void clif_spawn_unit2(struct block_list* bl, enum send_target target) { p.headpalette = vd->hair_color; p.bodypalette = vd->cloth_color; p.headDir = (sd)? sd->head_dir : 0; - p.isPKModeON = (sd) ? sd->status.karma : 0; + p.isPKModeON = (sd && sd->status.karma) ? 1 : 0; p.sex = vd->sex; WBUFPOS(&p.PosDir[0],0,bl->x,bl->y,unit->getdir(bl)); p.xSize = p.ySize = (sd) ? 5 : 0; @@ -1050,15 +1069,17 @@ void clif_spawn_unit(struct block_list* bl, enum send_target target) { struct packet_spawn_unit p; int g_id = status->get_guild_id(bl); + nullpo_retv(bl); + #if PACKETVER < 20091103 if( !pcdb_checkid(vd->class_) ) { clif->spawn_unit2(bl,target); return; } #endif - + sd = BL_CAST(BL_PC, bl); - + p.PacketType = spawn_unitType; #if PACKETVER >= 20091103 p.PacketLength = sizeof(p); @@ -1093,15 +1114,15 @@ void clif_spawn_unit(struct block_list* bl, enum send_target target) { p.GEmblemVer = status->get_emblem_id(bl); p.honor = (sd) ? sd->status.manner : 0; p.virtue = (sc) ? sc->opt3 : 0; - p.isPKModeON = (sd) ? sd->status.karma : 0; + p.isPKModeON = (sd && sd->status.karma) ? 1 : 0; p.sex = vd->sex; WBUFPOS(&p.PosDir[0],0,bl->x,bl->y,unit->getdir(bl)); p.xSize = p.ySize = (sd) ? 5 : 0; p.clevel = clif_setlevel(bl); #if PACKETVER >= 20080102 - p.font = (sd) ? sd->user_font : 0; + p.font = (sd) ? sd->status.font : 0; #endif -#if PACKETVER >= 20140000 //actual 20120221 +#if PACKETVER >= 20150000 //actual 20120221 if( bl->type == BL_MOB ) { p.maxHP = status_get_max_hp(bl); p.HP = status_get_hp(bl); @@ -1113,6 +1134,7 @@ void clif_spawn_unit(struct block_list* bl, enum send_target target) { } #endif if( disguised(bl) ) { + nullpo_retv(sd); if( sd->status.class_ != sd->disguise ) clif->send(&p,sizeof(p),bl,target); #if PACKETVER >= 20091103 @@ -1136,9 +1158,11 @@ void clif_set_unit_walking(struct block_list* bl, struct map_session_data *tsd, struct view_data* vd = status->get_viewdata(bl); struct packet_unit_walking p; int g_id = status->get_guild_id(bl); - + + nullpo_retv(bl); + sd = BL_CAST(BL_PC, bl); - + p.PacketType = unit_walkingType; #if PACKETVER >= 20091103 p.PacketLength = sizeof(p); @@ -1155,7 +1179,7 @@ void clif_set_unit_walking(struct block_list* bl, struct map_session_data *tsd, p.head = vd->hair_style; p.weapon = vd->weapon; p.accessory = vd->head_bottom; - p.moveStartTime = timer->gettick(); + p.moveStartTime = (unsigned int)timer->gettick(); #if PACKETVER < 7 p.shield = vd->shield; #endif @@ -1171,15 +1195,15 @@ void clif_set_unit_walking(struct block_list* bl, struct map_session_data *tsd, p.GEmblemVer = status->get_emblem_id(bl); p.honor = (sd) ? sd->status.manner : 0; p.virtue = (sc) ? sc->opt3 : 0; - p.isPKModeON = (sd) ? sd->status.karma : 0; + p.isPKModeON = (sd && sd->status.karma) ? 1 : 0; p.sex = vd->sex; WBUFPOS2(&p.MoveData[0],0,bl->x,bl->y,ud->to_x,ud->to_y,8,8); p.xSize = p.ySize = (sd) ? 5 : 0; p.clevel = clif_setlevel(bl); #if PACKETVER >= 20080102 - p.font = (sd) ? sd->user_font : 0; + p.font = (sd) ? sd->status.font : 0; #endif -#if PACKETVER >= 20140000 //actual 20120221 +#if PACKETVER >= 20150000 //actual 20120221 if( bl->type == BL_MOB ) { p.maxHP = status_get_max_hp(bl); p.HP = status_get_hp(bl); @@ -1190,7 +1214,7 @@ void clif_set_unit_walking(struct block_list* bl, struct map_session_data *tsd, p.isBoss = 0; } #endif - + clif->send(&p,sizeof(p),tsd?&tsd->bl:bl,target); if( disguised(bl) ) { @@ -1292,19 +1316,20 @@ void clif_weather(int16 m) /** * Main function to spawn a unit on the client (player/mob/pet/etc) **/ -int clif_spawn(struct block_list *bl) +bool clif_spawn(struct block_list *bl) { struct view_data *vd; vd = status->get_viewdata(bl); - if( !vd || vd->class_ == INVISIBLE_CLASS ) - return 0; + if( !vd ) + return false; - /** - * Hide NPC from maya purple card. - **/ - if(bl->type == BL_NPC && !((TBL_NPC*)bl)->chat_id && (((TBL_NPC*)bl)->option&OPTION_INVISIBLE)) - return 0; + if( ( bl->type == BL_NPC + && !((TBL_NPC*)bl)->chat_id + && (((TBL_NPC*)bl)->option&OPTION_INVISIBLE) ) // Hide NPC from maya purple card. + || ( vd->class_ == INVISIBLE_CLASS ) + ) + return true; // Doesn't need to be spawned, so everything is alright clif->spawn_unit(bl,AREA_WOS); @@ -1321,7 +1346,7 @@ int clif_spawn(struct block_list *bl) clif->spiritball(&sd->bl); if(sd->state.size==SZ_BIG) // tiny/big players [Valaris] clif->specialeffect(bl,423,AREA); - else if(sd->state.size==SZ_MEDIUM) + else if(sd->state.size==SZ_SMALL) clif->specialeffect(bl,421,AREA); if( sd->bg_id && map->list[sd->bl.m].flag.battleground ) clif->sendbgemblem_area(sd); @@ -1341,7 +1366,7 @@ int clif_spawn(struct block_list *bl) TBL_MOB *md = ((TBL_MOB*)bl); if(md->special_state.size==SZ_BIG) // tiny/big mobs [Valaris] clif->specialeffect(&md->bl,423,AREA); - else if(md->special_state.size==SZ_MEDIUM) + else if(md->special_state.size==SZ_SMALL) clif->specialeffect(&md->bl,421,AREA); } break; @@ -1350,7 +1375,7 @@ int clif_spawn(struct block_list *bl) TBL_NPC *nd = ((TBL_NPC*)bl); if( nd->size == SZ_BIG ) clif->specialeffect(&nd->bl,423,AREA); - else if( nd->size == SZ_MEDIUM ) + else if( nd->size == SZ_SMALL ) clif->specialeffect(&nd->bl,421,AREA); } break; @@ -1359,7 +1384,7 @@ int clif_spawn(struct block_list *bl) clif->send_petdata(NULL, (TBL_PET*)bl, 3, vd->head_bottom); // needed to display pet equip properly break; } - return 0; + return true; } /// Sends information about owned homunculus to the client (ZC_PROPERTY_HOMUN). [orn] @@ -1378,7 +1403,7 @@ void clif_hominfo(struct map_session_data *sd, struct homun_data *hd, int flag) WBUFW(buf,0)=0x22e; memcpy(WBUFP(buf,2),hd->homunculus.name,NAME_LENGTH); // Bit field, bit 0 : rename_flag (1 = already renamed), bit 1 : homunc vaporized (1 = true), bit 2 : homunc dead (1 = true) - WBUFB(buf,26)=(battle_config.hom_rename?0:hd->homunculus.rename_flag) | (hd->homunculus.vaporize << 1) | (hd->homunculus.hp?0:4); + WBUFB(buf,26)=(battle_config.hom_rename && hd->homunculus.rename_flag ? 0x1 : 0x0) | (hd->homunculus.vaporize == HOM_ST_REST ? 0x2 : 0) | (hd->homunculus.hp > 0 ? 0x4 : 0); WBUFW(buf,27)=hd->homunculus.level; WBUFW(buf,29)=hd->homunculus.hunger; WBUFW(buf,31)=(unsigned short) (hd->homunculus.intimacy / 100) ; @@ -1453,18 +1478,23 @@ void clif_send_homdata(struct map_session_data *sd, int state, int param) WFIFOSET(fd,packet_len(0x230)); } - -int clif_homskillinfoblock(struct map_session_data *sd) { //[orn] +/// Prepares and sends homun related information [orn] +void clif_homskillinfoblock(struct map_session_data *sd) { struct homun_data *hd; - int fd = sd->fd; - int i,j,len=4,id; - WFIFOHEAD(fd, 4+37*MAX_HOMUNSKILL); + int fd; + int i,j; + int len=4,id; + nullpo_retv(sd); + fd = sd->fd; hd = sd->hd; + if ( !hd ) - return 0 ; + return; + WFIFOHEAD(fd, 4+37*MAX_HOMUNSKILL); WFIFOW(fd,0)=0x235; + for ( i = 0; i < MAX_HOMUNSKILL; i++){ if( (id = hd->homunculus.hskill[i].id) != 0 ){ j = id - HM_SKILLBASE; @@ -1482,7 +1512,7 @@ int clif_homskillinfoblock(struct map_session_data *sd) { //[orn] WFIFOW(fd,2)=len; WFIFOSET(fd,len); - return 0; + return; } void clif_homskillup(struct map_session_data *sd, uint16 skill_id) { //[orn] @@ -1504,16 +1534,19 @@ void clif_homskillup(struct map_session_data *sd, uint16 skill_id) { //[orn] WFIFOSET(fd,packet_len(0x239)); } -int clif_hom_food(struct map_session_data *sd,int foodid,int fail) //[orn] +void clif_hom_food(struct map_session_data *sd,int foodid,int fail) //[orn] { - int fd=sd->fd; + int fd; + nullpo_retv(sd); + + fd = sd->fd; WFIFOHEAD(fd,packet_len(0x22f)); WFIFOW(fd,0)=0x22f; WFIFOB(fd,2)=fail; WFIFOW(fd,3)=foodid; WFIFOSET(fd,packet_len(0x22f)); - return 0; + return; } @@ -1525,14 +1558,19 @@ void clif_walkok(struct map_session_data *sd) WFIFOHEAD(fd, packet_len(0x87)); WFIFOW(fd,0)=0x87; - WFIFOL(fd,2)=timer->gettick(); + WFIFOL(fd,2)=(unsigned int)timer->gettick(); WFIFOPOS2(fd,6,sd->bl.x,sd->bl.y,sd->ud.to_x,sd->ud.to_y,8,8); WFIFOSET(fd,packet_len(0x87)); } void clif_move2(struct block_list *bl, struct view_data *vd, struct unit_data *ud) { +#ifdef ANTI_MAYAP_CHEAT + struct status_change *sc = NULL; + if( (sc = status->get_sc(bl)) && sc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_INVISIBLE|OPTION_CHASEWALK) ) + clif->ally_only = true; +#endif clif->set_unit_walking(bl,NULL,ud,AREA_WOS); if(vd->cloth_color) @@ -1545,7 +1583,7 @@ void clif_move2(struct block_list *bl, struct view_data *vd, struct unit_data *u // clif_movepc(sd); if(sd->state.size==SZ_BIG) // tiny/big players [Valaris] clif->specialeffect(&sd->bl,423,AREA); - else if(sd->state.size==SZ_MEDIUM) + else if(sd->state.size==SZ_SMALL) clif->specialeffect(&sd->bl,421,AREA); } break; @@ -1554,7 +1592,7 @@ void clif_move2(struct block_list *bl, struct view_data *vd, struct unit_data *u TBL_MOB *md = ((TBL_MOB*)bl); if(md->special_state.size==SZ_BIG) // tiny/big mobs [Valaris] clif->specialeffect(&md->bl,423,AREA); - else if(md->special_state.size==SZ_MEDIUM) + else if(md->special_state.size==SZ_SMALL) clif->specialeffect(&md->bl,421,AREA); } break; @@ -1563,6 +1601,9 @@ void clif_move2(struct block_list *bl, struct view_data *vd, struct unit_data *u clif->send_petdata(NULL, (TBL_PET*)bl, 3, vd->head_bottom); break; } +#ifdef ANTI_MAYAP_CHEAT + clif->ally_only = false; +#endif } @@ -1572,9 +1613,11 @@ void clif_move2(struct block_list *bl, struct view_data *vd, struct unit_data *u void clif_move(struct unit_data *ud) { unsigned char buf[16]; - struct view_data* vd; - struct block_list* bl = ud->bl; - + struct view_data *vd; + struct block_list *bl = ud->bl; +#ifdef ANTI_MAYAP_CHEAT + struct status_change *sc = NULL; +#endif vd = status->get_viewdata(bl); if (!vd || vd->class_ == INVISIBLE_CLASS) return; //This performance check is needed to keep GM-hidden objects from being notified to bots. @@ -1592,23 +1635,32 @@ void clif_move(struct unit_data *ud) clif->move2(bl, vd, ud); return; } +#ifdef ANTI_MAYAP_CHEAT + if( (sc = status->get_sc(bl)) && sc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_INVISIBLE) ) + clif->ally_only = true; +#endif WBUFW(buf,0)=0x86; WBUFL(buf,2)=bl->id; WBUFPOS2(buf,6,bl->x,bl->y,ud->to_x,ud->to_y,8,8); - WBUFL(buf,12)=timer->gettick(); + WBUFL(buf,12)=(unsigned int)timer->gettick(); + clif->send(buf, packet_len(0x86), bl, AREA_WOS); + if (disguised(bl)) { WBUFL(buf,2)=-bl->id; clif->send(buf, packet_len(0x86), bl, SELF); } +#ifdef ANTI_MAYAP_CHEAT + clif->ally_only = false; +#endif } /*========================================== * Delays the map->quit of a player after they are disconnected. [Skotlex] *------------------------------------------*/ -int clif_delayquit(int tid, unsigned int tick, int id, intptr_t data) { +int clif_delayquit(int tid, int64 tick, int id, intptr_t data) { struct map_session_data *sd = NULL; //Remove player from map server @@ -1642,7 +1694,7 @@ void clif_changemap(struct map_session_data *sd, short m, int x, int y) { WFIFOHEAD(fd,packet_len(0x91)); WFIFOW(fd,0) = 0x91; - mapindex_getmapname_ext(map->list[m].custom_name ? map->list[map->list[m].instance_src_map].name : map->list[m].name, (char*)WFIFOP(fd,2)); + mapindex->getmapname_ext(map->list[m].custom_name ? map->list[map->list[m].instance_src_map].name : map->list[m].name, (char*)WFIFOP(fd,2)); WFIFOW(fd,18) = x; WFIFOW(fd,20) = y; WFIFOSET(fd,packet_len(0x91)); @@ -1658,7 +1710,7 @@ void clif_changemapserver(struct map_session_data* sd, unsigned short map_index, WFIFOHEAD(fd,packet_len(0x92)); WFIFOW(fd,0) = 0x92; - mapindex_getmapname_ext(mapindex_id2name(map_index), (char*)WFIFOP(fd,2)); + mapindex->getmapname_ext(mapindex_id2name(map_index), (char*)WFIFOP(fd,2)); WFIFOW(fd,18) = x; WFIFOW(fd,20) = y; WFIFOL(fd,22) = htonl(ip); @@ -1679,9 +1731,9 @@ void clif_blown(struct block_list *bl) /// isn't walkable, the char doesn't move at all. If the char is /// sitting it will stand up (ZC_STOPMOVE). /// 0088 <id>.L <x>.W <y>.W -void clif_fixpos(struct block_list *bl) -{ +void clif_fixpos(struct block_list *bl) { unsigned char buf[10]; + nullpo_retv(bl); WBUFW(buf,0) = 0x88; @@ -1715,29 +1767,40 @@ void clif_npcbuysell(struct map_session_data* sd, int id) /// Presents list of items, that can be bought in an NPC shop (ZC_PC_PURCHASE_ITEMLIST). /// 00c6 <packet len>.W { <price>.L <discount price>.L <item type>.B <name id>.W }* -void clif_buylist(struct map_session_data *sd, struct npc_data *nd) -{ +void clif_buylist(struct map_session_data *sd, struct npc_data *nd) { + struct npc_item_list *shop = NULL; + unsigned short shop_size = 0; int fd,i,c; nullpo_retv(sd); nullpo_retv(nd); + if( nd->subtype == SCRIPT ) { + shop = nd->u.scr.shop->item; + shop_size = nd->u.scr.shop->items; + } else { + shop = nd->u.shop.shop_item; + shop_size = nd->u.shop.count; + } + fd = sd->fd; - WFIFOHEAD(fd, 4 + nd->u.shop.count * 11); + + WFIFOHEAD(fd, 4 + shop_size * 11); WFIFOW(fd,0) = 0xc6; c = 0; - for( i = 0; i < nd->u.shop.count; i++ ) - { - struct item_data* id = itemdb->exists(nd->u.shop.shop_item[i].nameid); - int val = nd->u.shop.shop_item[i].value; - if( id == NULL ) - continue; - WFIFOL(fd, 4+c*11) = val; - WFIFOL(fd, 8+c*11) = pc->modifybuyvalue(sd,val); - WFIFOB(fd,12+c*11) = itemtype(id->type); - WFIFOW(fd,13+c*11) = ( id->view_id > 0 ) ? id->view_id : id->nameid; - c++; + for( i = 0; i < shop_size; i++ ) { + if( shop[i].nameid ) { + struct item_data* id = itemdb->exists(shop[i].nameid); + int val = shop[i].value; + if( id == NULL ) + continue; + WFIFOL(fd, 4+c*11) = val; + WFIFOL(fd, 8+c*11) = pc->modifybuyvalue(sd,val); + WFIFOB(fd,12+c*11) = itemtype(id->type); + WFIFOW(fd,13+c*11) = ( id->view_id > 0 ) ? id->view_id : id->nameid; + c++; + } } WFIFOW(fd,2) = 4 + c*11; @@ -1752,12 +1815,12 @@ void clif_hercules_chsys_create(struct hChSysCh *channel, char *name, char *pass channel->pass[0] = '\0'; else safestrncpy(channel->pass, pass, HCHSYS_NAME_LENGTH); - + channel->opt = hChSys_OPT_BASE; channel->banned = NULL; - + channel->msg_delay = 0; - + if( channel->type != hChSys_MAP && channel->type != hChSys_ALLY ) strdb_put(clif->channel_db, channel->name, channel); } @@ -1777,11 +1840,14 @@ void clif_selllist(struct map_session_data *sd) { if( sd->status.inventory[i].nameid > 0 && sd->inventory_data[i] ) { - if( !itemdb_cansell(&sd->status.inventory[i], pc->get_group_level(sd)) ) + if( !itemdb_cansell(&sd->status.inventory[i], pc_get_group_level(sd)) ) continue; if( sd->status.inventory[i].expire_time ) continue; // Cannot Sell Rental Items + + if( sd->status.inventory[i].bound && !pc_can_give_bound_items(sd)) + continue; // Don't allow sale of bound items val=sd->inventory_data[i]->value_sell; if( val < 0 ) @@ -1807,10 +1873,10 @@ void clif_selllist(struct map_session_data *sd) /// - append this text void clif_scriptmes(struct map_session_data *sd, int npcid, const char *mes) { int fd = sd->fd; - int slen = strlen(mes) + 9; + size_t slen = strlen(mes) + 9; sd->state.dialog = 1; - + WFIFOHEAD(fd, slen); WFIFOW(fd,0)=0xb4; WFIFOW(fd,2)=slen; @@ -1919,7 +1985,7 @@ void clif_sendfakenpc(struct map_session_data *sd, int npcid) { /// TODO investigate behavior of other windows [FlavioJS] void clif_scriptmenu(struct map_session_data* sd, int npcid, const char* mes) { int fd = sd->fd; - int slen = strlen(mes) + 9; + size_t slen = strlen(mes) + 9; struct block_list *bl = NULL; if (!sd->state.using_fake_npc && (npcid == npc->fake_nd->bl.id || ((bl = map->id2bl(npcid)) && (bl->m!=sd->bl.m || @@ -2026,10 +2092,10 @@ void clif_viewpoint(struct map_session_data *sd, int npc_id, int type, int x, in void clif_hercules_chsys_join(struct hChSysCh *channel, struct map_session_data *sd) { if( idb_put(channel->users, sd->status.char_id, sd) ) return; - + RECREATE(sd->channels, struct hChSysCh *, ++sd->channel_count); sd->channels[ sd->channel_count - 1 ] = channel; - + if( sd->stealth ) { sd->stealth = false; } else if( channel->opt & hChSys_OPT_ANNOUNCE_JOIN ) { @@ -2037,12 +2103,12 @@ void clif_hercules_chsys_join(struct hChSysCh *channel, struct map_session_data sprintf(message, "#%s '%s' joined",channel->name,sd->status.name); clif->chsys_msg(channel,sd,message); } - + /* someone is cheating, we kindly disconnect the bastard */ if( sd->channel_count > 200 ) { set_eof(sd->fd); } - + } /// Displays an illustration image. /// 0145 <image name>.16B <type>.B (ZC_SHOW_IMAGE) @@ -2146,23 +2212,23 @@ void clif_addcards2(unsigned short *cards, struct item* item) { //Client only receives four cards.. so randomly send them a set of cards. [Skotlex] if( MAX_SLOTS > 4 && (j = itemdb_slot(item->nameid)) > 4 ) i = rnd()%(j-3); //eg: 6 slots, possible i values: 0->3, 1->4, 2->5 => i = rnd()%3; - + //Normal items. if( item->card[i] > 0 && (j=itemdb_viewid(item->card[i])) > 0 ) cards[0] = j; else cards[0] = item->card[i]; - + if( item->card[++i] > 0 && (j=itemdb_viewid(item->card[i])) > 0 ) cards[1] = j; else cards[1] = item->card[i]; - + if( item->card[++i] > 0 && (j=itemdb_viewid(item->card[i])) > 0 ) cards[2] = j; else cards[2] = item->card[i]; - + if( item->card[++i] > 0 && (j=itemdb_viewid(item->card[i])) > 0 ) cards[3] = j; else @@ -2187,18 +2253,18 @@ void clif_additem(struct map_session_data *sd, int n, int amount, int fail) { p.PacketType = additemType; p.Index = n+2; p.count = amount; - + if( !fail ) { if( n < 0 || n >= MAX_INVENTORY || sd->status.inventory[n].nameid <=0 || sd->inventory_data[n] == NULL ) return; - + if (sd->inventory_data[n]->view_id > 0) p.nameid = sd->inventory_data[n]->view_id; else p.nameid = sd->status.inventory[n].nameid; - - p.IsIdentified = sd->status.inventory[n].identify; - p.IsDamaged = sd->status.inventory[n].attribute; + + p.IsIdentified = sd->status.inventory[n].identify ? 1 : 0; + p.IsDamaged = sd->status.inventory[n].attribute ? 1 : 0; p.refiningLevel =sd->status.inventory[n].refine; clif->addcards2(&p.slot.card[0], &sd->status.inventory[n]); p.location = pc->equippoint(sd,n); @@ -2207,7 +2273,10 @@ void clif_additem(struct map_session_data *sd, int n, int amount, int fail) { p.HireExpireDate = sd->status.inventory[n].expire_time; #endif #if PACKETVER >= 20071002 - p.bindOnEquipType = 0; // unused + /* why restrict the flag to non-stackable? because this is the only packet allows stackable to, + * show the color, and therefore it'd be inconsistent with the rest (aka it'd show yellow, you relog/refresh and boom its gone) + */ + p.bindOnEquipType = sd->status.inventory[n].bound && !itemdb->isstackable2(sd->inventory_data[n]) ? 2 : sd->inventory_data[n]->flag.bindonequip ? 1 : 0; #endif } p.result = (unsigned char)fail; @@ -2289,91 +2358,112 @@ void clif_item_sub(unsigned char *buf, int n, struct item *i, struct item_data * } } -//Unified inventory function which sends all of the inventory (requires two packets, one for equipable items and one for stackable ones. [Skotlex] -void clif_inventorylist(struct map_session_data *sd) { - int i,n,ne,arrow=-1; - unsigned char *buf; - unsigned char *bufe; +void clif_item_equip(short idx, struct EQUIPITEM_INFO *p, struct item *i, struct item_data *id, int eqp_pos) { -#if PACKETVER < 5 - const int s = 10; //Entry size. -#elif PACKETVER < 20080102 - const int s = 18; -#else - const int s = 22; -#endif -#if PACKETVER < 20071002 - const int se = 20; -#elif PACKETVER < 20100629 - const int se = 26; -#else - const int se = 28; + p->index = idx; + + if (id->view_id > 0) + p->ITID = id->view_id; + else + p->ITID = i->nameid; + + p->type = itemtype(id->type); + +#if PACKETVER < 20120925 + p->IsIdentified = i->identify ? 1 : 0; #endif - buf = (unsigned char*)aMalloc(MAX_INVENTORY * s + 4); - bufe = (unsigned char*)aMalloc(MAX_INVENTORY * se + 4); + p->location = eqp_pos; + p->WearState = i->equip; + +#if PACKETVER < 20120925 + p->IsDamaged = i->attribute ? 1 : 0; +#endif + p->RefiningLevel = i->refine; - for( i = 0, n = 0, ne = 0; i < MAX_INVENTORY; i++ ) - { - if( sd->status.inventory[i].nameid <=0 || sd->inventory_data[i] == NULL ) - continue; + clif->addcards2(&p->slot.card[0], i); - if( !itemdb->isstackable2(sd->inventory_data[i]) ) - { //Non-stackable (Equippable) - WBUFW(bufe,ne*se+4)=i+2; - clif->item_sub(bufe, ne*se+6, &sd->status.inventory[i], sd->inventory_data[i], pc->equippoint(sd,i)); - clif->addcards(WBUFP(bufe, ne*se+16), &sd->status.inventory[i]); #if PACKETVER >= 20071002 - WBUFL(bufe,ne*se+24)=sd->status.inventory[i].expire_time; - WBUFW(bufe,ne*se+28)=0; //Unknown + p->HireExpireDate = i->expire_time; +#endif + +#if PACKETVER >= 20080102 + p->bindOnEquipType = i->bound ? 2 : id->flag.bindonequip ? 1 : 0; #endif + #if PACKETVER >= 20100629 - if (sd->inventory_data[i]->equip&EQP_VISIBLE) - WBUFW(bufe,ne*se+30)= sd->inventory_data[i]->look; - else - WBUFW(bufe,ne*se+30)=0; + p->wItemSpriteNumber = id->equip&EQP_VISIBLE ? id->look : 0; #endif - ne++; - } - else - { //Stackable. - WBUFW(buf,n*s+4)=i+2; - clif->item_sub(buf, n*s+6, &sd->status.inventory[i], sd->inventory_data[i], -2); - if( sd->inventory_data[i]->equip == EQP_AMMO && sd->status.inventory[i].equip ) - arrow=i; + +#if PACKETVER >= 20120925 + p->Flag.IsIdentified = i->identify ? 1 : 0; + p->Flag.IsDamaged = i->attribute ? 1 : 0; + p->Flag.PlaceETCTab = i->favorite ? 1 : 0; + p->Flag.SpareBits = 0; +#endif +} +void clif_item_normal(short idx, struct NORMALITEM_INFO *p, struct item *i, struct item_data *id) { + p->index = idx; + + if (id->view_id > 0) + p->ITID = id->view_id; + else + p->ITID = i->nameid; + + p->type = itemtype(id->type); + +#if PACKETVER < 20120925 + p->IsIdentified = i->identify ? 1 : 0; +#endif + + p->count = i->amount; + p->WearState = id->equip; + #if PACKETVER >= 5 - clif->addcards(WBUFP(buf, n*s+14), &sd->status.inventory[i]); + clif->addcards2(&p->slot.card[0], i); #endif + #if PACKETVER >= 20080102 - WBUFL(buf,n*s+22)=sd->status.inventory[i].expire_time; + p->HireExpireDate = i->expire_time; #endif - n++; - } - } - if( n ) { -#if PACKETVER < 5 - WBUFW(buf,0)=0xa3; -#elif PACKETVER < 20080102 - WBUFW(buf,0)=0x1ee; -#else - WBUFW(buf,0)=0x2e8; + +#if PACKETVER >= 20120925 + p->Flag.IsIdentified = i->identify ? 1 : 0; + p->Flag.PlaceETCTab = i->favorite ? 1 : 0; + p->Flag.SpareBits = 0; #endif - WBUFW(buf,2)=4+n*s; - clif->send(buf, WBUFW(buf,2), &sd->bl, SELF); +} +void clif_inventorylist(struct map_session_data *sd) { + int i, normal = 0, equip = 0; + + for( i = 0; i < MAX_INVENTORY; i++ ) { + + if( sd->status.inventory[i].nameid <= 0 || sd->inventory_data[i] == NULL ) + continue; + if( !itemdb->isstackable2(sd->inventory_data[i]) ) //Non-stackable (Equippable) + clif_item_equip(i+2,&itemlist_equip.list[equip++],&sd->status.inventory[i],sd->inventory_data[i],pc->equippoint(sd,i)); + else //Stackable (Normal) + clif_item_normal(i+2,&itemlist_normal.list[normal++],&sd->status.inventory[i],sd->inventory_data[i]); } - if( arrow >= 0 ) - clif->arrowequip(sd,arrow); - if( ne ) { -#if PACKETVER < 20071002 - WBUFW(bufe,0)=0xa4; -#else - WBUFW(bufe,0)=0x2d0; -#endif - WBUFW(bufe,2)=4+ne*se; - clif->send(bufe, WBUFW(bufe,2), &sd->bl, SELF); + if( normal ) { + itemlist_normal.PacketType = inventorylistnormalType; + itemlist_normal.PacketLength = 4 + (sizeof(struct NORMALITEM_INFO) * normal); + + clif->send(&itemlist_normal, itemlist_normal.PacketLength, &sd->bl, SELF); } -#if PACKETVER >= 20111122 + + if( sd->equip_index[EQI_AMMO] >= 0 ) + clif->arrowequip(sd,sd->equip_index[EQI_AMMO]); + + if( equip ) { + itemlist_equip.PacketType = inventorylistequipType; + itemlist_equip.PacketLength = 4 + (sizeof(struct EQUIPITEM_INFO) * equip); + + clif->send(&itemlist_equip, itemlist_equip.PacketLength, &sd->bl, SELF); + } +/* on 20120925 onwards this is a field on clif_item_equip/normal */ +#if PACKETVER >= 20111122 && PACKETVER < 20120925 for( i = 0; i < MAX_INVENTORY; i++ ) { if( sd->status.inventory[i].nameid <= 0 || sd->inventory_data[i] == NULL ) continue; @@ -2382,218 +2472,115 @@ void clif_inventorylist(struct map_session_data *sd) { clif->favorite_item(sd, i); } #endif - - if( buf ) aFree(buf); - if( bufe ) aFree(bufe); } //Required when items break/get-repaired. Only sends equippable item list. -void clif_equiplist(struct map_session_data *sd) -{ - int i,n,fd = sd->fd; - unsigned char *buf; -#if PACKETVER < 20071002 - const int cmd = 20; -#elif PACKETVER < 20100629 - const int cmd = 26; -#else - const int cmd = 28; -#endif +void clif_equiplist(struct map_session_data *sd) { + int i, equip = 0; - WFIFOHEAD(fd, MAX_INVENTORY * cmd + 4); - buf = WFIFOP(fd,0); + for( i = 0; i < MAX_INVENTORY; i++ ) { - for(i=0,n=0;i<MAX_INVENTORY;i++){ - if (sd->status.inventory[i].nameid <=0 || sd->inventory_data[i] == NULL) + if( sd->status.inventory[i].nameid <= 0 || sd->inventory_data[i] == NULL ) continue; + if( !itemdb->isstackable2(sd->inventory_data[i]) ) //Non-stackable (Equippable) + clif_item_equip(i+2,&itemlist_equip.list[equip++],&sd->status.inventory[i],sd->inventory_data[i],pc->equippoint(sd,i)); + } + + if( equip ) { + itemlist_equip.PacketType = inventorylistequipType; + itemlist_equip.PacketLength = 4 + (sizeof(struct EQUIPITEM_INFO) * equip); - if(itemdb->isstackable2(sd->inventory_data[i])) + clif->send(&itemlist_equip, itemlist_equip.PacketLength, &sd->bl, SELF); + } + + /* on 20120925 onwards this is a field on clif_item_equip */ +#if PACKETVER >= 20111122 && PACKETVER < 20120925 + for( i = 0; i < MAX_INVENTORY; i++ ) { + if( sd->status.inventory[i].nameid <= 0 || sd->inventory_data[i] == NULL ) continue; - //Equippable - WBUFW(buf,n*cmd+4)=i+2; - clif->item_sub(buf, n*cmd+6, &sd->status.inventory[i], sd->inventory_data[i], pc->equippoint(sd,i)); - clif->addcards(WBUFP(buf, n*cmd+16), &sd->status.inventory[i]); -#if PACKETVER >= 20071002 - WBUFL(buf,n*cmd+24)=sd->status.inventory[i].expire_time; - WBUFW(buf,n*cmd+28)=0; //Unknown -#endif -#if PACKETVER >= 20100629 - if (sd->inventory_data[i]->equip&EQP_VISIBLE) - WBUFW(buf,n*cmd+30)= sd->inventory_data[i]->look; - else - WBUFW(buf,n*cmd+30)=0; -#endif - n++; + + if ( sd->status.inventory[i].favorite ) + clif->favorite_item(sd, i); } - if (n) { -#if PACKETVER < 20071002 - WBUFW(buf,0)=0xa4; -#else - WBUFW(buf,0)=0x2d0; #endif - WBUFW(buf,2)=4+n*cmd; - WFIFOSET(fd,WFIFOW(fd,2)); - } } -void clif_storagelist(struct map_session_data* sd, struct item* items, int items_length) -{ +void clif_storagelist(struct map_session_data* sd, struct item* items, int items_length) { + int i = 0; struct item_data *id; - int i,n,ne; - unsigned char *buf; - unsigned char *bufe; -#if PACKETVER < 5 - const int s = 10; //Entry size. -#elif PACKETVER < 20080102 - const int s = 18; -#else - const int s = 22; -#endif -#if PACKETVER < 20071002 - const int cmd = 20; -#elif PACKETVER < 20100629 - const int cmd = 26; -#else - const int cmd = 28; -#endif - buf = (unsigned char*)aMalloc(items_length * s + 4); - bufe = (unsigned char*)aMalloc(items_length * cmd + 4); + do { + int normal = 0, equip = 0, k = 0; - for( i = 0, n = 0, ne = 0; i < items_length; i++ ) - { - if( items[i].nameid <= 0 ) - continue; - id = itemdb->search(items[i].nameid); - if( !itemdb->isstackable2(id) ) - { //Equippable - WBUFW(bufe,ne*cmd+4)=i+1; - clif->item_sub(bufe, ne*cmd+6, &items[i], id, id->equip); - clif->addcards(WBUFP(bufe, ne*cmd+16), &items[i]); -#if PACKETVER >= 20071002 - WBUFL(bufe,ne*cmd+24)=items[i].expire_time; - WBUFW(bufe,ne*cmd+28)=0; //Unknown -#endif - ne++; + for( ; i < items_length && k < 500; i++, k++ ) { + + if( items[i].nameid <= 0 ) + continue; + + id = itemdb->search(items[i].nameid); + + if( !itemdb->isstackable2(id) ) //Non-stackable (Equippable) + clif_item_equip(i+1,&storelist_equip.list[equip++],&items[i],id,id->equip); + else //Stackable (Normal) + clif_item_normal(i+1,&storelist_normal.list[normal++],&items[i],id); } - else - { //Stackable - WBUFW(buf,n*s+4)=i+1; - clif->item_sub(buf, n*s+6, &items[i], id,-1); -#if PACKETVER >= 5 - clif->addcards(WBUFP(buf,n*s+14), &items[i]); -#endif -#if PACKETVER >= 20080102 - WBUFL(buf,n*s+22)=items[i].expire_time; + + if( normal ) { + storelist_normal.PacketType = storagelistnormalType; + storelist_normal.PacketLength = ( sizeof( storelist_normal ) - sizeof( storelist_normal.list ) ) + (sizeof(struct NORMALITEM_INFO) * normal); + +#if PACKETVER >= 20120925 + safestrncpy(storelist_normal.name, "Storage", NAME_LENGTH); #endif - n++; + + clif->send(&storelist_normal, storelist_normal.PacketLength, &sd->bl, SELF); } - } - if( n ) - { -#if PACKETVER < 5 - WBUFW(buf,0)=0xa5; -#elif PACKETVER < 20080102 - WBUFW(buf,0)=0x1f0; -#else - WBUFW(buf,0)=0x2ea; -#endif - WBUFW(buf,2)=4+n*s; - clif->send(buf, WBUFW(buf,2), &sd->bl, SELF); - } - if( ne ) - { -#if PACKETVER < 20071002 - WBUFW(bufe,0)=0xa6; -#else - WBUFW(bufe,0)=0x2d1; + + if( equip ) { + storelist_equip.PacketType = storagelistequipType; + storelist_equip.PacketLength = ( sizeof( storelist_equip ) - sizeof( storelist_equip.list ) ) + (sizeof(struct EQUIPITEM_INFO) * equip); + +#if PACKETVER >= 20120925 + safestrncpy(storelist_equip.name, "Storage", NAME_LENGTH); #endif - WBUFW(bufe,2)=4+ne*cmd; - clif->send(bufe, WBUFW(bufe,2), &sd->bl, SELF); - } - if( buf ) aFree(buf); - if( bufe ) aFree(bufe); + clif->send(&storelist_equip, storelist_equip.PacketLength, &sd->bl, SELF); + } + + } while ( i < items_length ); + } -void clif_cartlist(struct map_session_data *sd) -{ +void clif_cartlist(struct map_session_data *sd) { + int i, normal = 0, equip = 0; struct item_data *id; - int i,n,ne; - unsigned char *buf; - unsigned char *bufe; -#if PACKETVER < 5 - const int s = 10; //Entry size. -#elif PACKETVER < 20080102 - const int s = 18; -#else - const int s = 22; -#endif -#if PACKETVER < 20071002 - const int cmd = 20; -#elif PACKETVER < 20100629 - const int cmd = 26; -#else - const int cmd = 28; -#endif - buf = (unsigned char*)aMalloc(MAX_CART * s + 4); - bufe = (unsigned char*)aMalloc(MAX_CART * cmd + 4); + for( i = 0; i < MAX_CART; i++ ) { - for( i = 0, n = 0, ne = 0; i < MAX_CART; i++ ) - { if( sd->status.cart[i].nameid <= 0 ) continue; + id = itemdb->search(sd->status.cart[i].nameid); - if( !itemdb->isstackable2(id) ) - { //Equippable - WBUFW(bufe,ne*cmd+4)=i+2; - clif->item_sub(bufe, ne*cmd+6, &sd->status.cart[i], id, id->equip); - clif->addcards(WBUFP(bufe, ne*cmd+16), &sd->status.cart[i]); -#if PACKETVER >= 20071002 - WBUFL(bufe,ne*cmd+24)=sd->status.cart[i].expire_time; - WBUFW(bufe,ne*cmd+28)=0; //Unknown -#endif - ne++; - } - else - { //Stackable - WBUFW(buf,n*s+4)=i+2; - clif->item_sub(buf, n*s+6, &sd->status.cart[i], id,-1); -#if PACKETVER >= 5 - clif->addcards(WBUFP(buf,n*s+14), &sd->status.cart[i]); -#endif -#if PACKETVER >= 20080102 - WBUFL(buf,n*s+22)=sd->status.cart[i].expire_time; -#endif - n++; - } - } - if( n ) - { -#if PACKETVER < 5 - WBUFW(buf,0)=0x123; -#elif PACKETVER < 20080102 - WBUFW(buf,0)=0x1ef; -#else - WBUFW(buf,0)=0x2e9; -#endif - WBUFW(buf,2)=4+n*s; - clif->send(buf, WBUFW(buf,2), &sd->bl, SELF); + + if( !itemdb->isstackable2(id) ) //Non-stackable (Equippable) + clif_item_equip(i+2,&itemlist_equip.list[equip++],&sd->status.cart[i],id,id->equip); + else //Stackable (Normal) + clif_item_normal(i+2,&itemlist_normal.list[normal++],&sd->status.cart[i],id); } - if( ne ) - { -#if PACKETVER < 20071002 - WBUFW(bufe,0)=0x122; -#else - WBUFW(bufe,0)=0x2d2; -#endif - WBUFW(bufe,2)=4+ne*cmd; - clif->send(bufe, WBUFW(bufe,2), &sd->bl, SELF); + + if( normal ) { + itemlist_normal.PacketType = cartlistnormalType; + itemlist_normal.PacketLength = 4 + (sizeof(struct NORMALITEM_INFO) * normal); + + clif->send(&itemlist_normal, itemlist_normal.PacketLength, &sd->bl, SELF); } - if( buf ) aFree(buf); - if( bufe ) aFree(bufe); + if( equip ) { + itemlist_equip.PacketType = cartlistequipType; + itemlist_equip.PacketLength = 4 + (sizeof(struct EQUIPITEM_INFO) * equip); + + clif->send(&itemlist_equip, itemlist_equip.PacketLength, &sd->bl, SELF); + } } @@ -2659,14 +2646,14 @@ void read_channels_config(void) { config_t channels_conf; config_setting_t *chsys = NULL; const char *config_filename = "conf/channels.conf"; // FIXME hardcoded name - - if (conf_read_file(&channels_conf, config_filename)) + + if (libconfig->read_file(&channels_conf, config_filename)) return; - - chsys = config_lookup(&channels_conf, "chsys"); - + + chsys = libconfig->lookup(&channels_conf, "chsys"); + if (chsys != NULL) { - config_setting_t *settings = config_setting_get_elem(chsys, 0); + config_setting_t *settings = libconfig->setting_get_elem(chsys, 0); config_setting_t *channels; config_setting_t *colors; int i,k; @@ -2677,46 +2664,46 @@ void read_channels_config(void) { local_autojoin = 0, ally_autojoin = 0, allow_user_channel_creation = 0, irc_enabled = 0; - - if( !config_setting_lookup_string(settings, "map_local_channel_name", &local_name) ) + + if( !libconfig->setting_lookup_string(settings, "map_local_channel_name", &local_name) ) local_name = "map"; safestrncpy(hChSys.local_name, local_name, HCHSYS_NAME_LENGTH); - - if( !config_setting_lookup_string(settings, "ally_channel_name", &ally_name) ) + + if( !libconfig->setting_lookup_string(settings, "ally_channel_name", &ally_name) ) ally_name = "ally"; safestrncpy(hChSys.ally_name, ally_name, HCHSYS_NAME_LENGTH); - - if( !config_setting_lookup_string(settings, "irc_channel_name", &irc_name) ) + + if( !libconfig->setting_lookup_string(settings, "irc_channel_name", &irc_name) ) irc_name = "irc"; safestrncpy(hChSys.irc_name, irc_name, HCHSYS_NAME_LENGTH); - - config_setting_lookup_bool(settings, "map_local_channel", &local_enabled); - config_setting_lookup_bool(settings, "ally_channel_enabled", &ally_enabled); - config_setting_lookup_bool(settings, "irc_channel_enabled", &irc_enabled); - + + libconfig->setting_lookup_bool(settings, "map_local_channel", &local_enabled); + libconfig->setting_lookup_bool(settings, "ally_channel_enabled", &ally_enabled); + libconfig->setting_lookup_bool(settings, "irc_channel_enabled", &irc_enabled); + if( local_enabled ) hChSys.local = true; if( ally_enabled ) hChSys.ally = true; if( irc_enabled ) hChSys.irc = true; - + hChSys.irc_server[0] = hChSys.irc_channel[0] = hChSys.irc_nick[0] = hChSys.irc_nick_pw[0] = '\0'; - + if( hChSys.irc ) { const char *irc_server, *irc_channel, *irc_nick, *irc_nick_pw; int irc_use_ghost = 0; - if( config_setting_lookup_string(settings, "irc_channel_network", &irc_server) ) { + if( libconfig->setting_lookup_string(settings, "irc_channel_network", &irc_server) ) { if( !strstr(irc_server,":") ) { hChSys.irc = false; ShowWarning("channels.conf : network port wasn't found in 'irc_channel_network', disabling irc channel...\n"); } else { unsigned char d = 0, dlen = strlen(irc_server); char server[40]; - + memset(server, '\0', sizeof(server)); - + for(d = 0; d < dlen; d++) { if(irc_server[d] == ':') { memcpy(server, irc_server, d); @@ -2731,13 +2718,13 @@ void read_channels_config(void) { hChSys.irc = false; ShowWarning("channels.conf : irc channel enabled but irc_channel_network wasn't found, disabling irc channel...\n"); } - if( config_setting_lookup_string(settings, "irc_channel_channel", &irc_channel) ) + if( libconfig->setting_lookup_string(settings, "irc_channel_channel", &irc_channel) ) safestrncpy(hChSys.irc_channel, irc_channel, 50); else { hChSys.irc = false; ShowWarning("channels.conf : irc channel enabled but irc_channel_channel wasn't found, disabling irc channel...\n"); } - if( config_setting_lookup_string(settings, "irc_channel_nick", &irc_nick) ) { + if( libconfig->setting_lookup_string(settings, "irc_channel_nick", &irc_nick) ) { if( strcmpi(irc_nick,"Hercules_chSysBot") == 0 ) { sprintf(hChSys.irc_nick, "Hercules_chSysBot%d",rand()%777); } else @@ -2746,106 +2733,106 @@ void read_channels_config(void) { hChSys.irc = false; ShowWarning("channels.conf : irc channel enabled but irc_channel_nick wasn't found, disabling irc channel...\n"); } - if( config_setting_lookup_string(settings, "irc_channel_nick_pw", &irc_nick_pw) ) { + if( libconfig->setting_lookup_string(settings, "irc_channel_nick_pw", &irc_nick_pw) ) { safestrncpy(hChSys.irc_nick_pw, irc_nick_pw, 30); config_setting_lookup_bool(settings, "irc_channel_use_ghost", &irc_use_ghost); hChSys.irc_use_ghost = irc_use_ghost; } } - - config_setting_lookup_bool(settings, "map_local_channel_autojoin", &local_autojoin); - config_setting_lookup_bool(settings, "ally_channel_autojoin", &ally_autojoin); + + libconfig->setting_lookup_bool(settings, "map_local_channel_autojoin", &local_autojoin); + libconfig->setting_lookup_bool(settings, "ally_channel_autojoin", &ally_autojoin); if( local_autojoin ) hChSys.local_autojoin = true; if( ally_autojoin ) hChSys.ally_autojoin = true; - - config_setting_lookup_bool(settings, "allow_user_channel_creation", &allow_user_channel_creation); + + libconfig->setting_lookup_bool(settings, "allow_user_channel_creation", &allow_user_channel_creation); if( allow_user_channel_creation ) hChSys.allow_user_channel_creation = true; - if( (colors = config_setting_get_member(settings, "colors")) != NULL ) { - int color_count = config_setting_length(colors); - CREATE( hChSys.colors, unsigned long, color_count ); + if( (colors = libconfig->setting_get_member(settings, "colors")) != NULL ) { + int color_count = libconfig->setting_length(colors); + CREATE( hChSys.colors, unsigned int, color_count ); CREATE( hChSys.colors_name, char *, color_count ); for(i = 0; i < color_count; i++) { - config_setting_t *color = config_setting_get_elem(colors, i); + config_setting_t *color = libconfig->setting_get_elem(colors, i); CREATE( hChSys.colors_name[i], char, HCHSYS_NAME_LENGTH ); - + safestrncpy(hChSys.colors_name[i], config_setting_name(color), HCHSYS_NAME_LENGTH); - hChSys.colors[i] = strtoul(config_setting_get_string_elem(colors,i),NULL,0); + hChSys.colors[i] = (unsigned int)strtoul(libconfig->setting_get_string_elem(colors,i),NULL,0); hChSys.colors[i] = (hChSys.colors[i] & 0x0000FF) << 16 | (hChSys.colors[i] & 0x00FF00) | (hChSys.colors[i] & 0xFF0000) >> 16;//RGB to BGR } hChSys.colors_count = color_count; } - - config_setting_lookup_string(settings, "map_local_channel_color", &local_color); - + + libconfig->setting_lookup_string(settings, "map_local_channel_color", &local_color); + for (k = 0; k < hChSys.colors_count; k++) { if( strcmpi(hChSys.colors_name[k],local_color) == 0 ) break; } - + if( k < hChSys.colors_count ) { hChSys.local_color = k; } else { ShowError("channels.conf: unknown color '%s' for 'map_local_channel_color', disabling '#%s'...\n",local_color,local_name); hChSys.local = false; } - - config_setting_lookup_string(settings, "ally_channel_color", &ally_color); - + + libconfig->setting_lookup_string(settings, "ally_channel_color", &ally_color); + for (k = 0; k < hChSys.colors_count; k++) { if( strcmpi(hChSys.colors_name[k],ally_color) == 0 ) break; } - + if( k < hChSys.colors_count ) { hChSys.ally_color = k; } else { ShowError("channels.conf: unknown color '%s' for 'ally_channel_color', disabling '#%s'...\n",ally_color,ally_name); hChSys.ally = false; } - - config_setting_lookup_string(settings, "irc_channel_color", &irc_color); - + + libconfig->setting_lookup_string(settings, "irc_channel_color", &irc_color); + for (k = 0; k < hChSys.colors_count; k++) { if( strcmpi(hChSys.colors_name[k],irc_color) == 0 ) break; } - + if( k < hChSys.colors_count ) { hChSys.irc_color = k; } else { ShowError("channels.conf: unknown color '%s' for 'irc_channel_color', disabling '#%s'...\n",irc_color,irc_name); hChSys.irc = false; } - + if( hChSys.irc ) { struct hChSysCh *chd; CREATE( chd, struct hChSysCh, 1 ); - + safestrncpy(chd->name, hChSys.irc_name, HCHSYS_NAME_LENGTH); chd->type = hChSys_IRC; - + clif->chsys_create(chd,NULL,NULL,hChSys.irc_color); ircbot->channel = chd; } - - if( (channels = config_setting_get_member(settings, "default_channels")) != NULL ) { - int channel_count = config_setting_length(channels); - + + if( (channels = libconfig->setting_get_member(settings, "default_channels")) != NULL ) { + int channel_count = libconfig->setting_length(channels); + for(i = 0; i < channel_count; i++) { - config_setting_t *channel = config_setting_get_elem(channels, i); + config_setting_t *channel = libconfig->setting_get_elem(channels, i); const char *name = config_setting_name(channel); - const char *color = config_setting_get_string_elem(channels,i); + const char *color = libconfig->setting_get_string_elem(channels,i); struct hChSysCh *chd; - + for (k = 0; k < hChSys.colors_count; k++) { if( strcmpi(hChSys.colors_name[k],color) == 0 ) break; @@ -2860,16 +2847,16 @@ void read_channels_config(void) { } CREATE( chd, struct hChSysCh, 1 ); - + safestrncpy(chd->name, name, HCHSYS_NAME_LENGTH); chd->type = hChSys_PUBLIC; - + clif->chsys_create(chd,NULL,NULL,k); } } - + ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' channels in '"CL_WHITE"%s"CL_RESET"'.\n", db_size(clif->channel_db), config_filename); - config_destroy(&channels_conf); + libconfig->destroy(&channels_conf); } } @@ -2894,7 +2881,7 @@ int clif_hpmeter_sub(struct block_list *bl, va_list ap) { if( !tsd->fd || tsd == sd ) return 0; - if( !pc->has_permission(tsd, PC_PERM_VIEW_HPMETER) ) + if( !pc_has_permission(tsd, PC_PERM_VIEW_HPMETER) ) return 0; WFIFOHEAD(tsd->fd,packet_len(cmd)); WFIFOW(tsd->fd,0) = cmd; @@ -2934,10 +2921,9 @@ int clif_hpmeter(struct map_session_data *sd) { /// 013a <atk range>.W (ZC_ATTACK_RANGE) /// 0141 <status id>.L <base status>.L <plus status>.L (ZC_COUPLESTATUS) /// TODO: Extract individual packets. -/// FIXME: Packet lengths from packet_len(cmd) void clif_updatestatus(struct map_session_data *sd,int type) { - int fd,len=8; + int fd,len; nullpo_retv(sd); @@ -2949,6 +2935,7 @@ void clif_updatestatus(struct map_session_data *sd,int type) WFIFOHEAD(fd, 14); WFIFOW(fd,0)=0xb0; WFIFOW(fd,2)=type; + len = packet_len(0xb0); switch(type){ // 00b0 case SP_WEIGHT: @@ -3000,7 +2987,8 @@ void clif_updatestatus(struct map_session_data *sd,int type) case SP_HP: WFIFOL(fd,4)=sd->battle_status.hp; // TODO: Won't these overwrite the current packet? - clif->hpmeter(sd); + if( map->list[sd->bl.m].hpmeter_visible ) + clif->hpmeter(sd); if( !battle_config.party_hp_mode && sd->status.party_id ) clif->party_hp(sd); if( sd->bg_id ) @@ -3053,22 +3041,27 @@ void clif_updatestatus(struct map_session_data *sd,int type) case SP_ZENY: WFIFOW(fd,0)=0xb1; WFIFOL(fd,4)=sd->status.zeny; + len = packet_len(0xb1); break; case SP_BASEEXP: WFIFOW(fd,0)=0xb1; WFIFOL(fd,4)=sd->status.base_exp; + len = packet_len(0xb1); break; case SP_JOBEXP: WFIFOW(fd,0)=0xb1; WFIFOL(fd,4)=sd->status.job_exp; + len = packet_len(0xb1); break; case SP_NEXTBASEEXP: WFIFOW(fd,0)=0xb1; WFIFOL(fd,4)=pc->nextbaseexp(sd); + len = packet_len(0xb1); break; case SP_NEXTJOBEXP: WFIFOW(fd,0)=0xb1; WFIFOL(fd,4)=pc->nextjobexp(sd); + len = packet_len(0xb1); break; /** @@ -3082,7 +3075,7 @@ void clif_updatestatus(struct map_session_data *sd,int type) case SP_ULUK: WFIFOW(fd,0)=0xbe; WFIFOB(fd,4)=pc->need_status_point(sd,type-SP_USTR+SP_STR,1); - len=5; + len = packet_len(0xbe); break; /** @@ -3091,7 +3084,7 @@ void clif_updatestatus(struct map_session_data *sd,int type) case SP_ATTACKRANGE: WFIFOW(fd,0)=0x13a; WFIFOW(fd,2)=sd->battle_status.rhw.range; - len=4; + len = packet_len(0x13a); break; case SP_STR: @@ -3099,42 +3092,42 @@ void clif_updatestatus(struct map_session_data *sd,int type) WFIFOL(fd,2)=type; WFIFOL(fd,6)=sd->status.str; WFIFOL(fd,10)=sd->battle_status.str - sd->status.str; - len=14; + len = packet_len(0x141); break; case SP_AGI: WFIFOW(fd,0)=0x141; WFIFOL(fd,2)=type; WFIFOL(fd,6)=sd->status.agi; WFIFOL(fd,10)=sd->battle_status.agi - sd->status.agi; - len=14; + len = packet_len(0x141); break; case SP_VIT: WFIFOW(fd,0)=0x141; WFIFOL(fd,2)=type; WFIFOL(fd,6)=sd->status.vit; WFIFOL(fd,10)=sd->battle_status.vit - sd->status.vit; - len=14; + len = packet_len(0x141); break; case SP_INT: WFIFOW(fd,0)=0x141; WFIFOL(fd,2)=type; WFIFOL(fd,6)=sd->status.int_; WFIFOL(fd,10)=sd->battle_status.int_ - sd->status.int_; - len=14; + len = packet_len(0x141); break; case SP_DEX: WFIFOW(fd,0)=0x141; WFIFOL(fd,2)=type; WFIFOL(fd,6)=sd->status.dex; WFIFOL(fd,10)=sd->battle_status.dex - sd->status.dex; - len=14; + len = packet_len(0x141); break; case SP_LUK: WFIFOW(fd,0)=0x141; WFIFOL(fd,2)=type; WFIFOL(fd,6)=sd->status.luk; WFIFOL(fd,10)=sd->battle_status.luk - sd->status.luk; - len=14; + len = packet_len(0x141); break; case SP_CARTINFO: @@ -3143,7 +3136,7 @@ void clif_updatestatus(struct map_session_data *sd,int type) WFIFOW(fd,4)=MAX_CART; WFIFOL(fd,6)=sd->cart_weight; WFIFOL(fd,10)=sd->cart_weight_max; - len=14; + len = packet_len(0x121); break; default: @@ -3153,7 +3146,6 @@ void clif_updatestatus(struct map_session_data *sd,int type) WFIFOSET(fd,len); } - /// Notifies client of a parameter change of an another player (ZC_PAR_CHANGE_USER). /// 01ab <account id>.L <var id>.W <value>.L void clif_changestatus(struct map_session_data* sd,int type,int val) @@ -3195,7 +3187,7 @@ void clif_changelook(struct block_list *bl,int type,int val) sd = BL_CAST(BL_PC, bl); sc = status->get_sc(bl); vd = status->get_viewdata(bl); - //nullpo_ret(vd); + if( vd ) //temp hack to let Warp Portal change appearance switch(type) { case LOOK_WEAPON: @@ -3216,13 +3208,13 @@ void clif_changelook(struct block_list *bl,int type,int val) break; case LOOK_BASE: if( !sd ) break; - - if( sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER|OPTION_HANBOK) ) + + if( sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER|OPTION_HANBOK|OPTION_OKTOBERFEST) ) vd->weapon = vd->shield = 0; - + if( !vd->cloth_color ) break; - + if( sd ) { if( sd->sc.option&OPTION_WEDDING && battle_config.wedding_ignorepalette ) vd->cloth_color = 0; @@ -3232,6 +3224,8 @@ void clif_changelook(struct block_list *bl,int type,int val) vd->cloth_color = 0; if( sd->sc.option&OPTION_HANBOK && battle_config.hanbok_ignorepalette ) vd->cloth_color = 0; + if( sd->sc.option&OPTION_OKTOBERFEST /* TODO: config? */ ) + vd->cloth_color = 0; } break; case LOOK_HAIR: @@ -3259,6 +3253,8 @@ void clif_changelook(struct block_list *bl,int type,int val) val = 0; if( sd->sc.option&OPTION_HANBOK && battle_config.hanbok_ignorepalette ) val = 0; + if( sd->sc.option&OPTION_OKTOBERFEST /* TODO: config? */ ) + val = 0; } vd->cloth_color = val; break; @@ -3304,6 +3300,7 @@ void clif_changelook(struct block_list *bl,int type,int val) WBUFW(buf,0)=0x1d7; WBUFL(buf,2)=bl->id; if(type == LOOK_WEAPON || type == LOOK_SHIELD) { + nullpo_retv(vd); WBUFB(buf,6)=LOOK_WEAPON; WBUFW(buf,7)=vd->weapon; WBUFW(buf,9)=vd->shield; @@ -3312,7 +3309,7 @@ void clif_changelook(struct block_list *bl,int type,int val) WBUFL(buf,7)=val; } clif->send(buf,packet_len(0x1d7),bl,target); - if( disguised(bl) && ((TBL_PC*)sd)->fontcolor ) { + if( disguised(bl) && sd && sd->fontcolor ) { WBUFL(buf,2)=-bl->id; clif->send(buf,packet_len(0x1d7),bl,SELF); } @@ -3527,52 +3524,39 @@ void clif_statusupack(struct map_session_data *sd,int type,int ok,int val) /// Notifies the client about the result of a request to equip an item (ZC_REQ_WEAR_EQUIP_ACK). /// 00aa <index>.W <equip location>.W <result>.B /// 00aa <index>.W <equip location>.W <view id>.W <result>.B (PACKETVER >= 20100629) -/// result: -/// 0 = failure -/// 1 = success -/// 2 = failure due to low level -void clif_equipitemack(struct map_session_data *sd,int n,int pos,int ok) -{ - int fd; +void clif_equipitemack(struct map_session_data *sd,int n,int pos,enum e_EQUIP_ITEM_ACK result) { + struct packet_equipitem_ack p; nullpo_retv(sd); - fd=sd->fd; - WFIFOHEAD(fd,packet_len(0xaa)); - WFIFOW(fd,0)=0xaa; - WFIFOW(fd,2)=n+2; - WFIFOW(fd,4)=pos; -#if PACKETVER < 20100629 - WFIFOB(fd,6)=ok; -#else - if (ok && sd->inventory_data[n]->equip&EQP_VISIBLE) - WFIFOW(fd,6)=sd->inventory_data[n]->look; + p.PacketType = equipitemackType; + p.index = n+2; + p.wearLocation = pos; +#if PACKETVER >= 20100629 + if (result == EIA_SUCCESS && sd->inventory_data[n]->equip&EQP_VISIBLE) + p.wItemSpriteNumber = sd->inventory_data[n]->look; else - WFIFOW(fd,6)=0; - WFIFOB(fd,8)=ok; + p.wItemSpriteNumber = 0; #endif - WFIFOSET(fd,packet_len(0xaa)); + p.result = (unsigned char)result; + + clif->send(&p, sizeof(p), &sd->bl, SELF); } /// Notifies the client about the result of a request to take off an item (ZC_REQ_TAKEOFF_EQUIP_ACK). /// 00ac <index>.W <equip location>.W <result>.B -/// result: -/// 0 = failure -/// 1 = success -void clif_unequipitemack(struct map_session_data *sd,int n,int pos,int ok) -{ - int fd; +void clif_unequipitemack(struct map_session_data *sd,int n,int pos,enum e_UNEQUIP_ITEM_ACK result) { + struct packet_unequipitem_ack p; nullpo_retv(sd); - fd=sd->fd; - WFIFOHEAD(fd,packet_len(0xac)); - WFIFOW(fd,0)=0xac; - WFIFOW(fd,2)=n+2; - WFIFOW(fd,4)=pos; - WFIFOB(fd,6)=ok; - WFIFOSET(fd,packet_len(0xac)); + p.PacketType = unequipitemackType; + p.index = n+2; + p.wearLocation = pos; + p.result = (unsigned char)result; + + clif->send(&p, sizeof(p), &sd->bl, SELF); } @@ -3613,9 +3597,9 @@ void clif_changeoption(struct block_list* bl) struct map_session_data* sd; nullpo_retv(bl); - + if ( !(sc = status->get_sc(bl)) && bl->type != BL_NPC ) return; //How can an option change if there's no sc? - + sd = BL_CAST(BL_PC, bl); #if PACKETVER >= 7 @@ -3722,7 +3706,7 @@ void clif_useitemack(struct map_session_data *sd,int index,int amount,bool ok) } void clif_hercules_chsys_send(struct hChSysCh *channel, struct map_session_data *sd, const char *msg) { - if( channel->msg_delay != 0 && DIFF_TICK(sd->hchsysch_tick + ( channel->msg_delay * 1000 ), timer->gettick()) > 0 && !pc->has_permission(sd, PC_PERM_HCHSYS_ADMIN) ) { + if( channel->msg_delay != 0 && DIFF_TICK(sd->hchsysch_tick + ( channel->msg_delay * 1000 ), timer->gettick()) > 0 && !pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN) ) { clif->colormes(sd->fd,COLOR_RED,msg_txt(1455)); return; } else { @@ -4291,7 +4275,7 @@ void clif_getareachar_pc(struct map_session_data* sd,struct map_session_data* ds } if( (sd->status.party_id && dstsd->status.party_id == sd->status.party_id) || //Party-mate, or hpdisp setting. (sd->bg_id && sd->bg_id == dstsd->bg_id) || //BattleGround - pc->has_permission(sd, PC_PERM_VIEW_HPMETER) + pc_has_permission(sd, PC_PERM_VIEW_HPMETER) ) clif->hpmeter_single(sd->fd, dstsd->bl.id, dstsd->battle_status.hp, dstsd->battle_status.max_hp); @@ -4334,7 +4318,7 @@ void clif_getareachar_unit(struct map_session_data* sd,struct block_list *bl) { clif->getareachar_pc(sd, tsd); if(tsd->state.size==SZ_BIG) // tiny/big players [Valaris] clif->specialeffect_single(bl,423,sd->fd); - else if(tsd->state.size==SZ_MEDIUM) + else if(tsd->state.size==SZ_SMALL) clif->specialeffect_single(bl,421,sd->fd); if( tsd->bg_id && map->list[tsd->bl.m].flag.battleground ) clif->sendbgemblem_single(sd->fd,tsd); @@ -4353,7 +4337,7 @@ void clif_getareachar_unit(struct map_session_data* sd,struct block_list *bl) { clif->dispchat((struct chat_data*)map->id2bl(nd->chat_id),sd->fd); if( nd->size == SZ_BIG ) clif->specialeffect_single(bl,423,sd->fd); - else if( nd->size == SZ_MEDIUM ) + else if( nd->size == SZ_SMALL ) clif->specialeffect_single(bl,421,sd->fd); } break; @@ -4362,7 +4346,7 @@ void clif_getareachar_unit(struct map_session_data* sd,struct block_list *bl) { TBL_MOB* md = (TBL_MOB*)bl; if(md->special_state.size==SZ_BIG) // tiny/big mobs [Valaris] clif->specialeffect_single(bl,423,sd->fd); - else if(md->special_state.size==SZ_MEDIUM) + else if(md->special_state.size==SZ_SMALL) clif->specialeffect_single(bl,421,sd->fd); #if PACKETVER >= 20120404 if( !(md->status.mode&MD_BOSS) ){ @@ -4429,83 +4413,74 @@ int clif_calc_walkdelay(struct block_list *bl,int delay, int type, int damage, i /// 10 = critical hit /// 11 = lucky dodge /// 12 = (touch skill?) -int clif_damage(struct block_list* src, struct block_list* dst, unsigned int tick, int sdelay, int ddelay, int64 in_damage, int div, int type, int64 in_damage2) -{ - unsigned char buf[33]; +int clif_damage(struct block_list* src, struct block_list* dst, int sdelay, int ddelay, int64 in_damage, short div, unsigned char type, int64 in_damage2) { + struct packet_damage p; struct status_change *sc; - int damage,damage2; #if PACKETVER < 20071113 - const int cmd = 0x8a; + short damage,damage2; #else - const int cmd = 0x2e1; + int damage,damage2; #endif nullpo_ret(src); nullpo_ret(dst); - - damage = (int)cap_value(in_damage,INT_MIN,INT_MAX); - damage2 = (int)cap_value(in_damage2,INT_MIN,INT_MAX); - - type = clif_calc_delay(type,div,damage+damage2,ddelay); + sc = status->get_sc(dst); - if(sc && sc->count) { - if(sc->data[SC_ILLUSION]) { - if(damage) damage = damage*(sc->data[SC_ILLUSION]->val2) + rnd()%100; - if(damage2) damage2 = damage2*(sc->data[SC_ILLUSION]->val2) + rnd()%100; - } - } - WBUFW(buf,0)=cmd; - WBUFL(buf,2)=src->id; - WBUFL(buf,6)=dst->id; - WBUFL(buf,10)=tick; - WBUFL(buf,14)=sdelay; - WBUFL(buf,18)=ddelay; -#if PACKETVER < 20071113 - if (battle_config.hide_woe_damage && map_flag_gvg2(src->m)) { - WBUFW(buf,22)=damage?div:0; - WBUFW(buf,27)=damage2?div:0; - } else { - WBUFW(buf,22)=min(damage, INT16_MAX); - WBUFW(buf,27)=damage2; + if(sc && sc->count && sc->data[SC_ILLUSION]) { + if(in_damage) in_damage = in_damage*(sc->data[SC_ILLUSION]->val2) + rnd()%100; + if(in_damage2) in_damage2 = in_damage2*(sc->data[SC_ILLUSION]->val2) + rnd()%100; } - WBUFW(buf,24)=div; - WBUFB(buf,26)=type; + +#if PACKETVER < 20071113 + damage = (short)min(in_damage,INT16_MAX); + damage2 = (short)min(in_damage2,INT16_MAX); #else - if (battle_config.hide_woe_damage && map_flag_gvg2(src->m)) { - WBUFL(buf,22)=damage?div:0; - WBUFL(buf,29)=damage2?div:0; + damage = (int)min(in_damage,INT_MAX); + damage2 = (int)min(in_damage2,INT_MAX); +#endif + + type = clif_calc_delay(type,div,damage+damage2,ddelay); + + p.PacketType = damageType; + p.GID = src->id; + p.targetGID = dst->id; + p.startTime = (uint32)timer->gettick(); + p.attackMT = sdelay; + p.attackedMT = ddelay; + p.count = div; + p.action = type; + + if( battle_config.hide_woe_damage && map_flag_gvg2(src->m) ) { + p.damage = damage?div:0; + p.leftDamage = damage2?div:0; } else { - WBUFL(buf,22)=damage; - WBUFL(buf,29)=damage2; + p.damage = damage; + p.leftDamage = damage2; } - WBUFW(buf,26)=div; - WBUFB(buf,28)=type; -#endif + if(disguised(dst)) { - clif->send(buf,packet_len(cmd),dst,AREA_WOS); - WBUFL(buf,6) = -dst->id; - clif->send(buf,packet_len(cmd),dst,SELF); + clif->send(&p,sizeof(p),dst,AREA_WOS); + p.targetGID = -dst->id; + clif->send(&p,sizeof(p),dst,SELF); } else - clif->send(buf,packet_len(cmd),dst,AREA); + clif->send(&p,sizeof(p),dst,AREA); if(disguised(src)) { - WBUFL(buf,2) = -src->id; + p.GID = -src->id; if (disguised(dst)) - WBUFL(buf,6) = dst->id; -#if PACKETVER < 20071113 - if(damage > 0) WBUFW(buf,22) = -1; - if(damage2 > 0) WBUFW(buf,27) = -1; -#else - if(damage > 0) WBUFL(buf,22) = -1; - if(damage2 > 0) WBUFL(buf,29) = -1; -#endif - clif->send(buf,packet_len(cmd),src,SELF); + p.targetGID = dst->id; + + if(damage > 0) p.damage = -1; + if(damage2 > 0) p.leftDamage = -1; + + clif->send(&p,sizeof(p),src,SELF); } if(src == dst) { unit->setdir(src,unit->getdir(src)); } + //Return adjusted can't walk delay for further processing. return clif->calc_walkdelay(dst,ddelay,type,damage+damage2,div); } @@ -4515,7 +4490,7 @@ int clif_damage(struct block_list* src, struct block_list* dst, unsigned int tic *------------------------------------------*/ void clif_takeitem(struct block_list* src, struct block_list* dst) { - //clif_damage(src,dst,0,0,0,0,0,1,0); + //clif->damage(src,dst,0,0,0,0,1,0); unsigned char buf[32]; nullpo_retv(src); @@ -4570,15 +4545,14 @@ void clif_standing(struct block_list* bl) /// Inform client(s) about a map-cell change (ZC_UPDATE_MAPINFO). /// 0192 <x>.W <y>.W <type>.W <map name>.16B -void clif_changemapcell(int fd, int16 m, int x, int y, int type, enum send_target target) -{ +void clif_changemapcell(int fd, int16 m, int x, int y, int type, enum send_target target) { unsigned char buf[32]; WBUFW(buf,0) = 0x192; WBUFW(buf,2) = x; WBUFW(buf,4) = y; WBUFW(buf,6) = type; - mapindex_getmapname_ext(map->list[m].custom_name ? map->list[map->list[m].instance_src_map].name : map->list[m].name,(char*)WBUFP(buf,8)); + mapindex->getmapname_ext(map->list[m].custom_name ? map->list[map->list[m].instance_src_map].name : map->list[m].name,(char*)WBUFP(buf,8)); if( fd ) { WFIFOHEAD(fd,packet_len(0x192)); @@ -4617,65 +4591,72 @@ void clif_getareachar_item(struct map_session_data* sd,struct flooritem_data* fi WFIFOSET(fd,packet_len(0x9d)); } +void clif_graffiti_entry(struct block_list *bl, struct skill_unit *su, enum send_target target) { + struct packet_graffiti_entry p; + + p.PacketType = graffiti_entryType; + p.AID = su->bl.id; + p.creatorAID = su->group->src_id; + p.xPos = su->bl.x; + p.yPos = su->bl.y; + p.job = su->group->unit_id; + p.isContens = 1; + p.isVisible = 1; + safestrncpy(p.msg, su->group->valstr, 80); + + clif->send(&p,sizeof(p),bl,target); +} /// Notifies the client of a skill unit. /// 011f <id>.L <creator id>.L <x>.W <y>.W <unit id>.B <visible>.B (ZC_SKILL_ENTRY) /// 01c9 <id>.L <creator id>.L <x>.W <y>.W <unit id>.B <visible>.B <has msg>.B <msg>.80B (ZC_SKILL_ENTRY2) /// 08c7 <lenght>.W <id> L <creator id>.L <x>.W <y>.W <unit id>.B <range>.W <visible>.B (ZC_SKILL_ENTRY3) /// 099f <lenght>.W <id> L <creator id>.L <x>.W <y>.W <unit id>.L <range>.W <visible>.B (ZC_SKILL_ENTRY4) -void clif_getareachar_skillunit(struct map_session_data *sd, struct skill_unit *su) { - int fd = sd->fd, header = 0x11f, pos=0; +void clif_getareachar_skillunit(struct block_list *bl, struct skill_unit *su, enum send_target target) { + struct packet_skill_entry p; if( su->group->state.guildaura ) return; -#if PACKETVER >= 20130320 - if(su->group->unit_id > UCHAR_MAX) { - header = 0x99f; - pos = 2; - } -#endif - #if PACKETVER >= 3 - if(su->group->unit_id==UNT_GRAFFITI) { - // Graffiti [Valaris] - WFIFOHEAD(fd,packet_len(0x1c9)); - WFIFOW(fd, 0)=0x1c9; - WFIFOL(fd, 2)=su->bl.id; - WFIFOL(fd, 6)=su->group->src_id; - WFIFOW(fd,10)=su->bl.x; - WFIFOW(fd,12)=su->bl.y; - WFIFOB(fd,14)=su->group->unit_id; - WFIFOB(fd,15)=1; - WFIFOB(fd,16)=1; - safestrncpy((char*)WFIFOP(fd,17),su->group->valstr,MESSAGE_SIZE); - WFIFOSET(fd,packet_len(0x1c9)); + if(su->group->unit_id == UNT_GRAFFITI) { + clif->graffiti_entry(bl,su,target); return; } #endif - WFIFOHEAD(fd,packet_len(header)); - WFIFOW(fd, 0)=header; - if(pos > 0) - WFIFOL(fd, pos)=packet_len(header); - WFIFOL(fd, 2 + pos)=su->bl.id; - WFIFOL(fd, 6 + pos)=su->group->src_id; - WFIFOW(fd,10 + pos)=su->bl.x; - WFIFOW(fd,12 + pos)=su->bl.y; - if (battle_config.traps_setting&1 && skill->get_inf2(su->group->skill_id)&INF2_TRAP) - WFIFOB(fd,14)=UNT_DUMMYSKILL; //Use invisible unit id for traps. - else if (skill->get_unit_flag(su->group->skill_id) & UF_RANGEDSINGLEUNIT && !(su->val2 & UF_RANGEDSINGLEUNIT)) - WFIFOB(fd,14)=UNT_DUMMYSKILL; //Use invisible unit id for traps. - else if(pos > 0){ - WFIFOL(fd,16)=su->group->unit_id; - WFIFOW(fd,20)=su->range; - pos += 5; - }else - WFIFOB(fd,14)=su->group->unit_id; - WFIFOB(fd,15 + pos)=1; // ignored by client (always gets set to 1) - WFIFOSET(fd,packet_len(header)); + + p.PacketType = skill_entryType; + +#if PACKETVER >= 20110718 + p.PacketLength = sizeof(p); +#endif + + p.AID = su->bl.id; + p.creatorAID = su->group->src_id; + p.xPos = su->bl.x; + p.yPos = su->bl.y; + + //Use invisible unit id for traps. + if ((battle_config.traps_setting&1 && skill->get_inf2(su->group->skill_id)&INF2_TRAP) || + (skill->get_unit_flag(su->group->skill_id) & UF_RANGEDSINGLEUNIT && !(su->val2 & UF_RANGEDSINGLEUNIT))) + p.job = UNT_DUMMYSKILL; + else + p.job = su->group->unit_id; + +#if PACKETVER >= 20110718 + p.RadiusRange = (unsigned char)su->range; +#endif + + p.isVisible = 1; + +#if PACKETVER >= 20130731 + p.level = (unsigned char)su->group->skill_lv; +#endif + + clif->send(&p,sizeof(p),bl,target); if(su->group->skill_id == WZ_ICEWALL) - clif->changemapcell(fd,su->bl.m,su->bl.x,su->bl.y,5,SELF); + clif->changemapcell(bl->type == BL_PC ? ((TBL_PC*)bl)->fd : 0,su->bl.m,su->bl.x,su->bl.y,5,SELF); } @@ -4741,7 +4722,7 @@ int clif_getareachar(struct block_list* bl,va_list ap) { clif->getareachar_item(sd,(struct flooritem_data*) bl); break; case BL_SKILL: - clif->getareachar_skillunit(sd,(TBL_SKILL*)bl); + clif->getareachar_skillunit(&sd->bl,(TBL_SKILL*)bl,SELF); break; default: if(&sd->bl == bl) @@ -4766,6 +4747,7 @@ int clif_outsight(struct block_list *bl,va_list ap) tsd = BL_CAST(BL_PC, tbl); if (tsd && tsd->fd) { //tsd has lost sight of the bl object. + nullpo_ret(bl); switch(bl->type){ case BL_PC: if (sd->vd.class_ != INVISIBLE_CLASS) @@ -4798,6 +4780,7 @@ int clif_outsight(struct block_list *bl,va_list ap) } } if (sd && sd->fd) { //sd is watching tbl go out of view. + nullpo_ret(tbl); if (((vd=status->get_viewdata(tbl)) && vd->class_ != INVISIBLE_CLASS) && !(tbl->type == BL_NPC && (((TBL_NPC*)tbl)->option&OPTION_INVISIBLE))) clif->clearunit_single(tbl->id,CLR_OUTSIGHT,sd->fd); @@ -4820,12 +4803,13 @@ int clif_insight(struct block_list *bl,va_list ap) tsd = BL_CAST(BL_PC, tbl); if (tsd && tsd->fd) { //Tell tsd that bl entered into his view - switch(bl->type){ + nullpo_ret(bl); + switch(bl->type) { case BL_ITEM: clif->getareachar_item(tsd,(struct flooritem_data*)bl); break; case BL_SKILL: - clif->getareachar_skillunit(tsd,(TBL_SKILL*)bl); + clif->getareachar_skillunit(&tsd->bl,(TBL_SKILL*)bl,SELF); break; default: clif->getareachar_unit(tsd,bl); @@ -4936,23 +4920,31 @@ void clif_deleteskill(struct map_session_data *sd, int id) clif->skillinfoblock(sd); } - /// Updates a skill in the skill tree (ZC_SKILLINFO_UPDATE). /// 010e <skill id>.W <level>.W <sp cost>.W <attack range>.W <upgradable>.B -void clif_skillup(struct map_session_data *sd,uint16 skill_id) { - int fd, idx = skill->get_index(skill_id); - +/// Merged clif_skillup and clif_guild_skillup, same packet was used [panikon] +/// flag: +/// 0: guild call +/// 1: player call +void clif_skillup(struct map_session_data *sd, uint16 skill_id, int skill_lv, int flag) +{ + int fd; nullpo_retv(sd); - fd=sd->fd; - WFIFOHEAD(fd,packet_len(0x10e)); - WFIFOW(fd,0) = 0x10e; - WFIFOW(fd,2) = skill_id; - WFIFOW(fd,4) = sd->status.skill[idx].lv; - WFIFOW(fd,6) = skill->get_sp(skill_id,sd->status.skill[idx].lv); - WFIFOW(fd,8) = skill->get_range2(&sd->bl,skill_id,sd->status.skill[idx].lv); - WFIFOB(fd,10) = (sd->status.skill[idx].lv < skill->tree_get_max(sd->status.skill[idx].id, sd->status.class_)) ? 1 : 0; - WFIFOSET(fd,packet_len(0x10e)); + fd = sd->fd; + + WFIFOHEAD(fd, packet_len(0x10e)); + WFIFOW(fd, 0) = 0x10e; + WFIFOW(fd, 2) = skill_id; + WFIFOW(fd, 4) = skill_lv; + WFIFOW(fd, 6) = skill->get_sp(skill_id, skill_lv); + WFIFOW(fd, 8) = (flag)?skill->get_range2(&sd->bl, skill_id, skill_lv) : skill->get_range(skill_id, skill_lv); + if( flag ) + WFIFOB(fd,10) = (skill_lv < skill->tree_get_max(skill_id, sd->status.class_)) ? 1 : 0; + else + WFIFOB(fd,10) = 1; + + WFIFOSET(fd, packet_len(0x10e)); } @@ -5096,7 +5088,7 @@ void clif_skill_fail(struct map_session_data *sd,uint16 skill_id,enum useskill_f /// Skill cooldown display icon (ZC_SKILL_POSTDELAY). /// 043d <skill ID>.W <tick>.L -void clif_skill_cooldown(struct map_session_data *sd, uint16 skill_id, unsigned int tick) +void clif_skill_cooldown(struct map_session_data *sd, uint16 skill_id, unsigned int duration) { #if PACKETVER>=20081112 int fd; @@ -5107,7 +5099,7 @@ void clif_skill_cooldown(struct map_session_data *sd, uint16 skill_id, unsigned WFIFOHEAD(fd,packet_len(0x43d)); WFIFOW(fd,0) = 0x43d; WFIFOW(fd,2) = skill_id; - WFIFOL(fd,4) = tick; + WFIFOL(fd,4) = duration; WFIFOSET(fd,packet_len(0x43d)); #endif } @@ -5116,7 +5108,7 @@ void clif_skill_cooldown(struct map_session_data *sd, uint16 skill_id, unsigned /// Skill attack effect and damage. /// 0114 <skill id>.W <src id>.L <dst id>.L <tick>.L <src delay>.L <dst delay>.L <damage>.W <level>.W <div>.W <type>.B (ZC_NOTIFY_SKILL) /// 01de <skill id>.W <src id>.L <dst id>.L <tick>.L <src delay>.L <dst delay>.L <damage>.L <level>.W <div>.W <type>.B (ZC_NOTIFY_SKILL2) -int clif_skill_damage(struct block_list *src,struct block_list *dst,unsigned int tick,int sdelay,int ddelay,int64 in_damage,int div,uint16 skill_id,uint16 skill_lv,int type) { +int clif_skill_damage(struct block_list *src, struct block_list *dst, int64 tick, int sdelay, int ddelay, int64 in_damage, int div, uint16 skill_id, uint16 skill_lv, int type) { unsigned char buf[64]; struct status_change *sc; int damage; @@ -5137,7 +5129,7 @@ int clif_skill_damage(struct block_list *src,struct block_list *dst,unsigned int WBUFW(buf,2)=skill_id; WBUFL(buf,4)=src->id; WBUFL(buf,8)=dst->id; - WBUFL(buf,12)=tick; + WBUFL(buf,12)=(uint32)tick; WBUFL(buf,16)=sdelay; WBUFL(buf,20)=ddelay; if (battle_config.hide_woe_damage && map_flag_gvg2(src->m)) { @@ -5168,7 +5160,7 @@ int clif_skill_damage(struct block_list *src,struct block_list *dst,unsigned int WBUFW(buf,2)=skill_id; WBUFL(buf,4)=src->id; WBUFL(buf,8)=dst->id; - WBUFL(buf,12)=tick; + WBUFL(buf,12)=(uint32)tick; WBUFL(buf,16)=sdelay; WBUFL(buf,20)=ddelay; if (battle_config.hide_woe_damage && map_flag_gvg2(src->m)) { @@ -5204,7 +5196,7 @@ int clif_skill_damage(struct block_list *src,struct block_list *dst,unsigned int /// Ground skill attack effect and damage (ZC_NOTIFY_SKILL_POSITION). /// 0115 <skill id>.W <src id>.L <dst id>.L <tick>.L <src delay>.L <dst delay>.L <x>.W <y>.W <damage>.W <level>.W <div>.W <type>.B #if 0 -int clif_skill_damage2(struct block_list *src,struct block_list *dst,unsigned int tick,int sdelay,int ddelay,int damage,int div,uint16 skill_id,uint16 skill_lv,int type) { +int clif_skill_damage2(struct block_list *src, struct block_list *dst, int64 tick, int sdelay, int ddelay, int damage, int div, uint16 skill_id, uint16 skill_lv, int type) { unsigned char buf[64]; struct status_change *sc; @@ -5224,7 +5216,7 @@ int clif_skill_damage2(struct block_list *src,struct block_list *dst,unsigned in WBUFW(buf,2)=skill_id; WBUFL(buf,4)=src->id; WBUFL(buf,8)=dst->id; - WBUFL(buf,12)=tick; + WBUFL(buf,12)=(uint32)tick; WBUFL(buf,16)=sdelay; WBUFL(buf,20)=ddelay; WBUFW(buf,24)=dst->x; @@ -5294,8 +5286,7 @@ int clif_skill_nodamage(struct block_list *src,struct block_list *dst,uint16 ski /// Non-damaging ground skill effect (ZC_NOTIFY_GROUNDSKILL). /// 0117 <skill id>.W <src id>.L <level>.W <x>.W <y>.W <tick>.L -void clif_skill_poseffect(struct block_list *src,uint16 skill_id,int val,int x,int y,int tick) -{ +void clif_skill_poseffect(struct block_list *src, uint16 skill_id, int val, int x, int y, int64 tick) { unsigned char buf[32]; nullpo_retv(src); @@ -5306,7 +5297,7 @@ void clif_skill_poseffect(struct block_list *src,uint16 skill_id,int val,int x,i WBUFW(buf,8)=val; WBUFW(buf,10)=x; WBUFW(buf,12)=y; - WBUFL(buf,14)=tick; + WBUFL(buf,14)=(uint32)tick; if(disguised(src)) { clif->send(buf,packet_len(0x117),src,AREA_WOS); WBUFL(buf,4)=-src->id; @@ -5315,65 +5306,6 @@ void clif_skill_poseffect(struct block_list *src,uint16 skill_id,int val,int x,i clif->send(buf,packet_len(0x117),src,AREA); } - -/*========================================== - * Tells all client's nearby 'unit' sight range that it spawned - *------------------------------------------*/ -//FIXME: this is just an AREA version of clif_getareachar_skillunit() -void clif_skill_setunit(struct skill_unit *su) { - unsigned char buf[128]; - int header = 0x11f, pos = 0; - - nullpo_retv(su); - - if( su->group->state.guildaura ) - return; - -#if PACKETVER >= 20130320 - if(su->group->unit_id > UCHAR_MAX) { - header = 0x99f; - pos = 2; - } -#endif - -#if PACKETVER >= 3 - if(su->group->unit_id==UNT_GRAFFITI) { - // Graffiti [Valaris] - WBUFW(buf, 0)=0x1c9; - WBUFL(buf, 2)=su->bl.id; - WBUFL(buf, 6)=su->group->src_id; - WBUFW(buf,10)=su->bl.x; - WBUFW(buf,12)=su->bl.y; - WBUFB(buf,14)=su->group->unit_id; - WBUFB(buf,15)=1; - WBUFB(buf,16)=1; - safestrncpy((char*)WBUFP(buf,17),su->group->valstr,MESSAGE_SIZE); - clif->send(buf,packet_len(0x1c9),&su->bl,AREA); - return; - } -#endif - WBUFW(buf, 0)=header; - if(pos > 0) - WBUFW(buf, pos)=packet_len(header); - WBUFL(buf, 2 + pos)=su->bl.id; - WBUFL(buf, 6 + pos)=su->group->src_id; - WBUFW(buf,10 + pos)=su->bl.x; - WBUFW(buf,12 + pos)=su->bl.y; - if (su->group->state.song_dance&0x1 && su->val2&UF_ENSEMBLE) - WBUFB(buf,14)=su->val2&UF_SONG?UNT_DISSONANCE:UNT_UGLYDANCE; - else if (skill->get_unit_flag(su->group->skill_id) & UF_RANGEDSINGLEUNIT && !(su->val2 & UF_RANGEDSINGLEUNIT)) - WBUFB(buf, 14) = UNT_DUMMYSKILL; // Only display the unit at center. - else if(pos > 0) { - WBUFL(buf,16)=su->group->unit_id; - WBUFW(buf,20)=su->range; - pos += 5; - }else - WBUFB(buf,14)=su->group->unit_id; - WBUFB(buf,15 + pos)=1; // ignored by client (always gets set to 1) - clif->send(buf,packet_len(header),&su->bl,AREA); -} - - /// Presents a list of available warp destinations (ZC_WARPLIST). /// 011c <skill id>.W { <map name>.16B }*4 void clif_skill_warppoint(struct map_session_data* sd, uint16 skill_id, uint16 skill_lv, unsigned short map1, unsigned short map2, unsigned short map3, unsigned short map4) @@ -5388,10 +5320,10 @@ void clif_skill_warppoint(struct map_session_data* sd, uint16 skill_id, uint16 s memset(WFIFOP(fd,4), 0x00, 4*MAP_NAME_LENGTH_EXT); if (map1 == (unsigned short)-1) strcpy((char*)WFIFOP(fd,4), "Random"); else // normal map name - if (map1 > 0) mapindex_getmapname_ext(mapindex_id2name(map1), (char*)WFIFOP(fd,4)); - if (map2 > 0) mapindex_getmapname_ext(mapindex_id2name(map2), (char*)WFIFOP(fd,20)); - if (map3 > 0) mapindex_getmapname_ext(mapindex_id2name(map3), (char*)WFIFOP(fd,36)); - if (map4 > 0) mapindex_getmapname_ext(mapindex_id2name(map4), (char*)WFIFOP(fd,52)); + if (map1 > 0) mapindex->getmapname_ext(mapindex_id2name(map1), (char*)WFIFOP(fd,4)); + if (map2 > 0) mapindex->getmapname_ext(mapindex_id2name(map2), (char*)WFIFOP(fd,20)); + if (map3 > 0) mapindex->getmapname_ext(mapindex_id2name(map3), (char*)WFIFOP(fd,36)); + if (map4 > 0) mapindex->getmapname_ext(mapindex_id2name(map4), (char*)WFIFOP(fd,52)); WFIFOSET(fd,packet_len(0x11c)); sd->menuskill_id = skill_id; @@ -5592,22 +5524,22 @@ void clif_cooking_list(struct map_session_data *sd, int trigger, uint16 skill_id void clif_status_change_notick(struct block_list *bl,int type,int flag,int tick,int val1, int val2, int val3) { struct packet_sc_notick p; struct map_session_data *sd; - + nullpo_retv(bl); - - if (!(status->type2relevant_bl_types(type)&bl->type)) // only send status changes that actually matter to the client - return; - + if (type == SI_BLANK) //It shows nothing on the client... return; - + + if (!(status->type2relevant_bl_types(type)&bl->type)) // only send status changes that actually matter to the client + return; + sd = BL_CAST(BL_PC, bl); - + p.PacketType = sc_notickType; p.index = type; p.AID = bl->id; p.state = (unsigned char)flag; - + clif->send(&p,packet_len(p.PacketType), bl, (sd && sd->status.option&OPTION_INVISIBLE) ? SELF : AREA); } @@ -5655,11 +5587,11 @@ void clif_status_change(struct block_list *bl,int type,int flag,int tick,int val void clif_displaymessage(const int fd, const char* mes) { nullpo_retv(mes); - if( fd == -2 ) { + if( map->cpsd_active && fd == 0 ) { ShowInfo("HCP: %s\n",mes); } else if ( fd > 0 ) { - int len; - + size_t len; + if ( ( len = strnlen(mes, 255) ) > 0 ) { // don't send a void message (it's not displaying on the client chat). @help can send void line. WFIFOHEAD(fd, 5 + len); WFIFOW(fd,0) = 0x8e; @@ -5672,22 +5604,22 @@ void clif_displaymessage(const int fd, const char* mes) { void clif_displaymessage2(const int fd, const char* mes) { // invalid pointer? nullpo_retv(mes); - + //Scrapped, as these are shared by disconnected players =X [Skotlex] if (fd == 0) ; else { // Limit message to 255+1 characters (otherwise it causes a buffer overflow in the client) char *message, *line; - + message = aStrdup(mes); line = strtok(message, "\n"); while(line != NULL) { // Limit message to 255+1 characters (otherwise it causes a buffer overflow in the client) - int len = strnlen(line, 255); - + size_t len = strnlen(line, 255); + if (len > 0) { // don't send a void message (it's not displaying on the client chat). @help can send void line. - if( fd == -2 ) { + if( map->cpsd_active && fd == 0 ) { ShowInfo("HCP: %s\n",line); } else { WFIFOHEAD(fd, 5 + len); @@ -5702,10 +5634,41 @@ void clif_displaymessage2(const int fd, const char* mes) { aFree(message); } } +/* oh noo! another version of 0x8e! */ +void clif_displaymessage_sprintf(const int fd, const char* mes, ...) { + va_list ap; + + if( map->cpsd_active && fd == 0 ) { + ShowInfo("HCP: "); + va_start(ap,mes); + _vShowMessage(MSG_NONE,mes,ap); + va_end(ap); + ShowMessage("\n"); + } else if ( fd > 0 ) { + int len = 1; + char *ptr; + WFIFOHEAD(fd, 5 + 255);/* ensure the maximum */ + + /* process */ + va_start(ap,mes); + len += vsnprintf((char *)WFIFOP(fd,4), 255, mes, ap); + va_end(ap); + + /* adjusting */ + ptr = (char *)WFIFOP(fd,4); + ptr[len - 1] = '\0'; + + /* */ + WFIFOW(fd,0) = 0x8e; + WFIFOW(fd,2) = 5 + len; // 4 + len + NULL teminate + + WFIFOSET(fd, 5 + len); + } +} /// Send broadcast message in yellow or blue without font formatting (ZC_BROADCAST). /// 009a <packet len>.W <message>.?B -void clif_broadcast(struct block_list* bl, const char* mes, int len, int type, enum send_target target) +void clif_broadcast(struct block_list* bl, const char* mes, size_t len, int type, enum send_target target) { int lp = (type&BC_COLOR_MASK) ? 4 : 0; unsigned char *buf = (unsigned char*)aMalloc((4 + lp + len)*sizeof(unsigned char)); @@ -5729,7 +5692,7 @@ void clif_broadcast(struct block_list* bl, const char* mes, int len, int type, e *------------------------------------------*/ void clif_GlobalMessage(struct block_list* bl, const char* message) { char buf[256]; - int len; + size_t len; nullpo_retv(bl); if(!message) @@ -5752,7 +5715,7 @@ void clif_GlobalMessage(struct block_list* bl, const char* message) { /// Send broadcast message with font formatting (ZC_BROADCAST2). /// 01c3 <packet len>.W <fontColor>.L <fontType>.W <fontSize>.W <fontAlign>.W <fontY>.W <message>.?B -void clif_broadcast2(struct block_list* bl, const char* mes, int len, unsigned long fontColor, short fontType, short fontSize, short fontAlign, short fontY, enum send_target target) +void clif_broadcast2(struct block_list* bl, const char* mes, size_t len, unsigned int fontColor, short fontType, short fontSize, short fontAlign, short fontY, enum send_target target) { unsigned char *buf = (unsigned char*)aMalloc((16 + len)*sizeof(unsigned char)); @@ -5796,7 +5759,7 @@ void clif_resurrection(struct block_list *bl,int type) unsigned char buf[16]; nullpo_retv(bl); - + WBUFW(buf,0)=0x148; WBUFL(buf,2)=bl->id; WBUFW(buf,6)=0; @@ -5819,7 +5782,7 @@ void clif_map_property(struct map_session_data* sd, enum map_property property) int fd; nullpo_retv(sd); - + fd=sd->fd; WFIFOHEAD(fd,packet_len(0x199)); WFIFOW(fd,0)=0x199; @@ -5881,7 +5844,7 @@ void clif_map_property_mapall(int mapid, enum map_property property) { struct block_list bl; unsigned char buf[16]; - + bl.id = 0; bl.type = BL_NUL; bl.m = mapid; @@ -5928,7 +5891,7 @@ void clif_upgrademessage(int fd, int result, int item_id) /// Whisper is transmitted to the destination player (ZC_WHISPER). /// 0097 <packet len>.W <nick>.24B <message>.?B /// 0097 <packet len>.W <nick>.24B <isAdmin>.L <message>.?B (PACKETVER >= 20091104) -void clif_wis_message(int fd, const char* nick, const char* mes, int mes_len) { +void clif_wis_message(int fd, const char* nick, const char* mes, size_t mes_len) { #if PACKETVER < 20091104 WFIFOHEAD(fd, mes_len + NAME_LENGTH + 4); WFIFOW(fd,0) = 0x97; @@ -5943,7 +5906,7 @@ void clif_wis_message(int fd, const char* nick, const char* mes, int mes_len) { WFIFOW(fd,0) = 0x97; WFIFOW(fd,2) = mes_len + NAME_LENGTH + 8; safestrncpy((char*)WFIFOP(fd,4), nick, NAME_LENGTH); - WFIFOL(fd,28) = (ssd && pc->get_group_level(ssd) == 99) ? 1 : 0; // isAdmin; if nonzero, also displays text above char + WFIFOL(fd,28) = (ssd && pc_get_group_level(ssd) == 99) ? 1 : 0; // isAdmin; if nonzero, also displays text above char safestrncpy((char*)WFIFOP(fd,32), mes, mes_len); WFIFOSET(fd,WFIFOW(fd,2)); #endif @@ -5959,10 +5922,15 @@ void clif_wis_message(int fd, const char* nick, const char* mes, int mes_len) { /// 3 = everyone ignored by target void clif_wis_end(int fd, int flag) { - WFIFOHEAD(fd,packet_len(0x98)); - WFIFOW(fd,0) = 0x98; +#if PACKETVER >= 20131223 + const int cmd = 0x9df; +#else + const int cmd = 0x98; +#endif + WFIFOHEAD(fd,packet_len(cmd)); + WFIFOW(fd,0) = cmd; WFIFOW(fd,2) = flag; - WFIFOSET(fd,packet_len(0x98)); + WFIFOSET(fd,packet_len(cmd)); } @@ -6019,9 +5987,15 @@ void clif_use_card(struct map_session_data *sd,int idx) if( j == sd->inventory_data[i]->slot ) // No room continue; + if( sd->status.inventory[i].equip > 0 ) // Do not check items that are already equipped + continue; + WFIFOW(fd,4+c*2)=i+2; c++; } + + if( !c ) return; // no item is available for card insertion + WFIFOW(fd,2)=4+c*2; WFIFOSET(fd,WFIFOW(fd,2)); } @@ -6181,7 +6155,7 @@ void clif_item_refine_list(struct map_session_data *sd) skill_lv = pc->checkskill(sd,WS_WEAPONREFINE); fd=sd->fd; - + WFIFOHEAD(fd, MAX_INVENTORY * 13 + 4); WFIFOW(fd,0)=0x221; for(i=c=0;i<MAX_INVENTORY;i++){ @@ -6529,7 +6503,7 @@ void clif_party_member_info(struct party_data *p, struct map_session_data *sd) WBUFB(buf,14) = (p->party.member[i].online)?0:1; memcpy(WBUFP(buf,15), p->party.name, NAME_LENGTH); memcpy(WBUFP(buf,39), sd->status.name, NAME_LENGTH); - mapindex_getmapname_ext(map->list[sd->bl.m].custom_name ? map->list[map->list[sd->bl.m].instance_src_map].name : map->list[sd->bl.m].name, (char*)WBUFP(buf,63)); + mapindex->getmapname_ext(map->list[sd->bl.m].custom_name ? map->list[map->list[sd->bl.m].instance_src_map].name : map->list[sd->bl.m].name, (char*)WBUFP(buf,63)); WBUFB(buf,79) = (p->party.item&1)?1:0; WBUFB(buf,80) = (p->party.item&2)?1:0; clif->send(buf,packet_len(0x1e9),&sd->bl,PARTY); @@ -6563,7 +6537,7 @@ void clif_party_info(struct party_data* p, struct map_session_data *sd) WBUFL(buf,28+c*46) = m->account_id; memcpy(WBUFP(buf,28+c*46+4), m->name, NAME_LENGTH); - mapindex_getmapname_ext(mapindex_id2name(m->map), (char*)WBUFP(buf,28+c*46+28)); + mapindex->getmapname_ext(mapindex_id2name(m->map), (char*)WBUFP(buf,28+c*46+28)); WBUFB(buf,28+c*46+44) = (m->leader) ? 0 : 1; WBUFB(buf,28+c*46+45) = (m->online) ? 0 : 1; c++; @@ -7889,29 +7863,6 @@ void clif_guild_message(struct guild *g,int account_id,const char *mes,int len) clif->send(buf, WBUFW(buf,2), &sd->bl, GUILD_NOBG); } - -/*========================================== - * Server tells client 'sd' that his guild skill 'skill_id' gone to level 'lv' - *------------------------------------------*/ -int clif_guild_skillup(struct map_session_data *sd,uint16 skill_id,int lv) -{// TODO: Merge with clif_skillup (same packet). - int fd; - - nullpo_ret(sd); - - fd=sd->fd; - WFIFOHEAD(fd,11); - WFIFOW(fd,0) = 0x10e; - WFIFOW(fd,2) = skill_id; - WFIFOW(fd,4) = lv; - WFIFOW(fd,6) = skill->get_sp(skill_id,lv); - WFIFOW(fd,8) = skill->get_range(skill_id,lv); - WFIFOB(fd,10) = 1; - WFIFOSET(fd,11); - return 0; -} - - /// Request for guild alliance (ZC_REQ_ALLY_GUILD). /// 0171 <inviter account id>.L <guild name>.24B void clif_guild_reqalliance(struct map_session_data *sd,int account_id,const char *name) @@ -8148,18 +8099,10 @@ void clif_marriage_proposal(int fd, struct map_session_data *sd, struct map_sess } */ - -/*========================================== - * - *------------------------------------------*/ -void clif_disp_onlyself(struct map_session_data *sd, const char *mes, int len) { - clif->disp_message(&sd->bl, mes, len, SELF); -} - /*========================================== * Displays a message using the guild-chat colors to the specified targets. [Skotlex] *------------------------------------------*/ -void clif_disp_message(struct block_list* src, const char* mes, int len, enum send_target target) +void clif_disp_message(struct block_list* src, const char* mes, size_t len, enum send_target target) { unsigned char buf[256]; @@ -8416,7 +8359,7 @@ void clif_specialeffect_value(struct block_list* bl, int effect_id, int num, sen // Modification of clif_messagecolor to send colored messages to players to chat log only (doesn't display overhead) /// 02c1 <packet len>.W <id>.L <color>.L <message>.?B int clif_colormes(int fd, enum clif_colors color, const char* msg) { - unsigned short msg_len = strlen(msg) + 1; + size_t msg_len = strlen(msg) + 1; WFIFOHEAD(fd,msg_len + 12); WFIFOW(fd,0) = 0x2C1; @@ -8431,8 +8374,8 @@ int clif_colormes(int fd, enum clif_colors color, const char* msg) { /// Monster/NPC color chat [SnakeDrak] (ZC_NPC_CHAT). /// 02c1 <packet len>.W <id>.L <color>.L <message>.?B -void clif_messagecolor(struct block_list* bl, unsigned long color, const char* msg) { - unsigned short msg_len = strlen(msg) + 1; +void clif_messagecolor(struct block_list* bl, unsigned int color, const char* msg) { + size_t msg_len = strlen(msg) + 1; uint8 buf[256]; color = (color & 0x0000FF) << 16 | (color & 0x00FF00) | (color & 0xFF0000) >> 16; // RGB to BGR @@ -8525,13 +8468,13 @@ void clif_refresh(struct map_session_data *sd) buyingstore->close(sd); mail->clear(sd); - + if( disguised(&sd->bl) ) {/* refresh-da */ short disguise = sd->disguise; pc->disguise(sd, -1); pc->disguise(sd, disguise); } - + } @@ -8756,7 +8699,7 @@ void clif_slide(struct block_list *bl, int x, int y) void clif_disp_overhead(struct block_list *bl, const char* mes) { unsigned char buf[256]; //This should be more than sufficient, the theorical max is CHAT_SIZE + 8 (pads and extra inserted crap) - int len_mes = strlen(mes)+1; //Account for \0 + size_t len_mes = strlen(mes)+1; //Account for \0 if (len_mes > sizeof(buf)-8) { ShowError("clif_disp_overhead: Message too long (length %d)\n", len_mes); @@ -8776,7 +8719,7 @@ void clif_disp_overhead(struct block_list *bl, const char* mes) safestrncpy((char*)WBUFP(buf,4), mes, len_mes); clif->send(buf, WBUFW(buf,2), bl, SELF); } - + } /*========================== @@ -8870,7 +8813,7 @@ void clif_feel_info(struct map_session_data* sd, unsigned char feel_level, unsig { char mapname[MAP_NAME_LENGTH_EXT]; - mapindex_getmapname_ext(mapindex_id2name(sd->feel_map[feel_level].index), mapname); + mapindex->getmapname_ext(mapindex_id2name(sd->feel_map[feel_level].index), mapname); clif->starskill(sd, mapname, 0, feel_level, type ? 1 : 0); } @@ -8950,69 +8893,41 @@ void clif_equpcheckbox(struct map_session_data* sd) /// 02d7 <packet len>.W <name>.24B <class>.W <hairstyle>.W <bottom-viewid>.W <mid-viewid>.W <up-viewid>.W <haircolor>.W <cloth-dye>.W <gender>.B {equip item}.28B* (ZC_EQUIPWIN_MICROSCOPE, PACKETVER >= 20100629) /// 0859 <packet len>.W <name>.24B <class>.W <hairstyle>.W <bottom-viewid>.W <mid-viewid>.W <up-viewid>.W <haircolor>.W <cloth-dye>.W <gender>.B {equip item}.28B* (ZC_EQUIPWIN_MICROSCOPE2, PACKETVER >= 20101124) /// 0859 <packet len>.W <name>.24B <class>.W <hairstyle>.W <bottom-viewid>.W <mid-viewid>.W <up-viewid>.W <robe>.W <haircolor>.W <cloth-dye>.W <gender>.B {equip item}.28B* (ZC_EQUIPWIN_MICROSCOPE2, PACKETVER >= 20110111) -void clif_viewequip_ack(struct map_session_data* sd, struct map_session_data* tsd) -{ - uint8* buf; - int i, n, fd, offset = 0; -#if PACKETVER < 20100629 - const int s = 26; -#else - const int s = 28; -#endif +void clif_viewequip_ack(struct map_session_data* sd, struct map_session_data* tsd) { + int i, k, equip = 0; + nullpo_retv(sd); nullpo_retv(tsd); - fd = sd->fd; - WFIFOHEAD(fd, MAX_INVENTORY * s + 43); - buf = WFIFOP(fd,0); + for( i = 0; i < EQI_MAX; i++ ) { + if( (k = tsd->equip_index[i]) >= 0 ) { -#if PACKETVER < 20101124 - WBUFW(buf, 0) = 0x2d7; -#else - WBUFW(buf, 0) = 0x859; -#endif - safestrncpy((char*)WBUFP(buf, 4), tsd->status.name, NAME_LENGTH); - WBUFW(buf,28) = tsd->status.class_; - WBUFW(buf,30) = tsd->vd.hair_style; - WBUFW(buf,32) = tsd->vd.head_bottom; - WBUFW(buf,34) = tsd->vd.head_mid; - WBUFW(buf,36) = tsd->vd.head_top; -#if PACKETVER >= 20110111 - WBUFW(buf,38) = tsd->vd.robe; - offset+= 2; - buf = WBUFP(buf,2); -#endif - WBUFW(buf,38) = tsd->vd.hair_color; - WBUFW(buf,40) = tsd->vd.cloth_color; - WBUFB(buf,42) = tsd->vd.sex; + if (tsd->status.inventory[k].nameid <= 0 || tsd->inventory_data[k] == NULL) // Item doesn't exist + continue; - for(i=0,n=0; i < MAX_INVENTORY; i++) - { - if (tsd->status.inventory[i].nameid <= 0 || tsd->inventory_data[i] == NULL) // Item doesn't exist - continue; - if (!itemdb->isequip2(tsd->inventory_data[i])) // Is not equippable - continue; + clif_item_equip(k+2,&viewequip_list.list[equip++],&tsd->status.inventory[k],tsd->inventory_data[k],pc->equippoint(tsd,k)); - // Inventory position - WBUFW(buf, n*s+43) = i + 2; - // Add refine, identify flag, element, etc. - clif->item_sub(WBUFP(buf,0), n*s+45, &tsd->status.inventory[i], tsd->inventory_data[i], pc->equippoint(tsd, i)); - // Add cards - clif->addcards(WBUFP(buf, n*s+55), &tsd->status.inventory[i]); - // Expiration date stuff, if all of those are set to 0 then the client doesn't show anything related (6 bytes) - WBUFL(buf, n*s+63) = tsd->status.inventory[i].expire_time; - WBUFW(buf, n*s+67) = 0; -#if PACKETVER >= 20100629 - if (tsd->inventory_data[i]->equip&EQP_VISIBLE) - WBUFW(buf, n*s+69) = tsd->inventory_data[i]->look; - else - WBUFW(buf, n*s+69) = 0; -#endif - n++; + } } - WFIFOW(fd, 2) = 43+offset+n*s; // Set length - WFIFOSET(fd, WFIFOW(fd, 2)); + viewequip_list.PacketType = viewequipackType; + viewequip_list.PacketLength = ( sizeof( viewequip_list ) - sizeof( viewequip_list.list ) ) + ( sizeof(struct EQUIPITEM_INFO) * equip ); + + safestrncpy(viewequip_list.characterName, tsd->status.name, NAME_LENGTH); + + viewequip_list.job = tsd->status.class_; + viewequip_list.head = tsd->vd.hair_style; + viewequip_list.accessory = tsd->vd.head_bottom; + viewequip_list.accessory2 = tsd->vd.head_mid; + viewequip_list.accessory3 = tsd->vd.head_top; +#if PACKETVER >= 20110111 + viewequip_list.robe = tsd->vd.robe; +#endif + viewequip_list.headpalette = tsd->vd.hair_color; + viewequip_list.bodypalette = tsd->vd.cloth_color; + viewequip_list.sex = tsd->vd.sex; + + clif->send(&viewequip_list, viewequip_list.PacketLength, &sd->bl, SELF); } @@ -9061,21 +8976,14 @@ void clif_msg_skill(struct map_session_data* sd, uint16 skill_id, int msg_id) WFIFOSET(fd, packet_len(0x7e6)); } - -/// View player equip request denied -void clif_viewequip_fail(struct map_session_data* sd) -{ - clif_msg(sd, 0x54d); -} - - /// Validates one global/guild/party/whisper message packet and tries to recognize its components. /// Returns true if the packet was parsed successfully. /// Formats: 0 - <packet id>.w <packet len>.w (<name> : <message>).?B 00 /// 1 - <packet id>.w <packet len>.w <name>.24B <message>.?B 00 -bool clif_process_message(struct map_session_data* sd, int format, char** name_, int* namelen_, char** message_, int* messagelen_) { +bool clif_process_message(struct map_session_data *sd, int format, char **name_, size_t *namelen_, char **message_, size_t *messagelen_) { char *text, *name, *message; - unsigned int packetlen, textlen, namelen, messagelen; + unsigned int packetlen, textlen; + size_t namelen, messagelen; int fd = sd->fd; *name_ = NULL; @@ -9167,14 +9075,14 @@ void clif_hercules_chsys_msg(struct hChSysCh *channel, struct map_session_data * DBIterator *iter = db_iterator(channel->users); struct map_session_data *user; unsigned short msg_len = strlen(msg) + 1; - + WFIFOHEAD(sd->fd,msg_len + 12); WFIFOW(sd->fd,0) = 0x2C1; WFIFOW(sd->fd,2) = msg_len + 12; WFIFOL(sd->fd,4) = 0; WFIFOL(sd->fd,8) = hChSys.colors[channel->color]; safestrncpy((char*)WFIFOP(sd->fd,12), msg, msg_len); - + for( user = dbi_first(iter); dbi_exists(iter); user = dbi_next(iter) ) { if( user->fd == sd->fd ) continue; @@ -9182,9 +9090,9 @@ void clif_hercules_chsys_msg(struct hChSysCh *channel, struct map_session_data * memcpy(WFIFOP(user->fd,0), WFIFOP(sd->fd,0), msg_len + 12); WFIFOSET(user->fd, msg_len + 12); } - + WFIFOSET(sd->fd, msg_len + 12); - + dbi_destroy(iter); } @@ -9193,19 +9101,19 @@ void clif_hercules_chsys_msg2(struct hChSysCh *channel, char *msg) { struct map_session_data *user; unsigned char buf[210]; unsigned short msg_len = strlen(msg) + 1; - + WBUFW(buf,0) = 0x2C1; WBUFW(buf,2) = msg_len + 12; WBUFL(buf,4) = 0; WBUFL(buf,8) = hChSys.colors[channel->color]; safestrncpy((char*)WBUFP(buf,12), msg, msg_len); - + for( user = dbi_first(iter); dbi_exists(iter); user = dbi_next(iter) ) { WFIFOHEAD(user->fd,msg_len + 12); memcpy(WFIFOP(user->fd,0), WBUFP(buf,0), msg_len + 12); WFIFOSET(user->fd, msg_len + 12); } - + dbi_destroy(iter); } @@ -9287,24 +9195,30 @@ void clif_parse_WantToConnection(int fd, struct map_session_data* sd) { WFIFOSET(fd,packet_len(0x283)); #endif - chrif->authreq(sd); + chrif->authreq(sd,false); } void clif_hercules_chsys_mjoin(struct map_session_data *sd) { + if( sd->state.autotrade || sd->state.standalone ) + return; if( !map->list[sd->bl.m].channel ) { + + if (map->list[sd->bl.m].flag.chsysnolocalaj || (map->list[sd->bl.m].instance_id >= 0 && instance->list[map->list[sd->bl.m].instance_id].owner_type != IOT_NONE) ) + return; + CREATE(map->list[sd->bl.m].channel, struct hChSysCh , 1); safestrncpy(map->list[sd->bl.m].channel->name, hChSys.local_name, HCHSYS_NAME_LENGTH); map->list[sd->bl.m].channel->type = hChSys_MAP; map->list[sd->bl.m].channel->m = sd->bl.m; - + clif->chsys_create(map->list[sd->bl.m].channel,NULL,NULL,hChSys.local_color); } - + if( map->list[sd->bl.m].channel->banned && idb_exists(map->list[sd->bl.m].channel->banned, sd->status.account_id) ) { return; } - + clif->chsys_join(map->list[sd->bl.m].channel,sd); - + if( !( map->list[sd->bl.m].channel->opt & hChSys_OPT_ANNOUNCE_JOIN ) ) { char mout[60]; sprintf(mout, msg_txt(1435),hChSys.local_name,map->list[sd->bl.m].name); // You're now in the '#%s' channel for '%s' @@ -9315,6 +9229,10 @@ void clif_hercules_chsys_mjoin(struct map_session_data *sd) { /// Notification from the client, that it has finished map loading and is about to display player's character (CZ_NOTIFY_ACTORINIT). /// 007d void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) { +#if PACKETVER >= 20090218 + int i; +#endif + if(sd->bl.prev != NULL) return; @@ -9368,13 +9286,21 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) { if( map->list[sd->bl.m].users++ == 0 && battle_config.dynamic_mobs ) map->spawnmobs(sd->bl.m); - if( !(sd->sc.option&OPTION_INVISIBLE) ) { // increment the number of pvp players on the map - map->list[sd->bl.m].users_pvp++; - } + if( map->list[sd->bl.m].instance_id >= 0 ) { instance->list[map->list[sd->bl.m].instance_id].users++; instance->check_idle(map->list[sd->bl.m].instance_id); } + + if( pc_has_permission(sd,PC_PERM_VIEW_HPMETER) ) { + map->list[sd->bl.m].hpmeter_visible++; + sd->state.hpmeter_visible = 1; + } + + if( !(sd->sc.option&OPTION_INVISIBLE) ) { // increment the number of pvp players on the map + map->list[sd->bl.m].users_pvp++; + } + sd->state.debug_remove_map = 0; // temporary state to track double remove_map's [FlavioJS] // reset the callshop flag if the player changes map @@ -9391,7 +9317,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) { } if( sd->bg_id ) clif->bg_hp(sd); // BattleGround System - + if(map->list[sd->bl.m].flag.pvp && !(sd->sc.option&OPTION_INVISIBLE)) { if(!battle_config.pk_mode) { // remove pvp stuff for pk_mode [Valaris] if (!map->list[sd->bl.m].flag.pvp_nocalcrank) @@ -9428,7 +9354,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) { clif->spawn(&sd->pd->bl); clif->send_petdata(sd,sd->pd,0,0); clif->send_petstatus(sd); -// skill->unit_move(&sd->pd->bl,gettick(),1); +// skill->unit_move(&sd->pd->bl,timer->gettick(),1); } } @@ -9484,14 +9410,14 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) { clif->status_change(&sd->bl, SI_WUGRIDER, 1, 0, 0, 0, 0); if(sd->status.manner < 0) - sc_start(&sd->bl,SC_NOCHAT,100,0,0); + sc_start(NULL,&sd->bl,SC_NOCHAT,100,0,0); //Auron reported that This skill only triggers when you logon on the map o.O [Skotlex] if ((lv = pc->checkskill(sd,SG_KNOWLEDGE)) > 0) { if(sd->bl.m == sd->feel_map[0].m || sd->bl.m == sd->feel_map[1].m || sd->bl.m == sd->feel_map[2].m) - sc_start(&sd->bl, SC_KNOWLEDGE, 100, lv, skill->get_time(SG_KNOWLEDGE, lv)); + sc_start(NULL,&sd->bl, SC_KNOWLEDGE, 100, lv, skill->get_time(SG_KNOWLEDGE, lv)); } if(sd->pd && sd->pd->pet.intimate > 900) @@ -9526,7 +9452,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) { if(sd->npc_id) npc->event_dequeue(sd); - + if( sd->guild && ( battle_config.guild_notice_changemap == 2 || ( battle_config.guild_notice_changemap == 1 && sd->state.changemap ) ) ) clif->guild_notice(sd,sd->guild); } @@ -9565,10 +9491,10 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) { } map->iwall_get(sd); // Updates Walls Info on this Map to Client - status_calc_pc(sd, false);/* some conditions are map-dependent so we must recalculate */ + status_calc_pc(sd, SCO_NONE);/* some conditions are map-dependent so we must recalculate */ sd->state.changemap = false; - - if( hChSys.local && hChSys.local_autojoin && !map->list[sd->bl.m].flag.chsysnolocalaj ) { + + if( hChSys.local && hChSys.local_autojoin ) { clif->chsys_mjoin(sd); } } @@ -9576,7 +9502,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) { mail->clear(sd); clif->maptypeproperty2(&sd->bl,SELF); - + /* Guild Aura Init */ if( sd->state.gmaster_flag ) { guild->aura_refresh(sd,GD_LEADERSHIP,guild->checkskill(sd->guild,GD_LEADERSHIP)); @@ -9599,6 +9525,11 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) { if (sd->sc.opt2) //Client loses these on warp. clif->changeoption(&sd->bl); + if( sd->sc.data[SC_MONSTER_TRANSFORM] && battle_config.mon_trans_disable_in_gvg && map_flag_gvg2(sd->bl.m) ){ + status_change_end(&sd->bl, SC_MONSTER_TRANSFORM, INVALID_TIMER); + clif->message(sd->fd, msg_txt(1488)); // Transforming into monster is not allowed in Guild Wars. + } + clif->weather_check(sd); // For automatic triggering of NPCs after map loading (so you don't need to walk 1 step first) @@ -9616,24 +9547,38 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) { clif->clearunit_area(&sd->bl, CLR_DEAD); else { skill->usave_trigger(sd); - clif->changed_dir(&sd->bl, SELF); + sd->ud.dir = 0;/* enforce north-facing (not visually, virtually) */ } -// Trigger skill effects if you appear standing on them + // Trigger skill effects if you appear standing on them if(!battle_config.pc_invincible_time) skill->unit_move(&sd->bl,timer->gettick(),1); - + + // NPC Quest / Event Icon Check [Kisuka] +#if PACKETVER >= 20090218 + for(i = 0; i < map->list[sd->bl.m].qi_count; i++) { + struct questinfo *qi = &map->list[sd->bl.m].qi_data[i]; + if( quest->check(sd, qi->quest_id, HAVEQUEST) == -1 ) {// Check if quest is not started + if( qi->hasJob ) { // Check if quest is job-specific, check is user is said job class. + if( sd->class_ == qi->job ) + clif->quest_show_event(sd, &qi->nd->bl, qi->icon, qi->color); + } else { + clif->quest_show_event(sd, &qi->nd->bl, qi->icon, qi->color); + } + } + } +#endif } /// Server's tick (ZC_NOTIFY_TIME). /// 007f <time>.L -void clif_notify_time(struct map_session_data* sd, unsigned long time) { +void clif_notify_time(struct map_session_data* sd, int64 time) { int fd = sd->fd; WFIFOHEAD(fd,packet_len(0x7f)); WFIFOW(fd,0) = 0x7f; - WFIFOL(fd,2) = time; + WFIFOL(fd,2) = (uint32)time; WFIFOSET(fd,packet_len(0x7f)); } @@ -9696,7 +9641,8 @@ void clif_parse_Hotkey(int fd, struct map_session_data *sd) { /// Displays cast-like progress bar (ZC_PROGRESS). /// 02f0 <color>.L <time>.L -void clif_progressbar(struct map_session_data * sd, unsigned long color, unsigned int second) +/* TODO ZC_PROGRESS_ACTOR <account_id>.L */ +void clif_progressbar(struct map_session_data * sd, unsigned int color, unsigned int second) { int fd = sd->fd; @@ -9729,7 +9675,7 @@ void clif_parse_progressbar(int fd, struct map_session_data * sd) if( timer->gettick() < sd->progressbar.timeout && sd->st ) sd->st->state = END; - sd->state.workinprogress = sd->progressbar.npc_id = sd->progressbar.timeout = 0; + sd->progressbar.timeout = sd->state.workinprogress = sd->progressbar.npc_id = 0; npc->scriptcont(sd, npc_id, false); } @@ -9762,7 +9708,8 @@ void clif_parse_WalkToXY(int fd, struct map_session_data *sd) RFIFOPOS(fd, packet_db[RFIFOW(fd,0)].pos[0], &x, &y, NULL); //Set last idle time... [Skotlex] - sd->idletime = last_tick; + if( battle_config.idletime_criteria & BCIDLE_WALK ) + sd->idletime = sockt->last_tick; unit->walktoxy(&sd->bl, x, y, 4); } @@ -9792,7 +9739,7 @@ void clif_disconnect_ack(struct map_session_data* sd, short result) void clif_parse_QuitGame(int fd, struct map_session_data *sd) { /* Rovert's prevent logout option fixed [Valaris] */ - if( !sd->sc.data[SC_CLOAKING] && !sd->sc.data[SC_HIDING] && !sd->sc.data[SC_CHASEWALK] && !sd->sc.data[SC_CLOAKINGEXCEED] && + if( !sd->sc.data[SC_CLOAKING] && !sd->sc.data[SC_HIDING] && !sd->sc.data[SC_CHASEWALK] && !sd->sc.data[SC_CLOAKINGEXCEED] && !sd->sc.data[SC__INVISIBILITY] && (!battle_config.prevent_logout || DIFF_TICK(timer->gettick(), sd->canlog_tick) > battle_config.prevent_logout) ) { set_eof(fd); @@ -9828,7 +9775,7 @@ void clif_parse_GetCharNameRequest(int fd, struct map_session_data *sd) { sc = status->get_sc(bl); if (sc && sc->option&OPTION_INVISIBLE && !disguised(bl) && bl->type != BL_NPC && //Skip hidden NPCs which can be seen using Maya Purple - pc->get_group_level(sd) < battle_config.hack_info_GM_level + pc_get_group_level(sd) < battle_config.hack_info_GM_level ) { char gm_msg[256]; sprintf(gm_msg, "Hack on NameRequest: character '%s' (account: %d) requested the name of an invisible target (id: %d).\n", sd->status.name, sd->status.account_id, id); @@ -9841,7 +9788,7 @@ void clif_parse_GetCharNameRequest(int fd, struct map_session_data *sd) { clif->charnameack(fd, bl); } -int clif_undisguise_timer(int tid, unsigned int tick, int id, intptr_t data) { +int clif_undisguise_timer(int tid, int64 tick, int id, intptr_t data) { struct map_session_data * sd; if( (sd = map->id2sd(id)) ) { sd->fontcolor_tid = INVALID_TIMER; @@ -9857,10 +9804,10 @@ int clif_undisguise_timer(int tid, unsigned int tick, int id, intptr_t data) { void clif_parse_GlobalMessage(int fd, struct map_session_data* sd) { const char* text = (char*)RFIFOP(fd,4); - int textlen = RFIFOW(fd,2) - 4; + size_t textlen = RFIFOW(fd,2) - 4; char *name, *message, *fakename = NULL; - int namelen, messagelen; + size_t namelen, messagelen; bool is_fake; @@ -9868,10 +9815,10 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data* sd) if( !clif->process_message(sd, 0, &name, &namelen, &message, &messagelen) ) return; - if( atcommand->parse(fd, sd, message, 1) ) + if( atcommand->exec(fd, sd, message, true) ) return; - if( sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEP_SLEEP] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) ) + if( sd->sc.data[SC_BERSERK] || (sd->sc.data[SC_DEEP_SLEEP] && sd->sc.data[SC_DEEP_SLEEP]->val2) || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) ) return; if( battle_config.min_chat_delay ) { //[Skotlex] @@ -9903,7 +9850,7 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data* sd) sd->state.snovice_call_flag = 3; break; case 3: - sc_start(&sd->bl, status->skill2sc(MO_EXPLOSIONSPIRITS), 100, 17, skill->get_time(MO_EXPLOSIONSPIRITS, 5)); //Lv17-> +50 critical (noted by Poki) [Skotlex] + sc_start(NULL,&sd->bl, status->skill2sc(MO_EXPLOSIONSPIRITS), 100, 17, skill->get_time(MO_EXPLOSIONSPIRITS, 5)); //Lv17-> +50 critical (noted by Poki) [Skotlex] clif->skill_nodamage(&sd->bl, &sd->bl, MO_EXPLOSIONSPIRITS, 5, 1); // prayer always shows successful Lv5 cast and disregards noskill restrictions sd->state.snovice_call_flag = 0; break; @@ -9911,7 +9858,10 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data* sd) } } } - + + if( battle_config.idletime_criteria & BCIDLE_CHAT ) + sd->idletime = sockt->last_tick; + if( sd->gcbind ) { clif->chsys_send(sd->gcbind,sd,message); return; @@ -9932,9 +9882,9 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data* sd) timer->settick(sd->fontcolor_tid, td->tick+5000); } } - + mylen += snprintf(mout, 200, "%s : %s",sd->fakename[0]?sd->fakename:sd->status.name,message); - + WFIFOHEAD(fd,mylen + 12); WFIFOW(fd,0) = 0x2C1; WFIFOW(fd,2) = mylen + 12; @@ -9946,7 +9896,7 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data* sd) WFIFOSET(fd, mylen + 12); return; } - + /** * Fake Name Design by FatalEror (bug report #9) **/ @@ -9977,6 +9927,7 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data* sd) WFIFOW(fd,0) = 0x8e; } WFIFOSET(fd, WFIFOW(fd,2)); + #ifdef PCRE_SUPPORT // trigger listening npcs map->foreachinrange(npc_chat->sub, &sd->bl, AREA_SIZE, BL_NPC, text, textlen, &sd->bl); @@ -9998,7 +9949,7 @@ void clif_parse_MapMove(int fd, struct map_session_data *sd) map_name = (char*)RFIFOP(fd,2); map_name[MAP_NAME_LENGTH_EXT-1]='\0'; sprintf(command, "%cmapmove %s %d %d", atcommand->at_symbol, map_name, RFIFOW(fd,18), RFIFOW(fd,20)); - atcommand->parse(fd, sd, command, 1); + atcommand->exec(fd, sd, command, true); } @@ -10073,6 +10024,9 @@ void clif_parse_Emotion(int fd, struct map_session_data *sd) } sd->emotionlasttime = time(NULL); + if( battle_config.idletime_criteria & BCIDLE_EMOTION ) + sd->idletime = sockt->last_tick; + if(battle_config.client_reshuffle_dice && emoticon>=E_DICE1 && emoticon<=E_DICE6) {// re-roll dice emoticon = rnd()%6+E_DICE1; } @@ -10103,8 +10057,7 @@ void clif_parse_HowManyConnections(int fd, struct map_session_data *sd) { } -void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type, int target_id, unsigned int tick) -{ +void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type, int target_id, int64 tick) { if (pc_isdead(sd)) { clif->clearunit_area(&sd->bl, CLR_DEAD); return; @@ -10114,6 +10067,7 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type, (sd->sc.data[SC_TRICKDEAD] || sd->sc.data[SC_AUTOCOUNTER] || sd->sc.data[SC_BLADESTOP] || + sd->sc.data[SC_DEEP_SLEEP] || sd->sc.data[SC__MANHOLE] || sd->sc.data[SC_CURSEDCIRCLE_ATKER] || sd->sc.data[SC_CURSEDCIRCLE_TARGET] )) @@ -10132,10 +10086,11 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type, if( pc_cant_act(sd) || sd->sc.option&OPTION_HIDE ) return; - if( sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER|OPTION_HANBOK) ) + if( sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER|OPTION_HANBOK|OPTION_OKTOBERFEST) ) return; - if( sd->sc.data[SC_BASILICA] || sd->sc.data[SC__SHADOWFORM] ) + if( sd->sc.data[SC_BASILICA] || sd->sc.data[SC__SHADOWFORM] || + (sd->sc.data[SC_SIREN] && sd->sc.data[SC_SIREN]->val2 == target_id) ) return; if (!battle_config.sdelay_attack_enable && pc->checkskill(sd, SA_FREECAST) <= 0) { @@ -10146,7 +10101,8 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type, } pc->delinvincibletimer(sd); - sd->idletime = last_tick; + if( battle_config.idletime_criteria & BCIDLE_ATTACK ) + sd->idletime = sockt->last_tick; unit->attack(&sd->bl, target_id, action_type != 0); break; case 0x02: // sitdown @@ -10170,6 +10126,9 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type, )) //No sitting during these states either. break; + if( battle_config.idletime_criteria & BCIDLE_SIT ) + sd->idletime = sockt->last_tick; + pc_setsit(sd); skill->sit(sd,1); clif->sitting(&sd->bl); @@ -10180,6 +10139,10 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type, clif->standing(&sd->bl); return; } + + if( battle_config.idletime_criteria & BCIDLE_SIT ) + sd->idletime = sockt->last_tick; + pc->setstand(sd); skill->sit(sd,0); clif->standing(&sd->bl); @@ -10189,13 +10152,13 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type, void clif_hercules_chsys_left(struct hChSysCh *channel, struct map_session_data *sd) { unsigned char i; - + if ( !idb_remove(channel->users,sd->status.char_id) ) return; - + if( channel == sd->gcbind ) sd->gcbind = NULL; - + if( !db_size(channel->users) && channel->type == hChSys_PRIVATE ) { clif->chsys_delete(channel); } else if( !hChSys.closing && (channel->opt & hChSys_OPT_ANNOUNCE_JOIN) ) { @@ -10203,14 +10166,14 @@ void clif_hercules_chsys_left(struct hChSysCh *channel, struct map_session_data sprintf(message, "#%s '%s' left",channel->name,sd->status.name); clif->chsys_msg(channel,sd,message); } - + for( i = 0; i < sd->channel_count; i++ ) { if( sd->channels[i] == channel ) { sd->channels[i] = NULL; break; } } - + if( i < sd->channel_count ) { unsigned char cursor = 0; for( i = 0; i < sd->channel_count; i++ ) { @@ -10232,16 +10195,16 @@ void clif_hercules_chsys_left(struct hChSysCh *channel, struct map_session_data void clif_hercules_chsys_quitg(struct map_session_data *sd) { unsigned char i; struct hChSysCh *channel = NULL; - + for( i = 0; i < sd->channel_count; i++ ) { if( (channel = sd->channels[i] ) != NULL && channel->type == hChSys_ALLY ) { - + if ( !idb_remove(channel->users,sd->status.char_id) ) continue; - + if( channel == sd->gcbind ) sd->gcbind = NULL; - + if( !db_size(channel->users) && channel->type == hChSys_PRIVATE ) { clif->chsys_delete(channel); } else if( !hChSys.closing && (channel->opt & hChSys_OPT_ANNOUNCE_JOIN) ) { @@ -10252,7 +10215,7 @@ void clif_hercules_chsys_quitg(struct map_session_data *sd) { sd->channels[i] = NULL; } } - + if( i < sd->channel_count ) { unsigned char cursor = 0; for( i = 0; i < sd->channel_count; i++ ) { @@ -10268,21 +10231,21 @@ void clif_hercules_chsys_quitg(struct map_session_data *sd) { sd->channels = NULL; } } - + } void clif_hercules_chsys_quit(struct map_session_data *sd) { unsigned char i; struct hChSysCh *channel = NULL; - + for( i = 0; i < sd->channel_count; i++ ) { if( (channel = sd->channels[i] ) != NULL ) { idb_remove(channel->users,sd->status.char_id); - + if( channel == sd->gcbind ) sd->gcbind = NULL; - + if( !db_size(channel->users) && channel->type == hChSys_PRIVATE ) { clif->chsys_delete(channel); } else if( !hChSys.closing && (channel->opt & hChSys_OPT_ANNOUNCE_JOIN) ) { @@ -10290,7 +10253,7 @@ void clif_hercules_chsys_quit(struct map_session_data *sd) { sprintf(message, "#%s '%s' left",channel->name,sd->status.name); clif->chsys_msg(channel,sd,message); } - + } } @@ -10332,7 +10295,7 @@ void clif_parse_Restart(int fd, struct map_session_data *sd) { break; case 0x01: /* Rovert's Prevent logout option - Fixed [Valaris] */ - if( !sd->sc.data[SC_CLOAKING] && !sd->sc.data[SC_HIDING] && !sd->sc.data[SC_CHASEWALK] && !sd->sc.data[SC_CLOAKINGEXCEED] && + if( !sd->sc.data[SC_CLOAKING] && !sd->sc.data[SC_HIDING] && !sd->sc.data[SC_CHASEWALK] && !sd->sc.data[SC_CLOAKINGEXCEED] && !sd->sc.data[SC__INVISIBILITY] && (!battle_config.prevent_logout || DIFF_TICK(timer->gettick(), sd->canlog_tick) > battle_config.prevent_logout) ) { //Send to char-server for character selection. chrif->charselectreq(sd, session[fd]->client_addr); @@ -10352,16 +10315,16 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd) int i; char *target, *message; - int namelen, messagelen; + size_t namelen, messagelen; // validate packet and retrieve name and message if( !clif->process_message(sd, 1, &target, &namelen, &message, &messagelen) ) return; - if ( atcommand->parse(fd, sd, message, 1) ) + if ( atcommand->exec(fd, sd, message, true) ) return; - if (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEP_SLEEP] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT)) + if (sd->sc.data[SC_BERSERK] || (sd->sc.data[SC_DEEP_SLEEP] && sd->sc.data[SC_DEEP_SLEEP]->val2) || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT)) return; if (battle_config.min_chat_delay) { //[Skotlex] @@ -10371,6 +10334,9 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd) sd->cantalk_tick = timer->gettick() + battle_config.min_chat_delay; } + if( battle_config.idletime_criteria & BCIDLE_CHAT ) + sd->idletime = sockt->last_tick; + // Chat logging type 'W' / Whisper logs->chat(LOG_CHAT_WHISPER, 0, sd->status.char_id, sd->status.account_id, mapindex_id2name(sd->mapindex), sd->bl.x, sd->bl.y, target, message); @@ -10417,7 +10383,7 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd) char* chname = target; chname++; - + if( hChSys.local && strcmpi(chname, hChSys.local_name) == 0 ) { if( !map->list[sd->bl.m].channel ) { clif->chsys_mjoin(sd); @@ -10426,10 +10392,10 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd) } else if( hChSys.ally && sd->status.guild_id && strcmpi(chname, hChSys.ally_name) == 0 ) { struct guild *g = sd->guild; if( !g ) return; - channel = (struct hChSysCh *)g->channel; + channel = g->channel; } if( channel || (channel = strdb_get(clif->channel_db,chname)) ) { - unsigned char k; + int k; for( k = 0; k < sd->channel_count; k++ ) { if( sd->channels[k] == channel ) break; @@ -10439,11 +10405,10 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd) } else if( channel->pass[0] == '\0' && !(channel->banned && idb_exists(channel->banned, sd->status.account_id)) ) { if( channel->type == hChSys_ALLY ) { struct guild *g = sd->guild, *sg = NULL; - int k; for (k = 0; k < MAX_GUILDALLIANCE; k++) { if( g->alliance[k].opposition == 0 && g->alliance[k].guild_id && (sg = guild->search(g->alliance[k].guild_id) ) ) { - if( !(((struct hChSysCh*)sg->channel)->banned && idb_exists(((struct hChSysCh*)sg->channel)->banned, sd->status.account_id))) - clif->chsys_join((struct hChSysCh *)sg->channel,sd); + if( !(sg->channel->banned && idb_exists(sg->channel->banned, sd->status.account_id))) + clif->chsys_join(sg->channel,sd); } } } @@ -10470,8 +10435,8 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd) } // if player ignores everyone - if (dstsd->state.ignoreAll && pc->get_group_level(sd) <= pc->get_group_level(dstsd)) { - if (dstsd->sc.option & OPTION_INVISIBLE && pc->get_group_level(sd) < pc->get_group_level(dstsd)) + if (dstsd->state.ignoreAll && pc_get_group_level(sd) <= pc_get_group_level(dstsd)) { + if (dstsd->sc.option & OPTION_INVISIBLE && pc_get_group_level(sd) < pc_get_group_level(dstsd)) clif->wis_end(fd, 1); // 1: target character is not logged in else clif->wis_end(fd, 3); // 3: everyone ignored by target @@ -10486,7 +10451,7 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd) return; } - if( pc->get_group_level(sd) <= pc->get_group_level(dstsd) ) { + if( pc_get_group_level(sd) <= pc_get_group_level(dstsd) ) { // if player ignores the source character ARR_FIND(0, MAX_IGNORE_LIST, i, dstsd->ignore[i].name[0] == '\0' || strcmp(dstsd->ignore[i].name, sd->status.name) == 0); if(i < MAX_IGNORE_LIST && dstsd->ignore[i].name[0] != '\0') { // source char present in ignore list @@ -10515,7 +10480,7 @@ void clif_parse_Broadcast(int fd, struct map_session_data* sd) { mes_len_check(msg, len, CHAT_SIZE_MAX); sprintf(command, "%ckami %s", atcommand->at_symbol, msg); - atcommand->parse(fd, sd, command, 1); + atcommand->exec(fd, sd, command, true); } @@ -10589,6 +10554,9 @@ void clif_parse_DropItem(int fd, struct map_session_data *sd) if (!pc->dropitem(sd, item_index, item_amount)) break; + if( battle_config.idletime_criteria & BCIDLE_DROPITEM ) + sd->idletime = sockt->last_tick; + return; } @@ -10614,7 +10582,8 @@ void clif_parse_UseItem(int fd, struct map_session_data *sd) return; //Whether the item is used or not is irrelevant, the char ain't idle. [Skotlex] - sd->idletime = last_tick; + if( battle_config.idletime_criteria & BCIDLE_USEITEM ) + sd->idletime = sockt->last_tick; n = RFIFOW(fd,packet_db[RFIFOW(fd,0)].pos[0])-2; if(n <0 || n >= MAX_INVENTORY) @@ -10626,16 +10595,17 @@ void clif_parse_UseItem(int fd, struct map_session_data *sd) /// Request to equip an item (CZ_REQ_WEAR_EQUIP). /// 00a9 <index>.W <position>.W -void clif_parse_EquipItem(int fd,struct map_session_data *sd) -{ - int index; +/// 0998 <index>.W <position>.L +void clif_parse_EquipItem(int fd,struct map_session_data *sd) { + struct packet_equip_item *p = P2PTR(fd); if(pc_isdead(sd)) { clif->clearunit_area(&sd->bl,CLR_DEAD); return; } - index = RFIFOW(fd,2)-2; - if (index < 0 || index >= MAX_INVENTORY) + + p->index = p->index - 2; + if (p->index >= MAX_INVENTORY) return; //Out of bounds check. if( sd->npc_id ) { @@ -10646,24 +10616,27 @@ void clif_parse_EquipItem(int fd,struct map_session_data *sd) else if ( pc_cant_act2(sd) || sd->state.prerefining ) return; - if(!sd->status.inventory[index].identify) { - clif->equipitemack(sd,index,0,0); // fail + if(!sd->status.inventory[p->index].identify) { + clif->equipitemack(sd,p->index,0,EIA_FAIL);// fail return; } - if(!sd->inventory_data[index]) + if(!sd->inventory_data[p->index]) return; - if(sd->inventory_data[index]->type == IT_PETARMOR){ - pet->equipitem(sd,index); + if(sd->inventory_data[p->index]->type == IT_PETARMOR){ + pet->equipitem(sd,p->index); return; } + if( battle_config.idletime_criteria & BCIDLE_USEITEM ) + sd->idletime = sockt->last_tick; + //Client doesn't send the position for ammo. - if(sd->inventory_data[index]->type == IT_AMMO) - pc->equipitem(sd,index,EQP_AMMO); + if(sd->inventory_data[p->index]->type == IT_AMMO) + pc->equipitem(sd,p->index,EQP_AMMO); else - pc->equipitem(sd,index,RFIFOW(fd,4)); + pc->equipitem(sd,p->index,p->wearLocation); } void clif_hercules_chsys_delete(struct hChSysCh *channel) { @@ -10714,20 +10687,20 @@ void clif_hercules_chsys_gjoin(struct guild *g1,struct guild *g2) { struct map_session_data *sd; struct hChSysCh *channel; int j; - - if( (channel = (struct hChSysCh*)g1->channel) ) { + + if( (channel = g1->channel) ) { for(j = 0; j < g2->max_member; j++) { if( (sd = g2->member[j].sd) != NULL ) { - if( !(((struct hChSysCh*)g1->channel)->banned && idb_exists(((struct hChSysCh*)g1->channel)->banned, sd->status.account_id))) + if( !(g1->channel->banned && idb_exists(g1->channel->banned, sd->status.account_id))) clif->chsys_join(channel,sd); } } } - - if( (channel = (struct hChSysCh*)g2->channel) ) { + + if( (channel = g2->channel) ) { for(j = 0; j < g1->max_member; j++) { if( (sd = g1->member[j].sd) != NULL ) { - if( !(((struct hChSysCh*)g2->channel)->banned && idb_exists(((struct hChSysCh*)g2->channel)->banned, sd->status.account_id))) + if( !(g2->channel->banned && idb_exists(g2->channel->banned, sd->status.account_id))) clif->chsys_join(channel,sd); } } @@ -10737,16 +10710,16 @@ void clif_hercules_chsys_gleave(struct guild *g1,struct guild *g2) { struct map_session_data *sd; struct hChSysCh *channel; int j; - - if( (channel = (struct hChSysCh*)g1->channel) ) { + + if( (channel = g1->channel) ) { for(j = 0; j < g2->max_member; j++) { if( (sd = g2->member[j].sd) != NULL ) { clif->chsys_left(channel,sd); } } } - - if( (channel = (struct hChSysCh*)g2->channel) ) { + + if( (channel = g2->channel) ) { for(j = 0; j < g1->max_member; j++) { if( (sd = g1->member[j].sd) != NULL ) { clif->chsys_left(channel,sd); @@ -10776,6 +10749,9 @@ void clif_parse_UnequipItem(int fd,struct map_session_data *sd) index = RFIFOW(fd,2)-2; + if( battle_config.idletime_criteria & BCIDLE_USEITEM ) + sd->idletime = sockt->last_tick; + pc->unequipitem(sd,index,1); } @@ -10800,7 +10776,7 @@ void clif_parse_NpcClicked(int fd,struct map_session_data *sd) } if ( pc_cant_act2(sd) || !(bl = map->id2bl(RFIFOL(fd,2))) || sd->state.vending ) return; - + switch (bl->type) { case BL_MOB: case BL_PC: @@ -11016,10 +10992,10 @@ void clif_noask_sub(struct map_session_data *src, struct map_session_data *targe char output[256]; // Your request has been rejected by autoreject option. msg = msg_txt(392); - clif->disp_onlyself(src, msg, strlen(msg)); + clif_disp_onlyself(src, msg, strlen(msg)); //Notice that a request was rejected. snprintf(output, 256, msg_txt(393+type), src->status.name, 256); - clif->disp_onlyself(target, output, strlen(output)); + clif_disp_onlyself(target, output, strlen(output)); } @@ -11153,7 +11129,9 @@ void clif_parse_ChangeCart(int fd,struct map_session_data *sd) {// TODO: State tracking? int type; - if( sd && pc->checkskill(sd, MC_CHANGECART) < 1 ) + nullpo_retv(sd); + + if( pc->checkskill(sd, MC_CHANGECART) < 1 ) return; #ifdef RENEWAL @@ -11190,11 +11168,10 @@ void clif_parse_ChangeCart(int fd,struct map_session_data *sd) /// status id: /// SP_STR ~ SP_LUK /// amount: -/// client sends always 1 for this, even when using /str+ and -/// the like -void clif_parse_StatusUp(int fd,struct map_session_data *sd) -{ - pc->statusup(sd,RFIFOW(fd,2)); +/// Old clients send always 1 for this, even when using /str+ and the like. +/// Newer clients (2013-12-23 and newer) send the correct amount. +void clif_parse_StatusUp(int fd,struct map_session_data *sd) { + pc->statusup(sd,RFIFOW(fd,2), RFIFOB(fd, 4)); } @@ -11205,8 +11182,7 @@ void clif_parse_SkillUp(int fd,struct map_session_data *sd) pc->skillup(sd,RFIFOW(fd,2)); } -void clif_parse_UseSkillToId_homun(struct homun_data *hd, struct map_session_data *sd, unsigned int tick, uint16 skill_id, uint16 skill_lv, int target_id) -{ +void clif_parse_UseSkillToId_homun(struct homun_data *hd, struct map_session_data *sd, int64 tick, uint16 skill_id, uint16 skill_lv, int target_id) { int lv; if( !hd ) @@ -11227,8 +11203,7 @@ void clif_parse_UseSkillToId_homun(struct homun_data *hd, struct map_session_dat unit->skilluse_id(&hd->bl, target_id, skill_id, skill_lv); } -void clif_parse_UseSkillToPos_homun(struct homun_data *hd, struct map_session_data *sd, unsigned int tick, uint16 skill_id, uint16 skill_lv, short x, short y, int skillmoreinfo) -{ +void clif_parse_UseSkillToPos_homun(struct homun_data *hd, struct map_session_data *sd, int64 tick, uint16 skill_id, uint16 skill_lv, short x, short y, int skillmoreinfo) { int lv; if( !hd ) return; @@ -11248,8 +11223,7 @@ void clif_parse_UseSkillToPos_homun(struct homun_data *hd, struct map_session_da unit->skilluse_pos(&hd->bl, x, y, skill_id, skill_lv); } -void clif_parse_UseSkillToId_mercenary(struct mercenary_data *md, struct map_session_data *sd, unsigned int tick, uint16 skill_id, uint16 skill_lv, int target_id) -{ +void clif_parse_UseSkillToId_mercenary(struct mercenary_data *md, struct map_session_data *sd, int64 tick, uint16 skill_id, uint16 skill_lv, int target_id) { int lv; if( !md ) @@ -11270,8 +11244,7 @@ void clif_parse_UseSkillToId_mercenary(struct mercenary_data *md, struct map_ses unit->skilluse_id(&md->bl, target_id, skill_id, skill_lv); } -void clif_parse_UseSkillToPos_mercenary(struct mercenary_data *md, struct map_session_data *sd, unsigned int tick, uint16 skill_id, uint16 skill_lv, short x, short y, int skillmoreinfo) -{ +void clif_parse_UseSkillToPos_mercenary(struct mercenary_data *md, struct map_session_data *sd, int64 tick, uint16 skill_id, uint16 skill_lv, short x, short y, int skillmoreinfo) { int lv; if( !md ) return; @@ -11302,7 +11275,7 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd) { uint16 skill_id, skill_lv; int tmp, target_id; - unsigned int tick = timer->gettick(); + int64 tick = timer->gettick(); skill_lv = RFIFOW(fd,packet_db[RFIFOW(fd,0)].pos[0]); skill_id = RFIFOW(fd,packet_db[RFIFOW(fd,0)].pos[1]); @@ -11325,7 +11298,8 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd) } // Whether skill fails or not is irrelevant, the char ain't idle. [Skotlex] - sd->idletime = last_tick; + if( battle_config.idletime_criteria & BCIDLE_USESKILLTOID ) + sd->idletime = sockt->last_tick; if( sd->npc_id || sd->state.workinprogress&1 ){ #ifdef RENEWAL @@ -11357,7 +11331,7 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd) } } - if( sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER|OPTION_HANBOK) ) + if( sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER|OPTION_HANBOK|OPTION_OKTOBERFEST) ) return; if( sd->sc.data[SC_BASILICA] && (skill_id != HP_BASILICA || sd->sc.data[SC_BASILICA]->val4 != sd->bl.id) ) @@ -11402,7 +11376,7 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd) *------------------------------------------*/ void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, uint16 skill_lv, uint16 skill_id, short x, short y, int skillmoreinfo) { - unsigned int tick = timer->gettick(); + int64 tick = timer->gettick(); if( !(skill->get_inf(skill_id)&INF_GROUND_SKILL) ) return; //Using a target skill on the ground? WRONG. @@ -11425,7 +11399,8 @@ void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, uint16 ski #endif //Whether skill fails or not is irrelevant, the char ain't idle. [Skotlex] - sd->idletime = last_tick; + if( battle_config.idletime_criteria & BCIDLE_USESKILLTOPOS ) + sd->idletime = sockt->last_tick; if( skill->not_ok(skill_id, sd) ) return; @@ -11448,7 +11423,7 @@ void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, uint16 ski } } - if( sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER|OPTION_HANBOK) ) + if( sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER|OPTION_HANBOK|OPTION_OKTOBERFEST) ) return; if( sd->sc.data[SC_BASILICA] && (skill_id != HP_BASILICA || sd->sc.data[SC_BASILICA]->val4 != sd->bl.id) ) @@ -11528,7 +11503,7 @@ void clif_parse_UseSkillMap(int fd, struct map_session_data* sd) uint16 skill_id = RFIFOW(fd,2); char map_name[MAP_NAME_LENGTH]; - mapindex_getmapname((char*)RFIFOP(fd,4), map_name); + mapindex->getmapname((char*)RFIFOP(fd,4), map_name); sd->state.workinprogress = 0; if(skill_id != sd->menuskill_id) @@ -11839,7 +11814,7 @@ void clif_parse_ResetChar(int fd, struct map_session_data *sd) { else sprintf(cmd,"%cstreset",atcommand->at_symbol); - atcommand->parse(fd, sd, cmd, 1); + atcommand->exec(fd, sd, cmd, true); } @@ -11856,7 +11831,7 @@ void clif_parse_LocalBroadcast(int fd, struct map_session_data* sd) mes_len_check(msg, len, CHAT_SIZE_MAX); sprintf(command, "%clkami %s", atcommand->at_symbol, msg); - atcommand->parse(fd, sd, command, 1); + atcommand->exec(fd, sd, command, true); } @@ -12161,16 +12136,16 @@ void clif_parse_PartyMessage(int fd, struct map_session_data* sd) int textlen = RFIFOW(fd,2) - 4; char *name, *message; - int namelen, messagelen; + size_t namelen, messagelen; // validate packet and retrieve name and message if( !clif->process_message(sd, 0, &name, &namelen, &message, &messagelen) ) return; - if( atcommand->parse(fd, sd, message, 1) ) + if( atcommand->exec(fd, sd, message, true) ) return; - if( sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEP_SLEEP] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) ) + if( sd->sc.data[SC_BERSERK] || (sd->sc.data[SC_DEEP_SLEEP] && sd->sc.data[SC_DEEP_SLEEP]->val2) || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) ) return; if( battle_config.min_chat_delay ) @@ -12180,6 +12155,9 @@ void clif_parse_PartyMessage(int fd, struct map_session_data* sd) sd->cantalk_tick = timer->gettick() + battle_config.min_chat_delay; } + if( battle_config.idletime_criteria & BCIDLE_CHAT ) + sd->idletime = sockt->last_tick; + party->send_message(sd, text, textlen); } @@ -12528,7 +12506,7 @@ void clif_parse_PartyRecruitUpdateReq(int fd, struct map_session_data *sd) const char *notice; notice = (const char*)RFIFOP(fd, 2); - + party->recruit_update(sd, notice); #else return; @@ -12563,7 +12541,7 @@ void clif_PartyRecruitUpdateNotify(struct map_session_data *sd, struct party_boo { #ifdef PARTY_RECRUIT unsigned char buf[2+6+37+1]; - + WBUFW(buf, 0) = 0x8ed; WBUFL(buf, 2) = pb_ad->index; memcpy(WBUFP(buf, 6), pb_ad->p_detail.notice, PB_NOTICE_LENGTH); @@ -12635,13 +12613,13 @@ void clif_PartyBookingVolunteerInfo(int index, struct map_session_data *sd) { #ifdef PARTY_RECRUIT unsigned char buf[2+4+4+2+24+1]; - + WBUFW(buf, 0) = 0x8f2; WBUFL(buf, 2) = sd->status.account_id; WBUFL(buf, 6) = sd->status.class_; WBUFW(buf, 10) = sd->status.base_level; memcpy(WBUFP(buf, 12), sd->status.name, NAME_LENGTH); - + clif->send(buf, packet_len(0x8f2), &sd->bl, ALL_CLIENT); #else return; @@ -12690,7 +12668,7 @@ void clif_PartyBookingFailedRecall(int fd, struct map_session_data *sd) void clif_parse_PartyBookingRefuseVolunteer(int fd, struct map_session_data *sd) { #ifdef PARTY_RECRUIT - unsigned long aid = RFIFOL(fd, 2); + unsigned int aid = RFIFOL(fd, 2); clif->PartyBookingRefuseVolunteer(aid, sd); #else @@ -12699,14 +12677,14 @@ void clif_parse_PartyBookingRefuseVolunteer(int fd, struct map_session_data *sd) } /// 08fa <index>.L -void clif_PartyBookingRefuseVolunteer(unsigned long aid, struct map_session_data *sd) +void clif_PartyBookingRefuseVolunteer(unsigned int aid, struct map_session_data *sd) { #ifdef PARTY_RECRUIT unsigned char buf[2+6]; - + WBUFW(buf, 0) = 0x8fa; WBUFL(buf, 2) = aid; - + clif->send(buf, packet_len(0x8fa), &sd->bl, ALL_CLIENT); #else return; @@ -12730,10 +12708,10 @@ void clif_PartyBookingCancelVolunteer(int index, struct map_session_data *sd) { #ifdef PARTY_RECRUIT unsigned char buf[2+6+1]; - + WBUFW(buf, 0) = 0x909; WBUFL(buf, 2) = index; - + clif->send(buf, packet_len(0x909), &sd->bl, ALL_CLIENT); #else return; @@ -12749,7 +12727,7 @@ void clif_PartyBookingAddFilteringList(int index, struct map_session_data *sd) WBUFW(buf, 0) = 0x90b; WBUFL(buf, 2) = sd->bl.id; memcpy(WBUFP(buf, 6), sd->status.name, NAME_LENGTH); - + clif->send(buf, packet_len(0x90b), &sd->bl, ALL_CLIENT); #else return; @@ -12765,7 +12743,7 @@ void clif_PartyBookingSubFilteringList(int gid, struct map_session_data *sd) WBUFW(buf, 0) = 0x90c; WBUFL(buf, 2) = gid; memcpy(WBUFP(buf, 6), sd->status.name, NAME_LENGTH); - + clif->send(buf, packet_len(0x90c), &sd->bl, ALL_CLIENT); #else return; @@ -12845,7 +12823,7 @@ void clif_parse_OpenVending(int fd, struct map_session_data* sd) { const char* message = (char*)RFIFOP(fd,4); bool flag = (bool)RFIFOB(fd,84); const uint8* data = (uint8*)RFIFOP(fd,85); - + if( !flag ) sd->state.prevend = sd->state.workinprogress = 0; @@ -12973,20 +12951,126 @@ void clif_parse_GuildRequestEmblem(int fd,struct map_session_data *sd) clif->guild_emblem(sd,g); } - /// Validates data of a guild emblem (compressed bitmap) -bool clif_validate_emblem(const uint8* emblem, unsigned long emblem_len) { - bool success; - uint8 buf[1800]; // no well-formed emblem bitmap is larger than 1782 (24 bit) / 1654 (8 bit) bytes +bool clif_validate_emblem(const uint8 *emblem, unsigned long emblem_len) { + enum e_bitmapconst { + RGBTRIPLE_SIZE = 3, // sizeof(RGBTRIPLE) + RGBQUAD_SIZE = 4, // sizeof(RGBQUAD) + BITMAPFILEHEADER_SIZE = 14, // sizeof(BITMAPFILEHEADER) + BITMAPINFOHEADER_SIZE = 40, // sizeof(BITMAPINFOHEADER) + BITMAP_WIDTH = 24, + BITMAP_HEIGHT = 24, + }; +#if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute +#pragma pack(push, 1) +#endif // not NetBSD < 6 / Solaris + struct s_bitmaptripple { + //uint8 b; + //uint8 g; + //uint8 r; + unsigned int rgb:24; + } __attribute__((packed)); +#if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute +#pragma pack(pop) +#endif // not NetBSD < 6 / Solaris + uint8 buf[1800]; // no well-formed emblem bitmap is larger than 1782 (24 bit) / 1654 (8 bit) bytes unsigned long buf_len = sizeof(buf); + int header = 0, bitmap = 0, offbits = 0, palettesize = 0, i = 0; + + if( decode_zip(buf, &buf_len, emblem, emblem_len) != 0 || buf_len < BITMAPFILEHEADER_SIZE + BITMAPINFOHEADER_SIZE + || RBUFW(buf,0) != 0x4d42 // BITMAPFILEHEADER.bfType (signature) + || RBUFL(buf,2) != buf_len // BITMAPFILEHEADER.bfSize (file size) + || RBUFL(buf,14) != BITMAPINFOHEADER_SIZE // BITMAPINFOHEADER.biSize (other headers are not supported) + || RBUFL(buf,18) != BITMAP_WIDTH // BITMAPINFOHEADER.biWidth + || RBUFL(buf,22) != BITMAP_HEIGHT // BITMAPINFOHEADER.biHeight (top-down bitmaps (-24) are not supported) + || RBUFL(buf,30) != 0 // BITMAPINFOHEADER.biCompression == BI_RGB (compression not supported) + ) { + // Invalid data + return false; + } - success = ( decode_zip(buf, &buf_len, emblem, emblem_len) == 0 && buf_len >= 18 ) // sizeof(BITMAPFILEHEADER) + sizeof(biSize) of the following info header struct - && RBUFW(buf,0) == 0x4d42 // BITMAPFILEHEADER.bfType (signature) - && RBUFL(buf,2) == buf_len // BITMAPFILEHEADER.bfSize (file size) - && RBUFL(buf,10) < buf_len // BITMAPFILEHEADER.bfOffBits (offset to bitmap bits) - ; + offbits = RBUFL(buf,10); // BITMAPFILEHEADER.bfOffBits (offset to bitmap bits) + + switch( RBUFW(buf,28) ) { // BITMAPINFOHEADER.biBitCount + case 8: + palettesize = RBUFL(buf,46); // BITMAPINFOHEADER.biClrUsed (number of colors in the palette) + if( palettesize == 0 ) + palettesize = 256; // Defaults to 2^n if set to zero + else if( palettesize > 256 ) + return false; + header = BITMAPFILEHEADER_SIZE + BITMAPINFOHEADER_SIZE + RGBQUAD_SIZE * palettesize; // headers + palette + bitmap = BITMAP_WIDTH * BITMAP_HEIGHT; + break; + case 24: + header = BITMAPFILEHEADER_SIZE + BITMAPINFOHEADER_SIZE; + bitmap = BITMAP_WIDTH * BITMAP_HEIGHT * RGBTRIPLE_SIZE; + break; + default: + return false; + } - return success; + // NOTE: This check gives a little freedom for bitmap-producing implementations, + // that align the start of bitmap data, which is harmless but unnecessary. + // If you want it paranoidly strict, change the first condition from < to !=. + // This also allows files with trailing garbage at the end of the file. + // If you want to avoid that, change the last condition to !=. + if( offbits < header || buf_len <= bitmap || offbits > buf_len - bitmap ) { + return false; + } + + if( battle_config.client_emblem_max_blank_percent < 100 ) { + int required_pixels = BITMAP_WIDTH * BITMAP_HEIGHT * (100 - battle_config.client_emblem_max_blank_percent) / 100; + int found_pixels = 0; + /// Checks what percentage of a guild emblem is blank. A blank emblem + /// consists solely of magenta pixels. Since the client uses 16-bit + /// colors, any magenta shade that reduces to #ff00ff passes off as + /// transparent color as well (down to #f807f8). + /// + /// Unlike real magenta, reduced magenta causes the guild window to + /// become see-through in the transparent parts of the emblem + /// background (glitch). + switch( RBUFW(buf,28) ) { + case 8: // palette indexes + { + const uint8 *indexes = (const uint8 *)RBUFP(buf,offbits); + const uint32 *palette = (const uint32 *)RBUFP(buf,BITMAPFILEHEADER_SIZE + BITMAPINFOHEADER_SIZE); + + for( i = 0; i < BITMAP_WIDTH * BITMAP_HEIGHT; i++ ) { + if( indexes[i] >= palettesize ) // Invalid color + return false; + + // if( color->r < 0xF8 || color->g > 0x07 || color->b < 0xF8 ) + if( ( palette[indexes[i]]&0x00F8F8F8 ) != 0x00F800F8 ) { + if( ++found_pixels >= required_pixels ) { + // Enough valid pixels were found + return true; + } + } + } + break; + } + case 24: // full colors + { + const struct s_bitmaptripple *pixels = (const struct s_bitmaptripple*)RBUFP(buf,offbits); + + for( i = 0; i < BITMAP_WIDTH * BITMAP_HEIGHT; i++ ) { + // if( pixels[i].r < 0xF8 || pixels[i].g > 0x07 || pixels[i].b < 0xF8 ) + if( ( pixels[i].rgb&0xF8F8F8 ) != 0xF800F8 ) { + if( ++found_pixels >= required_pixels ) { + // Enough valid pixels were found + return true; + } + } + } + break; + } + } + + // Not enough non-blank pixels found + return false; + } + + return true; } @@ -12994,7 +13078,7 @@ bool clif_validate_emblem(const uint8* emblem, unsigned long emblem_len) { /// 0153 <packet len>.W <emblem data>.?B void clif_parse_GuildChangeEmblem(int fd,struct map_session_data *sd) { - unsigned long emblem_len = RFIFOW(fd,2)-4; + unsigned int emblem_len = RFIFOW(fd,2)-4; const uint8* emblem = RFIFOP(fd,4); if( !emblem_len || !sd->state.gmaster_flag ) @@ -13029,25 +13113,23 @@ void clif_parse_GuildChangeNotice(int fd, struct map_session_data* sd) } // Helper function for guild invite functions -int -clif_sub_guild_invite(int fd, struct map_session_data *sd, struct map_session_data *t_sd) { - if (t_sd == NULL) {// not online or does not exist - return 1; - } - - if (map->list[sd->bl.m].flag.guildlock) { +bool clif_sub_guild_invite(int fd, struct map_session_data *sd, struct map_session_data *t_sd) { + if ( t_sd == NULL )// not online or does not exist + return false; + + if ( map->list[sd->bl.m].flag.guildlock ) { //Guild locked. clif->message(fd, msg_txt(228)); - return 1; + return false; } - - if (t_sd && t_sd->state.noask) {// @noask [LuzZza] + + if ( t_sd && t_sd->state.noask ) {// @noask [LuzZza] clif->noask_sub(sd, t_sd, 2); - return 1; + return false; } guild->invite(sd,t_sd); - return 0; + return true; } /// Guild invite request (CZ_REQ_JOIN_GUILD). @@ -13055,7 +13137,7 @@ clif_sub_guild_invite(int fd, struct map_session_data *sd, struct map_session_da void clif_parse_GuildInvite(int fd,struct map_session_data *sd) { struct map_session_data *t_sd = map->id2sd(RFIFOL(fd,2)); - if (clif_sub_guild_invite(fd, sd, t_sd)) + if (!clif_sub_guild_invite(fd, sd, t_sd)) return; } @@ -13063,8 +13145,8 @@ void clif_parse_GuildInvite(int fd,struct map_session_data *sd) { /// 0916 <char name>.24B void clif_parse_GuildInvite2(int fd, struct map_session_data *sd) { struct map_session_data *t_sd = map->nick2sd((char *)RFIFOP(fd, 2)); - - if (clif_sub_guild_invite(fd, sd, t_sd)) + + if (!clif_sub_guild_invite(fd, sd, t_sd)) return; } @@ -13116,16 +13198,16 @@ void clif_parse_GuildMessage(int fd, struct map_session_data* sd) int textlen = RFIFOW(fd,2) - 4; char *name, *message; - int namelen, messagelen; + size_t namelen, messagelen; // validate packet and retrieve name and message if( !clif->process_message(sd, 0, &name, &namelen, &message, &messagelen) ) return; - if( atcommand->parse(fd, sd, message, 1) ) + if( atcommand->exec(fd, sd, message, true) ) return; - if( sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEP_SLEEP] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) ) + if( sd->sc.data[SC_BERSERK] || (sd->sc.data[SC_DEEP_SLEEP] && sd->sc.data[SC_DEEP_SLEEP]->val2) || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) ) return; if( battle_config.min_chat_delay ) @@ -13135,6 +13217,9 @@ void clif_parse_GuildMessage(int fd, struct map_session_data* sd) sd->cantalk_tick = timer->gettick() + battle_config.min_chat_delay; } + if( battle_config.idletime_criteria & BCIDLE_CHAT ) + sd->idletime = sockt->last_tick; + if( sd->bg_id ) bg->send_message(sd, text, textlen); else @@ -13268,8 +13353,6 @@ void clif_parse_CatchPet(int fd, struct map_session_data *sd) void clif_parse_SelectEgg(int fd, struct map_session_data *sd) { if (sd->menuskill_id != SA_TAMINGMONSTER || sd->menuskill_val != -1) { - //Forged packet, disconnect them [Kevin] - clif->authfail_fd(fd, 0); return; } pet->select_egg(sd,RFIFOW(fd,2)-2); @@ -13336,7 +13419,7 @@ void clif_parse_GMKick(int fd, struct map_session_data *sd) { { char command[NAME_LENGTH+6]; sprintf(command, "%ckick %s", atcommand->at_symbol, status->get_name(target)); - atcommand->parse(fd, sd, command, 1); + atcommand->exec(fd, sd, command, true); } break; @@ -13381,7 +13464,7 @@ void clif_parse_GMKick(int fd, struct map_session_data *sd) { void clif_parse_GMKickAll(int fd, struct map_session_data* sd) { char cmd[15]; sprintf(cmd,"%ckickall",atcommand->at_symbol); - atcommand->parse(fd, sd, cmd, 1); + atcommand->exec(fd, sd, cmd, true); } @@ -13401,7 +13484,7 @@ void clif_parse_GMShift(int fd, struct map_session_data *sd) player_name[NAME_LENGTH-1] = '\0'; sprintf(command, "%cjumpto %s", atcommand->at_symbol, player_name); - atcommand->parse(fd, sd, command, 1); + atcommand->exec(fd, sd, command, true); } @@ -13416,7 +13499,7 @@ void clif_parse_GMRemove2(int fd, struct map_session_data* sd) { if( (pl_sd = map->id2sd(account_id)) != NULL ) { char command[NAME_LENGTH+8]; sprintf(command, "%cjumpto %s", atcommand->at_symbol, pl_sd->status.name); - atcommand->parse(fd, sd, command, 1); + atcommand->exec(fd, sd, command, true); } } @@ -13437,7 +13520,7 @@ void clif_parse_GMRecall(int fd, struct map_session_data *sd) player_name[NAME_LENGTH-1] = '\0'; sprintf(command, "%crecall %s", atcommand->at_symbol, player_name); - atcommand->parse(fd, sd, command, 1); + atcommand->exec(fd, sd, command, true); } @@ -13452,7 +13535,7 @@ void clif_parse_GMRecall2(int fd, struct map_session_data* sd) { if( (pl_sd = map->id2sd(account_id)) != NULL ) { char command[NAME_LENGTH+8]; sprintf(command, "%crecall %s", atcommand->at_symbol, pl_sd->status.name); - atcommand->parse(fd, sd, command, 1); + atcommand->exec(fd, sd, command, true); } } @@ -13469,48 +13552,59 @@ void clif_parse_GMRecall2(int fd, struct map_session_data* sd) { /// /item cap_n - capture n monster as pet.(not yet implemented) /// /item agitinvest - reset current global agit investments.(not yet implemented) /// 013f <item/mob name>.24B -void clif_parse_GM_Monster_Item(int fd, struct map_session_data *sd) -{ +/// 09ce <item/mob name>.100B [Ind/Yommy<3] +void clif_parse_GM_Monster_Item(int fd, struct map_session_data *sd) { + struct packet_gm_monster_item *p = P2PTR(fd); int i, count; char *item_monster_name; struct item_data *item_array[10]; struct mob_db *mob_array[10]; - char command[NAME_LENGTH+10]; + char command[256]; - item_monster_name = (char*)RFIFOP(fd,2); - item_monster_name[NAME_LENGTH-1] = '\0'; + item_monster_name = p->str; + item_monster_name[(sizeof(struct packet_gm_monster_item)-2)-1] = '\0'; - if ( (count=itemdb->search_name_array(item_array, 10, item_monster_name, 1)) > 0 ){ - for(i = 0; i < count; i++){ - if( item_array[i] && strcmp(item_array[i]->name, item_monster_name) == 0 )// It only accepts aegis name + if ( (count=itemdb->search_name_array(item_array, 10, item_monster_name, 1)) > 0 ) { + for(i = 0; i < count; i++) { + if( !item_array[i] ) + continue; + // It only accepts aegis name + if( battle_config.case_sensitive_aegisnames && strcmp(item_array[i]->name, item_monster_name) == 0 ) + break; + if( !battle_config.case_sensitive_aegisnames && strcasecmp(item_array[i]->name, item_monster_name) == 0 ) break; } - if( i < count ){ + if( i < count ) { if( item_array[i]->type == IT_WEAPON || item_array[i]->type == IT_ARMOR ) // nonstackable snprintf(command, sizeof(command)-1, "%citem2 %d 1 0 0 0 0 0 0 0", atcommand->at_symbol, item_array[i]->nameid); else snprintf(command, sizeof(command)-1, "%citem %d 20", atcommand->at_symbol, item_array[i]->nameid); - atcommand->parse(fd, sd, command, 1); + atcommand->exec(fd, sd, command, true); return; } } if( strcmp("money", item_monster_name) == 0 ){ snprintf(command, sizeof(command)-1, "%czeny %d", atcommand->at_symbol, INT_MAX); - atcommand->parse(fd, sd, command, 1); + atcommand->exec(fd, sd, command, true); return; } - if( (count=mob->db_searchname_array(mob_array, 10, item_monster_name, 1)) > 0){ - for(i = 0; i < count; i++){ - if( mob_array[i] && strcmp(mob_array[i]->sprite, item_monster_name) == 0 ) // It only accepts sprite name + if( (count=mob->db_searchname_array(mob_array, 10, item_monster_name, 1)) > 0) { + for(i = 0; i < count; i++) { + if( !mob_array[i] ) + continue; + // It only accepts sprite name + if( battle_config.case_sensitive_aegisnames && strcmp(mob_array[i]->sprite, item_monster_name) == 0 ) + break; + if( !battle_config.case_sensitive_aegisnames && strcasecmp(mob_array[i]->sprite, item_monster_name) == 0 ) break; } if( i < count ){ snprintf(command, sizeof(command)-1, "%cmonster %s", atcommand->at_symbol, mob_array[i]->sprite); - atcommand->parse(fd, sd, command, 1); + atcommand->exec(fd, sd, command, true); } } } @@ -13525,7 +13619,7 @@ void clif_parse_GMHide(int fd, struct map_session_data *sd) { sprintf(cmd,"%chide",atcommand->at_symbol); - atcommand->parse(fd, sd, cmd, 1); + atcommand->exec(fd, sd, cmd, true); } @@ -13550,7 +13644,7 @@ void clif_parse_GMReqNoChat(int fd,struct map_session_data *sd) { if (type == 2) { if (!battle_config.client_accept_chatdori) return; - if (pc->get_group_level(sd) > 0 || sd->bl.id != id) + if (pc_get_group_level(sd) > 0 || sd->bl.id != id) return; value = battle_config.client_accept_chatdori; @@ -13560,26 +13654,26 @@ void clif_parse_GMReqNoChat(int fd,struct map_session_data *sd) { if( dstsd == NULL ) return; } - - if (type == 2 || ( (pc->get_group_level(sd)) > pc->get_group_level(dstsd) && !pc->can_use_command(sd, "@mute"))) { + + if (type == 2 || ( (pc_get_group_level(sd)) > pc_get_group_level(dstsd) && !pc->can_use_command(sd, "@mute"))) { clif->manner_message(sd, 0); clif->manner_message(dstsd, 5); if (dstsd->status.manner < value) { dstsd->status.manner -= value; - sc_start(&dstsd->bl,SC_NOCHAT,100,0,0); - + sc_start(NULL,&dstsd->bl,SC_NOCHAT,100,0,0); + } else { dstsd->status.manner = 0; status_change_end(&dstsd->bl, SC_NOCHAT, INVALID_TIMER); } - + if( type != 2 ) clif->GM_silence(sd, dstsd, type); } sprintf(command, "%cmute %d %s", atcommand->at_symbol, value, dstsd->status.name); - atcommand->parse(fd, sd, command, 1); + atcommand->exec(fd, sd, command, true); } @@ -13593,7 +13687,7 @@ void clif_parse_GMRc(int fd, struct map_session_data* sd) name[NAME_LENGTH-1] = '\0'; sprintf(command, "%cmute %d %s", atcommand->at_symbol, 60, name); - atcommand->parse(fd, sd, command, 1); + atcommand->exec(fd, sd, command, true); } @@ -13630,7 +13724,7 @@ void clif_parse_GMReqAccountName(int fd, struct map_session_data *sd) void clif_parse_GMChangeMapType(int fd, struct map_session_data *sd) { int x,y,type; - if (!pc->has_permission(sd, PC_PERM_USE_CHANGEMAPTYPE)) + if (!pc_has_permission(sd, PC_PERM_USE_CHANGEMAPTYPE)) return; x = RFIFOW(fd,2); @@ -13796,7 +13890,7 @@ void clif_parse_NoviceExplosionSpirits(int fd, struct map_session_data *sd) int percent = (int)( ( (float)sd->status.base_exp/(float)next )*1000. ); if( percent && ( percent%100 ) == 0 ) {// 10.0%, 20.0%, ..., 90.0% - sc_start(&sd->bl, status->skill2sc(MO_EXPLOSIONSPIRITS), 100, 17, skill->get_time(MO_EXPLOSIONSPIRITS, 5)); //Lv17-> +50 critical (noted by Poki) [Skotlex] + sc_start(NULL,&sd->bl, status->skill2sc(MO_EXPLOSIONSPIRITS), 100, 17, skill->get_time(MO_EXPLOSIONSPIRITS, 5)); //Lv17-> +50 critical (noted by Poki) [Skotlex] clif->skill_nodamage(&sd->bl, &sd->bl, MO_EXPLOSIONSPIRITS, 5, 1); // prayer always shows successful Lv5 cast and disregards noskill restrictions } } @@ -14064,7 +14158,7 @@ void clif_parse_FriendsListRemove(int fd, struct map_session_data *sd) } } else { //friend not online -- ask char server to delete from his friendlist - if(chrif->removefriend(char_id,sd->status.char_id)) { // char-server offline, abort + if(!chrif->removefriend(char_id,sd->status.char_id)) { // char-server offline, abort clif->message(fd, msg_txt(673)); //"This action can't be performed at the moment. Please try again later." return; } @@ -14329,7 +14423,7 @@ void clif_parse_FeelSaveOk(int fd,struct map_session_data *sd) sd->feel_map[i].index = map_id2index(sd->bl.m); sd->feel_map[i].m = sd->bl.m; - pc_setglobalreg(sd,pc->sg_info[i].feel_var,sd->feel_map[i].index); + pc_setglobalreg(sd,script->add_str(pc->sg_info[i].feel_var),sd->feel_map[i].index); //Are these really needed? Shouldn't they show up automatically from the feel save packet? // clif_misceffect2(&sd->bl, 0x1b0); @@ -14514,12 +14608,12 @@ void clif_parse_Check(int fd, struct map_session_data *sd) char charname[NAME_LENGTH]; struct map_session_data* pl_sd; - if(!pc->has_permission(sd, PC_PERM_USE_CHECK)) + if(!pc_has_permission(sd, PC_PERM_USE_CHECK)) return; safestrncpy(charname, (const char*)RFIFOP(fd,packet_db[RFIFOW(fd,0)].pos[0]), sizeof(charname)); - if( ( pl_sd = map->nick2sd(charname) ) == NULL || pc->get_group_level(sd) < pc->get_group_level(pl_sd) ) { + if( ( pl_sd = map->nick2sd(charname) ) == NULL || pc_get_group_level(sd) < pc_get_group_level(pl_sd) ) { return; } @@ -14669,7 +14763,7 @@ void clif_Mail_refreshinbox(struct map_session_data *sd) if( md->full ) {// TODO: is this official? char output[100]; sprintf(output, "Inbox is full (Max %d). Delete some mails.", MAIL_MAX_INBOX); - clif->disp_onlyself(sd, output, strlen(output)); + clif_disp_onlyself(sd, output, strlen(output)); } } @@ -14707,7 +14801,7 @@ void clif_Mail_read(struct map_session_data *sd, int mail_id) struct mail_message *msg = &sd->mail.inbox.msg[i]; struct item *item = &msg->item; struct item_data *data; - int msg_len = strlen(msg->body), len; + size_t msg_len = strlen(msg->body), len; if( msg_len == 0 ) { strcpy(msg->body, "(no message)"); @@ -14801,6 +14895,11 @@ void clif_parse_Mail_getattach(int fd, struct map_session_data *sd) if ((data = itemdb->exists(sd->mail.inbox.msg[i].item.nameid)) == NULL) return; + if( pc_is90overweight(sd) ) { + clif->mail_getattachment(fd, 2); + return; + } + switch( pc->checkadditem(sd, data->nameid, sd->mail.inbox.msg[i].item.amount) ) { case ADDITEM_NEW: fail = ( pc->inventoryblank(sd) == 0 ); @@ -14987,6 +15086,9 @@ void clif_Auction_openwindow(struct map_session_data *sd) if( sd->state.storage_flag || sd->state.vending || sd->state.buyingstore || sd->state.trading ) return; + if( !battle_config.feature_auction ) + return; + WFIFOHEAD(fd,packet_len(0x25f)); WFIFOW(fd,0) = 0x25f; WFIFOL(fd,2) = 0; @@ -15076,6 +15178,9 @@ void clif_parse_Auction_setitem(int fd, struct map_session_data *sd) int amount = RFIFOL(fd,4); // Always 1 struct item_data *item; + if( !battle_config.feature_auction ) + return; + if( sd->auction.amount > 0 ) sd->auction.amount = 0; @@ -15095,10 +15200,11 @@ void clif_parse_Auction_setitem(int fd, struct map_session_data *sd) return; } - if( !pc->can_give_items(sd) || sd->status.inventory[idx].expire_time || + if( !pc_can_give_items(sd) || sd->status.inventory[idx].expire_time || !sd->status.inventory[idx].identify || - !itemdb_canauction(&sd->status.inventory[idx],pc->get_group_level(sd)) ) { // Quest Item or something else - clif->auction_setitem(sd->fd, idx, true); + !itemdb_canauction(&sd->status.inventory[idx],pc_get_group_level(sd)) || // Quest Item or something else + (sd->status.inventory[idx].bound && !pc_can_give_bound_items(sd)) ) { + clif->auction_setitem(sd->fd, idx, true); return; } @@ -15151,6 +15257,9 @@ void clif_parse_Auction_register(int fd, struct map_session_data *sd) struct auction_data auction; struct item_data *item; + if( !battle_config.feature_auction ) + return; + auction.price = RFIFOL(fd,2); auction.buynow = RFIFOL(fd,6); auction.hours = RFIFOW(fd,10); @@ -15171,9 +15280,8 @@ void clif_parse_Auction_register(int fd, struct map_session_data *sd) return; } - // Auction checks... if( sd->status.zeny < (auction.hours * battle_config.auction_feeperhour) ) { - clif->auction_message(fd, 5); // You do not have enough zeny to pay the Auction Fee. + clif_Auction_message(fd, 5); // You do not have enough zeny to pay the Auction Fee. return; } @@ -15202,6 +15310,13 @@ void clif_parse_Auction_register(int fd, struct map_session_data *sd) return; } + // Auction checks... + if( sd->status.inventory[sd->auction.index].bound && !pc_can_give_bound_items(sd) ) { + clif->message(sd->fd, msg_txt(293)); + clif->auction_message(fd, 2); // The auction has been canceled + return; + } + safestrncpy(auction.item_name, item->jname, sizeof(auction.item_name)); auction.type = item->type; memcpy(&auction.item, &sd->status.inventory[sd->auction.index], sizeof(struct item)); @@ -15249,7 +15364,7 @@ void clif_parse_Auction_bid(int fd, struct map_session_data *sd) unsigned int auction_id = RFIFOL(fd,2); int bid = RFIFOL(fd,6); - if( !pc->can_give_items(sd) ) { //They aren't supposed to give zeny [Inkfish] + if( !pc_can_give_items(sd) ) { //They aren't supposed to give zeny [Inkfish] clif->message(sd->fd, msg_txt(246)); return; } @@ -15282,6 +15397,9 @@ void clif_parse_Auction_search(int fd, struct map_session_data* sd) short type = RFIFOW(fd,2), page = RFIFOW(fd,32); int price = RFIFOL(fd,4); // FIXME: bug #5071 + if( !battle_config.feature_auction ) + return; + clif->pAuction_cancelreg(fd, sd); safestrncpy(search_text, (char*)RFIFOP(fd,8), sizeof(search_text)); @@ -15297,6 +15415,10 @@ void clif_parse_Auction_search(int fd, struct map_session_data* sd) void clif_parse_Auction_buysell(int fd, struct map_session_data* sd) { short type = RFIFOW(fd,2) + 6; + + if( !battle_config.feature_auction ) + return; + clif->pAuction_cancelreg(fd, sd); intif->Auction_requestlist(sd->status.char_id, type, 0, "", 1); @@ -15309,9 +15431,11 @@ void clif_parse_Auction_buysell(int fd, struct map_session_data* sd) /// List of items offered in a cash shop (ZC_PC_CASH_POINT_ITEMLIST). /// 0287 <packet len>.W <cash point>.L { <sell price>.L <discount price>.L <item type>.B <name id>.W }* /// 0287 <packet len>.W <cash point>.L <kafra point>.L { <sell price>.L <discount price>.L <item type>.B <name id>.W }* (PACKETVER >= 20070711) -void clif_cashshop_show(struct map_session_data *sd, struct npc_data *nd) -{ - int fd,i; +void clif_cashshop_show(struct map_session_data *sd, struct npc_data *nd) { + struct npc_item_list *shop = NULL; + unsigned short shop_size = 0; + int fd,i, c = 0; + int currency[2] = { 0,0 }; #if PACKETVER < 20070711 const int offset = 8; #else @@ -15321,23 +15445,43 @@ void clif_cashshop_show(struct map_session_data *sd, struct npc_data *nd) nullpo_retv(sd); nullpo_retv(nd); + if( nd->subtype == SCRIPT ) { + shop = nd->u.scr.shop->item; + shop_size = nd->u.scr.shop->items; + + npc->trader_count_funds(nd, sd); + + currency[0] = npc->trader_funds[0]; + currency[1] = npc->trader_funds[1]; + } else { + shop = nd->u.shop.shop_item; + shop_size = nd->u.shop.count; + + currency[0] = sd->cashPoints; + currency[1] = sd->kafraPoints; + } + fd = sd->fd; sd->npc_shopid = nd->bl.id; - WFIFOHEAD(fd,offset+nd->u.shop.count*11); + WFIFOHEAD(fd,offset+shop_size*11); WFIFOW(fd,0) = 0x287; - WFIFOW(fd,2) = offset+nd->u.shop.count*11; - WFIFOL(fd,4) = sd->cashPoints; // Cash Points + /* 0x2 = length, set after parsing */ + WFIFOL(fd,4) = currency[0]; // Cash Points #if PACKETVER >= 20070711 - WFIFOL(fd,8) = sd->kafraPoints; // Kafra Points + WFIFOL(fd,8) = currency[1]; // Kafra Points #endif - for( i = 0; i < nd->u.shop.count; i++ ) { - struct item_data* id = itemdb->search(nd->u.shop.shop_item[i].nameid); - WFIFOL(fd,offset+0+i*11) = nd->u.shop.shop_item[i].value; - WFIFOL(fd,offset+4+i*11) = nd->u.shop.shop_item[i].value; // Discount Price - WFIFOB(fd,offset+8+i*11) = itemtype(id->type); - WFIFOW(fd,offset+9+i*11) = ( id->view_id > 0 ) ? id->view_id : id->nameid; + for( i = 0; i < shop_size; i++ ) { + if( shop[i].nameid ) { + struct item_data* id = itemdb->search(shop[i].nameid); + WFIFOL(fd,offset+0+i*11) = shop[i].value; + WFIFOL(fd,offset+4+i*11) = shop[i].value; // Discount Price + WFIFOB(fd,offset+8+i*11) = itemtype(id->type); + WFIFOW(fd,offset+9+i*11) = ( id->view_id > 0 ) ? id->view_id : id->nameid; + c++; + } } + WFIFOW(fd,2) = offset+c*11; WFIFOSET(fd,WFIFOW(fd,2)); } @@ -15356,15 +15500,26 @@ void clif_cashshop_show(struct map_session_data *sd, struct npc_data *nd) /// 7 = You can purchase up to 10 items. /// 8 = Some items could not be purchased. void clif_cashshop_ack(struct map_session_data* sd, int error) { - int fd = sd->fd; + struct npc_data *nd; + int fd = sd->fd; + int currency[2] = { 0,0 }; + + if( (nd = map->id2nd(sd->npc_shopid)) && nd->subtype == SCRIPT ) { + npc->trader_count_funds(nd,sd); + currency[0] = npc->trader_funds[0]; + currency[1] = npc->trader_funds[1]; + } else { + currency[0] = sd->cashPoints; + currency[1] = sd->kafraPoints; + } WFIFOHEAD(fd, packet_len(0x289)); WFIFOW(fd,0) = 0x289; - WFIFOL(fd,2) = sd->cashPoints; + WFIFOL(fd,2) = currency[0]; #if PACKETVER < 20070711 WFIFOW(fd,6) = TOW(error); #else - WFIFOL(fd,6) = sd->kafraPoints; + WFIFOL(fd,6) = currency[1]; WFIFOW(fd,10) = TOW(error); #endif WFIFOSET(fd, packet_len(0x289)); @@ -15508,7 +15663,7 @@ void clif_bossmapinfo(int fd, struct mob_data *md, short flag) unsigned int seconds; int hours, minutes; - seconds = DIFF_TICK(timer_data->tick, timer->gettick()) / 1000 + 60; + seconds = (unsigned int)(DIFF_TICK(timer_data->tick, timer->gettick()) / 1000 + 60); hours = seconds / (60 * 60); seconds = seconds - (60 * 60 * hours); minutes = seconds / 60; @@ -15533,10 +15688,10 @@ void clif_parse_ViewPlayerEquip(int fd, struct map_session_data* sd) { if (!tsd) return; - if( tsd->status.show_equip || pc->has_permission(sd, PC_PERM_VIEW_EQUIPMENT) ) + if( tsd->status.show_equip || pc_has_permission(sd, PC_PERM_VIEW_EQUIPMENT) ) clif->viewequip_ack(sd, tsd); else - clif->viewequip_fail(sd); + clif_viewequip_fail(sd); } @@ -15570,8 +15725,7 @@ void clif_parse_PartyTick(int fd, struct map_session_data* sd) /// Sends list of all quest states (ZC_ALL_QUEST_LIST). /// 02b1 <packet len>.W <num>.L { <quest id>.L <active>.B }*num -void clif_quest_send_list(struct map_session_data * sd) -{ +void clif_quest_send_list(struct map_session_data *sd) { int fd = sd->fd; int i; int len = sd->avail_quests*5+8; @@ -15592,8 +15746,7 @@ void clif_quest_send_list(struct map_session_data * sd) /// Sends list of all quest missions (ZC_ALL_QUEST_MISSION). /// 02b2 <packet len>.W <num>.L { <quest id>.L <start time>.L <expire time>.L <mobs>.W { <mob id>.L <mob count>.W <mob name>.24B }*3 }*num -void clif_quest_send_mission(struct map_session_data * sd) -{ +void clif_quest_send_mission(struct map_session_data *sd) { int fd = sd->fd; int i, j; int len = sd->avail_quests*104+8; @@ -15605,17 +15758,17 @@ void clif_quest_send_mission(struct map_session_data * sd) WFIFOL(fd, 4) = sd->avail_quests; for( i = 0; i < sd->avail_quests; i++ ) { + struct quest_db *qi = quest->db(sd->quest_log[i].quest_id); WFIFOL(fd, i*104+8) = sd->quest_log[i].quest_id; - WFIFOL(fd, i*104+12) = sd->quest_log[i].time - quest->db[sd->quest_index[i]].time; + WFIFOL(fd, i*104+12) = sd->quest_log[i].time - qi->time; WFIFOL(fd, i*104+16) = sd->quest_log[i].time; - WFIFOW(fd, i*104+20) = quest->db[sd->quest_index[i]].num_objectives; + WFIFOW(fd, i*104+20) = qi->num_objectives; - for( j = 0 ; j < quest->db[sd->quest_index[i]].num_objectives; j++ ) - { - WFIFOL(fd, i*104+22+j*30) = quest->db[sd->quest_index[i]].mob[j]; + for( j = 0 ; j < qi->num_objectives; j++ ) { + WFIFOL(fd, i*104+22+j*30) = qi->mob[j]; WFIFOW(fd, i*104+26+j*30) = sd->quest_log[i].count[j]; - monster = mob->db(quest->db[sd->quest_index[i]].mob[j]); - memcpy(WFIFOP(fd, i*104+28+j*30), monster?monster->jname:"NULL", NAME_LENGTH); + monster = mob->db(qi->mob[j]); + memcpy(WFIFOP(fd, i*104+28+j*30), monster->jname, NAME_LENGTH); } } @@ -15625,25 +15778,25 @@ void clif_quest_send_mission(struct map_session_data * sd) /// Notification about a new quest (ZC_ADD_QUEST). /// 02b3 <quest id>.L <active>.B <start time>.L <expire time>.L <mobs>.W { <mob id>.L <mob count>.W <mob name>.24B }*3 -void clif_quest_add(struct map_session_data * sd, struct quest * qd, int index) -{ +void clif_quest_add(struct map_session_data *sd, struct quest *qd) { int fd = sd->fd; int i; struct mob_db *monster; + struct quest_db *qi = quest->db(qd->quest_id); WFIFOHEAD(fd, packet_len(0x2b3)); WFIFOW(fd, 0) = 0x2b3; WFIFOL(fd, 2) = qd->quest_id; WFIFOB(fd, 6) = qd->state; - WFIFOB(fd, 7) = qd->time - quest->db[index].time; + WFIFOB(fd, 7) = qd->time - qi->time; WFIFOL(fd, 11) = qd->time; - WFIFOW(fd, 15) = quest->db[index].num_objectives; + WFIFOW(fd, 15) = qi->num_objectives; - for( i = 0; i < quest->db[index].num_objectives; i++ ) { - WFIFOL(fd, i*30+17) = quest->db[index].mob[i]; + for( i = 0; i < qi->num_objectives; i++ ) { + WFIFOL(fd, i*30+17) = qi->mob[i]; WFIFOW(fd, i*30+21) = qd->count[i]; - monster = mob->db(quest->db[index].mob[i]); - memcpy(WFIFOP(fd, i*30+23), monster?monster->jname:"NULL", NAME_LENGTH); + monster = mob->db(qi->mob[i]); + memcpy(WFIFOP(fd, i*30+23), monster->jname, NAME_LENGTH); } WFIFOSET(fd, packet_len(0x2b3)); @@ -15652,8 +15805,7 @@ void clif_quest_add(struct map_session_data * sd, struct quest * qd, int index) /// Notification about a quest being removed (ZC_DEL_QUEST). /// 02b4 <quest id>.L -void clif_quest_delete(struct map_session_data * sd, int quest_id) -{ +void clif_quest_delete(struct map_session_data *sd, int quest_id) { int fd = sd->fd; WFIFOHEAD(fd, packet_len(0x2b4)); @@ -15665,21 +15817,21 @@ void clif_quest_delete(struct map_session_data * sd, int quest_id) /// Notification of an update to the hunting mission counter (ZC_UPDATE_MISSION_HUNT). /// 02b5 <packet len>.W <mobs>.W { <quest id>.L <mob id>.L <total count>.W <current count>.W }*3 -void clif_quest_update_objective(struct map_session_data * sd, struct quest * qd, int index) -{ +void clif_quest_update_objective(struct map_session_data *sd, struct quest *qd) { int fd = sd->fd; int i; - int len = quest->db[index].num_objectives*12+6; + struct quest_db *qi = quest->db(qd->quest_id); + int len = qi->num_objectives*12+6; WFIFOHEAD(fd, len); WFIFOW(fd, 0) = 0x2b5; WFIFOW(fd, 2) = len; - WFIFOW(fd, 4) = quest->db[index].num_objectives; + WFIFOW(fd, 4) = qi->num_objectives; - for( i = 0; i < quest->db[index].num_objectives; i++ ) { + for( i = 0; i < qi->num_objectives; i++ ) { WFIFOL(fd, i*12+6) = qd->quest_id; - WFIFOL(fd, i*12+10) = quest->db[index].mob[i]; - WFIFOW(fd, i*12+14) = quest->db[index].count[i]; + WFIFOL(fd, i*12+10) = qi->mob[i]; + WFIFOW(fd, i*12+14) = qi->count[i]; WFIFOW(fd, i*12+16) = qd->count[i]; } @@ -15689,16 +15841,14 @@ void clif_quest_update_objective(struct map_session_data * sd, struct quest * qd /// Request to change the state of a quest (CZ_ACTIVE_QUEST). /// 02b6 <quest id>.L <active>.B -void clif_parse_questStateAck(int fd, struct map_session_data * sd) -{ +void clif_parse_questStateAck(int fd, struct map_session_data *sd) { quest->update_status(sd, RFIFOL(fd,2), RFIFOB(fd,6)?Q_ACTIVE:Q_INACTIVE); } /// Notification about the change of a quest state (ZC_ACTIVE_QUEST). /// 02b7 <quest id>.L <active>.B -void clif_quest_update_status(struct map_session_data * sd, int quest_id, bool active) -{ +void clif_quest_update_status(struct map_session_data *sd, int quest_id, bool active) { int fd = sd->fd; WFIFOHEAD(fd, packet_len(0x2b7)); @@ -16010,7 +16160,7 @@ void clif_bg_xy_remove(struct map_session_data *sd) /// Notifies clients of a battleground message (ZC_BATTLEFIELD_CHAT). /// 02dc <packet len>.W <account id>.L <name>.24B <message>.?B -void clif_bg_message(struct battleground_data *bgd, int src_id, const char *name, const char *mes, int len) +void clif_bg_message(struct battleground_data *bgd, int src_id, const char *name, const char *mes, size_t len) { struct map_session_data *sd; unsigned char *buf; @@ -16039,15 +16189,15 @@ void clif_parse_BattleChat(int fd, struct map_session_data* sd) int textlen = RFIFOW(fd,2) - 4; char *name, *message; - int namelen, messagelen; + size_t namelen, messagelen; if( !clif->process_message(sd, 0, &name, &namelen, &message, &messagelen) ) return; - if( atcommand->parse(fd, sd, message, 1) ) + if( atcommand->exec(fd, sd, message, true) ) return; - if( sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEP_SLEEP] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) ) + if( sd->sc.data[SC_BERSERK] || (sd->sc.data[SC_DEEP_SLEEP] && sd->sc.data[SC_DEEP_SLEEP]->val2) || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) ) return; if( battle_config.min_chat_delay ) { @@ -16056,6 +16206,9 @@ void clif_parse_BattleChat(int fd, struct map_session_data* sd) sd->cantalk_tick = timer->gettick() + battle_config.min_chat_delay; } + if( battle_config.idletime_criteria & BCIDLE_CHAT ) + sd->idletime = sockt->last_tick; + bg->send_message(sd, text, textlen); } @@ -16124,7 +16277,7 @@ void clif_font(struct map_session_data *sd) nullpo_retv(sd); WBUFW(buf,0) = 0x2ef; WBUFL(buf,2) = sd->bl.id; - WBUFW(buf,6) = sd->user_font; + WBUFW(buf,6) = sd->status.font; clif->send(buf, packet_len(0x2ef), &sd->bl, AREA); #endif } @@ -16137,7 +16290,7 @@ int clif_instance(int instance_id, int type, int flag) { struct map_session_data *sd = NULL; unsigned char buf[255]; enum send_target target = PARTY; - + switch( instance->list[instance_id].owner_type ) { case IOT_NONE: return 0; @@ -16157,7 +16310,7 @@ int clif_instance(int instance_id, int type, int flag) { if( !sd ) return 0; - + switch( type ) { case 1: // S 0x2cb <Instance name>.61B <Standby Position>.W @@ -16914,7 +17067,7 @@ void clif_parse_debug(int fd,struct map_session_data *sd) { } ShowDebug("Packet debug of 0x%04X (length %d), %s session #%d, %d/%d (AID/CID)\n", cmd, packet_len, sd->state.active ? "authed" : "unauthed", fd, sd->status.account_id, sd->status.char_id); } else { - packet_len = RFIFOREST(fd); + packet_len = (int)RFIFOREST(fd); ShowDebug("Packet debug of 0x%04X (length %d), session #%d\n", cmd, packet_len, fd); } @@ -16956,15 +17109,15 @@ int clif_elementalconverter_list(struct map_session_data *sd) { /** * Rune Knight **/ -void clif_millenniumshield(struct map_session_data *sd, short shields ) { +void clif_millenniumshield(struct block_list *bl, short shields ) { #if PACKETVER >= 20081217 unsigned char buf[10]; WBUFW(buf,0) = 0x440; - WBUFL(buf,2) = sd->bl.id; + WBUFL(buf,2) = bl->id; WBUFW(buf,6) = shields; WBUFW(buf,8) = 0; - clif->send(buf,packet_len(0x440),&sd->bl,AREA); + clif->send(buf,packet_len(0x440),bl,AREA); #endif } /** @@ -17226,82 +17379,68 @@ void clif_parse_MoveItem(int fd, struct map_session_data *sd) { /* [Ind/Hercules] */ void clif_cashshop_db(void) { config_t cashshop_conf; - config_setting_t *cashshop = NULL; + config_setting_t *cashshop = NULL, *cats = NULL; const char *config_filename = "db/cashshop_db.conf"; // FIXME hardcoded name - int i; + int i, item_count_t = 0; for( i = 0; i < CASHSHOP_TAB_MAX; i++ ) { CREATE(clif->cs.data[i], struct hCSData *, 1); clif->cs.item_count[i] = 0; } - - if (conf_read_file(&cashshop_conf, config_filename)) { + + if (libconfig->read_file(&cashshop_conf, config_filename)) { ShowError("can't read %s\n", config_filename); return; } - - cashshop = config_lookup(&cashshop_conf, "cash_shop"); - - if (cashshop != NULL) { - config_setting_t *cats = config_setting_get_elem(cashshop, 0); - config_setting_t *cat; - int k, item_count_t = 0; - + + cashshop = libconfig->lookup(&cashshop_conf, "cash_shop"); + + if( cashshop != NULL && (cats = libconfig->setting_get_elem(cashshop, 0)) != NULL ) { for(i = 0; i < CASHSHOP_TAB_MAX; i++) { + config_setting_t *cat; char entry_name[10]; - + sprintf(entry_name,"cat_%d",i); - - if( (cat = config_setting_get_member(cats, entry_name)) != NULL ) { - int item_count = config_setting_length(cat); - - if( item_count == 0 ) { - ShowWarning("cashshop_db: category '%s' is empty! adding dull apple!\n", entry_name); - RECREATE(clif->cs.data[i], struct hCSData *, ++clif->cs.item_count[i]); - CREATE(clif->cs.data[i][ clif->cs.item_count[i] - 1 ], struct hCSData , 1); - - clif->cs.data[i][ clif->cs.item_count[i] - 1 ]->id = UNKNOWN_ITEM_ID; - clif->cs.data[i][ clif->cs.item_count[i] - 1 ]->price = 999; - } else { - for(k = 0; k < item_count; k++) { - config_setting_t *entry = config_setting_get_elem(cat,k); - const char *name = config_setting_name(entry); - int price = config_setting_get_int(entry); - struct item_data * data = NULL; - - if( price < 1 ) { - ShowWarning("cashshop_db: unsupported price '%d' for entry named '%s' in category '%s'\n", price, name, entry_name); + + if( (cat = libconfig->setting_get_member(cats, entry_name)) != NULL ) { + int k, item_count = libconfig->setting_length(cat); + + for(k = 0; k < item_count; k++) { + config_setting_t *entry = libconfig->setting_get_elem(cat,k); + const char *name = config_setting_name(entry); + int price = libconfig->setting_get_int(entry); + struct item_data * data = NULL; + + if( price < 1 ) { + ShowWarning("cashshop_db: unsupported price '%d' for entry named '%s' in category '%s'\n", price, name, entry_name); + continue; + } + + if( name[0] == 'I' && name[1] == 'D' && strlen(name) <= 7 ) { + if( !( data = itemdb->exists(atoi(name+2))) ) { + ShowWarning("cashshop_db: unknown item id '%s' in category '%s'\n", name+2, entry_name); continue; } - - if( name[0] == 'I' && name[1] == 'D' && strlen(name) <= 7 ) { - if( !( data = itemdb->exists(atoi(name+2))) ) { - ShowWarning("cashshop_db: unknown item id '%s' in category '%s'\n", name+2, entry_name); - continue; - } - } else { - if( !( data = itemdb->search_name(name) ) ) { - ShowWarning("cashshop_db: unknown item name '%s' in category '%s'\n", name, entry_name); - continue; - } + } else { + if( !( data = itemdb->search_name(name) ) ) { + ShowWarning("cashshop_db: unknown item name '%s' in category '%s'\n", name, entry_name); + continue; } - - - RECREATE(clif->cs.data[i], struct hCSData *, ++clif->cs.item_count[i]); - CREATE(clif->cs.data[i][ clif->cs.item_count[i] - 1 ], struct hCSData , 1); - - clif->cs.data[i][ clif->cs.item_count[i] - 1 ]->id = data->nameid; - clif->cs.data[i][ clif->cs.item_count[i] - 1 ]->price = price; - item_count_t++; } + + + RECREATE(clif->cs.data[i], struct hCSData *, ++clif->cs.item_count[i]); + CREATE(clif->cs.data[i][ clif->cs.item_count[i] - 1 ], struct hCSData , 1); + + clif->cs.data[i][ clif->cs.item_count[i] - 1 ]->id = data->nameid; + clif->cs.data[i][ clif->cs.item_count[i] - 1 ]->price = price; + item_count_t++; } - } else { - ShowError("cashshop_db: category '%s' (%d) not found!!\n",entry_name,i); } } - - ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", item_count_t, config_filename); - config_destroy(&cashshop_conf); + + libconfig->destroy(&cashshop_conf); } + ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", item_count_t, config_filename); } /// Items that are in favorite tab of inventory (ZC_ITEM_FAVORITE). /// 0900 <index>.W <favorite>.B @@ -17328,12 +17467,12 @@ void clif_snap( struct block_list *bl, short x, short y ) { void clif_monster_hp_bar( struct mob_data* md, struct map_session_data *sd ) { struct packet_monster_hp p; - + p.PacketType = monsterhpType; p.GID = md->bl.id; p.HP = md->status.hp; p.MaxHP = md->status.max_hp; - + clif->send(&p,sizeof(p),&sd->bl,SELF); } /* [Ind/Hercules] placeholder for unsupported incoming packets (avoids server disconnecting client) */ @@ -17341,6 +17480,12 @@ void __attribute__ ((unused)) clif_parse_dull(int fd,struct map_session_data *sd return; } void clif_parse_CashShopOpen(int fd, struct map_session_data *sd) { + + if( map->list[sd->bl.m].flag.nocashshop ) { + clif->colormes(fd,COLOR_RED,msg_txt(1489)); //Cash Shop is disabled in this map + return; + } + WFIFOHEAD(fd, 10); WFIFOW(fd, 0) = 0x845; WFIFOL(fd, 2) = sd->cashPoints; //[Ryuuzaki] - switched positions to reflect proper values @@ -17354,19 +17499,22 @@ void clif_parse_CashShopClose(int fd, struct map_session_data *sd) { void clif_parse_CashShopSchedule(int fd, struct map_session_data *sd) { int i, j = 0; - + for( i = 0; i < CASHSHOP_TAB_MAX; i++ ) { + if( clif->cs.item_count[i] == 0 ) + continue; // Skip empty tabs, the client only expects filled ones + WFIFOHEAD(fd, 8 + ( clif->cs.item_count[i] * 6 ) ); WFIFOW(fd, 0) = 0x8ca; WFIFOW(fd, 2) = 8 + ( clif->cs.item_count[i] * 6 ); WFIFOW(fd, 4) = clif->cs.item_count[i]; WFIFOW(fd, 6) = i; - + for( j = 0; j < clif->cs.item_count[i]; j++ ) { WFIFOW(fd, 8 + ( 6 * j ) ) = clif->cs.data[i][j]->id; WFIFOL(fd, 10 + ( 6 * j ) ) = clif->cs.data[i][j]->price; } - + WFIFOSET(fd, 8 + ( clif->cs.item_count[i] * 6 )); } } @@ -17374,15 +17522,20 @@ void clif_parse_CashShopBuy(int fd, struct map_session_data *sd) { unsigned short limit = RFIFOW(fd, 4), i, j; unsigned int kafra_pay = RFIFOL(fd, 6);// [Ryuuzaki] - These are free cash points (strangely #CASH = main cash curreny for us, confusing) + if( map->list[sd->bl.m].flag.nocashshop ) { + clif->colormes(fd,COLOR_RED,msg_txt(1489)); //Cash Shop is disabled in this map + return; + } + for(i = 0; i < limit; i++) { int qty = RFIFOL(fd, 14 + ( i * 10 )); int id = RFIFOL(fd, 10 + ( i * 10 )); short tab = RFIFOW(fd, 18 + ( i * 10 )); enum CASH_SHOP_BUY_RESULT result = CSBR_UNKNOWN; - + if( tab < 0 || tab > CASHSHOP_TAB_MAX ) continue; - + for( j = 0; j < clif->cs.item_count[tab]; j++ ) { if( clif->cs.data[tab][j]->id == id ) break; @@ -17398,19 +17551,19 @@ void clif_parse_CashShopBuy(int fd, struct map_session_data *sd) { } else { struct item item_tmp; int k, get_count; - + get_count = qty; - + if (!itemdb->isstackable2(data)) get_count = 1; - + pc->paycash(sd, clif->cs.data[tab][j]->price * qty, kafra_pay);// [Ryuuzaki] for (k = 0; k < qty; k += get_count) { if (!pet->create_egg(sd, data->nameid)) { memset(&item_tmp, 0, sizeof(item_tmp)); item_tmp.nameid = data->nameid; item_tmp.identify = 1; - + switch (pc->additem(sd, &item_tmp, get_count, LOG_TYPE_NPC)) { case 0: result = CSBR_SUCCESS; @@ -17431,16 +17584,17 @@ void clif_parse_CashShopBuy(int fd, struct map_session_data *sd) { result = CSBR_RUNE_OVERCOUNT; break; } - + if( result != CSBR_SUCCESS ) pc->getcash(sd, clif->cs.data[tab][j]->price * get_count,0); - } + } else /* create_egg succeeded so mark as success */ + result = CSBR_SUCCESS; } } } else { result = CSBR_UNKONWN_ITEM; } - + WFIFOHEAD(fd, 16); WFIFOW(fd, 0) = 0x849; WFIFOL(fd, 2) = id; @@ -17456,7 +17610,7 @@ void clif_parse_CashShopReqTab(int fd, struct map_session_data *sd) { short tab = RFIFOW(fd, 2); int j; - if( tab < 0 || tab > CASHSHOP_TAB_MAX ) + if( tab < 0 || tab > CASHSHOP_TAB_MAX || clif->cs.item_count[tab] == 0 ) return; WFIFOHEAD(fd, 10 + ( clif->cs.item_count[tab] * 6 ) ); @@ -17464,19 +17618,19 @@ void clif_parse_CashShopReqTab(int fd, struct map_session_data *sd) { WFIFOW(fd, 2) = 10 + ( clif->cs.item_count[tab] * 6 ); WFIFOL(fd, 4) = tab; WFIFOW(fd, 8) = clif->cs.item_count[tab]; - + for( j = 0; j < clif->cs.item_count[tab]; j++ ) { WFIFOW(fd, 10 + ( 6 * j ) ) = clif->cs.data[tab][j]->id; WFIFOL(fd, 12 + ( 6 * j ) ) = clif->cs.data[tab][j]->price; } - + WFIFOSET(fd, 10 + ( clif->cs.item_count[tab] * 6 )); } /* [Ind/Hercules] */ void clif_maptypeproperty2(struct block_list *bl,enum send_target t) { #if PACKETVER >= 20121010 struct packet_maptypeproperty2 p; - + p.PacketType = maptypeproperty2Type; p.type = 0x28; p.flag.party = map->list[bl->m].flag.pvp ? 1 : 0; @@ -17491,14 +17645,14 @@ void clif_maptypeproperty2(struct block_list *bl,enum send_target t) { p.flag.summonstarmiracle = 0; // TODO p.flag.usecart = 1; // TODO p.flag.SpareBits = 0; - + clif->send(&p,sizeof(p),bl,t); #endif } void clif_status_change2(struct block_list *bl, int tid, enum send_target target, int type, int val1, int val2, int val3) { struct packet_status_change2 p; - + p.PacketType = status_change2Type; p.index = type; p.AID = tid; @@ -17507,29 +17661,51 @@ void clif_status_change2(struct block_list *bl, int tid, enum send_target target p.val1 = val1; p.val2 = val2; p.val3 = val3; - + clif->send(&p,sizeof(p), bl, target); } void clif_partytickack(struct map_session_data* sd, bool flag) { - + WFIFOHEAD(sd->fd, packet_len(0x2c9)); WFIFOW(sd->fd, 0) = 0x2c9; WFIFOB(sd->fd, 2) = flag; WFIFOSET(sd->fd, packet_len(0x2c9)); } +void clif_ShowScript(struct block_list* bl, const char* message) { + char buf[256]; + size_t len; + nullpo_retv(bl); + + if(!message) + return; + + len = strlen(message)+1; + + if( len > sizeof(buf)-8 ) { + ShowWarning("clif_ShowScript: Truncating too long message '%s' (len=%d).\n", message, len); + len = sizeof(buf)-8; + } + + WBUFW(buf,0)=0x8b3; + WBUFW(buf,2)=len+8; + WBUFL(buf,4)=bl->id; + safestrncpy((char *) WBUFP(buf,8),message,len); + clif->send((unsigned char *) buf,WBUFW(buf,2),bl,ALL_CLIENT); +} + void clif_status_change_end(struct block_list *bl, int tid, enum send_target target, int type) { struct packet_status_change_end p; - + if( bl->type == BL_PC && !((TBL_PC*)bl)->state.active ) return; - + p.PacketType = status_change_endType; p.index = type; p.AID = tid; p.state = 0; - + clif->send(&p,sizeof(p), bl, target); } @@ -17541,11 +17717,11 @@ void clif_bgqueue_ack(struct map_session_data *sd, enum BATTLEGROUNDS_QUEUE_ACK break; default: { struct packet_bgqueue_ack p; - + p.PacketType = bgqueue_ackType; p.type = response; safestrncpy(p.bg_name, bg->arena[arena_id]->name, sizeof(p.bg_name)); - + clif->send(&p,sizeof(p), &sd->bl, SELF); } break; @@ -17555,11 +17731,11 @@ void clif_bgqueue_ack(struct map_session_data *sd, enum BATTLEGROUNDS_QUEUE_ACK void clif_bgqueue_notice_delete(struct map_session_data *sd, enum BATTLEGROUNDS_QUEUE_NOTICE_DELETED response, char *name) { struct packet_bgqueue_notice_delete p; - + p.PacketType = bgqueue_notice_deleteType; p.type = response; safestrncpy(p.bg_name, name, sizeof(p.bg_name)); - + clif->send(&p,sizeof(p), &sd->bl, SELF); } @@ -17567,14 +17743,12 @@ void clif_parse_bgqueue_register(int fd, struct map_session_data *sd) { struct packet_bgqueue_register *p = P2PTR(fd); struct bg_arena *arena = NULL; if( !bg->queue_on ) return; /* temp, until feature is complete */ - + if( !(arena = bg->name2arena(p->bg_name)) ) { clif->bgqueue_ack(sd,BGQA_FAIL_BGNAME_INVALID,0); return; } - //debug - safestrncpy(arena->name, p->bg_name, sizeof(arena->name)); - + switch( (enum bg_queue_types)p->type ) { case BGQT_INDIVIDUAL: case BGQT_PARTY: @@ -17584,19 +17758,19 @@ void clif_parse_bgqueue_register(int fd, struct map_session_data *sd) { clif->bgqueue_ack(sd,BGQA_FAIL_TYPE_INVALID, arena->id); return; } - + bg->queue_add(sd, arena, (enum bg_queue_types)p->type); } void clif_bgqueue_update_info(struct map_session_data *sd, unsigned char arena_id, int position) { struct packet_bgqueue_update_info p; - + p.PacketType = bgqueue_updateinfoType; safestrncpy(p.bg_name, bg->arena[arena_id]->name, sizeof(p.bg_name)); p.position = position; - + sd->bg_queue.client_has_bg_data = true; // Client creates bg data when this packet arrives - + clif->send(&p,sizeof(p), &sd->bl, SELF); } @@ -17623,7 +17797,7 @@ void clif_parse_bgqueue_battlebegin_ack(int fd, struct map_session_data *sd) { struct bg_arena *arena; if( !bg->queue_on ) return; /* temp, until feature is complete */ - + if( ( arena = bg->name2arena(p->bg_name) ) ) { bg->queue_ready_ack(arena,sd, ( p->result == 1 ) ? true : false); } else { @@ -17633,7 +17807,7 @@ void clif_parse_bgqueue_battlebegin_ack(int fd, struct map_session_data *sd) { void clif_bgqueue_joined(struct map_session_data *sd, int pos) { struct packet_bgqueue_notify_entry p; - + p.PacketType = bgqueue_notify_entryType; safestrncpy(p.name,sd->status.name,sizeof(p.name)); p.position = pos; @@ -17649,26 +17823,26 @@ void clif_bgqueue_pcleft(struct map_session_data *sd) { // Sends BG ready req to all with same bg arena/type as sd void clif_bgqueue_battlebegins(struct map_session_data *sd, unsigned char arena_id, enum send_target target) { struct packet_bgqueue_battlebegins p; - - p.PacketType = bgqueue_battlebegins; + + p.PacketType = bgqueue_battlebeginsType; safestrncpy(p.bg_name, bg->arena[arena_id]->name, sizeof(p.bg_name)); safestrncpy(p.game_name, bg->arena[arena_id]->name, sizeof(p.game_name)); - + clif->send(&p,sizeof(p), &sd->bl, target); } void clif_scriptclear(struct map_session_data *sd, int npcid) { struct packet_script_clear p; - + p.PacketType = script_clearType; p.NpcID = npcid; - + clif->send(&p,sizeof(p), &sd->bl, SELF); } /* Made Possible Thanks to Yommy! */ void clif_package_item_announce(struct map_session_data *sd, unsigned short nameid, unsigned short containerid) { struct packet_package_item_announce p; - + p.PacketType = package_item_announceType; p.PacketLength = 11+NAME_LENGTH; p.type = 0x0; @@ -17677,7 +17851,22 @@ void clif_package_item_announce(struct map_session_data *sd, unsigned short name safestrncpy(p.Name, sd->status.name, sizeof(p.Name)); p.unknown = 0x2; // some strange byte, IDA shows.. BYTE3(BoxItemIDLength) = 2; p.BoxItemID = containerid; - + + clif->send(&p,sizeof(p), &sd->bl, ALL_CLIENT); +} +/* Made Possible Thanks to Yommy! */ +void clif_item_drop_announce(struct map_session_data *sd, unsigned short nameid, char *monsterName) { + struct packet_item_drop_announce p; + + p.PacketType = item_drop_announceType; + p.PacketLength = sizeof(p); + p.type = 0x1; + p.ItemID = nameid; + p.len = NAME_LENGTH; + safestrncpy(p.Name, sd->status.name, sizeof(p.Name)); + p.monsterNameLen = NAME_LENGTH; + safestrncpy(p.monsterName, monsterName, sizeof(p.monsterName)); + clif->send(&p,sizeof(p), &sd->bl, ALL_CLIENT); } /* [Ind/Hercules] special thanks to Yommy~! */ @@ -17688,7 +17877,7 @@ void clif_skill_cooldown_list(int fd, struct skill_cd* cd) { const int offset = 6; #endif int i, count = 0; - + WFIFOHEAD(fd,4+(offset*cd->cursor)); #if PACKETVER >= 20120604 @@ -17696,19 +17885,20 @@ void clif_skill_cooldown_list(int fd, struct skill_cd* cd) { #else WFIFOW(fd,0) = 0x43e; #endif - + for( i = 0; i < cd->cursor; i++ ) { if( cd->entry[i]->duration < 1 ) continue; - - WFIFOW(fd, 4 + (count*offset)) = cd->entry[i]->skill_id; - WFIFOL(fd, 6 + (count*offset)) = cd->entry[i]->duration; + + WFIFOW(fd, 4 + (count*offset)) = cd->entry[i]->skill_id; #if PACKETVER >= 20120604 + WFIFOL(fd, 6 + (count*offset)) = cd->entry[i]->total; WFIFOL(fd, 10 + (count*offset)) = cd->entry[i]->duration; +#else + WFIFOL(fd, 6 + (count*offset)) = cd->entry[i]->duration; #endif - count++; } - + WFIFOW(fd,2) = 4+(offset*count); WFIFOSET(fd,4+(offset*count)); @@ -17719,12 +17909,278 @@ void clif_skill_cooldown_list(int fd, struct skill_cd* cd) { */ void clif_cart_additem_ack(struct map_session_data *sd, int flag) { struct packet_cart_additem_ack p; - + p.PacketType = cart_additem_ackType; p.result = (char)flag; - + + clif->send(&p,sizeof(p), &sd->bl, SELF); +} +/* Bank System [Yommy/Hercules] */ +void clif_parse_BankDeposit(int fd, struct map_session_data* sd) { + struct packet_banking_deposit_req *p = P2PTR(fd); + int money; + + if( !battle_config.feature_banking ) { + clif->colormes(fd,COLOR_RED,msg_txt(1483)); + return; + } + + money = (int)cap_value(p->Money,0,INT_MAX); + + pc->bank_deposit(sd,money); +} + +void clif_parse_BankWithdraw(int fd, struct map_session_data* sd) { + struct packet_banking_withdraw_req *p = P2PTR(fd); + int money; + + if( !battle_config.feature_banking ) { + clif->colormes(fd,COLOR_RED,msg_txt(1483)); + return; + } + + money = (int)cap_value(p->Money,0,INT_MAX); + + pc->bank_withdraw(sd,money); +} + +void clif_parse_BankCheck(int fd, struct map_session_data* sd) { + struct packet_banking_check p; + + if( !battle_config.feature_banking ) { + clif->colormes(fd,COLOR_RED,msg_txt(1483)); + return; + } + + p.PacketType = banking_checkType; + p.Money = (int)sd->status.bank_vault; + p.Reason = (short)0; + + clif->send(&p,sizeof(p), &sd->bl, SELF); +} + +void clif_parse_BankOpen(int fd, struct map_session_data* sd) { + return; +} + +void clif_parse_BankClose(int fd, struct map_session_data* sd) { + return; +} + +void clif_bank_deposit(struct map_session_data *sd, enum e_BANKING_DEPOSIT_ACK reason) { + struct packet_banking_deposit_ack p; + + p.PacketType = banking_deposit_ackType; + p.Balance = sd->status.zeny;/* how much zeny char has after operation */ + p.Money = (int64)sd->status.bank_vault;/* money in the bank */ + p.Reason = (short)reason; + + clif->send(&p,sizeof(p), &sd->bl, SELF); +} +void clif_bank_withdraw(struct map_session_data *sd,enum e_BANKING_WITHDRAW_ACK reason) { + struct packet_banking_withdraw_ack p; + + p.PacketType = banking_withdraw_ackType; + p.Balance = sd->status.zeny;/* how much zeny char has after operation */ + p.Money = (int64)sd->status.bank_vault;/* money in the bank */ + p.Reason = (short)reason; + + clif->send(&p,sizeof(p), &sd->bl, SELF); +} +/* TODO: official response packet (tried 0x8cb/0x97b but the display was quite screwed up.) */ +/* currently mimicing */ +void clif_show_modifiers (struct map_session_data *sd) { + + if( sd->status.mod_exp != 100 || sd->status.mod_drop != 100 || sd->status.mod_death != 100 ) { + char output[128]; + + snprintf(output,128,"Base EXP : %d%% | Base Drop: %d%% | Base Death Penalty: %d%%", + sd->status.mod_exp,sd->status.mod_drop,sd->status.mod_death); + clif->broadcast2(&sd->bl,output, strlen(output) + 1, 0xffbc90, 0x190, 12, 0, 0, SELF); + } + +} + +void clif_notify_bounditem(struct map_session_data *sd, unsigned short index) { + struct packet_notify_bounditem p; + + p.PacketType = notify_bounditemType; + p.index = index+2; + clif->send(&p,sizeof(p), &sd->bl, SELF); } + +/** + * Parses the (GM) right click option 'remove all equipment' + **/ +void clif_parse_GMFullStrip(int fd, struct map_session_data *sd) { + struct map_session_data *tsd = map->id2sd(RFIFOL(fd,2)); + int i; + + /* TODO maybe this could be a new permission? using gm level in the meantime */ + if( !tsd || pc_get_group_level(tsd) >= pc_get_group_level(sd) ) + return; + + for( i = 0; i < EQI_MAX; i++ ) { + if( tsd->equip_index[ i ] >= 0 ) + pc->unequipitem( tsd , tsd->equip_index[ i ] , 2 ); + } +} +/** + * clif_delay_damage timer, sends the stored data and clears the memory afterwards + **/ +int clif_delay_damage_sub(int tid, int64 tick, int id, intptr_t data) { + struct cdelayed_damage *dd = (struct cdelayed_damage *)data; + + clif->send(&dd->p,sizeof(struct packet_damage),&dd->bl,AREA_WOS); + + ers_free(clif->delayed_damage_ers,dd); + + return 0; +} +/** + * Delays sending a damage packet in order to avoid the visual display to overlap + * + * @param tick when to trigger the timer (e.g. timer->gettick() + 500) + * @param src block_list pointer of the src + * @param dst block_list pointer of the damage source + * @param sdelay attack motion usually status_get_amotion() + * @param ddelay damage motion usually status_get_dmotion() + * @param in_damage total damage to be sent + * @param div amount of hits + * @param type action type + * + * @return clif->calc_walkdelay used in further processing + **/ +int clif_delay_damage(int64 tick, struct block_list *src, struct block_list *dst, int sdelay, int ddelay, int64 in_damage, short div, unsigned char type) { + struct cdelayed_damage *dd; + struct status_change *sc; +#if PACKETVER < 20071113 + short damage; +#else + int damage; +#endif + + nullpo_ret(src); + nullpo_ret(dst); + + sc = status->get_sc(dst); + + if(sc && sc->count && sc->data[SC_ILLUSION]) { + if(in_damage) in_damage = in_damage*(sc->data[SC_ILLUSION]->val2) + rnd()%100; + } + +#if PACKETVER < 20071113 + damage = (short)min(in_damage,INT16_MAX); +#else + damage = (int)min(in_damage,INT_MAX); +#endif + + type = clif_calc_delay(type,div,damage,ddelay); + + dd = ers_alloc(clif->delayed_damage_ers, struct cdelayed_damage); + + dd->p.PacketType = damageType; + dd->p.GID = src->id; + dd->p.targetGID = dst->id; + dd->p.startTime = (uint32)timer->gettick(); + dd->p.attackMT = sdelay; + dd->p.attackedMT = ddelay; + dd->p.count = div; + dd->p.action = type; + dd->p.leftDamage = 0; + + if( battle_config.hide_woe_damage && map_flag_gvg2(src->m) ) + dd->p.damage = damage?div:0; + else + dd->p.damage = damage; + + dd->bl.m = dst->m; + dd->bl.x = dst->x; + dd->bl.y = dst->y; + dd->bl.type = BL_NUL; + + if( tick > timer->gettick() ) + timer->add(tick,clif->delay_damage_sub,0,(intptr_t)dd); + else { + clif->send(&dd->p,sizeof(struct packet_damage),&dd->bl,AREA_WOS); + + ers_free(clif->delayed_damage_ers,dd); + } + + return clif->calc_walkdelay(dst,ddelay,type,damage,div); +} +/* Thanks to Yommy */ +void clif_parse_NPCShopClosed(int fd, struct map_session_data *sd) { + /* TODO track the state <3~ */ + sd->npc_shopid = 0; +} +/* NPC Market (by Ind after an extensive debugging of the packet, only possible thanks to Yommy <3) */ +void clif_npc_market_open(struct map_session_data *sd, struct npc_data *nd) { + struct npc_item_list *shop = nd->u.scr.shop->item; + unsigned short shop_size = nd->u.scr.shop->items, i, c; + struct item_data *id = NULL; + + npcmarket_open.PacketType = npcmarketopenType; + + for(i = 0, c = 0; i < shop_size; i++) { + if( shop[i].nameid && (id = itemdb->exists(shop[i].nameid)) ) { + npcmarket_open.list[c].nameid = shop[i].nameid; + npcmarket_open.list[c].price = shop[i].value; + npcmarket_open.list[c].qty = shop[i].qty; + npcmarket_open.list[c].type = itemtype(id->type); + npcmarket_open.list[c].view = ( id->view_id > 0 ) ? id->view_id : id->nameid; + c++; + } + } + + npcmarket_open.PacketLength = 4 + ( sizeof(npcmarket_open.list[0]) * c ); + + clif->send(&npcmarket_open,npcmarket_open.PacketLength,&sd->bl,SELF); +} +void clif_parse_NPCMarketClosed(int fd, struct map_session_data *sd) { + /* TODO track the state <3~ */ + sd->npc_shopid = 0; +} +void clif_npc_market_purchase_ack(struct map_session_data *sd, struct packet_npc_market_purchase *req, unsigned char response) { + unsigned short c = 0; + + npcmarket_result.PacketType = npcmarketresultackType; + npcmarket_result.result = response == 0 ? 1 : 0;/* find other values */ + + if( npcmarket_result.result ) { + unsigned short i, list_size = (req->PacketLength - 4) / sizeof(req->list[0]), j; + struct npc_data* nd; + struct npc_item_list *shop = NULL; + unsigned short shop_size = 0; + + nd = map->id2nd(sd->npc_shopid); + + shop = nd->u.scr.shop->item; + shop_size = nd->u.scr.shop->items; + + for(i = 0; i < list_size; i++) { + + npcmarket_result.list[i].ITID = req->list[i].ITID; + npcmarket_result.list[i].qty = req->list[i].qty; + + ARR_FIND( 0, shop_size, j, req->list[i].ITID == shop[j].nameid ); + + npcmarket_result.list[i].price = (j != shop_size) ? shop[j].value : 0; + + c++; + } + } + + npcmarket_result.PacketLength = 5 + ( sizeof(npcmarket_result.list[0]) * c );; + + clif->send(&npcmarket_result,npcmarket_result.PacketLength,&sd->bl,SELF); +} +void clif_parse_NPCMarketPurchase(int fd, struct map_session_data *sd) { + struct packet_npc_market_purchase *p = P2PTR(fd); + + clif->npc_market_purchase_ack(sd,p,npc->market_buylist(sd,(p->PacketLength - 4) / sizeof(p->list[0]),p)); +} /* */ unsigned short clif_decrypt_cmd( int cmd, struct map_session_data *sd ) { if( sd ) { @@ -17735,10 +18191,6 @@ unsigned short clif_decrypt_cmd( int cmd, struct map_session_data *sd ) { unsigned short clif_parse_cmd_normal( int fd, struct map_session_data *sd ) { unsigned short cmd = RFIFOW(fd,0); - // filter out invalid / unsupported packets - if( cmd > MAX_PACKET_DB || cmd < MIN_PACKET_DB || packet_db[cmd].len == 0 ) - return 0; - return cmd; } unsigned short clif_parse_cmd_decrypt( int fd, struct map_session_data *sd ) { @@ -17746,10 +18198,6 @@ unsigned short clif_parse_cmd_decrypt( int fd, struct map_session_data *sd ) { cmd = clif->decrypt_cmd(cmd, sd); - // filter out invalid / unsupported packets - if( cmd > MAX_PACKET_DB || cmd < MIN_PACKET_DB || packet_db[cmd].len == 0 ) - return 0; - return cmd; } unsigned short clif_parse_cmd_optional( int fd, struct map_session_data *sd ) { @@ -17774,14 +18222,14 @@ int clif_parse(int fd) { int cmd, packet_len; TBL_PC* sd; int pnum; - + //TODO apply delays or disconnect based on packet throughput [FlavioJS] // Note: "click masters" can do 80+ clicks in 10 seconds - + for( pnum = 0; pnum < 3; ++pnum ) { // Limit max packets per cycle to 3 (delay packet spammers) [FlavioJS] -- This actually aids packet spammers, but stuff like /str+ gets slow without it [Ai4rei] unsigned short (*parse_cmd_func)(int fd, struct map_session_data *sd); // begin main client packet processing loop - + sd = (TBL_PC *)session[fd]->session_data; if (session[fd]->flag.eof) { @@ -17807,7 +18255,7 @@ int clif_parse(int fd) { do_close(fd); return 0; } - + if (RFIFOREST(fd) < 2) return 0; @@ -17818,13 +18266,16 @@ int clif_parse(int fd) { if( r == 2 ) return 0; } } - + if( sd ) parse_cmd_func = sd->parse_cmd_func; else parse_cmd_func = clif->parse_cmd; - if( !( cmd = parse_cmd_func(fd,sd) ) ) { + cmd = parse_cmd_func(fd,sd); + + // filter out invalid / unsupported packets + if( cmd > MAX_PACKET_DB || cmd < MIN_PACKET_DB || packet_db[cmd].len == 0 ) { ShowWarning("clif_parse: Received unsupported packet (packet 0x%04x (0x%04x), %d bytes received), disconnecting session #%d.\n", cmd, RFIFOW(fd,0), RFIFOREST(fd), fd); #ifdef DUMP_INVALID_PACKET ShowDump(RFIFOP(fd,0), RFIFOREST(fd)); @@ -17832,13 +18283,13 @@ int clif_parse(int fd) { set_eof(fd); return 0; } - + // determine real packet length if ( ( packet_len = packet_db[cmd].len ) == -1) { // variable-length packet if (RFIFOREST(fd) < 4) return 0; - + packet_len = RFIFOW(fd,2); if (packet_len < 4 || packet_len > 32768) { ShowWarning("clif_parse: Received packet 0x%04x specifies invalid packet_len (%d), disconnecting session #%d.\n", cmd, packet_len, fd); @@ -17876,36 +18327,36 @@ int clif_parse(int fd) { else { const char* packet_txt = "save/packet.txt"; FILE* fp; - + if( ( fp = fopen( packet_txt , "a" ) ) != NULL ) { if( sd ) { fprintf(fp, "Unknown packet 0x%04X (length %d), %s session #%d, %d/%d (AID/CID)\n", cmd, packet_len, sd->state.active ? "authed" : "unauthed", fd, sd->status.account_id, sd->status.char_id); } else { fprintf(fp, "Unknown packet 0x%04X (length %d), session #%d\n", cmd, packet_len, fd); } - + WriteDump(fp, RFIFOP(fd,0), packet_len); fprintf(fp, "\n"); fclose(fp); } else { ShowError("Failed to write '%s'.\n", packet_txt); - + // Dump on console instead if( sd ) { ShowDebug("Unknown packet 0x%04X (length %d), %s session #%d, %d/%d (AID/CID)\n", cmd, packet_len, sd->state.active ? "authed" : "unauthed", fd, sd->status.account_id, sd->status.char_id); } else { ShowDebug("Unknown packet 0x%04X (length %d), session #%d\n", cmd, packet_len, fd); } - + ShowDump(RFIFOP(fd,0), packet_len); } } #endif - + RFIFOSKIP(fd, packet_len); - + }; // main loop end - + return 0; } @@ -17914,43 +18365,44 @@ static void __attribute__ ((unused)) packetdb_addpacket(short cmd, int len, ...) int i; int pos; pFunc func; - + if (cmd > MAX_PACKET_DB) { ShowError("Packet Error: packet 0x%x is greater than the maximum allowed (0x%x), skipping...\n", cmd, MAX_PACKET_DB); return; } - + packet_db[cmd].len = len; - + va_start(va,len); - + pos = va_arg(va, int); - + if( pos == 0xFFFF ) /* nothing more to do */ return; - + va_end(va); va_start(va,len); - + func = va_arg(va,pFunc); - + packet_db[cmd].func = func; - + for (i = 0; i < MAX_PACKET_POS; i++) { pos = va_arg(va, int); - + if (pos == 0xFFFF) break; - + packet_db[cmd].pos[i] = pos; } + va_end(va); } void packetdb_loaddb(void) { - + memset(packet_db,0,sizeof(packet_db)); - #define packet(id, size, ...) packetdb_addpacket(id, size, ##__VA_ARGS__, 0xFFFF) - #define packetKeys(a,b,c) { clif->cryptKey[0] = a; clif->cryptKey[1] = b; clif->cryptKey[2] = c; } + #define packet(id, size, ...) packetdb_addpacket((id), (size), ##__VA_ARGS__, 0xFFFF) + #define packetKeys(a,b,c) do { clif->cryptKey[0] = (a); clif->cryptKey[1] = (b); clif->cryptKey[2] = (c); } while(0) #include "packets.h" /* load structure data */ #undef packet #undef packetKeys @@ -17960,7 +18412,7 @@ void clif_bc_ready(void) { clif->status_change = clif_status_change; else clif->status_change = clif_status_change_notick; - + switch( battle_config.packet_obfuscation ) { case 0: clif->parse_cmd = clif_parse_cmd_normal; @@ -17977,20 +18429,23 @@ void clif_bc_ready(void) { /*========================================== * *------------------------------------------*/ -int do_init_clif(void) { +int do_init_clif(bool minimal) { const char* colors[COLOR_MAX] = { "0xFF0000", "0x00ff00", "0xffffff" }; int i; + if (minimal) + return 0; + /** * Setup Color Table (saves unnecessary load of strtoul on every call) **/ for(i = 0; i < COLOR_MAX; i++) { - color_table[i] = strtoul(colors[i],NULL,0); + color_table[i] = (unsigned int)strtoul(colors[i],NULL,0); color_table[i] = (color_table[i] & 0x0000FF) << 16 | (color_table[i] & 0x00FF00) | (color_table[i] & 0xFF0000) >> 16;//RGB to BGR } - + packetdb_loaddb(); - + set_defaultparse(clif->parse); if( make_listen_bind(clif->bind_ip,clif->map_port) == -1 ) { ShowFatalError("Failed to bind to port '"CL_WHITE"%d"CL_RESET"'\n",clif->map_port); @@ -18001,11 +18456,12 @@ int do_init_clif(void) { timer->add_func_list(clif->delayquit, "clif_delayquit"); clif->delay_clearunit_ers = ers_new(sizeof(struct block_list),"clif.c::delay_clearunit_ers",ERS_OPT_CLEAR); + clif->delayed_damage_ers = ers_new(sizeof(struct cdelayed_damage),"clif.c::delayed_damage_ers",ERS_OPT_CLEAR); clif->channel_db = stridb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, HCHSYS_NAME_LENGTH); hChSys.ally = hChSys.local = hChSys.irc = hChSys.ally_autojoin = hChSys.local_autojoin = false; clif->chann_config_read(); - + return 0; } @@ -18013,17 +18469,17 @@ void do_final_clif(void) { DBIterator *iter = db_iterator(clif->channel_db); struct hChSysCh *channel; unsigned char i; - + for( channel = dbi_first(iter); dbi_exists(iter); channel = dbi_next(iter) ) { clif->chsys_delete(channel); } - + dbi_destroy(iter); - + for(i = 0; i < hChSys.colors_count; i++) { aFree(hChSys.colors_name[i]); } - + if( hChSys.colors_count ) { aFree(hChSys.colors_name); aFree(hChSys.colors); @@ -18031,7 +18487,8 @@ void do_final_clif(void) { db_destroy(clif->channel_db); ers_destroy(clif->delay_clearunit_ers); - + ers_destroy(clif->delayed_damage_ers); + for(i = 0; i < CASHSHOP_TAB_MAX; i++) { int k; for( k = 0; k < clif->cs.item_count[i]; k++ ) { @@ -18046,6 +18503,8 @@ void clif_defaults(void) { /* vars */ clif->bind_ip = INADDR_ANY; clif->map_port = 5121; + clif->ally_only = false; + clif->delayed_damage_ers = NULL; /* core */ clif->init = do_init_clif; clif->final = do_final_clif; @@ -18085,6 +18544,7 @@ void clif_defaults(void) { clif->cart_additem_ack = clif_cart_additem_ack; clif->cashshop_load = clif_cashshop_db; clif->package_announce = clif_package_item_announce; + clif->item_drop_announce = clif_item_drop_announce; /* unit-related */ clif->clearunit_single = clif_clearunit_single; clif->clearunit_area = clif_clearunit_area; @@ -18099,7 +18559,6 @@ void clif_defaults(void) { clif->changetraplook = clif_changetraplook; clif->refreshlook = clif_refreshlook; clif->class_change = clif_class_change; - clif->skill_setunit = clif_skill_setunit; clif->skill_delunit = clif_skill_delunit; clif->skillunit_update = clif_skillunit_update; clif->clearunit_delayed_sub = clif_clearunit_delayed_sub; @@ -18113,6 +18572,7 @@ void clif_defaults(void) { clif->getareachar_unit = clif_getareachar_unit; clif->clearchar_skillunit = clif_clearchar_skillunit; clif->getareachar = clif_getareachar; + clif->graffiti_entry = clif_graffiti_entry; /* main unit spawn */ clif->spawn = clif_spawn; /* map-related */ @@ -18204,7 +18664,6 @@ void clif_defaults(void) { clif->partytickack = clif_partytickack; clif->equiptickack = clif_equiptickack; clif->viewequip_ack = clif_viewequip_ack; - clif->viewequip_fail = clif_viewequip_fail; clif->equpcheckbox = clif_equpcheckbox; clif->displayexp = clif_displayexp; clif->font = clif_font; @@ -18287,7 +18746,6 @@ void clif_defaults(void) { clif->changechatstatus = clif_changechatstatus; clif->wis_message = clif_wis_message; clif->wis_end = clif_wis_end; - clif->disp_onlyself = clif_disp_onlyself; clif->disp_message = clif_disp_message; clif->broadcast = clif_broadcast; clif->broadcast2 = clif_broadcast2; @@ -18300,11 +18758,13 @@ void clif_defaults(void) { clif->msgtable_num = clif_msgtable_num; clif->message = clif_displaymessage; clif->messageln = clif_displaymessage2; + clif->messages = clif_displaymessage_sprintf; clif->colormes = clif_colormes; clif->process_message = clif_process_message; clif->wisexin = clif_wisexin; clif->wisall = clif_wisall; clif->PMIgnoreList = clif_PMIgnoreList; + clif->ShowScript = clif_ShowScript; /* trade handling */ clif->traderequest = clif_traderequest; clif->tradestart = clif_tradestart; @@ -18369,7 +18829,6 @@ void clif_defaults(void) { clif->guild_emblem_area = clif_guild_emblem_area; clif->guild_notice = clif_guild_notice; clif->guild_message = clif_guild_message; - clif->guild_skillup = clif_guild_skillup; clif->guild_reqalliance = clif_guild_reqalliance; clif->guild_allianceack = clif_guild_allianceack; clif->guild_delalliance = clif_guild_delalliance; @@ -18523,6 +18982,19 @@ void clif_defaults(void) { clif->chsys_quitg = clif_hercules_chsys_quitg; clif->chsys_gjoin = clif_hercules_chsys_gjoin; clif->chsys_gleave = clif_hercules_chsys_gleave; + /* Bank System [Yommy/Hercules] */ + clif->bank_deposit = clif_bank_deposit; + clif->bank_withdraw = clif_bank_withdraw; + /* */ + clif->show_modifiers = clif_show_modifiers; + /* */ + clif->notify_bounditem = clif_notify_bounditem; + /* */ + clif->delay_damage = clif_delay_damage; + clif->delay_damage_sub = clif_delay_damage_sub; + /* NPC Market */ + clif->npc_market_open = clif_npc_market_open; + clif->npc_market_purchase_ack = clif_npc_market_purchase_ack; /*------------------------ *- Parse Incoming Packet *------------------------*/ @@ -18665,6 +19137,7 @@ void clif_defaults(void) { clif->pGMRc = clif_parse_GMRc; clif->pGMReqAccountName = clif_parse_GMReqAccountName; clif->pGMChangeMapType = clif_parse_GMChangeMapType; + clif->pGMFullStrip = clif_parse_GMFullStrip; clif->pPMIgnore = clif_parse_PMIgnore; clif->pPMIgnoreAll = clif_parse_PMIgnoreAll; clif->pPMIgnoreList = clif_parse_PMIgnoreList; @@ -18745,4 +19218,15 @@ void clif_defaults(void) { clif->pPartyBookingReqVolunteer = clif_parse_PartyBookingReqVolunteer; clif->pPartyBookingRefuseVolunteer = clif_parse_PartyBookingRefuseVolunteer; clif->pPartyBookingCancelVolunteer = clif_parse_PartyBookingCancelVolunteer; + /* Bank System [Yommy/Hercules] */ + clif->pBankDeposit = clif_parse_BankDeposit; + clif->pBankWithdraw = clif_parse_BankWithdraw; + clif->pBankCheck = clif_parse_BankCheck; + clif->pBankOpen = clif_parse_BankOpen; + clif->pBankClose = clif_parse_BankClose; + /* */ + clif->pNPCShopClosed = clif_parse_NPCShopClosed; + /* NPC Market */ + clif->pNPCMarketClosed = clif_parse_NPCMarketClosed; + clif->pNPCMarketPurchase = clif_parse_NPCMarketPurchase; } diff --git a/src/map/clif.h b/src/map/clif.h index 1a2748353..36bd42718 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -2,13 +2,15 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _CLIF_H_ -#define _CLIF_H_ +#ifndef _MAP_CLIF_H_ +#define _MAP_CLIF_H_ #include "../common/cbasetypes.h" #include "../common/db.h" #include "../common/mmo.h" #include "../common/socket.h" +#include "../map/map.h" +#include "../map/packets_struct.h" #include <stdarg.h> /** @@ -45,7 +47,9 @@ struct skill_cd; **/ #define packet_len(cmd) packet_db[cmd].len #define P2PTR(fd) RFIFO2PTR(fd) -#define clif_menuskill_clear(sd) (sd)->menuskill_id = (sd)->menuskill_val = (sd)->menuskill_val2 = 0; +#define clif_menuskill_clear(sd) ((sd)->menuskill_id = (sd)->menuskill_val = (sd)->menuskill_val2 = 0) +#define clif_disp_onlyself(sd,mes,len) clif->disp_message( &(sd)->bl, (mes), (len), SELF ) +#define clif_viewequip_fail( sd ) clif_msg( (sd), 0x54d ); #define HCHSYS_NAME_LENGTH 20 /** @@ -340,6 +344,7 @@ typedef enum useskill_fail_cause { // clif_skill_fail }useskill_fail_cause; enum clif_messages { + ITEM_CANT_OBTAIN_WEIGHT = 0x34, /* you cannot carry more items because you are overweight. */ SKILL_CANT_USE_AREA = 0x536, ITEM_CANT_USE_AREA = 0x537, }; @@ -414,6 +419,50 @@ enum BATTLEGROUNDS_QUEUE_NOTICE_DELETED { BGQND_FAIL_NOT_QUEUING = 11, }; +enum e_BANKING_DEPOSIT_ACK { + BDA_SUCCESS = 0x0, + BDA_ERROR = 0x1, + BDA_NO_MONEY = 0x2, + BDA_OVERFLOW = 0x3, +}; +enum e_BANKING_WITHDRAW_ACK { + BWA_SUCCESS = 0x0, + BWA_NO_MONEY = 0x1, + BWA_UNKNOWN_ERROR = 0x2, +}; + +/* because the client devs were replaced by monkeys. */ +enum e_EQUIP_ITEM_ACK { +#if PACKETVER >= 20120925 + EIA_SUCCESS = 0x0, + EIA_FAIL_LV = 0x1, + EIA_FAIL = 0x2, +#else + EIA_SUCCESS = 0x1, + EIA_FAIL_LV = 0x2, + EIA_FAIL = 0x0, +#endif +}; + +/* and again. because the client devs were replaced by monkeys. */ +enum e_UNEQUIP_ITEM_ACK { +#if PACKETVER >= 20120925 + UIA_SUCCESS = 0x0, + UIA_FAIL = 0x1, +#else + UIA_SUCCESS = 0x1, + UIA_FAIL = 0x0, +#endif +}; + +enum e_trade_item_ok { + TIO_SUCCESS = 0x0, + TIO_OVERWEIGHT = 0x1, + TIO_CANCEL = 0x2, + /* feedback-friendly code that causes the client not to display a error message */ + TIO_INDROCKS = 0x9, +}; + /** * Structures **/ @@ -425,7 +474,7 @@ struct s_packet_db { }; struct { - unsigned long *colors; + unsigned int *colors; char **colors_name; unsigned char colors_count; bool local, ally, irc; @@ -461,11 +510,16 @@ struct hCSData { unsigned int price; }; +struct cdelayed_damage { + struct packet_damage p; + struct block_list bl; +}; + /** * Vars **/ struct s_packet_db packet_db[MAX_PACKET_DB + 1]; -unsigned long color_table[COLOR_MAX]; +unsigned int color_table[COLOR_MAX]; /** * Clif.c Interface @@ -487,14 +541,18 @@ struct clif_interface { } cs; /* */ unsigned int cryptKey[3]; + /* */ + bool ally_only; + /* */ + struct eri *delayed_damage_ers; /* core */ - int (*init) (void); + int (*init) (bool minimal); void (*final) (void); - int (*setip) (const char* ip); - void (*setbindip) (const char* ip); + bool (*setip) (const char* ip); + bool (*setbindip) (const char* ip); void (*setport) (uint16 port); uint32 (*refresh_ip) (void); - int (*send) (const void* buf, int len, struct block_list* bl, enum send_target type); + bool (*send) (const void* buf, int len, struct block_list* bl, enum send_target type); int (*send_sub) (struct block_list *bl, va_list ap); int (*parse) (int fd); unsigned short (*parse_cmd) ( int fd, struct map_session_data *sd ); @@ -516,8 +574,8 @@ struct clif_interface { void (*use_card) (struct map_session_data *sd,int idx); void (*cart_additem) (struct map_session_data *sd,int n,int amount,int fail); void (*cart_delitem) (struct map_session_data *sd,int n,int amount); - void (*equipitemack) (struct map_session_data *sd,int n,int pos,int ok); - void (*unequipitemack) (struct map_session_data *sd,int n,int pos,int ok); + void (*equipitemack) (struct map_session_data *sd,int n,int pos,enum e_EQUIP_ITEM_ACK result); + void (*unequipitemack) (struct map_session_data *sd,int n,int pos,enum e_UNEQUIP_ITEM_ACK result); void (*useitemack) (struct map_session_data *sd,int index,int amount,bool ok); void (*addcards) (unsigned char* buf, struct item* item); void (*addcards2) (unsigned short *cards, struct item* item); @@ -526,10 +584,11 @@ struct clif_interface { void (*cart_additem_ack) (struct map_session_data *sd, int flag); void (*cashshop_load) (void); void (*package_announce) (struct map_session_data *sd, unsigned short nameid, unsigned short containerid); + void (*item_drop_announce) (struct map_session_data *sd, unsigned short nameid, char *monsterName); /* unit-related */ void (*clearunit_single) (int id, clr_type type, int fd); void (*clearunit_area) (struct block_list* bl, clr_type type); - void (*clearunit_delayed) (struct block_list* bl, clr_type type, unsigned int tick); + void (*clearunit_delayed) (struct block_list* bl, clr_type type, int64 tick); void (*walkok) (struct map_session_data *sd); void (*move) (struct unit_data *ud); void (*move2) (struct block_list *bl, struct view_data *vd, struct unit_data *ud); @@ -540,22 +599,22 @@ struct clif_interface { void (*changetraplook) (struct block_list *bl,int val); void (*refreshlook) (struct block_list *bl,int id,int type,int val,enum send_target target); void (*class_change) (struct block_list *bl,int class_,int type); - void (*skill_setunit) (struct skill_unit *su); void (*skill_delunit) (struct skill_unit *su); void (*skillunit_update) (struct block_list* bl); - int (*clearunit_delayed_sub) (int tid, unsigned int tick, int id, intptr_t data); + int (*clearunit_delayed_sub) (int tid, int64 tick, int id, intptr_t data); void (*set_unit_idle) (struct block_list* bl, struct map_session_data *tsd,enum send_target target); void (*spawn_unit) (struct block_list* bl, enum send_target target); void (*spawn_unit2) (struct block_list* bl, enum send_target target); void (*set_unit_idle2) (struct block_list* bl, struct map_session_data *tsd, enum send_target target); void (*set_unit_walking) (struct block_list* bl, struct map_session_data *tsd,struct unit_data* ud, enum send_target target); int (*calc_walkdelay) (struct block_list *bl,int delay, int type, int damage, int div_); - void (*getareachar_skillunit) (struct map_session_data *sd, struct skill_unit *su); + void (*getareachar_skillunit) (struct block_list *bl, struct skill_unit *su, enum send_target target); void (*getareachar_unit) (struct map_session_data* sd,struct block_list *bl); void (*clearchar_skillunit) (struct skill_unit *su, int fd); int (*getareachar) (struct block_list* bl,va_list ap); + void (*graffiti_entry) (struct block_list *bl, struct skill_unit *su, enum send_target target); /* main unit spawn */ - int (*spawn) (struct block_list *bl); + bool (*spawn) (struct block_list *bl); /* map-related */ void (*changemap) (struct map_session_data *sd, short m, int x, int y); void (*changemapcell) (int fd, int16 m, int x, int y, int type, enum send_target target); @@ -587,7 +646,7 @@ struct clif_interface { void (*scriptclear) (struct map_session_data *sd, int npcid); /* client-user-interface-related */ void (*viewpoint) (struct map_session_data *sd, int npc_id, int type, int x, int y, int id, int color); - int (*damage) (struct block_list* src, struct block_list* dst, unsigned int tick, int sdelay, int ddelay, int64 damage, int div, int type, int64 damage2); + int (*damage) (struct block_list* src, struct block_list* dst, int sdelay, int ddelay, int64 damage, short div, unsigned char type, int64 damage2); void (*sitting) (struct block_list* bl); void (*standing) (struct block_list* bl); void (*arrow_create_list) (struct map_session_data *sd); @@ -603,7 +662,7 @@ struct clif_interface { int (*outsight) (struct block_list *bl,va_list ap); void (*skillcastcancel) (struct block_list* bl); void (*skill_fail) (struct map_session_data *sd,uint16 skill_id,enum useskill_fail_cause cause,int btype); - void (*skill_cooldown) (struct map_session_data *sd, uint16 skill_id, unsigned int tick); + void (*skill_cooldown) (struct map_session_data *sd, uint16 skill_id, unsigned int duration); void (*skill_memomessage) (struct map_session_data* sd, int type); void (*skill_mapinfomessage) (struct map_session_data *sd, int type); void (*skill_produce_mix_list) (struct map_session_data *sd, int skill_id, int trigger); @@ -645,11 +704,10 @@ struct clif_interface { void (*partytickack) (struct map_session_data* sd, bool flag); void (*equiptickack) (struct map_session_data* sd, int flag); void (*viewequip_ack) (struct map_session_data* sd, struct map_session_data* tsd); - void (*viewequip_fail) (struct map_session_data* sd); void (*equpcheckbox) (struct map_session_data* sd); void (*displayexp) (struct map_session_data *sd, unsigned int exp, char type, bool is_quest); void (*font) (struct map_session_data *sd); - void (*progressbar) (struct map_session_data * sd, unsigned long color, unsigned int second); + void (*progressbar) (struct map_session_data * sd, unsigned int color, unsigned int second); void (*progressbar_abort) (struct map_session_data * sd); void (*showdigit) (struct map_session_data* sd, unsigned char type, int value); int (*elementalconverter_list) (struct map_session_data *sd); @@ -669,7 +727,7 @@ struct clif_interface { void (*movetoattack) (struct map_session_data *sd,struct block_list *bl); void (*solved_charname) (int fd, int charid, const char* name); void (*charnameupdate) (struct map_session_data *ssd); - int (*delayquit) (int tid, unsigned int tick, int id, intptr_t data); + int (*delayquit) (int tid, int64 tick, int id, intptr_t data); void (*getareachar_pc) (struct map_session_data* sd,struct map_session_data* dstsd); void (*disconnect_ack) (struct map_session_data* sd, short result); void (*PVPInfo) (struct map_session_data* sd); @@ -687,9 +745,9 @@ struct clif_interface { void (*wedding_effect) (struct block_list *bl); void (*divorced) (struct map_session_data* sd, const char* name); void (*callpartner) (struct map_session_data *sd); - int (*skill_damage) (struct block_list *src,struct block_list *dst,unsigned int tick,int sdelay,int ddelay,int64 damage,int div,uint16 skill_id,uint16 skill_lv,int type); + int (*skill_damage) (struct block_list *src, struct block_list *dst, int64 tick, int sdelay, int ddelay, int64 damage, int div, uint16 skill_id, uint16 skill_lv, int type); int (*skill_nodamage) (struct block_list *src,struct block_list *dst,uint16 skill_id,int heal,int fail); - void (*skill_poseffect) (struct block_list *src,uint16 skill_id,int val,int x,int y,int tick); + void (*skill_poseffect) (struct block_list *src, uint16 skill_id, int val, int x, int y, int64 tick); void (*skill_estimation) (struct map_session_data *sd,struct block_list *dst); void (*skill_warppoint) (struct map_session_data* sd, uint16 skill_id, uint16 skill_lv, unsigned short map1, unsigned short map2, unsigned short map3, unsigned short map4); void (*skillcasting) (struct block_list* bl, int src_id, int dst_id, int dst_x, int dst_y, uint16 skill_id, int property, int casttime); @@ -706,7 +764,7 @@ struct clif_interface { void (*specialeffect) (struct block_list* bl, int type, enum send_target target); void (*specialeffect_single) (struct block_list* bl, int type, int fd); void (*specialeffect_value) (struct block_list* bl, int effect_id, int num, send_target target); - void (*millenniumshield) (struct map_session_data *sd, short shields ); + void (*millenniumshield) (struct block_list *bl, short shields ); void (*charm) (struct map_session_data *sd, short type); void (*charm_single) (int fd, struct map_session_data *sd, short type); void (*snap) ( struct block_list *bl, short x, short y ); @@ -726,13 +784,12 @@ struct clif_interface { void (*clearchat) (struct chat_data *cd,int fd); void (*leavechat) (struct chat_data* cd, struct map_session_data* sd, bool flag); void (*changechatstatus) (struct chat_data* cd); - void (*wis_message) (int fd, const char* nick, const char* mes, int mes_len); + void (*wis_message) (int fd, const char* nick, const char* mes, size_t mes_len); void (*wis_end) (int fd, int flag); - void (*disp_onlyself) (struct map_session_data *sd, const char *mes, int len); - void (*disp_message) (struct block_list* src, const char* mes, int len, enum send_target target); - void (*broadcast) (struct block_list* bl, const char* mes, int len, int type, enum send_target target); - void (*broadcast2) (struct block_list* bl, const char* mes, int len, unsigned long fontColor, short fontType, short fontSize, short fontAlign, short fontY, enum send_target target); - void (*messagecolor) (struct block_list* bl, unsigned long color, const char* msg); + void (*disp_message) (struct block_list* src, const char* mes, size_t len, enum send_target target); + void (*broadcast) (struct block_list* bl, const char* mes, size_t len, int type, enum send_target target); + void (*broadcast2) (struct block_list* bl, const char* mes, size_t len, unsigned int fontColor, short fontType, short fontSize, short fontAlign, short fontY, enum send_target target); + void (*messagecolor) (struct block_list* bl, unsigned int color, const char* msg); void (*disp_overhead) (struct block_list *bl, const char* mes); void (*msg) (struct map_session_data* sd, unsigned short id); void (*msg_value) (struct map_session_data* sd, unsigned short id, int value); @@ -741,11 +798,14 @@ struct clif_interface { void (*msgtable_num) (int fd, int line, int num); void (*message) (const int fd, const char* mes); void (*messageln) (const int fd, const char* mes); + /* message+s(printf) */ + void (*messages) (const int fd, const char* mes, ...); int (*colormes) (int fd, enum clif_colors color, const char* msg); - bool (*process_message) (struct map_session_data* sd, int format, char** name_, int* namelen_, char** message_, int* messagelen_); + bool (*process_message) (struct map_session_data *sd, int format, char **name_, size_t *namelen_, char **message_, size_t *messagelen_); void (*wisexin) (struct map_session_data *sd,int type,int flag); void (*wisall) (struct map_session_data *sd,int type,int flag); void (*PMIgnoreList) (struct map_session_data* sd); + void (*ShowScript) (struct block_list* bl, const char* message); /* trade handling */ void (*traderequest) (struct map_session_data* sd, const char* name); void (*tradestart) (struct map_session_data* sd, uint8 type); @@ -771,7 +831,7 @@ struct clif_interface { void (*storageclose) (struct map_session_data* sd); /* skill-list handling */ void (*skillinfoblock) (struct map_session_data *sd); - void (*skillup) (struct map_session_data *sd,uint16 skill_id); + void (*skillup) (struct map_session_data *sd, uint16 skill_id, int skill_lv, int flag); void (*skillinfo) (struct map_session_data *sd,int skill_id, int inf); void (*addskill) (struct map_session_data *sd, int id); void (*deleteskill) (struct map_session_data *sd, int id); @@ -810,7 +870,6 @@ struct clif_interface { void (*guild_emblem_area) (struct block_list* bl); void (*guild_notice) (struct map_session_data* sd, struct guild* g); void (*guild_message) (struct guild *g,int account_id,const char *mes,int len); - int (*guild_skillup) (struct map_session_data *sd,uint16 skill_id,int lv); void (*guild_reqalliance) (struct map_session_data *sd,int account_id,const char *name); void (*guild_allianceack) (struct map_session_data *sd,int flag); void (*guild_delalliance) (struct map_session_data *sd,int guild_id,int flag); @@ -827,7 +886,7 @@ struct clif_interface { void (*bg_hp) (struct map_session_data *sd); void (*bg_xy) (struct map_session_data *sd); void (*bg_xy_remove) (struct map_session_data *sd); - void (*bg_message) (struct battleground_data *bgd, int src_id, const char *name, const char *mes, int len); + void (*bg_message) (struct battleground_data *bgd, int src_id, const char *name, const char *mes, size_t len); void (*bg_updatescore) (int16 m); void (*bg_updatescore_single) (struct map_session_data *sd); void (*sendbgemblem_area) (struct map_session_data *sd); @@ -859,17 +918,17 @@ struct clif_interface { void (*check) (int fd, struct map_session_data* pl_sd); /* hom-related */ void (*hominfo) (struct map_session_data *sd, struct homun_data *hd, int flag); - int (*homskillinfoblock) (struct map_session_data *sd); + void (*homskillinfoblock) (struct map_session_data *sd); void (*homskillup) (struct map_session_data *sd, uint16 skill_id); - int (*hom_food) (struct map_session_data *sd,int foodid,int fail); + void (*hom_food) (struct map_session_data *sd,int foodid,int fail); void (*send_homdata) (struct map_session_data *sd, int state, int param); /* questlog-related */ - void (*quest_send_list) (struct map_session_data * sd); - void (*quest_send_mission) (struct map_session_data * sd); - void (*quest_add) (struct map_session_data * sd, struct quest * qd, int index); - void (*quest_delete) (struct map_session_data * sd, int quest_id); - void (*quest_update_status) (struct map_session_data * sd, int quest_id, bool active); - void (*quest_update_objective) (struct map_session_data * sd, struct quest * qd, int index); + void (*quest_send_list) (struct map_session_data *sd); + void (*quest_send_mission) (struct map_session_data *sd); + void (*quest_add) (struct map_session_data *sd, struct quest *qd); + void (*quest_delete) (struct map_session_data *sd, int quest_id); + void (*quest_update_status) (struct map_session_data *sd, int quest_id, bool active); + void (*quest_update_objective) (struct map_session_data *sd, struct quest *qd); void (*quest_show_event) (struct map_session_data *sd, struct block_list *bl, short state, short color); /* mail-related */ void (*mail_window) (int fd, int flag); @@ -910,7 +969,7 @@ struct clif_interface { void (*PartyRecruitInsertNotify) (struct map_session_data* sd, struct party_booking_ad_info* pb_ad); /* Group Search System Update */ void (*PartyBookingVolunteerInfo) (int index, struct map_session_data *sd); - void (*PartyBookingRefuseVolunteer) (unsigned long aid, struct map_session_data *sd); + void (*PartyBookingRefuseVolunteer) (unsigned int aid, struct map_session_data *sd); void (*PartyBookingCancelVolunteer) (int index, struct map_session_data *sd); void (*PartyBookingAddFilteringList) (int index, struct map_session_data *sd); void (*PartyBookingSubFilteringList) (int gid, struct map_session_data *sd); @@ -946,11 +1005,11 @@ struct clif_interface { void (*adopt_reply) (struct map_session_data *sd, int type); void (*adopt_request) (struct map_session_data *sd, struct map_session_data *src, int p_id); void (*readbook) (int fd, int book_id, int page); - void (*notify_time) (struct map_session_data* sd, unsigned long time); + void (*notify_time) (struct map_session_data* sd, int64 time); void (*user_count) (struct map_session_data* sd, int count); void (*noask_sub) (struct map_session_data *src, struct map_session_data *target, int type); void (*bc_ready) (void); - int (*undisguise_timer) (int tid, unsigned int tick, int id, intptr_t data); + int (*undisguise_timer) (int tid, int64 tick, int id, intptr_t data); /* Hercules Channel System */ void (*chsys_create) (struct hChSysCh *channel, char *name, char *pass, unsigned char color); void (*chsys_msg) (struct hChSysCh *channel, struct map_session_data *sd, char *msg); @@ -964,6 +1023,19 @@ struct clif_interface { void (*chsys_quitg) (struct map_session_data *sd); void (*chsys_gjoin) (struct guild *g1,struct guild *g2); void (*chsys_gleave) (struct guild *g1,struct guild *g2); + /* Bank System [Yommy/Hercules] */ + void (*bank_deposit) (struct map_session_data *sd, enum e_BANKING_DEPOSIT_ACK reason); + void (*bank_withdraw) (struct map_session_data *sd,enum e_BANKING_WITHDRAW_ACK reason); + /* */ + void (*show_modifiers) (struct map_session_data *sd); + /* */ + void (*notify_bounditem) (struct map_session_data *sd, unsigned short index); + /* */ + int (*delay_damage) (int64 tick, struct block_list *src, struct block_list *dst, int sdelay, int ddelay, int64 in_damage, short div, unsigned char type); + int (*delay_damage_sub) (int tid, int64 tick, int id, intptr_t data); + /* NPC Market */ + void (*npc_market_open) (struct map_session_data *sd, struct npc_data *nd); + void (*npc_market_purchase_ack) (struct map_session_data *sd, struct packet_npc_market_purchase *req, unsigned char response); /*------------------------ *- Parse Incoming Packet *------------------------*/ @@ -981,7 +1053,7 @@ struct clif_interface { void (*pEmotion) (int fd, struct map_session_data *sd); void (*pHowManyConnections) (int fd, struct map_session_data *sd); void (*pActionRequest) (int fd, struct map_session_data *sd); - void (*pActionRequest_sub) (struct map_session_data *sd, int action_type, int target_id, unsigned int tick); + void (*pActionRequest_sub) (struct map_session_data *sd, int action_type, int target_id, int64 tick); void (*pRestart) (int fd, struct map_session_data *sd); void (*pWisMessage) (int fd, struct map_session_data* sd); void (*pBroadcast) (int fd, struct map_session_data* sd); @@ -1015,12 +1087,12 @@ struct clif_interface { void (*pStatusUp) (int fd,struct map_session_data *sd); void (*pSkillUp) (int fd,struct map_session_data *sd); void (*pUseSkillToId) (int fd, struct map_session_data *sd); - void (*pUseSkillToId_homun) (struct homun_data *hd, struct map_session_data *sd, unsigned int tick, uint16 skill_id, uint16 skill_lv, int target_id); - void (*pUseSkillToId_mercenary) (struct mercenary_data *md, struct map_session_data *sd, unsigned int tick, uint16 skill_id, uint16 skill_lv, int target_id); + void (*pUseSkillToId_homun) (struct homun_data *hd, struct map_session_data *sd, int64 tick, uint16 skill_id, uint16 skill_lv, int target_id); + void (*pUseSkillToId_mercenary) (struct mercenary_data *md, struct map_session_data *sd, int64 tick, uint16 skill_id, uint16 skill_lv, int target_id); void (*pUseSkillToPos) (int fd, struct map_session_data *sd); void (*pUseSkillToPosSub) (int fd, struct map_session_data *sd, uint16 skill_lv, uint16 skill_id, short x, short y, int skillmoreinfo); - void (*pUseSkillToPos_homun) (struct homun_data *hd, struct map_session_data *sd, unsigned int tick, uint16 skill_id, uint16 skill_lv, short x, short y, int skillmoreinfo); - void (*pUseSkillToPos_mercenary) (struct mercenary_data *md, struct map_session_data *sd, unsigned int tick, uint16 skill_id, uint16 skill_lv, short x, short y, int skillmoreinfo); + void (*pUseSkillToPos_homun) (struct homun_data *hd, struct map_session_data *sd, int64 tick, uint16 skill_id, uint16 skill_lv, short x, short y, int skillmoreinfo); + void (*pUseSkillToPos_mercenary) (struct mercenary_data *md, struct map_session_data *sd, int64 tick, uint16 skill_id, uint16 skill_lv, short x, short y, int skillmoreinfo); void (*pUseSkillToPosMoreInfo) (int fd, struct map_session_data *sd); void (*pUseSkillMap) (int fd, struct map_session_data* sd); void (*pRequestMemo) (int fd,struct map_session_data *sd); @@ -1106,6 +1178,7 @@ struct clif_interface { void (*pGMRc) (int fd, struct map_session_data* sd); void (*pGMReqAccountName) (int fd, struct map_session_data *sd); void (*pGMChangeMapType) (int fd, struct map_session_data *sd); + void (*pGMFullStrip) (int fd, struct map_session_data *sd); void (*pPMIgnore) (int fd, struct map_session_data* sd); void (*pPMIgnoreAll) (int fd, struct map_session_data *sd); void (*pPMIgnoreList) (int fd,struct map_session_data *sd); @@ -1184,10 +1257,21 @@ struct clif_interface { void (*pPartyBookingReqVolunteer) (int fd, struct map_session_data *sd); void (*pPartyBookingRefuseVolunteer) (int fd, struct map_session_data *sd); void (*pPartyBookingCancelVolunteer) (int fd, struct map_session_data *sd); + /* Bank System [Yommy/Hercules] */ + void (*pBankDeposit) (int fd, struct map_session_data *sd); + void (*pBankWithdraw) (int fd, struct map_session_data *sd); + void (*pBankCheck) (int fd, struct map_session_data *sd); + void (*pBankOpen) (int fd, struct map_session_data *sd); + void (*pBankClose) (int fd, struct map_session_data *sd); + /* */ + void (*pNPCShopClosed) (int fd, struct map_session_data *sd); + /* NPC Market (by Ind after an extensive debugging of the packet, only possible thanks to Yommy <3) */ + void (*pNPCMarketClosed) (int fd, struct map_session_data *sd); + void (*pNPCMarketPurchase) (int fd, struct map_session_data *sd); }; struct clif_interface *clif; void clif_defaults(void); -#endif /* _CLIF_H_ */ +#endif /* _MAP_CLIF_H_ */ diff --git a/src/map/date.c b/src/map/date.c index 9f2bc4bee..f38ead858 100644 --- a/src/map/date.c +++ b/src/map/date.c @@ -1,6 +1,7 @@ // Copyright (c) Athena Dev Teams - Licensed under GNU GPL // For more information, see LICENCE in the main folder +#include "../common/cbasetypes.h" #include "date.h" #include <time.h> @@ -55,17 +56,21 @@ int date_get_sec(void) return lt->tm_sec; } -int is_day_of_sun(void) +/*========================================== + * Star gladiator related checks + *------------------------------------------*/ + +bool is_day_of_sun(void) { return date_get_day()%2 == 0; } -int is_day_of_moon(void) +bool is_day_of_moon(void) { return date_get_day()%2 == 1; } -int is_day_of_star(void) +bool is_day_of_star(void) { return date_get_day()%5 == 0; } diff --git a/src/map/date.h b/src/map/date.h index cc19d88d1..46f0d86c3 100644 --- a/src/map/date.h +++ b/src/map/date.h @@ -1,8 +1,8 @@ // Copyright (c) Athena Dev Teams - Licensed under GNU GPL // For more information, see LICENCE in the main folder -#ifndef _DATE_H_ -#define _DATE_H_ +#ifndef _MAP_DATE_H_ +#define _MAP_DATE_H_ int date_get_year(void); int date_get_month(void); @@ -11,8 +11,8 @@ int date_get_hour(void); int date_get_min(void); int date_get_sec(void); -int is_day_of_sun(void); -int is_day_of_moon(void); -int is_day_of_star(void); +bool is_day_of_sun(void); +bool is_day_of_moon(void); +bool is_day_of_star(void); -#endif /* _DATE_H_ */ +#endif /* _MAP_DATE_H_ */ diff --git a/src/map/duel.c b/src/map/duel.c index 4e41865d4..af2741f77 100644 --- a/src/map/duel.c +++ b/src/map/duel.c @@ -24,7 +24,7 @@ void duel_savetime(struct map_session_data* sd) { time(&clock); t = localtime(&clock); - pc_setglobalreg(sd, "PC_LAST_DUEL_TIME", t->tm_mday*24*60 + t->tm_hour*60 + t->tm_min); + pc_setglobalreg(sd, script->add_str("PC_LAST_DUEL_TIME"), t->tm_mday*24*60 + t->tm_hour*60 + t->tm_min); } int duel_checktime(struct map_session_data* sd) { @@ -35,7 +35,7 @@ int duel_checktime(struct map_session_data* sd) { time(&clock); t = localtime(&clock); - diff = t->tm_mday*24*60 + t->tm_hour*60 + t->tm_min - pc_readglobalreg(sd, "PC_LAST_DUEL_TIME"); + diff = t->tm_mday*24*60 + t->tm_hour*60 + t->tm_min - pc_readglobalreg(sd, script->add_str("PC_LAST_DUEL_TIME") ); return !(diff >= 0 && diff < battle_config.duel_time_interval); } @@ -48,7 +48,7 @@ static int duel_showinfo_sub(struct map_session_data* sd, va_list va) if (sd->duel_group != ssd->duel_group) return 0; sprintf(output, " %d. %s", ++(*p), sd->status.name); - clif->disp_onlyself(ssd, output, strlen(output)); + clif_disp_onlyself(ssd, output, strlen(output)); return 1; } @@ -68,7 +68,7 @@ void duel_showinfo(const unsigned int did, struct map_session_data* sd) { duel->list[did].members_count, duel->list[did].members_count + duel->list[did].invites_count); - clif->disp_onlyself(sd, output, strlen(output)); + clif_disp_onlyself(sd, output, strlen(output)); map->foreachpc(duel_showinfo_sub, sd, &p); } @@ -86,7 +86,7 @@ int duel_create(struct map_session_data* sd, const unsigned int maxpl) { duel->list[i].max_players_limit = maxpl; strcpy(output, msg_txt(372)); // " -- Duel has been created (@invite/@leave) --" - clif->disp_onlyself(sd, output, strlen(output)); + clif_disp_onlyself(sd, output, strlen(output)); clif->map_property(sd, MAPPROPERTY_FREEPVPZONE); clif->maptypeproperty2(&sd->bl,SELF); @@ -166,7 +166,10 @@ void duel_reject(const unsigned int did, struct map_session_data* sd) { void do_final_duel(void) { } -void do_init_duel(void) { +void do_init_duel(bool minimal) { + if (minimal) + return; + memset(&duel->list[0], 0, sizeof(duel->list)); } diff --git a/src/map/duel.h b/src/map/duel.h index d1ec58415..5405d2eee 100644 --- a/src/map/duel.h +++ b/src/map/duel.h @@ -2,8 +2,8 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _DUEL_H_ -#define _DUEL_H_ +#ifndef _MAP_DUEL_H_ +#define _MAP_DUEL_H_ struct duel { int members_count; @@ -34,7 +34,7 @@ struct duel_interface { void (*showinfo) (const unsigned int did, struct map_session_data* sd); int (*checktime) (struct map_session_data* sd); - void (*init) (void); + void (*init) (bool minimal); void (*final) (void); } duel_s; @@ -42,4 +42,4 @@ struct duel_interface *duel; void duel_defaults(void); -#endif /* _DUEL_H_ */ +#endif /* _MAP_DUEL_H_ */ diff --git a/src/map/elemental.c b/src/map/elemental.c index 3251ca992..f335600d6 100644 --- a/src/map/elemental.c +++ b/src/map/elemental.c @@ -148,7 +148,7 @@ int elemental_get_lifetime(struct elemental_data *ed) { return 0; td = timer->get(ed->summon_timer); - return (td != NULL) ? DIFF_TICK(td->tick, timer->gettick()) : 0; + return (td != NULL) ? DIFF_TICK32(td->tick, timer->gettick()) : 0; } int elemental_save(struct elemental_data *ed) { @@ -169,7 +169,7 @@ int elemental_save(struct elemental_data *ed) { return 1; } -int elemental_summon_end_timer(int tid, unsigned int tick, int id, intptr_t data) { +int elemental_summon_end_timer(int tid, int64 tick, int id, intptr_t data) { struct map_session_data *sd; struct elemental_data *ed; @@ -258,7 +258,7 @@ int elemental_data_received(struct s_elemental *ele, bool flag) { ed->bl.y = ed->ud.to_y; map->addiddb(&ed->bl); - status_calc_elemental(ed,1); + status_calc_elemental(ed,SCO_FIRST); ed->last_spdrain_time = ed->last_thinktime = timer->gettick(); ed->summon_timer = INVALID_TIMER; elemental->summon_init(ed); @@ -388,7 +388,7 @@ int elemental_clean_effect(struct elemental_data *ed) { return 1; } -int elemental_action(struct elemental_data *ed, struct block_list *bl, unsigned int tick) { +int elemental_action(struct elemental_data *ed, struct block_list *bl, int64 tick) { struct skill_condition req; uint16 skill_id, skill_lv; int i; @@ -636,7 +636,7 @@ int elemental_ai_sub_timer_activesearch(struct block_list *bl, va_list ap) { return 0; } -int elemental_ai_sub_timer(struct elemental_data *ed, struct map_session_data *sd, unsigned int tick) { +int elemental_ai_sub_timer(struct elemental_data *ed, struct map_session_data *sd, int64 tick) { struct block_list *target = NULL; int master_dist, view_range, mode; @@ -723,7 +723,7 @@ int elemental_ai_sub_timer(struct elemental_data *ed, struct map_session_data *s } if( battle->check_range(&ed->bl,target,view_range) && rnd()%100 < 2 ) { // 2% chance to cast attack skill. - if( elemental->action(ed,target,tick) ) + if( elemental->action(ed,target,tick) ) return 1; } @@ -746,14 +746,14 @@ int elemental_ai_sub_timer(struct elemental_data *ed, struct map_session_data *s } int elemental_ai_sub_foreachclient(struct map_session_data *sd, va_list ap) { - unsigned int tick = va_arg(ap,unsigned int); + int64 tick = va_arg(ap,int64); if(sd->status.ele_id && sd->ed) elemental->ai_sub_timer(sd->ed,sd,tick); return 0; } -int elemental_ai_timer(int tid, unsigned int tick, int id, intptr_t data) { +int elemental_ai_timer(int tid, int64 tick, int id, intptr_t data) { map->foreachpc(elemental->ai_sub_foreachclient,tick); return 0; } @@ -931,7 +931,10 @@ void reload_elemental_skilldb(void) { elemental->read_skilldb(); } -int do_init_elemental(void) { +int do_init_elemental(bool minimal) { + if (minimal) + return 0; + elemental->read_db(); elemental->read_skilldb(); diff --git a/src/map/elemental.h b/src/map/elemental.h index b42d5c0b7..6d04a41a5 100644 --- a/src/map/elemental.h +++ b/src/map/elemental.h @@ -2,8 +2,8 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _ELEMENTAL_H_ -#define _ELEMENTAL_H_ +#ifndef _MAP_ELEMENTAL_H_ +#define _MAP_ELEMENTAL_H_ #include "status.h" // struct status_data, struct status_change #include "unit.h" // struct unit_data @@ -21,8 +21,8 @@ #define EL_SKILLMODE_ASSIST 0x2 #define EL_SKILLMODE_AGGRESSIVE 0x4 -#define elemental_stop_walking(ed, type) unit->stop_walking(&(ed)->bl, type) -#define elemental_stop_attack(ed) unit->stop_attack(&(ed)->bl) +#define elemental_stop_walking(ed, type) (unit->stop_walking(&(ed)->bl, (type))) +#define elemental_stop_attack(ed) (unit->stop_attack(&(ed)->bl)) /** * Structures @@ -57,7 +57,7 @@ struct elemental_data { int summon_timer; int skill_timer; - unsigned last_thinktime, last_linktime, last_spdrain_time; + int64 last_thinktime, last_linktime, last_spdrain_time; short min_chase; int target_id, attacked_id; }; @@ -73,7 +73,7 @@ struct elemental_interface { struct s_elemental_db db[MAX_ELEMENTAL_CLASS]; // Elemental Database /* */ - int (*init) (void); + int (*init) (bool minimal); void (*final) (void); /* funcs */ bool (*class) (int class_); @@ -99,7 +99,7 @@ struct elemental_interface { int (*set_target) (struct map_session_data *sd, struct block_list *bl); int (*clean_single_effect) (struct elemental_data *ed, uint16 skill_id); int (*clean_effect) (struct elemental_data *ed); - int (*action) (struct elemental_data *ed, struct block_list *bl, unsigned int tick); + int (*action) (struct elemental_data *ed, struct block_list *bl, int64 tick); struct skill_condition (*skill_get_requirements) (uint16 skill_id, uint16 skill_lv); int (*read_skilldb) (void); @@ -108,11 +108,11 @@ struct elemental_interface { int (*search_index) (int class_); void (*summon_init) (struct elemental_data *ed); - int (*summon_end_timer) (int tid, unsigned int tick, int id, intptr_t data); + int (*summon_end_timer) (int tid, int64 tick, int id, intptr_t data); int (*ai_sub_timer_activesearch) (struct block_list *bl, va_list ap); - int (*ai_sub_timer) (struct elemental_data *ed, struct map_session_data *sd, unsigned int tick); + int (*ai_sub_timer) (struct elemental_data *ed, struct map_session_data *sd, int64 tick); int (*ai_sub_foreachclient) (struct map_session_data *sd, va_list ap); - int (*ai_timer) (int tid, unsigned int tick, int id, intptr_t data); + int (*ai_timer) (int tid, int64 tick, int id, intptr_t data); int (*read_db) (void); }; @@ -120,4 +120,4 @@ struct elemental_interface *elemental; void elemental_defaults(void); -#endif /* _ELEMENTAL_H_ */ +#endif /* _MAP_ELEMENTAL_H_ */ diff --git a/src/map/guild.c b/src/map/guild.c index 30f989f58..27c3b71a9 100644 --- a/src/map/guild.c +++ b/src/map/guild.c @@ -11,6 +11,7 @@ #include "../common/ers.h" #include "../common/strlib.h" #include "../common/utils.h" +#include "../common/HPM.h" #include "map.h" #include "guild.h" @@ -124,14 +125,14 @@ int guild_check_skill_require(struct guild *g,int id) bool guild_read_castledb(char* str[], int columns, int current) {// <castle id>,<map name>,<castle name>,<castle event>[,<reserved/unused switch flag>] struct guild_castle *gc; - int mapindex = mapindex_name2id(str[1]); + int index = mapindex->name2id(str[1]); - if (map->mapindex2mapid(mapindex) < 0) // Map not found or on another map-server + if (map->mapindex2mapid(index) < 0) // Map not found or on another map-server return false; CREATE(gc, struct guild_castle, 1); gc->castle_id = atoi(str[0]); - gc->mapindex = mapindex; + gc->mapindex = index; safestrncpy(gc->castle_name, str[2], sizeof(gc->castle_name)); safestrncpy(gc->castle_event, str[3], sizeof(gc->castle_event)); @@ -171,14 +172,14 @@ struct guild_castle* guild_castle_search(int gcid) } /// lookup: map index -> castle* -struct guild_castle* guild_mapindex2gc(short mapindex) +struct guild_castle* guild_mapindex2gc(short map_index) { struct guild_castle* gc; DBIterator *iter = db_iterator(guild->castle_db); for( gc = dbi_first(iter); dbi_exists(iter); gc = dbi_next(iter) ) { - if( gc->mapindex == mapindex ) + if( gc->mapindex == map_index ) break; } dbi_destroy(iter); @@ -189,7 +190,7 @@ struct guild_castle* guild_mapindex2gc(short mapindex) /// lookup: map name -> castle* struct guild_castle* guild_mapname2gc(const char* mapname) { - return guild->mapindex2gc(mapindex_name2id(mapname)); + return guild->mapindex2gc(mapindex->name2id(mapname)); } struct map_session_data* guild_getavailablesd(struct guild* g) @@ -279,8 +280,7 @@ int guild_payexp_timer_sub(DBKey key, DBData *data, va_list ap) { return 0; } -int guild_payexp_timer(int tid, unsigned int tick, int id, intptr_t data) -{ +int guild_payexp_timer(int tid, int64 tick, int id, intptr_t data) { guild->expcache_db->clear(guild->expcache_db,guild->payexp_timer_sub); return 0; } @@ -314,8 +314,7 @@ int guild_send_xy_timer_sub(DBKey key, DBData *data, va_list ap) } //Code from party_send_xy_timer [Skotlex] -int guild_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data) -{ +int guild_send_xy_timer(int tid, int64 tick, int id, intptr_t data) { guild->db->foreach(guild->db,guild->send_xy_timer_sub,tick); return 0; } @@ -456,7 +455,7 @@ int guild_recv_info(struct guild *sg) { DBData data; struct map_session_data *sd; bool guild_new = false; - void *aChSysSave = NULL; + struct hChSysCh *aChSysSave = NULL; nullpo_ret(sg); @@ -496,8 +495,8 @@ int guild_recv_info(struct guild *sg) { if( sg->alliance[i].guild_id == sd->status.guild_id ) { clif->chsys_join(channel,sd); } else if( tg[i] != NULL ) { - if( !(((struct hChSysCh*)tg[i]->channel)->banned && idb_exists(((struct hChSysCh*)tg[i]->channel)->banned, sd->status.account_id))) - clif->chsys_join((struct hChSysCh*)tg[i]->channel,sd); + if( !(tg[i]->channel->banned && idb_exists(tg[i]->channel->banned, sd->status.account_id))) + clif->chsys_join(tg[i]->channel,sd); } } } @@ -508,7 +507,7 @@ int guild_recv_info(struct guild *sg) { } - aChSysSave = (void*)channel; + aChSysSave = channel; } before=*sg; @@ -727,14 +726,14 @@ void guild_member_joined(struct map_session_data *sd) if( hChSys.ally && hChSys.ally_autojoin ) { struct guild* sg = NULL; - struct hChSysCh *channel = (struct hChSysCh*)g->channel; + struct hChSysCh *channel = g->channel; if( !(channel->banned && idb_exists(channel->banned, sd->status.account_id) ) ) clif->chsys_join(channel,sd); for (i = 0; i < MAX_GUILDALLIANCE; i++) { if( g->alliance[i].opposition == 0 && g->alliance[i].guild_id && (sg = guild->search(g->alliance[i].guild_id) ) ) { - if( !(((struct hChSysCh*)sg->channel)->banned && idb_exists(((struct hChSysCh*)sg->channel)->banned, sd->status.account_id))) - clif->chsys_join((struct hChSysCh*)sg->channel,sd); + if( !(sg->channel->banned && idb_exists(sg->channel->banned, sd->status.account_id))) + clif->chsys_join(sg->channel,sd); } } } @@ -867,6 +866,11 @@ int guild_member_withdraw(int guild_id, int account_id, int char_id, int flag, c online_member_sd = guild->getavailablesd(g); if(online_member_sd == NULL) return 0; // noone online to inform + +#ifdef GP_BOUND_ITEMS + //Guild bound item check + guild->retrieveitembound(char_id,account_id,guild_id); +#endif if(!flag) clif->guild_leave(online_member_sd, name, mes); @@ -901,6 +905,28 @@ int guild_member_withdraw(int guild_id, int account_id, int char_id, int flag, c return 0; } +void guild_retrieveitembound(int char_id,int aid,int guild_id) { +#ifdef GP_BOUND_ITEMS + TBL_PC *sd = map->id2sd(aid); + if(sd){ //Character is online + pc->bound_clear(sd,IBT_GUILD); + } else { //Character is offline, ask char server to do the job + struct guild_storage *gstor = gstorage->id2storage2(guild_id); + if(gstor && gstor->storage_status == 1) { //Someone is in guild storage, close them + struct s_mapiterator* iter = mapit_getallusers(); + for( sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); sd = (TBL_PC*)mapit->next(iter) ) { + if(sd->status.guild_id == guild_id && sd->state.storage_flag == 2) { + gstorage->close(sd); + break; + } + } + mapit->free(iter); + } + intif->itembound_req(char_id,aid,guild_id); + } +#endif +} + int guild_send_memberinfoshort(struct map_session_data *sd,int online) { // cleaned up [LuzZza] struct guild *g; @@ -1299,7 +1325,7 @@ int guild_skillupack(int guild_id,uint16 skill_id,int account_id) { if(g==NULL) return 0; if( sd != NULL ) { - clif->guild_skillup(sd,skill_id,g->skill[skill_id-GD_SKILLBASE].lv); + clif->skillup(sd,skill_id,g->skill[skill_id-GD_SKILLBASE].lv, 0); /* Guild Aura handling */ switch( skill_id ) { @@ -1334,7 +1360,7 @@ void guild_guildaura_refresh(struct map_session_data *sd, uint16 skill_id, uint1 } group = skill->unitsetting(&sd->bl,skill_id,skill_lv,sd->bl.x,sd->bl.y,0); if( group ) { - sc_start4(&sd->bl,type,100,(battle_config.guild_aura&16)?0:skill_lv,0,0,group->group_id,600000);//duration doesn't matter these status never end with val4 + sc_start4(NULL,&sd->bl,type,100,(battle_config.guild_aura&16)?0:skill_lv,0,0,group->group_id,600000);//duration doesn't matter these status never end with val4 } return; } @@ -1365,7 +1391,7 @@ void guild_block_skill(struct map_session_data *sd, int time) uint16 skill_id[] = { GD_BATTLEORDER, GD_REGENERATION, GD_RESTORE, GD_EMERGENCYCALL }; int i; for (i = 0; i < 4; i++) - skill->blockpc_start(sd, skill_id[i], time , true); + skill->blockpc_start(sd, skill_id[i], time); } /*==================================================== @@ -1569,10 +1595,10 @@ int guild_opposition(struct map_session_data *sd,struct map_session_data *tsd) * Notification of a relationship between 2 guilds *---------------------------------------------------*/ int guild_allianceack(int guild_id1,int guild_id2,int account_id1,int account_id2,int flag,const char *name1,const char *name2) { - struct guild *g[2]; - int guild_id[2]; - const char *guild_name[2]; - struct map_session_data *sd[2]; + struct guild *g[2] = { NULL }; + int guild_id[2] = { 0 }; + const char *guild_name[2] = { NULL }; + struct map_session_data *sd[2] = { NULL }; int j,i; guild_id[0] = guild_id1; @@ -1639,11 +1665,11 @@ int guild_allianceack(int guild_id1,int guild_id2,int account_id1,int account_id for (i = 0; i < 2 - (flag & 1); i++) { // Retransmission of the relationship list to all members - struct map_session_data *sd; + struct map_session_data *msd; if(g[i]!=NULL) for(j=0;j<g[i]->max_member;j++) - if((sd=g[i]->member[j].sd)!=NULL) - clif->guild_allianceinfo(sd); + if((msd=g[i]->member[j].sd)!=NULL) + clif->guild_allianceinfo(msd); } return 0; } @@ -1728,9 +1754,21 @@ int guild_broken(int guild_id,int flag) gstorage->delete(guild_id); if( hChSys.ally ) { if( g->channel != NULL ) { - clif->chsys_delete(( struct hChSysCh * )g->channel); + clif->chsys_delete(g->channel); + } + } + if( g->instance ) + aFree(g->instance); + + for( i = 0; i < g->hdatac; i++ ) { + if( g->hdata[i]->flag.free ) { + aFree(g->hdata[i]->data); } + aFree(g->hdata[i]); } + if( g->hdata ) + aFree(g->hdata); + idb_remove(guild->db,guild_id); return 0; } @@ -1815,7 +1853,7 @@ int guild_break(struct map_session_data *sd,char *name) { struct guild *g; struct unit_data *ud; int i; - + nullpo_ret(sd); if( (g=sd->guild)==NULL ) @@ -1857,6 +1895,10 @@ int guild_break(struct map_session_data *sd,char *name) { skill->del_unitgroup(groups[i],ALC_MARK); } } + +#ifdef GP_BOUND_ITEMS + pc->bound_clear(sd,IBT_GUILD); +#endif intif->guild_break(g->guild_id); return 1; @@ -1925,7 +1967,7 @@ int guild_castledatasave(int castle_id, int index, int value) gc->defense = value; for (i = 0; i < MAX_GUARDIANS; i++) if (gc->guardian[i].visible && (gd = map->id2md(gc->guardian[i].id)) != NULL) - status_calc_mob(gd, 0); + status_calc_mob(gd, SCO_NONE); break; } case 4: @@ -2174,12 +2216,15 @@ void guild_flags_clear(void) { guild->flags_count = 0; } -void do_init_guild(void) { - guild->db = idb_alloc(DB_OPT_RELEASE_DATA); - guild->castle_db = idb_alloc(DB_OPT_BASE); - guild->expcache_db = idb_alloc(DB_OPT_BASE); - guild->infoevent_db = idb_alloc(DB_OPT_BASE); - guild->expcache_ers = ers_new(sizeof(struct guild_expcache),"guild.c::expcache_ers",ERS_OPT_NONE); +void do_init_guild(bool minimal) { + if (minimal) + return; + + guild->db = idb_alloc(DB_OPT_RELEASE_DATA); + guild->castle_db = idb_alloc(DB_OPT_BASE); + guild->expcache_db = idb_alloc(DB_OPT_BASE); + guild->infoevent_db = idb_alloc(DB_OPT_BASE); + guild->expcache_ers = ers_new(sizeof(struct guild_expcache),"guild.c::expcache_ers",ERS_OPT_NONE); sv->readdb(map->db_path, "castle_db.txt", ',', 4, 5, -1, guild->read_castledb); @@ -2194,14 +2239,23 @@ void do_init_guild(void) { void do_final_guild(void) { DBIterator *iter = db_iterator(guild->db); struct guild *g; + int i; for( g = dbi_first(iter); dbi_exists(iter); g = dbi_next(iter) ) { if( g->channel != NULL ) - clif->chsys_delete((struct hChSysCh *)g->channel); + clif->chsys_delete(g->channel); if( g->instance != NULL ) { aFree(g->instance); g->instance = NULL; } + for( i = 0; i < g->hdatac; i++ ) { + if( g->hdata[i]->flag.free ) { + aFree(g->hdata[i]->data); + } + aFree(g->hdata[i]); + } + if( g->hdata ) + aFree(g->hdata); } dbi_destroy(iter); @@ -2327,4 +2381,6 @@ void guild_defaults(void) { guild->check_member = guild_check_member; guild->get_alliance_count = guild_get_alliance_count; guild->castle_reconnect_sub = guild_castle_reconnect_sub; + /* */ + guild->retrieveitembound = guild_retrieveitembound; } diff --git a/src/map/guild.h b/src/map/guild.h index 566ca7ce4..b03bd664d 100644 --- a/src/map/guild.h +++ b/src/map/guild.h @@ -2,8 +2,8 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _GUILD_H_ -#define _GUILD_H_ +#ifndef _MAP_GUILD_H_ +#define _MAP_GUILD_H_ //#include "../common/mmo.h" #include "map.h" // NAME_LENGTH @@ -56,7 +56,7 @@ struct s_guild_skill_tree { struct guild_interface { - void (*init) (void); + void (*init) (bool minimal); void (*final) (void); /* */ DBMap* db; // int guild_id -> struct guild* @@ -83,7 +83,7 @@ struct guild_interface { struct guild_castle *(*castle_search) (int gcid); /* */ struct guild_castle *(*mapname2gc) (const char* mapname); - struct guild_castle *(*mapindex2gc) (short mapindex); + struct guild_castle *(*mapindex2gc) (short map_index); /* */ struct map_session_data *(*getavailablesd) (struct guild *g); int (*getindex) (struct guild *g,int account_id,int char_id); @@ -147,14 +147,16 @@ struct guild_interface { void (*flags_clear) (void); /* guild aura */ void (*aura_refresh) (struct map_session_data *sd, uint16 skill_id, uint16 skill_lv); + /* item bound [Mhalicot]*/ + void (*retrieveitembound) (int char_id,int aid,int guild_id); /* */ - int (*payexp_timer) (int tid, unsigned int tick, int id, intptr_t data); + int (*payexp_timer) (int tid, int64 tick, int id, intptr_t data); TBL_PC* (*sd_check) (int guild_id, int account_id, int char_id); bool (*read_guildskill_tree_db) (char* split[], int columns, int current); bool (*read_castledb) (char* str[], int columns, int current); int (*payexp_timer_sub) (DBKey key, DBData *data, va_list ap); int (*send_xy_timer_sub) (DBKey key, DBData *data, va_list ap); - int (*send_xy_timer) (int tid, unsigned int tick, int id, intptr_t data); + int (*send_xy_timer) (int tid, int64 tick, int id, intptr_t data); DBData (*create_expcache) (DBKey key, va_list args); int (*eventlist_db_final) (DBKey key, DBData *data, va_list ap); int (*expcache_db_final) (DBKey key, DBData *data, va_list ap); @@ -171,4 +173,4 @@ struct guild_interface *guild; void guild_defaults(void); -#endif /* _GUILD_H_ */ +#endif /* _MAP_GUILD_H_ */ diff --git a/src/map/homunculus.c b/src/map/homunculus.c index 45e9af2b0..94c2ae5b1 100644 --- a/src/map/homunculus.c +++ b/src/map/homunculus.c @@ -134,25 +134,25 @@ int homunculus_dead(struct homun_data *hd) { } //Vaporize a character's homun. If flag, HP needs to be 80% or above. -int homunculus_vaporize(struct map_session_data *sd, int flag) { +int homunculus_vaporize(struct map_session_data *sd, enum homun_state flag) { struct homun_data *hd; nullpo_ret(sd); hd = sd->hd; - if (!hd || hd->homunculus.vaporize) + if (!hd || hd->homunculus.vaporize != HOM_ST_ACTIVE) return 0; if (status->isdead(&hd->bl)) return 0; //Can't vaporize a dead homun. - if (flag && get_percentage(hd->battle_status.hp, hd->battle_status.max_hp) < 80) + if (flag == HOM_ST_REST && get_percentage(hd->battle_status.hp, hd->battle_status.max_hp) < 80) return 0; hd->regen.state.block = 3; //Block regen while vaporized. //Delete timers when vaporized. homun->hunger_timer_delete(hd); - hd->homunculus.vaporize = 1; + hd->homunculus.vaporize = flag; if(battle_config.hom_setting&0x40) memset(hd->blockskill, 0, sizeof(hd->blockskill)); clif->hominfo(sd, sd->hd, 0); @@ -260,7 +260,7 @@ void homunculus_skillup(struct homun_data *hd,uint16 skill_id) { int i = 0 ; nullpo_retv(hd); - if(hd->homunculus.vaporize) + if(hd->homunculus.vaporize != HOM_ST_ACTIVE) return; i = skill_id - HM_SKILLBASE; @@ -272,7 +272,7 @@ void homunculus_skillup(struct homun_data *hd,uint16 skill_id) { { hd->homunculus.hskill[i].lv++; hd->homunculus.skillpts-- ; - status_calc_homunculus(hd,0); + status_calc_homunculus(hd,SCO_NONE); if (hd->master) { clif->homskillup(hd->master, skill_id); clif->hominfo(hd->master,hd,0); @@ -352,7 +352,7 @@ bool homunculus_levelup(struct homun_data *hd) { growth_max_hp, growth_max_sp, growth_str/10.0, growth_agi/10.0, growth_vit/10.0, growth_int/10.0, growth_dex/10.0, growth_luk/10.0); - clif->disp_onlyself(hd->master,output,strlen(output)); + clif_disp_onlyself(hd->master,output,strlen(output)); } return true; } @@ -413,7 +413,7 @@ bool homunculus_evolve(struct homun_data *hd) { //status_Calc flag&1 will make current HP/SP be reloaded from hom structure hom->hp = hd->battle_status.hp; hom->sp = hd->battle_status.sp; - status_calc_homunculus(hd,1); + status_calc_homunculus(hd,SCO_FIRST); if (!(battle_config.hom_setting&0x2)) skill->unit_move(&sd->hd->bl,timer->gettick(),1); // apply land skills immediately @@ -460,7 +460,7 @@ bool homunculus_mutate(struct homun_data *hd, int homun_id) { hom->hp = hd->battle_status.hp; hom->sp = hd->battle_status.sp; hom->prev_class = prev_class; - status_calc_homunculus(hd,1); + status_calc_homunculus(hd,SCO_FIRST); if (!(battle_config.hom_setting&0x2)) skill->unit_move(&sd->hd->bl,timer->gettick(),1); // apply land skills immediately @@ -471,7 +471,7 @@ bool homunculus_mutate(struct homun_data *hd, int homun_id) { int homunculus_gainexp(struct homun_data *hd,unsigned int exp) { enum homun_type htype; - if(hd->homunculus.vaporize) + if(hd->homunculus.vaporize != HOM_ST_ACTIVE) return 1; if( (htype = homun->class2type(hd->homunculus.class_)) == HT_INVALID ) { @@ -505,7 +505,7 @@ int homunculus_gainexp(struct homun_data *hd,unsigned int exp) { hd->homunculus.exp = 0; clif->specialeffect(&hd->bl,568,AREA); - status_calc_homunculus(hd,0); + status_calc_homunculus(hd,SCO_NONE); status_percent_heal(&hd->bl, 100, 100); return 0; } @@ -571,7 +571,7 @@ unsigned char homunculus_menu(struct map_session_data *sd,unsigned char menu_num bool homunculus_feed(struct map_session_data *sd, struct homun_data *hd) { int i, foodID, emotion; - if(hd->homunculus.vaporize) + if(hd->homunculus.vaporize == HOM_ST_REST) return false; foodID = hd->homunculusDB->foodID; @@ -615,7 +615,7 @@ bool homunculus_feed(struct map_session_data *sd, struct homun_data *hd) { return true; } -int homunculus_hunger_timer(int tid, unsigned int tick, int id, intptr_t data) { +int homunculus_hunger_timer(int tid, int64 tick, int id, intptr_t data) { struct map_session_data *sd; struct homun_data *hd; @@ -755,9 +755,11 @@ bool homunculus_create(struct map_session_data *sd, struct s_homunculus *hom) { unit->calc_pos(&hd->bl, sd->bl.x, sd->bl.y, sd->ud.dir); hd->bl.x = hd->ud.to_x; hd->bl.y = hd->ud.to_y; - + hd->masterteleport_timer = 0; + map->addiddb(&hd->bl); - status_calc_homunculus(hd,1); + status_calc_homunculus(hd,SCO_FIRST); + status_percent_heal(&hd->bl, 100, 100); hd->hungry_timer = INVALID_TIMER; return true; @@ -781,11 +783,11 @@ bool homunculus_call(struct map_session_data *sd) { hd = sd->hd; - if (!hd->homunculus.vaporize) + if (hd->homunculus.vaporize != HOM_ST_REST) return false; //Can't use this if homun wasn't vaporized. homun->init_timers(hd); - hd->homunculus.vaporize = 0; + hd->homunculus.vaporize = HOM_ST_ACTIVE; if (hd->bl.prev == NULL) { //Spawn him hd->bl.x = sd->bl.x; hd->bl.y = sd->bl.y; @@ -833,7 +835,7 @@ bool homunculus_recv_data(int account_id, struct s_homunculus *sh, int flag) { homun->create(sd, sh); hd = sd->hd; - if(hd && hd->homunculus.hp && !hd->homunculus.vaporize && hd->bl.prev == NULL && sd->bl.prev != NULL) { + if(hd && hd->homunculus.hp && hd->homunculus.vaporize == HOM_ST_ACTIVE && hd->bl.prev == NULL && sd->bl.prev != NULL) { enum homun_type htype = homun->class2type(hd->homunculus.class_); map->addblock(&hd->bl); @@ -908,7 +910,7 @@ bool homunculus_ressurect(struct map_session_data* sd, unsigned char per, short hd = sd->hd; - if (hd->homunculus.vaporize) + if (hd->homunculus.vaporize != HOM_ST_ACTIVE) return false; // vaporized homunculi need to be 'called' if (!status->isdead(&hd->bl)) @@ -1003,7 +1005,7 @@ bool homunculus_shuffle(struct homun_data *hd) { memcpy(&hd->homunculus.hskill, &b_skill, sizeof(b_skill)); hd->homunculus.skillpts = skillpts; clif->homskillinfoblock(sd); - status_calc_homunculus(hd,0); + status_calc_homunculus(hd,SCO_NONE); status_percent_heal(&hd->bl, 100, 100); clif->specialeffect(&hd->bl,568,AREA); @@ -1207,7 +1209,7 @@ void homunculus_exp_db_read(void) { if(line[0] == '/' && line[1] == '/') continue; - if (!(homun->exptable[j++] = strtoul(line, NULL, 10))) + if (!(homun->exptable[j++] = (unsigned int)strtoul(line, NULL, 10))) break; } // Last permitted level have to be 0! @@ -1229,8 +1231,12 @@ void homunculus_skill_reload(void) { homun->skill_db_read(); } -void do_init_homunculus(void) { +void do_init_homunculus(bool minimal) { int class_; + + if (minimal) + return; + homun->read_db(); homun->exp_db_read(); homun->skill_db_read(); diff --git a/src/map/homunculus.h b/src/map/homunculus.h index 9562ed5c3..db250f511 100644 --- a/src/map/homunculus.h +++ b/src/map/homunculus.h @@ -2,16 +2,16 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _HOMUNCULUS_H_ -#define _HOMUNCULUS_H_ +#ifndef _MAP_HOMUNCULUS_H_ +#define _MAP_HOMUNCULUS_H_ #include "status.h" // struct status_data, struct status_change #include "unit.h" // struct unit_data #include "pc.h" #define MAX_HOM_SKILL_REQUIRE 5 -#define homdb_checkid(id) (id >= HM_CLASS_BASE && id <= HM_CLASS_MAX) -#define homun_alive(x) ((x) && (x)->homunculus.vaporize != 1 && (x)->battle_status.hp > 0) +#define homdb_checkid(id) ((id) >= HM_CLASS_BASE && (id) <= HM_CLASS_MAX) +#define homun_alive(x) ((x) && (x)->homunculus.vaporize == HOM_ST_ACTIVE && (x)->battle_status.hp > 0) struct h_stats { unsigned int HP, SP; @@ -44,6 +44,12 @@ enum { SP_HUNGRY = 0x2, }; +enum homun_state { + HOM_ST_ACTIVE = 0,/* either alive or dead */ + HOM_ST_REST = 1,/* is resting (vaporized) */ + HOM_ST_MORPH = 2,/* in morph state */ +}; + struct homun_data { struct block_list bl; struct unit_data ud; @@ -58,6 +64,8 @@ struct homun_data { int hungry_timer; //[orn] unsigned int exp_next; char blockskill[MAX_SKILL]; // [orn] + + int64 masterteleport_timer; }; struct homun_skill_tree_entry { @@ -85,7 +93,7 @@ struct homunculus_interface { struct s_homunculus_db db[MAX_HOMUNCULUS_CLASS]; struct homun_skill_tree_entry skill_tree[MAX_HOMUNCULUS_CLASS][MAX_SKILL_TREE]; /* */ - void (*init) (void); + void (*init) (bool minimal); void (*final) (void); void (*reload) (void); void (*reload_skill) (void); @@ -94,7 +102,7 @@ struct homunculus_interface { enum homun_type (*class2type) (int class_); void (*damaged) (struct homun_data *hd); int (*dead) (struct homun_data *hd); - int (*vaporize) (struct map_session_data *sd, int flag); + int (*vaporize) (struct map_session_data *sd, enum homun_state flag); int (*delete) (struct homun_data *hd, int emote); int (*checkskill) (struct homun_data *hd, uint16 skill_id); int (*calc_skilltree) (struct homun_data *hd, int flag_evolve); @@ -111,7 +119,7 @@ struct homunculus_interface { void (*save) (struct homun_data *hd); unsigned char (*menu) (struct map_session_data *sd,unsigned char menu_num); bool (*feed) (struct map_session_data *sd, struct homun_data *hd); - int (*hunger_timer) (int tid, unsigned int tick, int id, intptr_t data); + int (*hunger_timer) (int tid, int64 tick, int id, intptr_t data); void (*hunger_timer_delete) (struct homun_data *hd); int (*change_name) (struct map_session_data *sd,char *name); bool (*change_name_ack) (struct map_session_data *sd, char* name, int flag); @@ -138,4 +146,4 @@ struct homunculus_interface *homun; void homunculus_defaults(void); -#endif /* _HOMUNCULUS_H_ */ +#endif /* _MAP_HOMUNCULUS_H_ */ diff --git a/src/map/instance.c b/src/map/instance.c index 6ae1d6141..a111751d0 100644 --- a/src/map/instance.c +++ b/src/map/instance.c @@ -11,6 +11,7 @@ #include "../common/strlib.h" #include "../common/utils.h" #include "../common/db.h" +#include "../common/HPM.h" #include "clif.h" #include "instance.h" @@ -109,8 +110,12 @@ int instance_create(int owner_id, const char *name, enum instance_owner_type typ instance->list[i].num_map = 0; instance->list[i].owner_id = owner_id; instance->list[i].owner_type = type; - instance->list[i].vars = idb_alloc(DB_OPT_RELEASE_DATA); - + instance->list[i].vars = i64db_alloc(DB_OPT_RELEASE_DATA); + instance->list[i].array_db = NULL; + instance->list[i].respawn.map = 0; + instance->list[i].respawn.y = 0; + instance->list[i].respawn.x = 0; + safestrncpy( instance->list[i].name, name, sizeof(instance->list[i].name) ); if( type != IOT_NONE ) { @@ -154,7 +159,7 @@ int instance_add_map(const char *name, int instance_id, bool usebasename, const return -1; } - if( map_name != NULL && strdb_iget(mapindex_db, map_name) ) { + if( map_name != NULL && strdb_iget(mapindex->db, map_name) ) { ShowError("instance_add_map: trying to create instanced map with existent name '%s'\n", map_name); return -2; } @@ -183,7 +188,7 @@ int instance_add_map(const char *name, int instance_id, bool usebasename, const map->list[im].custom_name = true; } else snprintf(map->list[im].name, MAP_NAME_LENGTH, (usebasename ? "%.3d#%s" : "%.3d%s"), instance_id, name); // Generate Name for Instance Map - map->list[im].index = mapindex_addmap(-1, map->list[im].name); // Add map index + map->list[im].index = mapindex->addmap(-1, map->list[im].name); // Add map index map->list[im].channel = NULL; @@ -239,9 +244,17 @@ int instance_add_map(const char *name, int instance_id, bool usebasename, const } } + //Mimic questinfo + if( map->list[m].qi_count ) { + map->list[im].qi_count = map->list[m].qi_count; + CREATE( map->list[im].qi_data, struct questinfo, map->list[im].qi_count ); + memcpy( map->list[im].qi_data, map->list[m].qi_data, map->list[im].qi_count * sizeof(struct questinfo) ); + } + map->list[im].m = im; map->list[im].instance_id = instance_id; map->list[im].instance_src_map = m; + map->list[im].flag.src4instance = 0; //clear map->list[m].flag.src4instance = 1; // Flag this map as a src map for instances RECREATE(instance->list[instance_id].map, unsigned short, ++instance->list[instance_id].num_map); @@ -271,6 +284,21 @@ int instance_map2imap(int16 m, int instance_id) { return -1; } +int instance_mapname2imap(const char *map_name, int instance_id) { + int i; + + if( !instance->valid(instance_id) ) { + return -1; + } + + for( i = 0; i < instance->list[instance_id].num_map; i++ ) { + if( instance->list[instance_id].map[i] && !strcmpi(map->list[map->list[instance->list[instance_id].map[i]].instance_src_map].name,map_name) ) + return instance->list[instance_id].map[i]; + } + return -1; +} + + /*-------------------------------------- * m : source map * instance_id : where to search @@ -291,7 +319,6 @@ int instance_mapid2imapid(int16 m, int instance_id) { } /*-------------------------------------- - * map_instance_map_npcsub * Used on Init instance. Duplicates each script on source map *--------------------------------------*/ int instance_map_npcsub(struct block_list* bl, va_list args) { @@ -304,6 +331,19 @@ int instance_map_npcsub(struct block_list* bl, va_list args) { return 1; } +int instance_init_npc(struct block_list* bl, va_list args) { + struct npc_data *nd = (struct npc_data*)bl; + struct event_data *ev; + char evname[EVENT_NAME_LENGTH]; + + snprintf(evname, EVENT_NAME_LENGTH, "%s::OnInstanceInit", nd->exname); + + if( ( ev = strdb_get(npc->ev_db, evname) ) ) + script->run(ev->nd->u.scr.script, ev->pos, 0, ev->nd->bl.id); + + return 1; +} + /*-------------------------------------- * Init all map on the instance. Npcs are created here *--------------------------------------*/ @@ -314,8 +354,11 @@ void instance_init(int instance_id) { return; // nothing to do for( i = 0; i < instance->list[instance_id].num_map; i++ ) - map->foreachinmap(instance_map_npcsub, map->list[instance->list[instance_id].map[i]].instance_src_map, BL_NPC, instance->list[instance_id].map[i]); + map->foreachinmap(instance->map_npcsub, map->list[instance->list[instance_id].map[i]].instance_src_map, BL_NPC, instance->list[instance_id].map[i]); + /* cant be together with the previous because it will rely on all of them being up */ + map->foreachininstance(instance->init_npc, instance_id, BL_NPC); + instance->list[instance_id].state = INSTANCE_BUSY; } @@ -378,7 +421,7 @@ void instance_del_map(int16 m) { if( map->list[m].mob_delete_timer != INVALID_TIMER ) timer->delete(map->list[m].mob_delete_timer, map->removemobs_timer); - mapindex_removemap(map_id2index(m)); + mapindex->removemap(map_id2index(m)); // Free memory aFree(map->list[m].cell); @@ -409,6 +452,9 @@ void instance_del_map(int16 m) { aFree(map->list[m].zone_mf); } + if( map->list[m].qi_data ) + aFree(map->list[m].qi_data); + // Remove from instance for( i = 0; i < instance->list[map->list[m].instance_id].num_map; i++ ) { if( instance->list[map->list[m].instance_id].map[i] == m ) { @@ -436,7 +482,7 @@ void instance_del_map(int16 m) { /*-------------------------------------- * Timer to destroy instance by process or idle *--------------------------------------*/ -int instance_destroy_timer(int tid, unsigned int tick, int id, intptr_t data) { +int instance_destroy_timer(int tid, int64 tick, int id, intptr_t data) { instance->destroy(id); return 0; } @@ -507,6 +553,8 @@ void instance_destroy(int instance_id) { if( instance->list[instance_id].vars ) db_destroy(instance->list[instance_id].vars); + if( instance->list[instance_id].array_db ) + instance->list[instance_id].array_db->destroy(instance->list[instance_id].array_db,script->array_free_db); if( instance->list[instance_id].progress_timer != INVALID_TIMER ) timer->delete( instance->list[instance_id].progress_timer, instance->destroy_timer); @@ -521,6 +569,18 @@ void instance_destroy(int instance_id) { instance->list[instance_id].map = NULL; instance->list[instance_id].state = INSTANCE_FREE; instance->list[instance_id].num_map = 0; + + for( j = 0; j < instance->list[instance_id].hdatac; j++ ) { + if( instance->list[instance_id].hdata[j]->flag.free ) { + aFree(instance->list[instance_id].hdata[j]->data); + } + aFree(instance->list[instance_id].hdata[j]); + } + if( instance->list[instance_id].hdata ) + aFree(instance->list[instance_id].hdata); + + instance->list[instance_id].hdata = NULL; + instance->list[instance_id].hdatac = 0; } /*-------------------------------------- @@ -566,9 +626,11 @@ void instance_set_timeout(int instance_id, unsigned int progress_timeout, unsign if( progress_timeout ) { instance->list[instance_id].progress_timeout = now + progress_timeout; instance->list[instance_id].progress_timer = timer->add( timer->gettick() + progress_timeout * 1000, instance->destroy_timer, instance_id, 0); + instance->list[instance_id].original_progress_timeout = progress_timeout; } else { instance->list[instance_id].progress_timeout = 0; instance->list[instance_id].progress_timer = INVALID_TIMER; + instance->list[instance_id].original_progress_timeout = 0; } if( idle_timeout ) { @@ -600,6 +662,37 @@ void instance_check_kick(struct map_session_data *sd) { } } +void do_reload_instance(void) { + struct s_mapiterator *iter; + struct map_session_data *sd; + int i, k; + + for(i = 0; i < instance->instances; i++) { + for(k = 0; k < instance->list[i].num_map; k++) { + if( !map->list[map->list[instance->list[i].map[k]].instance_src_map].flag.src4instance ) + break; + } + + if( k != instance->list[i].num_map ) /* any (or all) of them were disabled, we destroy */ + instance->destroy(i); + else { + /* populate the instance again */ + instance->start(i); + /* restart timers */ + instance->set_timeout(i,instance->list[i].original_progress_timeout,instance->list[i].idle_timeoutval); + } + } + + iter = mapit_getallusers(); + for( sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); sd = (TBL_PC*)mapit->next(iter) ) { + if(sd && map->list[sd->bl.m].instance_id >= 0) { + pc->setpos(sd,instance->list[map->list[sd->bl.m].instance_id].respawn.map,instance->list[map->list[sd->bl.m].instance_id].respawn.x,instance->list[map->list[sd->bl.m].instance_id].respawn.y,CLR_TELEPORT); + } + } + mapit->free(iter); +} + + void do_final_instance(void) { int i; @@ -614,7 +707,10 @@ void do_final_instance(void) { instance->instances = 0; } -void do_init_instance(void) { +void do_init_instance(bool minimal) { + if (minimal) + return; + timer->add_func_list(instance->destroy_timer, "instance_destroy_timer"); } @@ -623,7 +719,7 @@ void instance_defaults(void) { instance->init = do_init_instance; instance->final = do_final_instance; - + instance->reload = do_reload_instance; /* start point */ instance->start_id = 0; /* count */ @@ -636,6 +732,9 @@ void instance_defaults(void) { instance->del_map = instance_del_map; instance->map2imap = instance_map2imap; instance->mapid2imapid = instance_mapid2imapid; + instance->mapname2imap = instance_mapname2imap; + instance->map_npcsub = instance_map_npcsub; + instance->init_npc = instance_init_npc; instance->destroy = instance_destroy; instance->start = instance_init; instance->check_idle = instance_check_idle; diff --git a/src/map/instance.h b/src/map/instance.h index ba6d26d59..66a7d0d6c 100644 --- a/src/map/instance.h +++ b/src/map/instance.h @@ -2,8 +2,8 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _INSTANCE_H_ -#define _INSTANCE_H_ +#ifndef _MAP_INSTANCE_H_ +#define _MAP_INSTANCE_H_ #define INSTANCE_NAME_LENGTH (60+1) @@ -33,18 +33,28 @@ struct instance_data { unsigned short num_map; unsigned short users; - struct DBMap* vars; // Instance Variable for scripts - + struct DBMap *vars; // Instance Variable for scripts + struct DBMap *array_db ; + int progress_timer; unsigned int progress_timeout; int idle_timer; unsigned int idle_timeout, idle_timeoutval; + + unsigned int original_progress_timeout; + + struct point respawn;/* reload spawn */ + + /* HPM Custom Struct */ + struct HPluginData **hdata; + unsigned int hdatac; }; struct instance_interface { - void (*init) (void); + void (*init) (bool minimal); void (*final) (void); + void (*reload) (void); /* start point */ unsigned short start_id; unsigned short instances;/* count */ @@ -56,17 +66,20 @@ struct instance_interface { void (*del_map) (int16 m); int (*map2imap) (int16 m, int instance_id); int (*mapid2imapid) (int16 m, int instance_id); + int (*mapname2imap) (const char *map_name, int instance_id); + int (*map_npcsub) (struct block_list* bl, va_list args); + int (*init_npc) (struct block_list* bl, va_list args); void (*destroy) (int instance_id); void (*start) (int instance_id); void (*check_idle) (int instance_id); void (*check_kick) (struct map_session_data *sd); void (*set_timeout) (int instance_id, unsigned int progress_timeout, unsigned int idle_timeout); bool (*valid) (int instance_id); - int (*destroy_timer) (int tid, unsigned int tick, int id, intptr_t data); + int (*destroy_timer) (int tid, int64 tick, int id, intptr_t data); }; struct instance_interface *instance; void instance_defaults(void); -#endif +#endif /* _MAP_INSTANCE_H_ */ diff --git a/src/map/intif.c b/src/map/intif.c index f31ab0f5a..6b39bd1a5 100644 --- a/src/map/intif.c +++ b/src/map/intif.c @@ -35,7 +35,7 @@ struct intif_interface intif_s; -#define inter_fd chrif->fd // alias +#define inter_fd (chrif->fd) // alias //----------------------------------------------------------------- // Send to inter server @@ -125,7 +125,7 @@ int intif_rename(struct map_session_data *sd, int type, char *name) } // GM Send a message -int intif_broadcast(const char* mes, int len, int type) +int intif_broadcast(const char* mes, size_t len, int type) { int lp = (type|BC_COLOR_MASK) ? 4 : 0; @@ -155,7 +155,7 @@ int intif_broadcast(const char* mes, int len, int type) return 0; } -int intif_broadcast2(const char* mes, int len, unsigned long fontColor, short fontType, short fontSize, short fontAlign, short fontY) +int intif_broadcast2(const char* mes, size_t len, unsigned int fontColor, short fontType, short fontSize, short fontAlign, short fontY) { // Send to the local players clif->broadcast2(NULL, mes, len, fontColor, fontType, fontSize, fontAlign, fontY, ALL_CLIENT); @@ -192,7 +192,7 @@ int intif_main_message(struct map_session_data* sd, const char* message) snprintf( output, sizeof(output), msg_txt(386), sd->status.name, message ); // send the message using the inter-server broadcast service - intif_broadcast2( output, strlen(output) + 1, 0xFE000000, 0, 0, 0, 0 ); + intif->broadcast2( output, strlen(output) + 1, 0xFE000000, 0, 0, 0, 0 ); // log the chat message logs->chat( LOG_CHAT_MAINCHAT, 0, sd->status.char_id, sd->status.account_id, mapindex_id2name(sd->mapindex), sd->bl.x, sd->bl.y, NULL, message ); @@ -201,7 +201,7 @@ int intif_main_message(struct map_session_data* sd, const char* message) } // The transmission of Wisp/Page to inter-server (player not found on this server) -int intif_wis_message(struct map_session_data *sd, char *nick, char *mes, int mes_len) +int intif_wis_message(struct map_session_data *sd, char *nick, char *mes, size_t mes_len) { nullpo_ret(sd); if (intif->CheckForCharServer()) @@ -247,7 +247,7 @@ int intif_wis_replay(int id, int flag) // The transmission of GM only Wisp/Page from server to inter-server int intif_wis_message_to_gm(char *wisp_name, int permission, char *mes) { - int mes_len; + size_t mes_len; if (intif->CheckForCharServer()) return 0; mes_len = strlen(mes) + 1; // + null @@ -265,60 +265,117 @@ int intif_wis_message_to_gm(char *wisp_name, int permission, char *mes) return 0; } -int intif_regtostr(char* str, struct global_reg *reg, int qty) -{ - int len =0, i; - - for (i = 0; i < qty; i++) { - len+= sprintf(str+len, "%s", reg[i].str)+1; //We add 1 to consider the '\0' in place. - len+= sprintf(str+len, "%s", reg[i].value)+1; - } - return len; -} - //Request for saving registry values. -int intif_saveregistry(struct map_session_data *sd, int type) -{ - struct global_reg *reg; - int count; - int i, p; - - if (intif->CheckForCharServer()) +int intif_saveregistry(struct map_session_data *sd) { + DBIterator *iter; + DBKey key; + DBData *data; + int plen = 0; + size_t len; + + if (intif->CheckForCharServer() || !sd->var_db) return -1; + + WFIFOHEAD(inter_fd, 60000 + 300); + WFIFOW(inter_fd,0) = 0x3004; + /* 0x2 = length (set later) */ + WFIFOL(inter_fd,4) = sd->status.account_id; + WFIFOL(inter_fd,8) = sd->status.char_id; + WFIFOW(inter_fd,12) = 0;/* count */ + + plen = 14; + + iter = db_iterator(sd->var_db); + for( data = iter->first(iter,&key); iter->exists(iter); data = iter->next(iter,&key) ) { + const char *varname = NULL; + struct script_reg_state *src = NULL; + + if( data->type != DB_DATA_PTR ) /* its a @number */ + continue; + + varname = script->get_str(script_getvarid(key.i64)); + + if( varname[0] == '@' ) /* @string$ can get here, so we skip */ + continue; + + src = DB->data2ptr(data); - switch (type) { - case 3: //Character reg - reg = sd->save_reg.global; - count = sd->save_reg.global_num; - sd->state.reg_dirty &= ~0x4; - break; - case 2: //Account reg - reg = sd->save_reg.account; - count = sd->save_reg.account_num; - sd->state.reg_dirty &= ~0x2; - break; - case 1: //Account2 reg - reg = sd->save_reg.account2; - count = sd->save_reg.account2_num; - sd->state.reg_dirty &= ~0x1; - break; - default: //Broken code? - ShowError("intif_saveregistry: Invalid type %d\n", type); - return -1; - } - WFIFOHEAD(inter_fd, 288 * MAX_REG_NUM+13); - WFIFOW(inter_fd,0)=0x3004; - WFIFOL(inter_fd,4)=sd->status.account_id; - WFIFOL(inter_fd,8)=sd->status.char_id; - WFIFOB(inter_fd,12)=type; - for( p = 13, i = 0; i < count; i++ ) { - if (reg[i].str[0] != '\0' && reg[i].value[0] != '\0') { - p+= sprintf((char*)WFIFOP(inter_fd,p), "%s", reg[i].str)+1; //We add 1 to consider the '\0' in place. - p+= sprintf((char*)WFIFOP(inter_fd,p), "%s", reg[i].value)+1; + /* no need! */ + if( !src->update ) + continue; + + src->update = false; + + len = strlen(varname)+1; + + WFIFOB(inter_fd, plen) = (unsigned char)len;/* won't be higher; the column size is 32 */ + plen += 1; + + safestrncpy((char*)WFIFOP(inter_fd,plen), varname, len); + plen += len; + + WFIFOL(inter_fd, plen) = script_getvaridx(key.i64); + plen += 4; + + if( src->type ) { + struct script_reg_str *p = (struct script_reg_str *)src; + + WFIFOB(inter_fd, plen) = p->value ? 2 : 3; + plen += 1; + + if( p->value ) { + len = strlen(p->value)+1; + + WFIFOB(inter_fd, plen) = (unsigned char)len;/* won't be higher; the column size is 254 */ + plen += 1; + + safestrncpy((char*)WFIFOP(inter_fd,plen), p->value, len); + plen += len; + } else { + script->reg_destroy_single(sd,key.i64,&p->flag); + } + + } else { + struct script_reg_num *p = (struct script_reg_num *)src; + + WFIFOB(inter_fd, plen) = p->value ? 0 : 1; + plen += 1; + + if( p->value ) { + WFIFOL(inter_fd, plen) = p->value; + plen += 4; + } else { + script->reg_destroy_single(sd,key.i64,&p->flag); + } + } + + WFIFOW(inter_fd,12) += 1; + + if( plen > 60000 ) { + WFIFOW(inter_fd, 2) = plen; + WFIFOSET(inter_fd, plen); + + /* prepare follow up */ + WFIFOHEAD(inter_fd, 60000 + 300); + WFIFOW(inter_fd,0) = 0x3004; + /* 0x2 = length (set later) */ + WFIFOL(inter_fd,4) = sd->status.account_id; + WFIFOL(inter_fd,8) = sd->status.char_id; + WFIFOW(inter_fd,12) = 0;/* count */ + + plen = 14; + } + } - WFIFOW(inter_fd,2)=p; - WFIFOSET(inter_fd,WFIFOW(inter_fd,2)); + dbi_destroy(iter); + + /* mark & go. */ + WFIFOW(inter_fd, 2) = plen; + WFIFOSET(inter_fd, plen); + + sd->vars_dirty = false; + return 0; } @@ -327,10 +384,7 @@ int intif_request_registry(struct map_session_data *sd, int flag) { nullpo_ret(sd); - sd->save_reg.account2_num = -1; - sd->save_reg.account_num = -1; - sd->save_reg.global_num = -1; - + /* if char server aint online it doesn't load, shouldn't we kill the session then? */ if (intif->CheckForCharServer()) return 0; @@ -447,7 +501,7 @@ int intif_party_leave(int party_id,int account_id, int char_id) // Request keeping party for new map ?? int intif_party_changemap(struct map_session_data *sd,int online) { - int16 m, mapindex; + int16 m, map_index; if (intif->CheckForCharServer()) return 0; @@ -455,16 +509,16 @@ int intif_party_changemap(struct map_session_data *sd,int online) { return 0; if( (m=map->mapindex2mapid(sd->mapindex)) >= 0 && map->list[m].instance_id >= 0 ) - mapindex = map_id2index(map->list[m].instance_src_map); + map_index = map_id2index(map->list[m].instance_src_map); else - mapindex = sd->mapindex; + map_index = sd->mapindex; WFIFOHEAD(inter_fd,19); WFIFOW(inter_fd,0)=0x3025; WFIFOL(inter_fd,2)=sd->status.party_id; WFIFOL(inter_fd,6)=sd->status.account_id; WFIFOL(inter_fd,10)=sd->status.char_id; - WFIFOW(inter_fd,14)=mapindex; + WFIFOW(inter_fd,14)=map_index; WFIFOB(inter_fd,16)=online; WFIFOW(inter_fd,17)=sd->status.base_level; WFIFOSET(inter_fd,19); @@ -560,7 +614,7 @@ int intif_guild_addmember(int guild_id,struct guild_member *m) } // Request a new leader for guild -int intif_guild_change_gm(int guild_id, const char* name, int len) +int intif_guild_change_gm(int guild_id, const char* name, size_t len) { if (intif->CheckForCharServer()) return 0; @@ -893,7 +947,7 @@ int mapif_parse_WisToGM_sub(struct map_session_data* sd,va_list va) { char *message; int len; - if (!pc->has_permission(sd, permission)) + if (!pc_has_permission(sd, permission)) return 0; wisp_name = va_arg(va, char*); message = va_arg(va, char*); @@ -927,54 +981,93 @@ void mapif_parse_WisToGM(int fd) // Request player registre void intif_parse_Registers(int fd) { - int j,p,len,max, flag; + int i, flag; struct map_session_data *sd; - struct global_reg *reg; - int *qty; int account_id = RFIFOL(fd,4), char_id = RFIFOL(fd,8); struct auth_node *node = chrif->auth_check(account_id, char_id, ST_LOGIN); + char type = RFIFOB(fd, 13); + if (node) sd = node->sd; else { //Normally registries should arrive for in log-in chars. sd = map->id2sd(account_id); - if (sd && RFIFOB(fd,12) == 3 && sd->status.char_id != char_id) - sd = NULL; //Character registry from another character. } - if (!sd) return; - - flag = (sd->save_reg.global_num == -1 || sd->save_reg.account_num == -1 || sd->save_reg.account2_num == -1); - + + if (!sd || sd->status.char_id != char_id) { + return; //Character registry from another character. + } + + flag = ( sd->vars_received&PRL_ACCG && sd->vars_received&PRL_ACCL && sd->vars_received&PRL_CHAR ) ? 0 : 1; + switch (RFIFOB(fd,12)) { case 3: //Character Registry - reg = sd->save_reg.global; - qty = &sd->save_reg.global_num; - max = GLOBAL_REG_NUM; - break; + sd->vars_received |= PRL_CHAR; + break; case 2: //Account Registry - reg = sd->save_reg.account; - qty = &sd->save_reg.account_num; - max = ACCOUNT_REG_NUM; - break; + sd->vars_received |= PRL_ACCL; + break; case 1: //Account2 Registry - reg = sd->save_reg.account2; - qty = &sd->save_reg.account2_num; - max = ACCOUNT_REG2_NUM; - break; + sd->vars_received |= PRL_ACCG; + break; + case 0: + break; default: ShowError("intif_parse_Registers: Unrecognized type %d\n",RFIFOB(fd,12)); return; } - for(j=0,p=13;j<max && p<RFIFOW(fd,2);j++){ - sscanf((char*)RFIFOP(fd,p), "%31c%n", reg[j].str,&len); - reg[j].str[len]='\0'; - p += len+1; //+1 to skip the '\0' between strings. - sscanf((char*)RFIFOP(fd,p), "%255c%n", reg[j].value,&len); - reg[j].value[len]='\0'; - p += len+1; + /* have it not complain about insertion of vars before loading, and not set those vars as new or modified */ + pc->reg_load = true; + + if( RFIFOW(fd, 14) ) { + char key[32], sval[254]; + unsigned int index; + int max = RFIFOW(fd, 14), cursor = 16, ival; + + /** + * Vessel!char_reg_num_db + * + * str type + * { keyLength(B), key(<keyLength>), index(L), valLength(B), val(<valLength>) } + **/ + if( type ) { + for(i = 0; i < max; i++) { + safestrncpy(key, (char*)RFIFOP(fd, cursor + 1), RFIFOB(fd, cursor)); + cursor += RFIFOB(fd, cursor) + 1; + + index = RFIFOL(fd, cursor); + cursor += 4; + + safestrncpy(sval, (char*)RFIFOP(fd, cursor + 1), RFIFOB(fd, cursor)); + cursor += RFIFOB(fd, cursor) + 1; + + script->set_reg(NULL,sd,reference_uid(script->add_str(key), index), key, (void*)sval, NULL); + } + /** + * Vessel! + * + * int type + * { keyLength(B), key(<keyLength>), index(L), value(L) } + **/ + } else { + for(i = 0; i < max; i++) { + safestrncpy(key, (char*)RFIFOP(fd, cursor + 1), RFIFOB(fd, cursor)); + cursor += RFIFOB(fd, cursor) + 1; + + index = RFIFOL(fd, cursor); + cursor += 4; + + ival = RFIFOL(fd, cursor); + cursor += 4; + + script->set_reg(NULL,sd,reference_uid(script->add_str(key), index), key, (void*)__64BPTRSIZE(ival), NULL); + } + } } - *qty = j; - - if (flag && sd->save_reg.global_num > -1 && sd->save_reg.account_num > -1 && sd->save_reg.account2_num > -1) + + /* flag it back */ + pc->reg_load = false; + + if (flag && sd->vars_received&PRL_ACCG && sd->vars_received&PRL_ACCL && sd->vars_received&PRL_CHAR) pc->reg_received(sd); //Received all registry values, execute init scripts and what-not. [Skotlex] } @@ -982,15 +1075,18 @@ void intif_parse_LoadGuildStorage(int fd) { struct guild_storage *gstor; struct map_session_data *sd; - int guild_id; + int guild_id, flag; guild_id = RFIFOL(fd,8); + flag = RFIFOL(fd,12); if(guild_id <= 0) return; sd=map->id2sd( RFIFOL(fd,4) ); - if(sd==NULL){ - ShowError("intif_parse_LoadGuildStorage: user not found %d\n",RFIFOL(fd,4)); - return; + if( flag ){ //If flag != 0, we attach a player and open the storage + if(sd==NULL){ + ShowError("intif_parse_LoadGuildStorage: user not found %d\n",RFIFOL(fd,4)); + return; + } } gstor=gstorage->id2storage(guild_id); if(!gstor) { @@ -998,21 +1094,22 @@ void intif_parse_LoadGuildStorage(int fd) return; } if (gstor->storage_status == 1) { // Already open.. lets ignore this update - ShowWarning("intif_parse_LoadGuildStorage: storage received for a client already open (User %d:%d)\n", sd->status.account_id, sd->status.char_id); + ShowWarning("intif_parse_LoadGuildStorage: storage received for a client already open (User %d:%d)\n", flag?sd->status.account_id:0, flag?sd->status.char_id:0); return; } if (gstor->dirty) { // Already have storage, and it has been modified and not saved yet! Exploit! [Skotlex] - ShowWarning("intif_parse_LoadGuildStorage: received storage for an already modified non-saved storage! (User %d:%d)\n", sd->status.account_id, sd->status.char_id); + ShowWarning("intif_parse_LoadGuildStorage: received storage for an already modified non-saved storage! (User %d:%d)\n", flag?sd->status.account_id:0, flag?sd->status.char_id:0); return; } - if( RFIFOW(fd,2)-12 != sizeof(struct guild_storage) ){ - ShowError("intif_parse_LoadGuildStorage: data size error %d %d\n",RFIFOW(fd,2)-12 , sizeof(struct guild_storage)); - gstor->storage_status = 0; + if( RFIFOW(fd,2)-13 != sizeof(struct guild_storage) ){ + ShowError("intif_parse_LoadGuildStorage: data size error %d %d\n",RFIFOW(fd,2)-13 , sizeof(struct guild_storage)); + gstor->storage_status = 0; return; } - memcpy(gstor,RFIFOP(fd,12),sizeof(struct guild_storage)); - gstorage->open(sd); + memcpy(gstor,RFIFOP(fd,13),sizeof(struct guild_storage)); + if( flag ) + gstorage->open(sd); } // ACK guild_storage saved @@ -1307,50 +1404,80 @@ QUESTLOG SYSTEM FUNCTIONS ***************************************/ -int intif_request_questlog(TBL_PC *sd) -{ +/** + * Requests a character's quest log entries to the inter server. + * + * @param sd Character's data + */ +void intif_request_questlog(TBL_PC *sd) { WFIFOHEAD(inter_fd,6); WFIFOW(inter_fd,0) = 0x3060; WFIFOL(inter_fd,2) = sd->status.char_id; WFIFOSET(inter_fd,6); - return 0; } +/** + * Parses the received quest log entries for a character from the inter server. + * + * Received in reply to the requests made by intif_request_questlog. + * + * @see intif_parse + */ void intif_parse_QuestLog(int fd) { - int char_id = RFIFOL(fd, 4); - int i; - TBL_PC * sd = map->charid2sd(char_id); + int char_id = RFIFOL(fd, 4), num_received = (RFIFOW(fd, 2)-8)/sizeof(struct quest); + TBL_PC *sd = map->charid2sd(char_id); - //User not online anymore - if(!sd) + if (!sd) // User not online anymore return; - sd->avail_quests = sd->num_quests = (RFIFOW(fd, 2)-8)/sizeof(struct quest); - - memset(&sd->quest_log, 0, sizeof(sd->quest_log)); + sd->num_quests = sd->avail_quests = 0; - for( i = 0; i < sd->num_quests; i++ ) - { - memcpy(&sd->quest_log[i], RFIFOP(fd, i*sizeof(struct quest)+8), sizeof(struct quest)); - - sd->quest_index[i] = quest->search_db(sd->quest_log[i].quest_id); - - if( sd->quest_index[i] < 0 ) - { - ShowError("intif_parse_QuestLog: quest %d not found in DB.\n",sd->quest_log[i].quest_id); - sd->avail_quests--; - sd->num_quests--; - i--; - continue; + if (num_received == 0) { + if (sd->quest_log) { + aFree(sd->quest_log); + sd->quest_log = NULL; + } + } else { + struct quest *received = (struct quest *)RFIFOP(fd, 8); + int i, k = num_received; + if (sd->quest_log) { + RECREATE(sd->quest_log, struct quest, num_received); + } else { + CREATE(sd->quest_log, struct quest, num_received); } - if( sd->quest_log[i].state == Q_COMPLETE ) - sd->avail_quests--; + for (i = 0; i < num_received; i++) { + if( quest->db(received[i].quest_id) == &quest->dummy ) { + ShowError("intif_parse_QuestLog: quest %d not found in DB.\n", received[i].quest_id); + continue; + } + if (received[i].state != Q_COMPLETE) { + // Insert at the beginning + memcpy(&sd->quest_log[sd->avail_quests++], &received[i], sizeof(struct quest)); + } else { + // Insert at the end + memcpy(&sd->quest_log[--k], &received[i], sizeof(struct quest)); + } + sd->num_quests++; + } + if (sd->avail_quests < k) { + // sd->avail_quests and k didn't meet in the middle: some entries were skipped + if (k < num_received) // Move the entries at the end to fill the gap + memmove(&sd->quest_log[k], &sd->quest_log[sd->avail_quests], sizeof(struct quest)*(num_received - k)); + sd->quest_log = aRealloc(sd->quest_log, sizeof(struct quest)*sd->num_quests); + } } quest->pc_login(sd); } +/** + * Parses the quest log save ack for a character from the inter server. + * + * Received in reply to the requests made by intif_quest_save. + * + * @see intif_parse + */ void intif_parse_QuestSave(int fd) { int cid = RFIFOL(fd, 2); TBL_PC *sd = map->id2sd(cid); @@ -1361,21 +1488,24 @@ void intif_parse_QuestSave(int fd) { sd->save_quest = false; } -int intif_quest_save(TBL_PC *sd) -{ - int len; +/** + * Requests to the inter server to save a character's quest log entries. + * + * @param sd Character's data + * @return 0 in case of success, nonzero otherwise + */ +int intif_quest_save(TBL_PC *sd) { + int len = sizeof(struct quest)*sd->num_quests + 8; if(intif->CheckForCharServer()) - return 0; - - len = sizeof(struct quest)*sd->num_quests + 8; + return 1; WFIFOHEAD(inter_fd, len); WFIFOW(inter_fd,0) = 0x3061; WFIFOW(inter_fd,2) = len; WFIFOL(inter_fd,4) = sd->status.char_id; if( sd->num_quests ) - memcpy(WFIFOP(inter_fd,8), &sd->quest_log, sizeof(struct quest)*sd->num_quests); + memcpy(WFIFOP(inter_fd,8), sd->quest_log, sizeof(struct quest)*sd->num_quests); WFIFOSET(inter_fd, len); return 0; @@ -1429,7 +1559,7 @@ void intif_parse_MailInboxReceived(int fd) { else if( battle_config.mail_show_status && ( battle_config.mail_show_status == 1 || sd->mail.inbox.unread ) ) { char output[128]; sprintf(output, msg_txt(510), sd->mail.inbox.unchecked, sd->mail.inbox.unread + sd->mail.inbox.unchecked); - clif->disp_onlyself(sd, output, strlen(output)); + clif_disp_onlyself(sd, output, strlen(output)); } } /*------------------------------------------ @@ -1522,7 +1652,7 @@ void intif_parse_MailDelete(int fd) { } if( sd->mail.inbox.full ) - intif_Mail_requestinbox(sd->status.char_id, 1); // Free space is available for new mails + intif->Mail_requestinbox(sd->status.char_id, 1); // Free space is available for new mails } clif->mail_delete(sd->fd, mail_id, failed); @@ -1563,7 +1693,7 @@ void intif_parse_MailReturn(int fd) { } if( sd->mail.inbox.full ) - intif_Mail_requestinbox(sd->status.char_id, 1); // Free space is available for new mails + intif->Mail_requestinbox(sd->status.char_id, 1); // Free space is available for new mails } clif->mail_return(sd->fd, mail_id, fail); @@ -1760,7 +1890,7 @@ void intif_parse_AuctionClose(int fd) { if( result == 0 ) { // FIXME: Leeching off a parse function clif->pAuction_cancelreg(fd, sd); - intif_Auction_requestlist(sd->status.char_id, 6, 0, "", 1); + intif->Auction_requestlist(sd->status.char_id, 6, 0, "", 1); } } @@ -1797,7 +1927,7 @@ void intif_parse_AuctionBid(int fd) { } if( result == 1 ) { // To update the list, display your buy list clif->pAuction_cancelreg(fd, sd); - intif_Auction_requestlist(sd->status.char_id, 7, 0, "", 1); + intif->Auction_requestlist(sd->status.char_id, 7, 0, "", 1); } } @@ -1995,7 +2125,7 @@ void intif_parse_MessageToFD(int fd) { int aid = RFIFOL(fd,8); struct map_session_data * sd = session[u_fd]->session_data; /* matching e.g. previous fd owner didn't dc during request or is still the same */ - if( sd->bl.id == aid ) { + if( sd && sd->bl.id == aid ) { char msg[512]; safestrncpy(msg, (char*)RFIFOP(fd,12), RFIFOW(fd,2) - 12); clif->message(u_fd,msg); @@ -2005,7 +2135,34 @@ void intif_parse_MessageToFD(int fd) { return; } +/*========================================== + * Item Bound System [Xantara][Mhalicot] + *------------------------------------------*/ +void intif_itembound_req(int char_id,int aid,int guild_id) { +#ifdef GP_BOUND_ITEMS + struct guild_storage *gstor = gstorage->id2storage2(guild_id); + WFIFOHEAD(inter_fd,12); + WFIFOW(inter_fd,0) = 0x3056; + WFIFOL(inter_fd,2) = char_id; + WFIFOL(inter_fd,6) = aid; + WFIFOW(inter_fd,10) = guild_id; + WFIFOSET(inter_fd,12); + if(gstor) + gstor->lock = 1; //Lock for retrieval process +#endif +} + +//3856 +void intif_parse_Itembound_ack(int fd) { +#ifdef GP_BOUND_ITEMS + struct guild_storage *gstor; + int guild_id = RFIFOW(fd,6); + gstor = gstorage->id2storage2(guild_id); + if(gstor) + gstor->lock = 0; //Unlock now that operation is completed +#endif +} //----------------------------------------------------------------- // Communication from the inter server // Return a 0 (false) if there were any errors. @@ -2088,7 +2245,14 @@ int intif_parse(int fd) case 0x3853: intif->pAuctionClose(fd); break; case 0x3854: intif->pAuctionMessage(fd); break; case 0x3855: intif->pAuctionBid(fd); break; - + //Bound items + case 0x3856: +#ifdef GP_BOUND_ITEMS + intif->pItembound_ack(fd); +#else + ShowWarning("intif_parse: Received 0x3856 with GP_BOUND_ITEMS disabled !!!\n"); +#endif + break; // Mercenary System case 0x3870: intif->pMercenaryReceived(fd); break; case 0x3871: intif->pMercenaryDeleted(fd); break; @@ -2127,7 +2291,7 @@ void intif_defaults(void) { 39,-1,15,15, 14,19, 7,-1, 0, 0, 0, 0, 0, 0, 0, 0, //0x3820 10,-1,15, 0, 79,19, 7,-1, 0,-1,-1,-1, 14,67,186,-1, //0x3830 -1, 0, 0,14, 0, 0, 0, 0, -1,74,-1,11, 11,-1, 0, 0, //0x3840 - -1,-1, 7, 7, 7,11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3850 Auctions [Zephyrus] + -1,-1, 7, 7, 7,11, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3850 Auctions [Zephyrus] itembound[Akinari] -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3860 Quests [Kevin] [Inkfish] -1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 3, 3, 0, //0x3870 Mercenaries [Zephyrus] / Elemental [pakpil] 11,-1, 7, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3880 @@ -2216,6 +2380,8 @@ void intif_defaults(void) { /* */ intif->CheckForCharServer = CheckForCharServer; /* */ + intif->itembound_req = intif_itembound_req; + /* parse functions */ intif->pWisMessage = intif_parse_WisMessage; intif->pWisEnd = intif_parse_WisEnd; intif->pWisToGM_sub = mapif_parse_WisToGM_sub; @@ -2263,6 +2429,7 @@ void intif_defaults(void) { intif->pAuctionClose = intif_parse_AuctionClose; intif->pAuctionMessage = intif_parse_AuctionMessage; intif->pAuctionBid = intif_parse_AuctionBid; + intif->pItembound_ack = intif_parse_Itembound_ack; intif->pMercenaryReceived = intif_parse_MercenaryReceived; intif->pMercenaryDeleted = intif_parse_MercenaryDeleted; intif->pMercenarySaved = intif_parse_MercenarySaved; diff --git a/src/map/intif.h b/src/map/intif.h index 768e735de..290dcfcdc 100644 --- a/src/map/intif.h +++ b/src/map/intif.h @@ -2,8 +2,8 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _INTIF_H_ -#define _INFIF_H_ +#ifndef _MAP_INTIF_H_ +#define _MAP_INTIF_H_ /** @@ -22,9 +22,9 @@ struct auction_data; /** * Defines **/ -#define intif_rename_pc(sd, name) intif->rename(sd, 0, name) -#define intif_rename_pet(sd, name) intif->rename(sd, 1, name) -#define intif_rename_hom(sd, name) intif->rename(sd, 2, name) +#define intif_rename_pc(sd, name) (intif->rename((sd), 0, (name))) +#define intif_rename_pet(sd, name) (intif->rename((sd), 1, (name))) +#define intif_rename_hom(sd, name) (intif->rename((sd), 2, (name))) #define INTIF_PACKET_LEN_TABLE_SIZE 161 @@ -40,12 +40,12 @@ struct intif_interface { int (*parse) (int fd); int (*create_pet)(int account_id, int char_id, short pet_type, short pet_lv, short pet_egg_id, short pet_equip, short intimate, short hungry, char rename_flag, char incuvate, char *pet_name); - int (*broadcast) (const char* mes, int len, int type); - int (*broadcast2) (const char* mes, int len, unsigned long fontColor, short fontType, short fontSize, short fontAlign, short fontY); + int (*broadcast) (const char* mes, size_t len, int type); + int (*broadcast2) (const char* mes, size_t len, unsigned int fontColor, short fontType, short fontSize, short fontAlign, short fontY); int (*main_message) (struct map_session_data* sd, const char* message); - int (*wis_message) (struct map_session_data *sd,char *nick,char *mes,int mes_len); + int (*wis_message) (struct map_session_data *sd,char *nick,char *mes,size_t mes_len); int (*wis_message_to_gm) (char *Wisp_name, int permission, char *mes); - int (*saveregistry) (struct map_session_data *sd, int type); + int (*saveregistry) (struct map_session_data *sd); int (*request_registry) (struct map_session_data *sd, int flag); int (*request_guild_storage) (int account_id, int guild_id); int (*send_guild_storage) (int account_id, struct guild_storage *gstor); @@ -65,7 +65,7 @@ struct intif_interface { int (*guild_memberinfoshort) (int guild_id, int account_id, int char_id, int online, int lv, int class_); int (*guild_break) (int guild_id); int (*guild_message) (int guild_id, int account_id, const char *mes, int len); - int (*guild_change_gm) (int guild_id, const char* name, int len); + int (*guild_change_gm) (int guild_id, const char* name, size_t len); int (*guild_change_basicinfo) (int guild_id, int type, const void *data, int len); int (*guild_change_memberinfo) (int guild_id, int account_id, int char_id, int type, const void *data, int len); int (*guild_position) (int guild_id, int idx, struct guild_position *p); @@ -75,6 +75,7 @@ struct intif_interface { int (*guild_emblem) (int guild_id, int len, const char *data); int (*guild_castle_dataload) (int num, int *castle_ids); int (*guild_castle_datasave) (int castle_id, int index, int value); + void (*itembound_req) (int char_id, int aid, int guild_id); int (*request_petdata) (int account_id, int char_id, int pet_id); int (*save_petdata) (int account_id, struct s_pet *p); int (*delete_petdata) (int pet_id); @@ -84,7 +85,7 @@ struct intif_interface { int (*homunculus_requestsave) (int account_id, struct s_homunculus* sh); int (*homunculus_requestdelete) (int homun_id); /******QUEST SYTEM*******/ - int (*request_questlog) (struct map_session_data * sd); + void (*request_questlog) (struct map_session_data * sd); int (*quest_save) (struct map_session_data * sd); // MERCENARY SYSTEM int (*mercenary_create) (struct s_mercenary *merc); @@ -161,6 +162,7 @@ struct intif_interface { void (*pAuctionClose) (int fd); void (*pAuctionMessage) (int fd); void (*pAuctionBid) (int fd); + void (*pItembound_ack) (int fd); void (*pMercenaryReceived) (int fd); void (*pMercenaryDeleted) (int fd); void (*pMercenarySaved) (int fd); @@ -181,4 +183,4 @@ struct intif_interface *intif; void intif_defaults(void); -#endif /* _INTIF_H_ */ +#endif /* _MAP_INTIF_H_ */ diff --git a/src/map/irc-bot.c b/src/map/irc-bot.c index 5225672af..ff28082e7 100644 --- a/src/map/irc-bot.c +++ b/src/map/irc-bot.c @@ -29,7 +29,7 @@ char send_string[IRC_MESSAGE_LENGTH]; * Timer callback to (re-)connect to an IRC server * @see timer->do_timer */ -int irc_connect_timer(int tid, unsigned int tick, int id, intptr_t data) { +int irc_connect_timer(int tid, int64 tick, int id, intptr_t data) { struct hSockOpt opt; if( ircbot->isOn || ++ircbot->fails >= 3 ) return 0; @@ -52,7 +52,7 @@ int irc_connect_timer(int tid, unsigned int tick, int id, intptr_t data) { * Timer callback to send identification commands to an IRC server * @see timer->do_timer */ -int irc_identify_timer(int tid, unsigned int tick, int id, intptr_t data) { +int irc_identify_timer(int tid, int64 tick, int id, intptr_t data) { if( !ircbot->isOn ) return 0; @@ -70,7 +70,7 @@ int irc_identify_timer(int tid, unsigned int tick, int id, intptr_t data) { * Timer callback to join channels (and optionally send NickServ commands) * @see timer->do_timer */ -int irc_join_timer(int tid, unsigned int tick, int id, intptr_t data) { +int irc_join_timer(int tid, int64 tick, int id, intptr_t data) { if( !ircbot->isOn ) return 0; @@ -152,7 +152,8 @@ int irc_parse(int fd) { * NULL, needs to be able to fit an IRC_HOST_LENGTH long string) */ void irc_parse_source(char *source, char *nick, char *ident, char *host) { - int i, len = strlen(source), pos = 0; + int i, pos = 0; + size_t len = strlen(source); unsigned char stage = 0; for(i = 0; i < len; i++) { @@ -208,7 +209,7 @@ void irc_parse_sub(int fd, char *str) { * @param str Command to send */ void irc_send(char *str) { - int len = strlen(str) + 2; + size_t len = strlen(str) + 2; if (len > IRC_MESSAGE_LENGTH-3) len = IRC_MESSAGE_LENGTH-3; WFIFOHEAD(ircbot->fd, len); @@ -289,7 +290,7 @@ void irc_privmsg(int fd, char *cmd, char *source, char *target, char *msg) { } else if( strcmpi(target,hChSys.irc_nick) == 0 ) { ShowDebug("irc_privmsg: Received message from %s: '%s'\n", source ? source : "(null)", msg); #endif // IRCBOT_DEBUG - } else if( strcmpi(target,hChSys.irc_channel) == 0 ) { + } else if( msg && strcmpi(target,hChSys.irc_channel) == 0 ) { char source_nick[IRC_NICK_LENGTH], source_ident[IRC_IDENT_LENGTH], source_host[IRC_HOST_LENGTH]; source_nick[0] = source_ident[0] = source_host[0] = '\0'; @@ -298,7 +299,7 @@ void irc_privmsg(int fd, char *cmd, char *source, char *target, char *msg) { ircbot->parse_source(source,source_nick,source_ident,source_host); if( ircbot->channel ) { - int padding_len = strlen(ircbot->channel->name) + strlen(source_nick) + 13; + size_t padding_len = strlen(ircbot->channel->name) + strlen(source_nick) + 13; while (1) { snprintf(send_string, 150, "[ #%s ] IRC.%s : %s",ircbot->channel->name,source_nick,msg); clif->chsys_msg2(ircbot->channel,send_string); @@ -386,7 +387,7 @@ void irc_relay(char *name, const char *msg) { /** * IRC bot initializer */ -void irc_bot_init(void) { +void irc_bot_init(bool minimal) { /// Command handlers const struct irc_func irc_func_base[] = { { "PING" , ircbot->pong }, @@ -399,6 +400,9 @@ void irc_bot_init(void) { struct irc_func* function; int i; + if (minimal) + return; + if( !hChSys.irc ) return; diff --git a/src/map/irc-bot.h b/src/map/irc-bot.h index aafbfccde..c15a5d46a 100644 --- a/src/map/irc-bot.h +++ b/src/map/irc-bot.h @@ -3,8 +3,8 @@ // Base Author: shennetsind @ http://hercules.ws -#ifndef _IRC_BOT_H_ -#define _IRC_BOT_H_ +#ifndef _MAP_IRC_BOT_H_ +#define _MAP_IRC_BOT_H_ #define IRC_NICK_LENGTH 40 #define IRC_IDENT_LENGTH 40 @@ -22,9 +22,9 @@ struct irc_func { struct irc_bot_interface { int fd; bool isIn, isOn; - unsigned int last_try; + int64 last_try; unsigned char fails; - unsigned long ip; + uint32 ip; unsigned short port; /* */ struct hChSysCh *channel; @@ -34,7 +34,7 @@ struct irc_bot_interface { unsigned int size; } funcs; /* */ - void (*init) (void); + void (*init) (bool minimal); void (*final) (void); /* */ int (*parse) (int fd); @@ -43,9 +43,9 @@ struct irc_bot_interface { /* */ struct irc_func* (*func_search) (char* function_name); /* */ - int (*connect_timer) (int tid, unsigned int tick, int id, intptr_t data); - int (*identify_timer) (int tid, unsigned int tick, int id, intptr_t data); - int (*join_timer) (int tid, unsigned int tick, int id, intptr_t data); + int (*connect_timer) (int tid, int64 tick, int id, intptr_t data); + int (*identify_timer) (int tid, int64 tick, int id, intptr_t data); + int (*join_timer) (int tid, int64 tick, int id, intptr_t data); /* */ void (*send)(char *str); void (*relay) (char *name, const char *msg); @@ -61,4 +61,4 @@ struct irc_bot_interface *ircbot; void ircbot_defaults(void); -#endif /* _IRC_BOT_H_ */ +#endif /* _MAP_IRC_BOT_H_ */ diff --git a/src/map/itemdb.c b/src/map/itemdb.c index fe2c43fcc..bfcc6f795 100644 --- a/src/map/itemdb.c +++ b/src/map/itemdb.c @@ -33,11 +33,13 @@ int itemdb_searchname_sub(DBKey key, DBData *data, va_list ap) str=va_arg(ap,char *); dst=va_arg(ap,struct item_data **); dst2=va_arg(ap,struct item_data **); - if(item == &itemdb->dummy) return 0; + if (item == &itemdb->dummy) return 0; //Absolute priority to Aegis code name. if (*dst != NULL) return 0; - if( strcmpi(item->name,str)==0 ) + if ( battle_config.case_sensitive_aegisnames && strcmp(item->name,str) == 0 ) + *dst=item; + else if ( !battle_config.case_sensitive_aegisnames && strcasecmp(item->name,str) == 0 ) *dst=item; //Second priority to Client displayed name. @@ -61,7 +63,9 @@ struct item_data* itemdb_searchname(const char *str) { continue; // Absolute priority to Aegis code name. - if( strcasecmp(item->name,str) == 0 ) + if ( battle_config.case_sensitive_aegisnames && strcmp(item->name,str) == 0 ) + return item; + else if ( !battle_config.case_sensitive_aegisnames && strcasecmp(item->name,str) == 0 ) return item; //Second priority to Client displayed name. @@ -90,7 +94,9 @@ int itemdb_searchname_array_sub(DBKey key, DBData data, va_list ap) return 1; //Invalid item. if(stristr(item->jname,str)) return 0; - if(stristr(item->name,str)) + if(battle_config.case_sensitive_aegisnames && strstr(item->name,str)) + return 0; + if(!battle_config.case_sensitive_aegisnames && stristr(item->name,str)) return 0; return strcmpi(item->jname,str); } @@ -113,9 +119,18 @@ int itemdb_searchname_array(struct item_data** data, int size, const char *str, if( item == NULL ) continue; - if( (!flag && (stristr(item->jname,str) || stristr(item->name,str))) || - (flag && (strcmp(item->jname,str) == 0 || strcmp(item->name,str) == 0)) ) - { + if( + (!flag + && (stristr(item->jname,str) + || (battle_config.case_sensitive_aegisnames && strstr(item->name,str)) + || (!battle_config.case_sensitive_aegisnames && stristr(item->name,str)) + )) + || (flag + && (strcmp(item->jname,str) == 0 + || (battle_config.case_sensitive_aegisnames && strcmp(item->name,str) == 0) + || (!battle_config.case_sensitive_aegisnames && strcasecmp(item->name,str) == 0) + )) + ) { if( count < size ) data[count] = item; ++count; @@ -138,7 +153,6 @@ int itemdb_searchname_array(struct item_data** data, int size, const char *str, /* [Ind/Hercules] */ int itemdb_chain_item(unsigned short chain_id, int *rate) { struct item_chain_entry *entry; - int i = 0; if( chain_id >= itemdb->chain_count ) { ShowError("itemdb_chain_item: unknown chain id %d\n", chain_id); @@ -147,18 +161,12 @@ int itemdb_chain_item(unsigned short chain_id, int *rate) { entry = &itemdb->chains[chain_id].items[ rnd()%itemdb->chains[chain_id].qty ]; - for( i = 0; i < itemdb->chains[chain_id].qty; i++ ) { - if( rnd()%10000 >= entry->rate ) { - entry = entry->next; - continue; - } else { - if( rate ) - rate[0] = entry->rate; - return entry->id; - } - } - - return 0; + if( rnd()%10000 >= entry->rate ) + return 0; + + if( rate ) + rate[0] = entry->rate; + return entry->id; } /* [Ind/Hercules] */ void itemdb_package_item(struct map_session_data *sd, struct item_package *package) { @@ -634,18 +642,18 @@ void itemdb_read_groups(void) { int i = 0, count = 0, c; unsigned int *gsize = NULL; - if (conf_read_file(&item_group_conf, config_filename)) { + if (libconfig->read_file(&item_group_conf, config_filename)) { ShowError("can't read %s\n", config_filename); return; } - gsize = aMalloc( config_setting_length(item_group_conf.root) * sizeof(unsigned int) ); + gsize = aMalloc( libconfig->setting_length(item_group_conf.root) * sizeof(unsigned int) ); - for(i = 0; i < config_setting_length(item_group_conf.root); i++) + for(i = 0; i < libconfig->setting_length(item_group_conf.root); i++) gsize[i] = 0; i = 0; - while( (itg = config_setting_get_elem(item_group_conf.root,i++)) ) { + while( (itg = libconfig->setting_get_elem(item_group_conf.root,i++)) ) { const char *name = config_setting_name(itg); if( !itemdb->name2id(name) ) { @@ -656,9 +664,9 @@ void itemdb_read_groups(void) { } c = 0; - while( (it = config_setting_get_elem(itg,c++)) ) { + while( (it = libconfig->setting_get_elem(itg,c++)) ) { if( config_setting_is_list(it) ) - gsize[ i - 1 ] += config_setting_get_int_elem(it,1); + gsize[ i - 1 ] += libconfig->setting_get_int_elem(it,1); else gsize[ i - 1 ] += 1; } @@ -666,10 +674,10 @@ void itemdb_read_groups(void) { } i = 0; - CREATE(itemdb->groups, struct item_group, config_setting_length(item_group_conf.root)); - itemdb->group_count = (unsigned short)config_setting_length(item_group_conf.root); + CREATE(itemdb->groups, struct item_group, libconfig->setting_length(item_group_conf.root)); + itemdb->group_count = (unsigned short)libconfig->setting_length(item_group_conf.root); - while( (itg = config_setting_get_elem(item_group_conf.root,i++)) ) { + while( (itg = libconfig->setting_get_elem(item_group_conf.root,i++)) ) { struct item_data *data = itemdb->name2id(config_setting_name(itg)); int ecount = 0; @@ -680,13 +688,13 @@ void itemdb_read_groups(void) { CREATE(itemdb->groups[count].nameid, unsigned short, gsize[ count ] + 1); c = 0; - while( (it = config_setting_get_elem(itg,c++)) ) { + while( (it = libconfig->setting_get_elem(itg,c++)) ) { int repeat = 1; if( config_setting_is_list(it) ) { - itname = config_setting_get_string_elem(it,0); - repeat = config_setting_get_int_elem(it,1); + itname = libconfig->setting_get_string_elem(it,0); + repeat = libconfig->setting_get_int_elem(it,1); } else - itname = config_setting_get_string_elem(itg,c - 1); + itname = libconfig->setting_get_string_elem(itg,c - 1); if( itname[0] == 'I' && itname[1] == 'D' && strlen(itname) < 8 ) { if( !( data = itemdb->exists(atoi(itname+2)) ) ) @@ -708,7 +716,7 @@ void itemdb_read_groups(void) { count++; } - config_destroy(&item_group_conf); + libconfig->destroy(&item_group_conf); aFree(gsize); ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, config_filename); @@ -798,7 +806,7 @@ bool itemdb_read_cached_packages(const char *config_filename) { for( i = 0; i < pcount; i++ ) { unsigned short id = 0, random_qty = 0, must_qty = 0; - struct item_data *data; + struct item_data *pdata; struct item_package *package = &itemdb->packages[i]; unsigned short c; @@ -809,10 +817,10 @@ bool itemdb_read_cached_packages(const char *config_filename) { //next 2 bytes = random count hread(&random_qty,sizeof(random_qty),1,file); - if( !(data = itemdb->exists(id)) ) + if( !(pdata = itemdb->exists(id)) ) ShowWarning("itemdb_read_packages: unknown package item '%d', skipping..\n",id); else - data->package = &itemdb->packages[i]; + pdata->package = &itemdb->packages[i]; package->id = id; package->random_qty = random_qty; @@ -926,18 +934,18 @@ void itemdb_read_packages(void) { return; } - if (conf_read_file(&item_packages_conf, config_filename)) { + if (libconfig->read_file(&item_packages_conf, config_filename)) { ShowError("can't read %s\n", config_filename); return; } - must = aMalloc( config_setting_length(item_packages_conf.root) * sizeof(unsigned int) ); - random = aMalloc( config_setting_length(item_packages_conf.root) * sizeof(unsigned int) ); - rgroup = aMalloc( config_setting_length(item_packages_conf.root) * sizeof(unsigned int) ); - rgroups = aMalloc( config_setting_length(item_packages_conf.root) * sizeof(unsigned int *) ); + must = aMalloc( libconfig->setting_length(item_packages_conf.root) * sizeof(unsigned int) ); + random = aMalloc( libconfig->setting_length(item_packages_conf.root) * sizeof(unsigned int) ); + rgroup = aMalloc( libconfig->setting_length(item_packages_conf.root) * sizeof(unsigned int) ); + rgroups = aMalloc( libconfig->setting_length(item_packages_conf.root) * sizeof(unsigned int *) ); - for(i = 0; i < config_setting_length(item_packages_conf.root); i++) { + for(i = 0; i < libconfig->setting_length(item_packages_conf.root); i++) { must[i] = 0; random[i] = 0; rgroup[i] = 0; @@ -946,22 +954,22 @@ void itemdb_read_packages(void) { /* validate tree, drop poisonous fruits! */ i = 0; - while( (itg = config_setting_get_elem(item_packages_conf.root,i++)) ) { + while( (itg = libconfig->setting_get_elem(item_packages_conf.root,i++)) ) { const char *name = config_setting_name(itg); if( !itemdb->name2id(name) ) { ShowWarning("itemdb_read_packages: unknown package item '%s', skipping..\n",name); - config_setting_remove(item_packages_conf.root, name); + libconfig->setting_remove(item_packages_conf.root, name); --i; continue; } c = 0; - while( (it = config_setting_get_elem(itg,c++)) ) { + while( (it = libconfig->setting_get_elem(itg,c++)) ) { int rval = 0; - if( !( t = config_setting_get_member(it, "Random") ) || (rval = config_setting_get_int(t)) < 0 ) { + if( !( t = libconfig->setting_get_member(it, "Random") ) || (rval = libconfig->setting_get_int(t)) < 0 ) { ShowWarning("itemdb_read_packages: invalid 'Random' value (%d) for item '%s' in package '%s', defaulting to must!\n",rval,config_setting_name(it),name); - config_setting_remove(it, config_setting_name(it)); + libconfig->setting_remove(it, config_setting_name(it)); --c; continue; } @@ -983,7 +991,7 @@ void itemdb_read_packages(void) { prev[i] = NULL; } - for(i = 0; i < config_setting_length(item_packages_conf.root); i++ ) { + for(i = 0; i < libconfig->setting_length(item_packages_conf.root); i++ ) { rgroups[i] = aMalloc( rgroup[i] * sizeof(unsigned int) ); for( c = 0; c < rgroup[i]; c++ ) { rgroups[i][c] = 0; @@ -992,29 +1000,28 @@ void itemdb_read_packages(void) { /* grab the known sizes */ i = 0; - while( (itg = config_setting_get_elem(item_packages_conf.root,i++)) ) { + while( (itg = libconfig->setting_get_elem(item_packages_conf.root,i++)) ) { c = 0; - while( (it = config_setting_get_elem(itg,c++)) ) { + while( (it = libconfig->setting_get_elem(itg,c++)) ) { int rval = 0; - if( ( t = config_setting_get_member(it, "Random")) && ( rval = config_setting_get_int(t) ) > 0 ) { + if( ( t = libconfig->setting_get_member(it, "Random")) && ( rval = libconfig->setting_get_int(t) ) > 0 ) { rgroups[i - 1][rval - 1] += 1; } } } - CREATE(itemdb->packages, struct item_package, config_setting_length(item_packages_conf.root)); - itemdb->package_count = (unsigned short)config_setting_length(item_packages_conf.root); + CREATE(itemdb->packages, struct item_package, libconfig->setting_length(item_packages_conf.root)); + itemdb->package_count = (unsigned short)libconfig->setting_length(item_packages_conf.root); /* write */ i = 0; - while( (itg = config_setting_get_elem(item_packages_conf.root,i++)) ) { + while( (itg = libconfig->setting_get_elem(item_packages_conf.root,i++)) ) { struct item_data *data = itemdb->name2id(config_setting_name(itg)); int r = 0, m = 0; for(r = 0; r < highest_gcount; r++) { prev[r] = NULL; } - r = 0; data->package = &itemdb->packages[count]; @@ -1027,7 +1034,10 @@ void itemdb_read_packages(void) { if( itemdb->packages[count].random_qty ) { CREATE(itemdb->packages[count].random_groups, struct item_package_rand_group, itemdb->packages[count].random_qty); for( c = 0; c < itemdb->packages[count].random_qty; c++ ) { - CREATE(itemdb->packages[count].random_groups[c].random_list, struct item_package_rand_entry, rgroups[ i - 1 ][c]); + if( !rgroups[ i - 1 ][c] ) + ShowError("itemdb_read_packages: package '%s' missing 'Random' field %d! there must not be gaps!\n",config_setting_name(itg),c+1); + else + CREATE(itemdb->packages[count].random_groups[c].random_list, struct item_package_rand_entry, rgroups[ i - 1 ][c]); itemdb->packages[count].random_groups[c].random_qty = 0; } } @@ -1035,7 +1045,7 @@ void itemdb_read_packages(void) { CREATE(itemdb->packages[count].must_items, struct item_package_must_entry, itemdb->packages[count].must_qty); c = 0; - while( (it = config_setting_get_elem(itg,c++)) ) { + while( (it = libconfig->setting_get_elem(itg,c++)) ) { int icount = 1, expire = 0, rate = 10000, gid = 0; bool announce = false, named = false; @@ -1047,30 +1057,30 @@ void itemdb_read_packages(void) { } else if( !( data = itemdb->name2id(itname) ) ) ShowWarning("itemdb_read_packages: unknown item '%s' in package '%s'!\n",itname,config_setting_name(itg)); - if( ( t = config_setting_get_member(it, "Count")) ) - icount = config_setting_get_int(t); + if( ( t = libconfig->setting_get_member(it, "Count")) ) + icount = libconfig->setting_get_int(t); - if( ( t = config_setting_get_member(it, "Expire")) ) - expire = config_setting_get_int(t); + if( ( t = libconfig->setting_get_member(it, "Expire")) ) + expire = libconfig->setting_get_int(t); - if( ( t = config_setting_get_member(it, "Rate")) ) { - if( (rate = (unsigned short)config_setting_get_int(t)) > 10000 ) { + if( ( t = libconfig->setting_get_member(it, "Rate")) ) { + if( (rate = (unsigned short)libconfig->setting_get_int(t)) > 10000 ) { ShowWarning("itemdb_read_packages: invalid rate (%d) for item '%s' in package '%s'!\n",rate,itname,config_setting_name(itg)); rate = 10000; } } - if( ( t = config_setting_get_member(it, "Announce")) && config_setting_get_bool(t) ) + if( ( t = libconfig->setting_get_member(it, "Announce")) && libconfig->setting_get_bool(t) ) announce = true; - if( ( t = config_setting_get_member(it, "Named")) && config_setting_get_bool(t) ) + if( ( t = libconfig->setting_get_member(it, "Named")) && libconfig->setting_get_bool(t) ) named = true; - if( !( t = config_setting_get_member(it, "Random") ) ) { + if( !( t = libconfig->setting_get_member(it, "Random") ) ) { ShowWarning("itemdb_read_packages: missing 'Random' field for item '%s' in package '%s', defaulting to must!\n",itname,config_setting_name(itg)); gid = 0; } else - gid = config_setting_get_int(t); + gid = libconfig->setting_get_int(t); if( gid == 0 ) { itemdb->packages[count].must_items[m].id = data ? data->nameid : 0; @@ -1090,7 +1100,7 @@ void itemdb_read_packages(void) { itemdb->packages[count].random_groups[gidx].random_list[r].id = data ? data->nameid : 0; itemdb->packages[count].random_groups[gidx].random_list[r].qty = icount; if( (itemdb->packages[count].random_groups[gidx].random_list[r].rate = rate) == 10000 ) { - ShowWarning("itemdb_read_packages: item '%s' in '%s' has 100% drop rate!! set this item as 'Random: 0' or other items won't drop!!!\n",itname,config_setting_name(itg)); + ShowWarning("itemdb_read_packages: item '%s' in '%s' has 100%% drop rate!! set this item as 'Random: 0' or other items won't drop!!!\n",itname,config_setting_name(itg)); } itemdb->packages[count].random_groups[gidx].random_list[r].hours = expire; itemdb->packages[count].random_groups[gidx].random_list[r].announce = announce == true ? 1 : 0; @@ -1121,14 +1131,14 @@ void itemdb_read_packages(void) { aFree(must); aFree(random); - for(i = 0; i < config_setting_length(item_packages_conf.root); i++ ) { + for(i = 0; i < libconfig->setting_length(item_packages_conf.root); i++ ) { aFree(rgroups[i]); } aFree(rgroups); aFree(rgroup); aFree(prev); - config_destroy(&item_packages_conf); + libconfig->destroy(&item_packages_conf); if( HCache->enabled ) itemdb->write_cached_packages(config_filename); @@ -1146,26 +1156,29 @@ void itemdb_read_chains(void) { #endif int i = 0, count = 0; - if (conf_read_file(&item_chain_conf, config_filename)) { + if (libconfig->read_file(&item_chain_conf, config_filename)) { ShowError("can't read %s\n", config_filename); return; } - CREATE(itemdb->chains, struct item_chain, config_setting_length(item_chain_conf.root)); - itemdb->chain_count = (unsigned short)config_setting_length(item_chain_conf.root); + CREATE(itemdb->chains, struct item_chain, libconfig->setting_length(item_chain_conf.root)); + itemdb->chain_count = (unsigned short)libconfig->setting_length(item_chain_conf.root); - while( (itc = config_setting_get_elem(item_chain_conf.root,i++)) ) { +#ifdef ENABLE_CASE_CHECK + script->parser_current_file = config_filename; +#endif // ENABLE_CASE_CHECK + while( (itc = libconfig->setting_get_elem(item_chain_conf.root,i++)) ) { struct item_data *data = NULL; struct item_chain_entry *prev = NULL; const char *name = config_setting_name(itc); int c = 0; script->set_constant2(name,i-1,0); - itemdb->chains[count].qty = (unsigned short)config_setting_length(itc); + itemdb->chains[count].qty = (unsigned short)libconfig->setting_length(itc); - CREATE(itemdb->chains[count].items, struct item_chain_entry, config_setting_length(itc)); + CREATE(itemdb->chains[count].items, struct item_chain_entry, libconfig->setting_length(itc)); - while( (entry = config_setting_get_elem(itc,c++)) ) { + while( (entry = libconfig->setting_get_elem(itc,c++)) ) { const char *itname = config_setting_name(entry); if( itname[0] == 'I' && itname[1] == 'D' && strlen(itname) < 8 ) { if( !( data = itemdb->exists(atoi(itname+2)) ) ) @@ -1177,7 +1190,7 @@ void itemdb_read_chains(void) { prev->next = &itemdb->chains[count].items[c - 1]; itemdb->chains[count].items[c - 1].id = data ? data->nameid : 0; - itemdb->chains[count].items[c - 1].rate = data ? config_setting_get_int(entry) : 0; + itemdb->chains[count].items[c - 1].rate = data ? libconfig->setting_get_int(entry) : 0; prev = &itemdb->chains[count].items[c - 1]; } @@ -1187,8 +1200,11 @@ void itemdb_read_chains(void) { count++; } +#ifdef ENABLE_CASE_CHECK + script->parser_current_file = NULL; +#endif // ENABLE_CASE_CHECK - config_destroy(&item_chain_conf); + libconfig->destroy(&item_chain_conf); if( !script->get_constant("ITMCHAIN_ORE",&i) ) ShowWarning("itemdb_read_chains: failed to find 'ITMCHAIN_ORE' chain to link to cache!\n"); @@ -1289,7 +1305,7 @@ bool itemdb_read_stack(char* fields[], int columns, int current) } amount = (unsigned short)strtoul(fields[1], NULL, 10); - type = strtoul(fields[2], NULL, 10); + type = (unsigned int)strtoul(fields[2], NULL, 10); if( !amount ) {// ignore @@ -1439,8 +1455,7 @@ void itemdb_read_combos() { } else { int items[MAX_ITEMS_PER_COMBO]; int v = 0, retcount = 0; - struct item_data * id = NULL; - int idx = 0; + struct item_combo *combo = NULL; if((retcount = itemdb->combo_split_atoi(str[0], items)) < 2) { ShowError("itemdb_read_combos: line %d of \"%s\" doesn't have enough items to make for a combo (min:2), skipping.\n", lines, filepath); @@ -1457,33 +1472,23 @@ void itemdb_read_combos() { /* failed at some item */ if( v < retcount ) continue; - - id = itemdb->exists(items[0]); - idx = id->combos_count; + RECREATE(itemdb->combos, struct item_combo*, ++itemdb->combo_count); - /* first entry, create */ - if( id->combos == NULL ) { - CREATE(id->combos, struct item_combo*, 1); - id->combos_count = 1; - } else { - RECREATE(id->combos, struct item_combo*, ++id->combos_count); - } + CREATE(combo, struct item_combo, 1); - CREATE(id->combos[idx],struct item_combo,1); - - id->combos[idx]->nameid = aMalloc( retcount * sizeof(unsigned short) ); - id->combos[idx]->count = retcount; - id->combos[idx]->script = script->parse(str[1], filepath, lines, 0); - id->combos[idx]->id = count; - id->combos[idx]->isRef = false; + combo->count = retcount; + combo->script = script->parse(str[1], filepath, lines, 0); + combo->id = itemdb->combo_count - 1; /* populate ->nameid field */ for( v = 0; v < retcount; v++ ) { - id->combos[idx]->nameid[v] = items[v]; + combo->nameid[v] = items[v]; } - /* populate the children to refer to this combo */ - for( v = 1; v < retcount; v++ ) { + itemdb->combos[itemdb->combo_count - 1] = combo; + + /* populate the items to refer to this combo */ + for( v = 0; v < retcount; v++ ) { struct item_data * it; int index; @@ -1491,19 +1496,9 @@ void itemdb_read_combos() { index = it->combos_count; - if( it->combos == NULL ) { - CREATE(it->combos, struct item_combo*, 1); - it->combos_count = 1; - } else { - RECREATE(it->combos, struct item_combo*, ++it->combos_count); - } - - CREATE(it->combos[index],struct item_combo,1); + RECREATE(it->combos, struct item_combo*, ++it->combos_count); - /* we copy previously alloc'd pointers and just set it to reference */ - memcpy(it->combos[index],id->combos[idx],sizeof(struct item_combo)); - /* we flag this way to ensure we don't double-dealloc same data */ - it->combos[index]->isRef = true; + it->combos[index] = combo; } } @@ -1536,336 +1531,436 @@ int itemdb_gendercheck(struct item_data *id) return (battle_config.ignore_items_gender) ? 2 : id->sex; } + /** - * [RRInd] - * For backwards compatibility, in Renewal mode, MATK from weapons comes from the atk slot - * We use a ':' delimiter which, if not found, assumes the weapon does not provide any matk. - **/ -void itemdb_re_split_atoi(char *str, int *atk, int *matk) { - int i, val[2]; + * Validates an item DB entry and inserts it into the database. + * This function is called after preparing the item entry data, and it takes + * care of inserting it and cleaning up any remainders of the previous one. + * + * @param *entry Pointer to the new item_data entry. Ownership is NOT taken, + * but the content is modified to reflect the validation. + * @param n Ordinal number of the entry, to be displayed in case of + * validation errors. + * @param *source Source of the entry (table or file name), to be displayed in + * case of validation errors. + * @return Nameid of the validated entry, or 0 in case of failure. + * + * Note: This is safe to call if the new entry is a copy of the old one (i.e. + * item_db2 inheritance), as it will make sure not to free any scripts still in + * use in the new entry. + */ +int itemdb_validate_entry(struct item_data *entry, int n, const char *source) { + struct item_data *item; + + if( entry->nameid <= 0 || entry->nameid >= MAX_ITEMDB ) { + ShowWarning("itemdb_validate_entry: Invalid item ID %d in entry %d of '%s', allowed values 0 < ID < %d (MAX_ITEMDB), skipping.\n", + entry->nameid, n, source, MAX_ITEMDB); + if (entry->script) { + script->free_code(entry->script); + entry->script = NULL; + } + if (entry->equip_script) { + script->free_code(entry->equip_script); + entry->equip_script = NULL; + } + if (entry->unequip_script) { + script->free_code(entry->unequip_script); + entry->unequip_script = NULL; + } + return 0; + } - for (i=0; i<2; i++) { - if (!str) break; - val[i] = atoi(str); - str = strchr(str,':'); - if (str) - *str++=0; + if( entry->type < 0 || entry->type == IT_UNKNOWN || entry->type == IT_UNKNOWN2 + || (entry->type > IT_DELAYCONSUME && entry->type < IT_CASH ) || entry->type >= IT_MAX + ) { + // catch invalid item types + ShowWarning("itemdb_validate_entry: Invalid item type %d for item %d. IT_ETC will be used.\n", entry->type, entry->nameid); + entry->type = IT_ETC; + } else if( entry->type == IT_DELAYCONSUME ) { + //Items that are consumed only after target confirmation + entry->type = IT_USABLE; + entry->flag.delay_consume = 1; } - if( i == 0 ) { - *atk = *matk = 0; - return;//no data found + + //When a particular price is not given, we should base it off the other one + //(it is important to make a distinction between 'no price' and 0z) + if( entry->value_buy < 0 && entry->value_sell < 0 ) { + entry->value_buy = entry->value_sell = 0; + } else if( entry->value_buy < 0 ) { + entry->value_buy = entry->value_sell * 2; + } else if( entry->value_sell < 0 ) { + entry->value_sell = entry->value_buy / 2; } - if( i == 1 ) {//Single Value, we assume it's the ATK - *atk = val[0]; - *matk = 0; - return; + if( entry->value_buy/124. < entry->value_sell/75. ) { + ShowWarning("itemdb_validate_entry: Buying/Selling [%d/%d] price of item %d (%s) allows Zeny making exploit through buying/selling at discounted/overcharged prices!\n", + entry->value_buy, entry->value_sell, entry->nameid, entry->jname); } - //We assume we have 2 values. - *atk = val[0]; - *matk = val[1]; - return; -} -/*========================================== - * processes one itemdb entry - *------------------------------------------*/ -int itemdb_parse_dbrow(char** str, const char* source, int line, int scriptopt) { - /* - +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+ - | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | - +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+ - | id | name_english | name_japanese | type | price_buy | price_sell | weight | attack | defence | range | slots | equip_jobs | equip_upper | equip_genders | equip_locations | weapon_level | equip_level | refineable | view | script | equip_script | unequip_script | - +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+ - */ - int nameid; - struct item_data* id; - unsigned char offset = 0; - - nameid = atoi(str[0]); - if( nameid <= 0 ) { - ShowWarning("itemdb_parse_dbrow: Invalid id %d in line %d of \"%s\", skipping.\n", nameid, line, source); - return 0; + + if( entry->slot > MAX_SLOTS ) { + ShowWarning("itemdb_validate_entry: Item %d (%s) specifies %d slots, but the server only supports up to %d. Using %d slots.\n", + entry->nameid, entry->jname, entry->slot, MAX_SLOTS, MAX_SLOTS); + entry->slot = MAX_SLOTS; } - //ID,Name,Jname,Type,Price,Sell,Weight,ATK,DEF,Range,Slot,Job,Job Upper,Gender,Loc,wLV,eLV,refineable,View - id = itemdb->load(nameid); - safestrncpy(id->name, str[1], sizeof(id->name)); - safestrncpy(id->jname, str[2], sizeof(id->jname)); + if (!entry->equip && itemdb->isequip2(entry)) { + ShowWarning("itemdb_validate_entry: Item %d (%s) is an equipment with no equip-field! Making it an etc item.\n", entry->nameid, entry->jname); + entry->type = IT_ETC; + } - id->type = atoi(str[3]); + entry->wlv = cap_value(entry->wlv, REFINE_TYPE_ARMOR, REFINE_TYPE_MAX); - if( id->type < 0 || id->type == IT_UNKNOWN || id->type == IT_UNKNOWN2 || ( id->type > IT_DELAYCONSUME && id->type < IT_CASH ) || id->type >= IT_MAX ) - {// catch invalid item types - ShowWarning("itemdb_parse_dbrow: Invalid item type %d for item %d. IT_ETC will be used.\n", id->type, nameid); - id->type = IT_ETC; - } + if( !entry->elvmax ) + entry->elvmax = MAX_LEVEL; + else if( entry->elvmax < entry->elv ) + entry->elvmax = entry->elv; - if (id->type == IT_DELAYCONSUME) - { //Items that are consumed only after target confirmation - id->type = IT_USABLE; - id->flag.delay_consume = 1; - } else //In case of an itemdb reload and the item type changed. - id->flag.delay_consume = 0; + if( entry->type != IT_ARMOR && entry->type != IT_WEAPON && !entry->flag.no_refine ) + entry->flag.no_refine = 1; - //When a particular price is not given, we should base it off the other one - //(it is important to make a distinction between 'no price' and 0z) - if ( str[4][0] ) - id->value_buy = atoi(str[4]); - else - id->value_buy = atoi(str[5]) * 2; + entry->flag.available = 1; + entry->view_id = 0; + entry->sex = itemdb->gendercheck(entry); //Apply gender filtering. - if ( str[5][0] ) - id->value_sell = atoi(str[5]); - else - id->value_sell = id->value_buy / 2; - /* - if ( !str[4][0] && !str[5][0]) - { - ShowWarning("itemdb_parse_dbrow: No buying/selling price defined for item %d (%s), using 20/10z\n", nameid, id->jname); - id->value_buy = 20; - id->value_sell = 10; - } else - */ - if (id->value_buy/124. < id->value_sell/75.) - ShowWarning("itemdb_parse_dbrow: Buying/Selling [%d/%d] price of item %d (%s) allows Zeny making exploit through buying/selling at discounted/overcharged prices!\n", - id->value_buy, id->value_sell, nameid, id->jname); - - id->weight = atoi(str[6]); -#ifdef RENEWAL - if( map->db_use_sql_item_db ) { - id->atk = atoi(str[7]); - id->matk = atoi(str[8]); - offset += 1; - } else - itemdb->re_split_atoi(str[7],&id->atk,&id->matk); -#else - id->atk = atoi(str[7]); -#endif - id->def = atoi(str[8+offset]); - id->range = atoi(str[9+offset]); - id->slot = atoi(str[10+offset]); + // Validated. Finally insert it + item = itemdb->load(entry->nameid); - if (id->slot > MAX_SLOTS) { - ShowWarning("itemdb_parse_dbrow: Item %d (%s) specifies %d slots, but the server only supports up to %d. Using %d slots.\n", nameid, id->jname, id->slot, MAX_SLOTS, MAX_SLOTS); - id->slot = MAX_SLOTS; + if (item->script && item->script != entry->script) { // Don't free if it's inheriting the same script + script->free_code(item->script); + item->script = NULL; + } + if (item->equip_script && item->equip_script != entry->equip_script) { // Don't free if it's inheriting the same script + script->free_code(item->equip_script); + item->equip_script = NULL; + } + if (item->unequip_script && item->unequip_script != entry->unequip_script) { // Don't free if it's inheriting the same script + script->free_code(item->unequip_script); + item->unequip_script = NULL; } - itemdb->jobid2mapid(id->class_base, (unsigned int)strtoul(str[11+offset],NULL,0)); - id->class_upper = atoi(str[12+offset]); - id->sex = atoi(str[13+offset]); - id->equip = atoi(str[14+offset]); + *item = *entry; + return item->nameid; +} - if (!id->equip && itemdb->isequip2(id)) { - ShowWarning("Item %d (%s) is an equipment with no equip-field! Making it an etc item.\n", nameid, id->jname); - id->type = IT_ETC; - } +/** + * Processes one itemdb entry from the sql backend, loading and inserting it + * into the item database. + * + * @param *handle MySQL connection handle. It is expected to have data + * available (i.e. already queried) and it won't be freed (it + * is care of the caller to do so) + * @param n Ordinal number of the entry, to be displayed in case of + * validation errors. + * @param *source Source of the entry (table name), to be displayed in case of + * validation errors. + * @return Nameid of the validated entry, or 0 in case of failure. + */ +int itemdb_readdb_sql_sub(Sql *handle, int n, const char *source) { + struct item_data id = { 0 }; + char *data = NULL; - id->wlv = cap_value(atoi(str[15+offset]), REFINE_TYPE_ARMOR, REFINE_TYPE_MAX); -#ifdef RENEWAL - if( map->db_use_sql_item_db ) { - id->elv = atoi(str[16+offset]); - id->elvmax = atoi(str[17+offset]); - offset += 1; - } else - itemdb->re_split_atoi(str[16],&id->elv,&id->elvmax); -#else - id->elv = atoi(str[16]); -#endif - id->flag.no_refine = atoi(str[17+offset]) ? 0 : 1; //FIXME: verify this - id->look = atoi(str[18+offset]); + /* + * `id` smallint(5) unsigned NOT NULL DEFAULT '0' + * `name_english` varchar(50) NOT NULL DEFAULT '' + * `name_japanese` varchar(50) NOT NULL DEFAULT '' + * `type` tinyint(2) unsigned NOT NULL DEFAULT '0' + * `price_buy` mediumint(10) DEFAULT NULL + * `price_sell` mediumint(10) DEFAULT NULL + * `weight` smallint(5) unsigned DEFAULT NULL + * `atk` smallint(5) unsigned DEFAULT NULL + * `matk` smallint(5) unsigned DEFAULT NULL + * `defence` smallint(5) unsigned DEFAULT NULL + * `range` tinyint(2) unsigned DEFAULT NULL + * `slots` tinyint(2) unsigned DEFAULT NULL + * `equip_jobs` int(12) unsigned DEFAULT NULL + * `equip_upper` tinyint(8) unsigned DEFAULT NULL + * `equip_genders` tinyint(2) unsigned DEFAULT NULL + * `equip_locations` smallint(4) unsigned DEFAULT NULL + * `weapon_level` tinyint(2) unsigned DEFAULT NULL + * `equip_level_min` smallint(5) unsigned DEFAULT NULL + * `equip_level_max` smallint(5) unsigned DEFAULT NULL + * `refineable` tinyint(1) unsigned DEFAULT NULL + * `view` smallint(3) unsigned DEFAULT NULL + * `bindonequip` tinyint(1) unsigned DEFAULT NULL + * `script` text + * `equip_script` text + * `unequip_script` text + */ + SQL->GetData(handle, 0, &data, NULL); id.nameid = (uint16)atoi(data); + SQL->GetData(handle, 1, &data, NULL); safestrncpy(id.name, data, sizeof(id.name)); + SQL->GetData(handle, 2, &data, NULL); safestrncpy(id.jname, data, sizeof(id.jname)); + SQL->GetData(handle, 3, &data, NULL); id.type = atoi(data); + SQL->GetData(handle, 4, &data, NULL); id.value_buy = data ? atoi(data) : -1; // Using invalid price -1 when missing, it'll be validated later + SQL->GetData(handle, 5, &data, NULL); id.value_sell = data ? atoi(data) : -1; + SQL->GetData(handle, 6, &data, NULL); id.weight = data ? atoi(data) : 0; + SQL->GetData(handle, 7, &data, NULL); id.atk = data ? atoi(data) : 0; + SQL->GetData(handle, 8, &data, NULL); id.matk = data ? atoi(data) : 0; + SQL->GetData(handle, 9, &data, NULL); id.def = data ? atoi(data) : 0; + SQL->GetData(handle, 10, &data, NULL); id.range = data ? atoi(data) : 0; + SQL->GetData(handle, 11, &data, NULL); id.slot = data ? atoi(data) : 0; + SQL->GetData(handle, 12, &data, NULL); itemdb->jobid2mapid(id.class_base, data ? (unsigned int)strtoul(data,NULL,0) : UINT_MAX); + SQL->GetData(handle, 13, &data, NULL); id.class_upper = data ? (unsigned int)atoi(data) : ITEMUPPER_ALL; + SQL->GetData(handle, 14, &data, NULL); id.sex = data ? atoi(data) : 2; + SQL->GetData(handle, 15, &data, NULL); id.equip = data ? atoi(data) : 0; + SQL->GetData(handle, 16, &data, NULL); id.wlv = data ? atoi(data) : 0; + SQL->GetData(handle, 17, &data, NULL); id.elv = data ? atoi(data) : 0; + SQL->GetData(handle, 18, &data, NULL); id.elvmax = data ? atoi(data) : 0; + SQL->GetData(handle, 19, &data, NULL); id.flag.no_refine = data && atoi(data) ? 0 : 1; + SQL->GetData(handle, 20, &data, NULL); id.look = data ? atoi(data) : 0; + SQL->GetData(handle, 21, &data, NULL); id.flag.bindonequip = data && atoi(data) ? 1 : 0; + SQL->GetData(handle, 22, &data, NULL); id.script = data && *data ? script->parse(data, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS) : NULL; + SQL->GetData(handle, 23, &data, NULL); id.equip_script = data && *data ? script->parse(data, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS) : NULL; + SQL->GetData(handle, 24, &data, NULL); id.unequip_script = data && *data ? script->parse(data, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS) : NULL; + + return itemdb->validate_entry(&id, n, source); +} - id->flag.available = 1; - id->view_id = 0; - id->sex = itemdb->gendercheck(id); //Apply gender filtering. +/** + * Processes one itemdb entry from the sql backend, loading and inserting it + * into the item database. + * + * @param *it Libconfig setting entry. It is expected to be valid and it + * won't be freed (it is care of the caller to do so if + * necessary) + * @param n Ordinal number of the entry, to be displayed in case of + * validation errors. + * @param *source Source of the entry (file name), to be displayed in case of + * validation errors. + * @return Nameid of the validated entry, or 0 in case of failure. + */ +int itemdb_readdb_libconfig_sub(config_setting_t *it, int n, const char *source) { + struct item_data id = { 0 }; + config_setting_t *t = NULL; + const char *str = NULL; + int i32 = 0; + bool inherit = false; - if (id->script) { - script->free_code(id->script); - id->script = NULL; + /* + * // Mandatory fields + * Id: ID + * AegisName: "Aegis_Name" + * Name: "Item Name" + * // Optional fields + * Type: Item Type + * Buy: Buy Price + * Sell: Sell Price + * Weight: Item Weight + * Atk: Attack + * Matk: Attack + * Def: Defense + * Range: Attack Range + * Slots: Slots + * Job: Job mask + * Upper: Upper mask + * Gender: Gender + * Loc: Equip location + * WeaponLv: Weapon Level + * EquipLv: Equip required level + * Refine: Refineable + * View: View ID + * BindOnEquip: (true or false) + * Script: <" + * Script + * (it can be multi-line) + * "> + * OnEquipScript: <" OnEquip Script "> + * OnUnequipScript: <" OnUnequip Script "> + * Inherit: inherit or override + */ + if( !libconfig->setting_lookup_int(it, "Id", &i32) ) { + ShowWarning("itemdb_readdb_libconfig_sub: Invalid or missing id in \"%s\", entry #%d, skipping.\n", source, n); + return 0; } - if (id->equip_script) { - script->free_code(id->equip_script); - id->equip_script = NULL; + id.nameid = (uint16)i32; + + if( (t = libconfig->setting_get_member(it, "Inherit")) && (inherit = libconfig->setting_get_bool(t)) ) { + if( !itemdb->exists(id.nameid) ) { + ShowWarning("itemdb_readdb_libconfig_sub: Trying to inherit nonexistent item %d, default values will be used instead.\n", id.nameid); + inherit = false; + } else { + // Use old entry as default + struct item_data *old_entry = itemdb->load(id.nameid); + memcpy(&id, old_entry, sizeof(struct item_data)); + } } - if (id->unequip_script) { - script->free_code(id->unequip_script); - id->unequip_script = NULL; + + if( !libconfig->setting_lookup_string(it, "AegisName", &str) || !*str ) { + if( !inherit ) { + ShowWarning("itemdb_readdb_libconfig_sub: Missing AegisName in item %d of \"%s\", skipping.\n", id.nameid, source); + return 0; + } + } else { + safestrncpy(id.name, str, sizeof(id.name)); } - if (*str[19+offset]) - id->script = script->parse(str[19+offset], source, line, scriptopt); - if (*str[20+offset]) - id->equip_script = script->parse(str[20+offset], source, line, scriptopt); - if (*str[21+offset]) - id->unequip_script = script->parse(str[21+offset], source, line, scriptopt); + if( !libconfig->setting_lookup_string(it, "Name", &str) || !*str ) { + if( !inherit ) { + ShowWarning("itemdb_readdb_libconfig_sub: Missing Name in item %d of \"%s\", skipping.\n", id.nameid, source); + return 0; + } + } else { + safestrncpy(id.jname, str, sizeof(id.jname)); + } - return id->nameid; -} + if( libconfig->setting_lookup_int(it, "Type", &i32) ) + id.type = i32; + else if( !inherit ) + id.type = IT_UNKNOWN; -/*========================================== - * Reading item from item db - * item_db2 overwriting item_db - *------------------------------------------*/ -int itemdb_readdb(void) -{ - const char* filename[] = { - DBPATH"item_db.txt", - "item_db2.txt" }; + if( libconfig->setting_lookup_int(it, "Buy", &i32) ) + id.value_buy = i32; + else if( !inherit ) + id.value_buy = -1; + if( libconfig->setting_lookup_int(it, "Sell", &i32) ) + id.value_sell = i32; + else if( !inherit ) + id.value_sell = -1; - int fi; + if( libconfig->setting_lookup_int(it, "Weight", &i32) && i32 >= 0 ) + id.weight = i32; - for( fi = 0; fi < ARRAYLENGTH(filename); ++fi ) { - uint32 lines = 0, count = 0; - char line[1024]; + if( libconfig->setting_lookup_int(it, "Atk", &i32) && i32 >= 0 ) + id.atk = i32; - char filepath[256]; - FILE* fp; + if( libconfig->setting_lookup_int(it, "Matk", &i32) && i32 >= 0 ) + id.matk = i32; - sprintf(filepath, "%s/%s", map->db_path, filename[fi]); - fp = fopen(filepath, "r"); - if( fp == NULL ) { - ShowWarning("itemdb_readdb: File not found \"%s\", skipping.\n", filepath); - continue; - } + if( libconfig->setting_lookup_int(it, "Def", &i32) && i32 >= 0 ) + id.def = i32; - // process rows one by one - while(fgets(line, sizeof(line), fp)) - { - char *str[32], *p; - int i; - lines++; - if(line[0] == '/' && line[1] == '/') - continue; - memset(str, 0, sizeof(str)); - - p = line; - while( ISSPACE(*p) ) - ++p; - if( *p == '\0' ) - continue;// empty line - for( i = 0; i < 19; ++i ) { - str[i] = p; - p = strchr(p,','); - if( p == NULL ) - break;// comma not found - *p = '\0'; - ++p; - } + if( libconfig->setting_lookup_int(it, "Range", &i32) && i32 >= 0 ) + id.range = i32; - if( p == NULL ) { - ShowError("itemdb_readdb: Insufficient columns in line %d of \"%s\" (item with id %d), skipping.\n", lines, filepath, atoi(str[0])); - continue; - } + if( libconfig->setting_lookup_int(it, "Slots", &i32) && i32 >= 0 ) + id.slot = i32; - // Script - if( *p != '{' ) { - ShowError("itemdb_readdb: Invalid format (Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, filepath, atoi(str[0])); - continue; - } - str[19] = p; - p = strstr(p+1,"},"); - if( p == NULL ) { - ShowError("itemdb_readdb: Invalid format (Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, filepath, atoi(str[0])); - continue; - } - p[1] = '\0'; - p += 2; + if( libconfig->setting_lookup_int(it, "Job", &i32) ) // This is an unsigned value, do not check for >= 0 + itemdb->jobid2mapid(id.class_base, (unsigned int)i32); + else if( !inherit ) + itemdb->jobid2mapid(id.class_base, UINT_MAX); - // OnEquip_Script - if( *p != '{' ) { - ShowError("itemdb_readdb: Invalid format (OnEquip_Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, filepath, atoi(str[0])); - continue; - } - str[20] = p; - p = strstr(p+1,"},"); - if( p == NULL ) { - ShowError("itemdb_readdb: Invalid format (OnEquip_Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, filepath, atoi(str[0])); - continue; - } - p[1] = '\0'; - p += 2; + if( libconfig->setting_lookup_int(it, "Upper", &i32) && i32 >= 0 ) + id.class_upper = (unsigned int)i32; + else if( !inherit ) + id.class_upper = ITEMUPPER_ALL; - // OnUnequip_Script (last column) - if( *p != '{' ) { - ShowError("itemdb_readdb: Invalid format (OnUnequip_Script column) in line %d of \"%s\" (item with id %d), skipping.\n", lines, filepath, atoi(str[0])); - continue; - } - str[21] = p; - - if ( str[21][strlen(str[21])-2] != '}' ) { - /* lets count to ensure it's not something silly e.g. a extra space at line ending */ - int v, lcurly = 0, rcurly = 0; - - for( v = 0; v < strlen(str[21]); v++ ) { - if( str[21][v] == '{' ) - lcurly++; - else if ( str[21][v] == '}' ) - rcurly++; - } - - if( lcurly != rcurly ) { - ShowError("itemdb_readdb: Mismatching curly braces in line %d of \"%s\" (item with id %d), skipping.\n", lines, filepath, atoi(str[0])); - continue; - } - } + if( libconfig->setting_lookup_int(it, "Gender", &i32) && i32 >= 0 ) + id.sex = i32; + else if( !inherit ) + id.sex = 2; - if (!itemdb->parse_dbrow(str, filepath, lines, 0)) - continue; - - count++; - } + if( libconfig->setting_lookup_int(it, "Loc", &i32) && i32 >= 0 ) + id.equip = i32; - fclose(fp); + if( libconfig->setting_lookup_int(it, "WeaponLv", &i32) && i32 >= 0 ) + id.wlv = i32; - ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, filename[fi]); + if( (t = libconfig->setting_get_member(it, "EquipLv")) ) { + if( config_setting_is_aggregate(t) ) { + if( libconfig->setting_length(t) >= 2 ) + id.elvmax = libconfig->setting_get_int_elem(t, 1); + if( libconfig->setting_length(t) >= 1 ) + id.elv = libconfig->setting_get_int_elem(t, 0); + } else { + id.elv = libconfig->setting_get_int(t); + } } - return 0; + if( (t = libconfig->setting_get_member(it, "Refine")) ) + id.flag.no_refine = libconfig->setting_get_bool(t) ? 0 : 1; + + if( libconfig->setting_lookup_int(it, "View", &i32) && i32 >= 0 ) + id.look = i32; + + if( (t = libconfig->setting_get_member(it, "BindOnEquip")) ) + id.flag.bindonequip = libconfig->setting_get_bool(t) ? 1 : 0; + + if( libconfig->setting_lookup_string(it, "Script", &str) ) + id.script = *str ? script->parse(str, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS) : NULL; + + if( libconfig->setting_lookup_string(it, "OnEquipScript", &str) ) + id.equip_script = *str ? script->parse(str, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS) : NULL; + + if( libconfig->setting_lookup_string(it, "OnUnequipScript", &str) ) + id.unequip_script = *str ? script->parse(str, source, -id.nameid, SCRIPT_IGNORE_EXTERNAL_BRACKETS) : NULL; + + return itemdb->validate_entry(&id, n, source); } -/*====================================== - * item_db table reading - *======================================*/ -int itemdb_read_sqldb(void) { - const char* item_db_name[] = { -#ifdef RENEWAL - map->item_db_re_db, -#else // not RENEWAL - map->item_db_db, -#endif // RENEWAL - map->item_db2_db }; - int fi; +/** + * Reads from a libconfig-formatted itemdb file and inserts the found entries into the + * item database, overwriting duplicate ones (i.e. item_db2 overriding item_db.) + * + * @param *filename File name, relative to the database path. + * @return The number of found entries. + */ +int itemdb_readdb_libconfig(const char *filename) { + bool duplicate[MAX_ITEMDB]; + config_t item_db_conf; + config_setting_t *itdb, *it; + char filepath[256]; + int i = 0, count = 0; - for( fi = 0; fi < ARRAYLENGTH(item_db_name); ++fi ) { - uint32 count = 0; + sprintf(filepath, "%s/%s", map->db_path, filename); + memset(&duplicate,0,sizeof(duplicate)); + if( libconfig->read_file(&item_db_conf, filepath) || !(itdb = libconfig->setting_get_member(item_db_conf.root, "item_db")) ) { + ShowError("can't read %s\n", filepath); + return 0; + } + + while( (it = libconfig->setting_get_elem(itdb,i++)) ) { + int nameid = itemdb->readdb_libconfig_sub(it, i-1, filename); - // retrieve all rows from the item database - if( SQL_ERROR == SQL->Query(map->mysql_handle, "SELECT * FROM `%s`", item_db_name[fi]) ) { - Sql_ShowDebug(map->mysql_handle); + if( !nameid ) continue; - } - // process rows one by one - while( SQL_SUCCESS == SQL->NextRow(map->mysql_handle) ) {// wrap the result into a TXT-compatible format - char* str[ITEMDB_SQL_COLUMNS]; - char* dummy = ""; - int i; - for( i = 0; i < ITEMDB_SQL_COLUMNS; ++i ) { - SQL->GetData(map->mysql_handle, i, &str[i], NULL); - if( str[i] == NULL ) - str[i] = dummy; // get rid of NULL columns - } + count++; - if (!itemdb->parse_dbrow(str, item_db_name[fi], -(atoi(str[0])), SCRIPT_IGNORE_EXTERNAL_BRACKETS)) - continue; - ++count; - } + if( duplicate[nameid] ) { + ShowWarning("itemdb_readdb:%s: duplicate entry of ID #%d (%s/%s)\n", + filename, nameid, itemdb_name(nameid), itemdb_jname(nameid)); + } else + duplicate[nameid] = true; + } + libconfig->destroy(&item_db_conf); + ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, filename); + + return count; +} - // free the query result - SQL->FreeResult(map->mysql_handle); +/** + * Reads from a sql itemdb table and inserts the found entries into the item + * database, overwriting duplicate ones (i.e. item_db2 overriding item_db.) + * + * @param *tablename Table name to query. + * @return The number of found entries. + */ +int itemdb_readdb_sql(const char *tablename) { + int i = 0, count = 0; + + // retrieve all rows from the item database + if( SQL_ERROR == SQL->Query(map->mysql_handle, "SELECT `id`, `name_english`, `name_japanese`, `type`," + " `price_buy`, `price_sell`, `weight`, `atk`," + " `matk`, `defence`, `range`, `slots`," + " `equip_jobs`, `equip_upper`, `equip_genders`, `equip_locations`," + " `weapon_level`, `equip_level_min`, `equip_level_max`, `refineable`," + " `view`, `bindonequip`, `script`, `equip_script`, `unequip_script`" + "FROM `%s`", tablename) ) { + Sql_ShowDebug(map->mysql_handle); + return 0; + } - ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, item_db_name[fi]); + // process rows one by one + while( SQL_SUCCESS == SQL->NextRow(map->mysql_handle) ) { + if( itemdb->readdb_sql_sub(map->mysql_handle, i++, tablename) ) + count++; } - return 0; + // free the query result + SQL->FreeResult(map->mysql_handle); + + ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, tablename); + + return count; } /*========================================== @@ -1911,17 +2006,33 @@ int itemdb_uid_load() { return 0; } -/*==================================== - * read all item-related databases - *------------------------------------*/ -void itemdb_read(void) { +/** + * Reads all item-related databases. + */ +void itemdb_read(bool minimal) { int i; DBData prev; - if (map->db_use_sql_item_db) - itemdb->read_sqldb(); - else - itemdb->readdb(); + if (map->db_use_sql_item_db) { + const char* item_db_name[] = { +#ifdef RENEWAL + map->item_db_re_db, +#else // not RENEWAL + map->item_db_db, +#endif // RENEWAL + map->item_db2_db + }; + for(i = 0; i < ARRAYLENGTH(item_db_name); i++) + itemdb->readdb_sql(item_db_name[i]); + } else { + const char* filename[] = { + DBPATH"item_db.conf", + "item_db2.conf", + }; + + for(i = 0; i < ARRAYLENGTH(filename); i++) + itemdb->readdb_libconfig(filename[i]); + } for( i = 0; i < ARRAYLENGTH(itemdb->array); ++i ) { if( itemdb->array[i] ) { @@ -1932,6 +2043,9 @@ void itemdb_read(void) { } } + if (minimal) + return; + itemdb->read_combos(); itemdb->read_groups(); itemdb->read_chains(); @@ -1939,7 +2053,7 @@ void itemdb_read(void) { sv->readdb(map->db_path, "item_avail.txt", ',', 2, 2, -1, itemdb->read_itemavail); sv->readdb(map->db_path, DBPATH"item_trade.txt", ',', 3, 3, -1, itemdb->read_itemtrade); - sv->readdb(map->db_path, "item_delay.txt", ',', 2, 2, -1, itemdb->read_itemdelay); + sv->readdb(map->db_path, DBPATH"item_delay.txt", ',', 2, 2, -1, itemdb->read_itemdelay); sv->readdb(map->db_path, "item_stack.txt", ',', 3, 3, -1, itemdb->read_stack); sv->readdb(map->db_path, DBPATH"item_buyingstore.txt", ',', 1, 1, -1, itemdb->read_buyingstore); sv->readdb(map->db_path, "item_nouse.txt", ',', 3, 3, -1, itemdb->read_nouse); @@ -1947,6 +2061,15 @@ void itemdb_read(void) { itemdb->uid_load(); } +/** + * retrieves item_combo data by combo id + **/ +struct item_combo * itemdb_id2combo( unsigned short id ) { + if( id > itemdb->combo_count ) + return NULL; + return itemdb->combos[id]; +} + /*========================================== * Initialize / Finalize *------------------------------------------*/ @@ -1963,17 +2086,8 @@ void destroy_item_data(struct item_data* self, int free_self) script->free_code(self->equip_script); if( self->unequip_script ) script->free_code(self->unequip_script); - if( self->combos_count ) { - int i; - for( i = 0; i < self->combos_count; i++ ) { - if( !self->combos[i]->isRef ) { - aFree(self->combos[i]->nameid); - script->free_code(self->combos[i]->script); - } - aFree(self->combos[i]); - } + if( self->combos ) aFree(self->combos); - } #if defined(DEBUG) // trash item memset(self, 0xDD, sizeof(struct item_data)); @@ -1995,18 +2109,13 @@ int itemdb_final_sub(DBKey key, DBData *data, va_list ap) return 0; } - -void itemdb_reload(void) { - struct s_mapiterator* iter; - struct map_session_data* sd; - - int i,d,k; - +void itemdb_clear(bool total) { + int i; // clear the previous itemdb data for( i = 0; i < ARRAYLENGTH(itemdb->array); ++i ) if( itemdb->array[i] ) itemdb->destroy_item_data(itemdb->array[i], 1); - + for( i = 0; i < itemdb->group_count; i++ ) { if( itemdb->groups[i].nameid ) aFree(itemdb->groups[i].nameid); @@ -2045,14 +2154,36 @@ void itemdb_reload(void) { itemdb->packages = NULL; itemdb->package_count = 0; + for(i = 0; i < itemdb->combo_count; i++) { + script->free_code(itemdb->combos[i]->script); + aFree(itemdb->combos[i]); + } + if( itemdb->combos ) + aFree(itemdb->combos); + + itemdb->combos = NULL; + itemdb->combo_count = 0; + + if( total ) + return; + itemdb->other->clear(itemdb->other, itemdb->final_sub); memset(itemdb->array, 0, sizeof(itemdb->array)); db_clear(itemdb->names); - + +} +void itemdb_reload(void) { + struct s_mapiterator* iter; + struct map_session_data* sd; + + int i,d,k; + + itemdb->clear(false); + // read new data - itemdb->read(); + itemdb->read(false); //Epoque's awesome @reloaditemdb fix - thanks! [Ind] //- Fixes the need of a @reloadmobdb after a @reloaditemdb to re-link monster drop data @@ -2087,17 +2218,17 @@ void itemdb_reload(void) { for( sd = (struct map_session_data*)mapit->first(iter); mapit->exists(iter); sd = (struct map_session_data*)mapit->next(iter) ) { memset(sd->item_delay, 0, sizeof(sd->item_delay)); // reset item delays pc->setinventorydata(sd); + if( battle_config.item_check ) + sd->state.itemcheck = 1; /* clear combo bonuses */ - if( sd->combos.count ) { - aFree(sd->combos.bonus); - aFree(sd->combos.id); - sd->combos.bonus = NULL; - sd->combos.id = NULL; - sd->combos.count = 0; + if( sd->combo_count ) { + aFree(sd->combos); + sd->combos = NULL; + sd->combo_count = 0; if( pc->load_combo(sd) > 0 ) - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_FORCE); } - + pc->checkitem(sd); } mapit->free(iter); } @@ -2105,68 +2236,35 @@ void itemdb_name_constants(void) { DBIterator *iter = db_iterator(itemdb->names); struct item_data *data; +#ifdef ENABLE_CASE_CHECK + script->parser_current_file = "Item Database (Likely an invalid or conflicting AegisName)"; +#endif // ENABLE_CASE_CHECK for( data = dbi_first(iter); dbi_exists(iter); data = dbi_next(iter) ) script->set_constant2(data->name,data->nameid,0); +#ifdef ENABLE_CASE_CHECK + script->parser_current_file = NULL; +#endif // ENABLE_CASE_CHECK dbi_destroy(iter); } -/* used to clear conflicts during script reload */ -void itemdb_force_name_constants(void) { - DBIterator *iter = db_iterator(itemdb->names); - struct item_data *data; - - for( data = dbi_first(iter); dbi_exists(iter); data = dbi_next(iter) ) - script->set_constant_force(data->name,data->nameid,0); - - dbi_destroy(iter); -} void do_final_itemdb(void) { - int i; - - for( i = 0; i < ARRAYLENGTH(itemdb->array); ++i ) - if( itemdb->array[i] ) - itemdb->destroy_item_data(itemdb->array[i], 1); - - for( i = 0; i < itemdb->group_count; i++ ) { - if( itemdb->groups[i].nameid ) - aFree(itemdb->groups[i].nameid); - } - - if( itemdb->groups ) - aFree(itemdb->groups); - - for( i = 0; i < itemdb->chain_count; i++ ) { - if( itemdb->chains[i].items ) - aFree(itemdb->chains[i].items); - } - - if( itemdb->chains ) - aFree(itemdb->chains); - - for( i = 0; i < itemdb->package_count; i++ ) { - int c; - for( c = 0; c < itemdb->packages[i].random_qty; c++ ) - aFree(itemdb->packages[i].random_groups[c].random_list); - if( itemdb->packages[i].random_groups ) - aFree(itemdb->packages[i].random_groups); - if( itemdb->packages[i].must_items ) - aFree(itemdb->packages[i].must_items); - } + itemdb->clear(true); - if( itemdb->packages ) - aFree(itemdb->packages); - itemdb->other->destroy(itemdb->other, itemdb->final_sub); itemdb->destroy_item_data(&itemdb->dummy, 0); db_destroy(itemdb->names); } -void do_init_itemdb(void) { +void do_init_itemdb(bool minimal) { memset(itemdb->array, 0, sizeof(itemdb->array)); itemdb->other = idb_alloc(DB_OPT_BASE); itemdb->names = strdb_alloc(DB_OPT_BASE,ITEM_NAME_LENGTH); itemdb->create_dummy_data(); //Dummy data item. - itemdb->read(); + itemdb->read(minimal); + + if (minimal) + return; + clif->cashshop_load(); } void itemdb_defaults(void) { @@ -2176,7 +2274,6 @@ void itemdb_defaults(void) { itemdb->final = do_final_itemdb; itemdb->reload = itemdb_reload; itemdb->name_constants = itemdb_name_constants; - itemdb->force_name_constants = itemdb_force_name_constants; /* */ itemdb->groups = NULL; itemdb->group_count = 0; @@ -2187,6 +2284,9 @@ void itemdb_defaults(void) { itemdb->packages = NULL; itemdb->package_count = 0; /* */ + itemdb->combos = NULL; + itemdb->combo_count = 0; + /* */ itemdb->names = NULL; /* */ /* itemdb->array is cleared on itemdb->init() */ @@ -2205,7 +2305,6 @@ void itemdb_defaults(void) { itemdb->search_name_array = itemdb_searchname_array; itemdb->load = itemdb_load; itemdb->search = itemdb_search; - itemdb->parse_dbrow = itemdb_parse_dbrow; itemdb->exists = itemdb_exists; itemdb->in_group = itemdb_in_group; itemdb->group_item = itemdb_searchrandomid; @@ -2243,12 +2342,16 @@ void itemdb_defaults(void) { itemdb->combo_split_atoi = itemdb_combo_split_atoi; itemdb->read_combos = itemdb_read_combos; itemdb->gendercheck = itemdb_gendercheck; - itemdb->re_split_atoi = itemdb_re_split_atoi; - itemdb->readdb = itemdb_readdb; - itemdb->read_sqldb = itemdb_read_sqldb; + itemdb->validate_entry = itemdb_validate_entry; + itemdb->readdb_sql_sub = itemdb_readdb_sql_sub; + itemdb->readdb_libconfig_sub = itemdb_readdb_libconfig_sub; + itemdb->readdb_libconfig = itemdb_readdb_libconfig; + itemdb->readdb_sql = itemdb_readdb_sql; itemdb->unique_id = itemdb_unique_id; itemdb->uid_load = itemdb_uid_load; itemdb->read = itemdb_read; itemdb->destroy_item_data = destroy_item_data; itemdb->final_sub = itemdb_final_sub; + itemdb->clear = itemdb_clear; + itemdb->id2combo = itemdb_id2combo; } diff --git a/src/map/itemdb.h b/src/map/itemdb.h index fe67ebbef..eebcd5d4d 100644 --- a/src/map/itemdb.h +++ b/src/map/itemdb.h @@ -2,8 +2,8 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _ITEMDB_H_ -#define _ITEMDB_H_ +#ifndef _MAP_ITEMDB_H_ +#define _MAP_ITEMDB_H_ #include "../common/db.h" #include "../common/mmo.h" // ITEM_NAME_LENGTH @@ -28,65 +28,297 @@ struct item_package; #define CARD0_PET ((short)0xFF00) //Marks if the card0 given is "special" (non-item id used to mark pets/created items. [Skotlex] -#define itemdb_isspecial(i) (i == CARD0_FORGE || i == CARD0_CREATE || i == CARD0_PET) +#define itemdb_isspecial(i) ((i) == CARD0_FORGE || (i) == CARD0_CREATE || (i) == CARD0_PET) //Use apple for unknown items. #define UNKNOWN_ITEM_ID 512 enum item_itemid { - ITEMID_HOLY_WATER = 523, - ITEMID_EMPERIUM = 714, - ITEMID_YELLOW_GEMSTONE = 715, - ITEMID_RED_GEMSTONE = 716, - ITEMID_BLUE_GEMSTONE = 717, - ITEMID_TRAP = 1065, - ITEMID_FACE_PAINT = 6120, - ITEMID_STONE = 7049, - ITEMID_SKULL_ = 7420, - ITEMID_TOKEN_OF_SIEGFRIED = 7621, - ITEMID_TRAP_ALLOY = 7940, - ITEMID_ANCILLA = 12333, - ITEMID_REINS_OF_MOUNT = 12622, + ITEMID_RED_POTION = 501, + ITEMID_YELLOW_POTION = 503, + ITEMID_WHITE_POTION = 504, + ITEMID_BLUE_POTION = 505, + ITEMID_HOLY_WATER = 523, + ITEMID_RED_SLIM_POTION = 545, + ITEMID_YELLOW_SLIM_POTION = 546, + ITEMID_WHITE_SLIM_POTION = 547, + ITEMID_WING_OF_FLY = 601, + ITEMID_WING_OF_BUTTERFLY = 602, + ITEMID_BRANCH_OF_DEAD_TREE = 604, + ITEMID_ANODYNE = 605, + ITEMID_ALOEBERA = 606, + ITEMID_EMPTY_BOTTLE = 713, + ITEMID_EMPERIUM = 714, + ITEMID_YELLOW_GEMSTONE = 715, + ITEMID_RED_GEMSTONE = 716, + ITEMID_BLUE_GEMSTONE = 717, + ITEMID_ORIDECON_STONE = 756, + ITEMID_ALCHOL = 970, + ITEMID_ORIDECON = 984, + ITEMID_BOODY_RED = 990, + ITEMID_CRYSTAL_BLUE = 991, + ITEMID_WIND_OF_VERDURE = 992, + ITEMID_YELLOW_LIVE = 993, + ITEMID_FLAME_HEART = 994, + ITEMID_MISTIC_FROZEN = 995, + ITEMID_ROUGH_WIND = 996, + ITEMID_GREAT_NATURE = 997, + ITEMID_IRON = 998, + ITEMID_STEEL = 999, + ITEMID_STAR_CRUMB = 1000, + ITEMID_IRON_ORE = 1002, + ITEMID_PHRACON = 1010, + ITEMID_EMVERETARCON = 1011, + ITEMID_TRAP = 1065, + ITEMID_PILEBUNCKER = 1549, + ITEMID_ANGRA_MANYU = 1599, + ITEMID_STRANGE_EMBRYO = 6415, + ITEMID_FACE_PAINT = 6120, + ITEMID_STONE = 7049, + ITEMID_FIRE_BOTTLE = 7135, + ITEMID_ACID_BOTTLE = 7136, + ITEMID_MENEATER_PLANT_BOTTLE = 7137, + ITEMID_MINI_BOTTLE = 7138, + ITEMID_COATING_BOTTLE = 7139, + ITEMID_FRAGMENT_OF_CRYSTAL = 7321, + ITEMID_SKULL_ = 7420, + ITEMID_TOKEN_OF_SIEGFRIED = 7621, + ITEMID_TRAP_ALLOY = 7940, + ITEMID_RED_POUCH_OF_SURPRISE = 12024, + ITEMID_BLOODY_DEAD_BRANCH = 12103, + ITEMID_PORING_BOX = 12109, + ITEMID_MERCENARY_RED_POTION = 12184, + ITEMID_MERCENARY_BLUE_POTION = 12185, + ITEMID_BATTLE_MANUAL = 12208, + ITEMID_BUBBLE_GUM = 12210, + ITEMID_GIANT_FLY_WING = 12212, + ITEMID_NEURALIZER = 12213, + ITEMID_M_CENTER_POTION = 12241, + ITEMID_M_AWAKENING_POTION = 12242, + ITEMID_M_BERSERK_POTION = 12243, + ITEMID_COMP_BATTLE_MANUAL = 12263, + ITEMID_COMP_BUBBLE_GUM = 12264, + ITEMID_LOVE_ANGEL = 12287, + ITEMID_SQUIRREL = 12288, + ITEMID_GOGO = 12289, + ITEMID_PICTURE_DIARY = 12304, + ITEMID_MINI_HEART = 12305, + ITEMID_NEWCOMER = 12306, + ITEMID_KID = 12307, + ITEMID_MAGIC_CASTLE = 12308, + ITEMID_BULGING_HEAD = 12309, + ITEMID_THICK_MANUAL50 = 12312, + ITEMID_ANCILLA = 12333, + ITEMID_REPAIR_A = 12392, + ITEMID_REPAIR_B = 12393, + ITEMID_REPAIR_C = 12394, + ITEMID_BLACK_THING = 12435, + ITEMID_REINS_OF_MOUNT = 12622, + ITEMID_NOBLE_NAMEPLATE = 12705, + ITEMID_DUN_TELE_SCROLL1 = 14527, + ITEMID_BATTLE_MANUAL25 = 14532, + ITEMIDBATTLE_MANUAL100 = 14533, + ITEMID_BATTLE_MANUAL_X3 = 14545, + ITEMID_DUN_TELE_SCROLL2 = 14581, + ITEMID_WOB_RUNE = 14582, + ITEMID_WOB_SCHWALTZ = 14583, + ITEMID_WOB_RACHEL = 14584, + ITEMID_WOB_LOCAL = 14585, + ITEMID_SIEGE_TELEPORT_SCROLL = 14591, + ITEMID_JOB_MANUAL50 = 14592, +}; + +enum cards_item_list { + ITEMID_GHOSTRING_CARD = 4047, + ITEMID_PHREEONI_CARD = 4121, + ITEMID_MISTRESS_CARD = 4132, + ITEMID_ORC_LOAD_CARD = 4135, + ITEMID_ORC_HERO_CARD = 4143, + ITEMID_TAO_GUNKA_CARD = 4302, }; /** - * Rune Knight + * Mechanic **/ +enum mechanic_item_list { + ITEMID_ACCELERATOR = 2800, + ITEMID_HOVERING_BOOSTER, // 2801 + ITEMID_SUICIDAL_DEVICE, // 2802 + ITEMID_SHAPE_SHIFTER, // 2803 + ITEMID_COOLING_DEVICE, // 2804 + ITEMID_MAGNETIC_FIELD_GENERATOR, // 2805 + ITEMID_BARRIER_BUILDER, // 2806 + ITEMID_REPAIR_KIT, // 2807 + ITEMID_CAMOUFLAGE_GENERATOR, // 2808 + ITEMID_HIGH_QUALITY_COOLER, // 2809 + ITEMID_SPECIAL_COOLER, // 2810 + ITEMID_MONKEY_SPANNER = 6186, +}; -enum { - ITEMID_NAUTHIZ = 12725, - ITEMID_RAIDO, - ITEMID_BERKANA, - ITEMID_ISA, - ITEMID_OTHILA, - ITEMID_URUZ, - ITEMID_THURISAZ, - ITEMID_WYRD, - ITEMID_HAGALAZ, - ITEMID_LUX_ANIMA = 22540, -} rune_list; +/** + * Spell Books + */ +enum spell_book_item_list { + ITEMID_MAGIC_BOOK_FB = 6189, + ITEMID_MAGIC_BOOK_CB, // 6190 + ITEMID_MAGIC_BOOK_LB, // 6191 + ITEMID_MAGIC_BOOK_SG, // 6192 + ITEMID_MAGIC_BOOK_LOV, // 6193 + ITEMID_MAGIC_BOOK_MS, // 6194 + ITEMID_MAGIC_BOOK_CM, // 6195 + ITEMID_MAGIC_BOOK_TV, // 6196 + ITEMID_MAGIC_BOOK_TS, // 6197 + ITEMID_MAGIC_BOOK_JT, // 6198 + ITEMID_MAGIC_BOOK_WB, // 6199 + ITEMID_MAGIC_BOOK_HD, // 6200 + ITEMID_MAGIC_BOOK_ES, // 6201 + ITEMID_MAGIC_BOOK_ES_, // 6202 + ITEMID_MAGIC_BOOK_CL, // 6203 + ITEMID_MAGIC_BOOK_CR, // 6204 + ITEMID_MAGIC_BOOK_DL, // 6205 +}; /** - * Mechanic + * Mercenary Scrolls + */ +enum mercenary_scroll_item_list { + ITEMID_BOW_MERCENARY_SCROLL1 = 12153, + ITEMID_BOW_MERCENARY_SCROLL2, // 12154 + ITEMID_BOW_MERCENARY_SCROLL3, // 12155 + ITEMID_BOW_MERCENARY_SCROLL4, // 12156 + ITEMID_BOW_MERCENARY_SCROLL5, // 12157 + ITEMID_BOW_MERCENARY_SCROLL6, // 12158 + ITEMID_BOW_MERCENARY_SCROLL7, // 12159 + ITEMID_BOW_MERCENARY_SCROLL8, // 12160 + ITEMID_BOW_MERCENARY_SCROLL9, // 12161 + ITEMID_BOW_MERCENARY_SCROLL10, // 12162 + ITEMID_SWORDMERCENARY_SCROLL1, // 12163 + ITEMID_SWORDMERCENARY_SCROLL2, // 12164 + ITEMID_SWORDMERCENARY_SCROLL3, // 12165 + ITEMID_SWORDMERCENARY_SCROLL4, // 12166 + ITEMID_SWORDMERCENARY_SCROLL5, // 12167 + ITEMID_SWORDMERCENARY_SCROLL6, // 12168 + ITEMID_SWORDMERCENARY_SCROLL7, // 12169 + ITEMID_SWORDMERCENARY_SCROLL8, // 12170 + ITEMID_SWORDMERCENARY_SCROLL9, // 12171 + ITEMID_SWORDMERCENARY_SCROLL10, // 12172 + ITEMID_SPEARMERCENARY_SCROLL1, // 12173 + ITEMID_SPEARMERCENARY_SCROLL2, // 12174 + ITEMID_SPEARMERCENARY_SCROLL3, // 12175 + ITEMID_SPEARMERCENARY_SCROLL4, // 12176 + ITEMID_SPEARMERCENARY_SCROLL5, // 12177 + ITEMID_SPEARMERCENARY_SCROLL6, // 12178 + ITEMID_SPEARMERCENARY_SCROLL7, // 12179 + ITEMID_SPEARMERCENARY_SCROLL8, // 12180 + ITEMID_SPEARMERCENARY_SCROLL9, // 12181 + ITEMID_SPEARMERCENARY_SCROLL10, // 12182 +}; + +/** + * Cash Food + */ +enum cash_food_item_list { + ITEMID_STR_DISH10_ = 12202, + ITEMID_AGI_DISH10_, // 12203 + ITEMID_INT_DISH10_, // 12204 + ITEMID_DEX_DISH10_, // 12205 + ITEMID_LUK_DISH10_, // 12206 + ITEMID_VIT_DISH10_, // 12207 +}; + +/** + * GC Poison + */ +enum poison_item_list { + ITEMID_POISON_PARALYSIS = 12717, + ITEMID_POISON_LEECH, // 12718 + ITEMID_POISON_OBLIVION, // 12719 + ITEMID_POISON_CONTAMINATION, // 12720 + ITEMID_POISON_NUMB, // 12721 + ITEMID_POISON_FEVER, // 12722 + ITEMID_POISON_LAUGHING, // 12723 + ITEMID_POISON_FATIGUE, // 12724 +}; + + +/** + * Rune Knight **/ -enum { - ITEMID_ACCELERATOR = 2800, - ITEMID_HOVERING_BOOSTER, - ITEMID_SUICIDAL_DEVICE, - ITEMID_SHAPE_SHIFTER, - ITEMID_COOLING_DEVICE, - ITEMID_MAGNETIC_FIELD_GENERATOR, - ITEMID_BARRIER_BUILDER, - ITEMID_REPAIR_KIT, - ITEMID_CAMOUFLAGE_GENERATOR, - ITEMID_HIGH_QUALITY_COOLER, - ITEMID_SPECIAL_COOLER, - ITEMID_MONKEY_SPANNER = 6186, -} mecha_item_list; - -enum { +enum rune_item_list { + ITEMID_NAUTHIZ = 12725, + ITEMID_RAIDO, // 12726 + ITEMID_BERKANA, // 12727 + ITEMID_ISA, // 12728 + ITEMID_OTHILA, // 12729 + ITEMID_URUZ, // 12730 + ITEMID_THURISAZ, // 12731 + ITEMID_WYRD, // 12732 + ITEMID_HAGALAZ, // 12733 + ITEMID_LUX_ANIMA = 22540, +}; + +/** + * Geneticist + */ +enum geneticist_item_list { + /// Pharmacy / Cooking + ITEMID_SEED_OF_HORNY_PLANT = 6210, + ITEMID_BLOODSUCK_PLANT_SEED, // 6211 + ITEMID_BOMB_MUSHROOM_SPORE, // 6212 + ITEMID_HP_INCREASE_POTIONS = 12422, + ITEMID_HP_INCREASE_POTIONM, // 12423 + ITEMID_HP_INCREASE_POTIONL, // 12424 + ITEMID_SP_INCREASE_POTIONS, // 12425 + ITEMID_SP_INCREASE_POTIONM, // 12426 + ITEMID_SP_INCREASE_POTIONL, // 12427 + ITEMID_ENRICH_WHITE_POTIONZ, // 12428 + ITEMID_SAVAGE_BBQ, // 12429 + ITEMID_WUG_BLOOD_COCKTAIL, // 12430 + ITEMID_MINOR_BRISKET, // 12431 + ITEMID_SIROMA_ICETEA, // 12432 + ITEMID_DROCERA_HERB_STEW, // 12433 + ITEMID_PETTI_TAIL_NOODLE, // 12434 + ITEMID_VITATA500, // 12436 + ITEMID_ENRICH_CELERMINE_JUICE, // 12437 + ITEMID_CURE_FREE, // 12475 + /// Bombs + ITEMID_APPLE_BOMB = 13260, + ITEMID_COCONUT_BOMB, // 13261 + ITEMID_MELON_BOMB, // 13262 + ITEMID_PINEAPPLE_BOMB, // 13263 + ITEMID_BANANA_BOMB, // 13264 + ITEMID_BLACK_LUMP, // 13265 + ITEMID_BLACK_HARD_LUMP, // 13266 + ITEMID_VERY_HARD_LUMP, // 13267 + /// Throwables + ITEMID_MYSTERIOUS_POWDER, // 13268 + ITEMID_BOOST500_TO_THROW, // 13269 + ITEMID_FULL_SWINGK_TO_THROW, // 13270 + ITEMID_MANA_PLUS_TO_THROW, // 13271 + ITEMID_CURE_FREE_TO_THROW, // 13272 + ITEMID_STAMINA_UP_M_TO_THROW, // 13273 + ITEMID_DIGESTIVE_F_TO_THROW, // 13274 + ITEMID_HP_INC_POTS_TO_THROW, // 13275 + ITEMID_HP_INC_POTM_TO_THROW, // 13276 + ITEMID_HP_INC_POTL_TO_THROW, // 13277 + ITEMID_SP_INC_POTS_TO_THROW, // 13278 + ITEMID_SP_INC_POTM_TO_THROW, // 13279 + ITEMID_SP_INC_POTL_TO_THROW, // 13280 + ITEMID_EN_WHITE_POTZ_TO_THROW, // 13281 + ITEMID_VITATA500_TO_THROW, // 13282 + ITEMID_EN_CEL_JUICE_TO_THROW, // 13283 + ITEMID_SAVAGE_BBQ_TO_THROW, // 13284 + ITEMID_WUG_COCKTAIL_TO_THROW, // 13285 + ITEMID_M_BRISKET_TO_THROW, // 13286 + ITEMID_SIROMA_ICETEA_TO_THROW, // 13287 + ITEMID_DROCERA_STEW_TO_THROW, // 13288 + ITEMID_PETTI_NOODLE_TO_THROW, // 13289 + ITEMID_BLACK_THING_TO_THROW, // 13290 +}; + +enum item_nouse_list { NOUSE_SITTING = 0x01, -} item_nouse_list; +}; // enum e_chain_cache { @@ -95,6 +327,17 @@ enum e_chain_cache { ECC_MAX, }; +enum item_class_upper { + ITEMUPPER_NONE = 0x00, + ITEMUPPER_NORMAL = 0x01, + ITEMUPPER_UPPER = 0x02, + ITEMUPPER_BABY = 0x04, + ITEMUPPER_THIRD = 0x08, + ITEMUPPER_THURDUPPER = 0x10, + ITEMUPPER_THIRDBABY = 0x20, + ITEMUPPER_ALL = 0x3f, // Sum of all the above +}; + struct item_data { uint16 nameid; char name[ITEM_NAME_LENGTH],jname[ITEM_NAME_LENGTH]; @@ -115,10 +358,8 @@ struct item_data { int elv; int wlv; int view_id; -#ifdef RENEWAL int matk; int elvmax;/* maximum level for this item */ -#endif int delay; //Lupus: I rearranged order of these fields due to compatibility with ITEMINFO script command @@ -139,6 +380,7 @@ struct item_data { unsigned trade_restriction : 9; //Item restrictions mask [Skotlex] unsigned autoequip: 1; unsigned buyingstore : 1; + unsigned bindonequip : 1; } flag; struct {// item stacking limitation unsigned short amount; @@ -162,10 +404,9 @@ struct item_data { struct item_combo { struct script_code *script; - unsigned short *nameid;/* nameid array */ + unsigned short nameid[MAX_ITEMS_PER_COMBO];/* nameid array */ unsigned char count; unsigned short id;/* id of this combo */ - bool isRef;/* whether this struct is a reference or the master */ }; struct item_group { @@ -216,51 +457,51 @@ struct item_package { unsigned short must_qty; }; -#define itemdb_name(n) itemdb->search(n)->name -#define itemdb_jname(n) itemdb->search(n)->jname -#define itemdb_type(n) itemdb->search(n)->type -#define itemdb_atk(n) itemdb->search(n)->atk -#define itemdb_def(n) itemdb->search(n)->def -#define itemdb_look(n) itemdb->search(n)->look -#define itemdb_weight(n) itemdb->search(n)->weight -#define itemdb_equip(n) itemdb->search(n)->equip -#define itemdb_usescript(n) itemdb->search(n)->script -#define itemdb_equipscript(n) itemdb->search(n)->script -#define itemdb_wlv(n) itemdb->search(n)->wlv -#define itemdb_range(n) itemdb->search(n)->range -#define itemdb_slot(n) itemdb->search(n)->slot -#define itemdb_available(n) (itemdb->search(n)->flag.available) -#define itemdb_viewid(n) (itemdb->search(n)->view_id) -#define itemdb_autoequip(n) (itemdb->search(n)->flag.autoequip) -#define itemdb_is_rune(n) ((n >= ITEMID_NAUTHIZ && n <= ITEMID_HAGALAZ) || n == ITEMID_LUX_ANIMA) -#define itemdb_is_element(n) (n >= 990 && n <= 993) -#define itemdb_is_spellbook(n) (n >= 6188 && n <= 6205) -#define itemdb_is_poison(n) (n >= 12717 && n <= 12724) -#define itemid_isgemstone(id) ( (id) >= ITEMID_YELLOW_GEMSTONE && (id) <= ITEMID_BLUE_GEMSTONE ) -#define itemdb_iscashfood(id) ( (id) >= 12202 && (id) <= 12207 ) -#define itemdb_is_GNbomb(n) (n >= 13260 && n <= 13267) -#define itemdb_is_GNthrowable(n) (n >= 13268 && n <= 13290) - -#define itemdb_value_buy(n) itemdb->search(n)->value_buy -#define itemdb_value_sell(n) itemdb->search(n)->value_sell -#define itemdb_canrefine(n) (!itemdb->search(n)->flag.no_refine) +#define itemdb_name(n) (itemdb->search(n)->name) +#define itemdb_jname(n) (itemdb->search(n)->jname) +#define itemdb_type(n) (itemdb->search(n)->type) +#define itemdb_atk(n) (itemdb->search(n)->atk) +#define itemdb_def(n) (itemdb->search(n)->def) +#define itemdb_look(n) (itemdb->search(n)->look) +#define itemdb_weight(n) (itemdb->search(n)->weight) +#define itemdb_equip(n) (itemdb->search(n)->equip) +#define itemdb_usescript(n) (itemdb->search(n)->script) +#define itemdb_equipscript(n) (itemdb->search(n)->script) +#define itemdb_wlv(n) (itemdb->search(n)->wlv) +#define itemdb_range(n) (itemdb->search(n)->range) +#define itemdb_slot(n) (itemdb->search(n)->slot) +#define itemdb_available(n) (itemdb->search(n)->flag.available) +#define itemdb_viewid(n) (itemdb->search(n)->view_id) +#define itemdb_autoequip(n) (itemdb->search(n)->flag.autoequip) +#define itemdb_value_buy(n) (itemdb->search(n)->value_buy) +#define itemdb_value_sell(n) (itemdb->search(n)->value_sell) +#define itemdb_canrefine(n) (!itemdb->search(n)->flag.no_refine) + +#define itemdb_is_rune(n) (((n) >= ITEMID_NAUTHIZ && (n) <= ITEMID_HAGALAZ) || (n) == ITEMID_LUX_ANIMA) +#define itemdb_is_element(n) ((n) >= ITEMID_BOODY_RED && (n) <= ITEMID_YELLOW_LIVE) +#define itemdb_is_spellbook(n) ((n) >= ITEMID_MAGIC_BOOK_FB && (n) <= ITEMID_MAGIC_BOOK_DL) +#define itemdb_is_poison(n) ((n) >= ITEMID_POISON_PARALYSIS && (n) <= ITEMID_POISON_FATIGUE) +#define itemid_isgemstone(n) ((n) >= ITEMID_YELLOW_GEMSTONE && (n) <= ITEMID_BLUE_GEMSTONE) +#define itemdb_iscashfood(n) ((n) >= ITEMID_STR_DISH10_ && (n) <= ITEMID_VIT_DISH10_) +#define itemdb_is_GNbomb(n) ((n) >= ITEMID_APPLE_BOMB && (n) <= ITEMID_VERY_HARD_LUMP) +#define itemdb_is_GNthrowable(n) ((n) >= ITEMID_MYSTERIOUS_POWDER && (n) <= ITEMID_BLACK_THING_TO_THROW) + //Item trade restrictions [Skotlex] -#define itemdb_isdropable(item, gmlv) itemdb->isrestricted(item, gmlv, 0, itemdb->isdropable_sub) -#define itemdb_cantrade(item, gmlv, gmlv2) itemdb->isrestricted(item, gmlv, gmlv2, itemdb->cantrade_sub) -#define itemdb_canpartnertrade(item, gmlv, gmlv2) itemdb->isrestricted(item, gmlv, gmlv2, itemdb->canpartnertrade_sub) -#define itemdb_cansell(item, gmlv) itemdb->isrestricted(item, gmlv, 0, itemdb->cansell_sub) -#define itemdb_cancartstore(item, gmlv) itemdb->isrestricted(item, gmlv, 0, itemdb->cancartstore_sub) -#define itemdb_canstore(item, gmlv) itemdb->isrestricted(item, gmlv, 0, itemdb->canstore_sub) -#define itemdb_canguildstore(item, gmlv) itemdb->isrestricted(item , gmlv, 0, itemdb->canguildstore_sub) -#define itemdb_canmail(item, gmlv) itemdb->isrestricted(item , gmlv, 0, itemdb->canmail_sub) -#define itemdb_canauction(item, gmlv) itemdb->isrestricted(item , gmlv, 0, itemdb->canauction_sub) +#define itemdb_isdropable(item, gmlv) (itemdb->isrestricted((item), (gmlv), 0, itemdb->isdropable_sub)) +#define itemdb_cantrade(item, gmlv, gmlv2) (itemdb->isrestricted((item), (gmlv), (gmlv2), itemdb->cantrade_sub)) +#define itemdb_canpartnertrade(item, gmlv, gmlv2) (itemdb->isrestricted((item), (gmlv), (gmlv2), itemdb->canpartnertrade_sub)) +#define itemdb_cansell(item, gmlv) (itemdb->isrestricted((item), (gmlv), 0, itemdb->cansell_sub)) +#define itemdb_cancartstore(item, gmlv) (itemdb->isrestricted((item), (gmlv), 0, itemdb->cancartstore_sub)) +#define itemdb_canstore(item, gmlv) (itemdb->isrestricted((item), (gmlv), 0, itemdb->canstore_sub)) +#define itemdb_canguildstore(item, gmlv) (itemdb->isrestricted((item), (gmlv), 0, itemdb->canguildstore_sub)) +#define itemdb_canmail(item, gmlv) (itemdb->isrestricted((item), (gmlv), 0, itemdb->canmail_sub)) +#define itemdb_canauction(item, gmlv) (itemdb->isrestricted((item), (gmlv), 0, itemdb->canauction_sub)) struct itemdb_interface { - void (*init) (void); + void (*init) (bool minimal); void (*final) (void); void (*reload) (void); void (*name_constants) (void); - void (*force_name_constants) (void); /* */ struct item_group *groups; unsigned short group_count; @@ -271,6 +512,9 @@ struct itemdb_interface { /* */ struct item_package *packages; unsigned short package_count; + /* list of item combos loaded */ + struct item_combo **combos; + unsigned short combo_count; /* */ DBMap *names; /* */ @@ -290,7 +534,6 @@ struct itemdb_interface { int (*search_name_array) (struct item_data** data, int size, const char *str, int flag); struct item_data* (*load)(int nameid); struct item_data* (*search)(int nameid); - int (*parse_dbrow) (char** str, const char* source, int line, int scriptopt); struct item_data* (*exists) (int nameid); bool (*in_group) (struct item_group *group, int nameid); int (*group_item) (struct item_group *group); @@ -328,18 +571,22 @@ struct itemdb_interface { int (*combo_split_atoi) (char *str, int *val); void (*read_combos) (); int (*gendercheck) (struct item_data *id); - void (*re_split_atoi) (char *str, int *atk, int *matk); - int (*readdb) (void); - int (*read_sqldb) (void); + int (*validate_entry) (struct item_data *entry, int n, const char *source); + int (*readdb_sql_sub) (Sql *handle, int n, const char *source); + int (*readdb_libconfig_sub) (config_setting_t *it, int n, const char *source); + int (*readdb_libconfig) (const char *filename); + int (*readdb_sql) (const char *tablename); uint64 (*unique_id) (int8 flag, int64 value); int (*uid_load) (); - void (*read) (void); + void (*read) (bool minimal); void (*destroy_item_data) (struct item_data *self, int free_self); int (*final_sub) (DBKey key, DBData *data, va_list ap); + void (*clear) (bool total); + struct item_combo * (*id2combo) (unsigned short id); }; struct itemdb_interface *itemdb; void itemdb_defaults(void); -#endif /* _ITEMDB_H_ */ +#endif /* _MAP_ITEMDB_H_ */ diff --git a/src/map/log.c b/src/map/log.c index e33240505..19a98f34b 100644 --- a/src/map/log.c +++ b/src/map/log.c @@ -40,6 +40,7 @@ char log_picktype2char(e_log_pick_type type) { case LOG_TYPE_AUCTION: return 'I'; // Auct(I)on case LOG_TYPE_BUYING_STORE: return 'B'; // (B)uying Store case LOG_TYPE_LOOT: return 'L'; // (L)oot (consumed monster pick/drop) + case LOG_TYPE_BANK: return 'K'; // Ban(K) Transactions case LOG_TYPE_OTHER: return 'X'; // Other } diff --git a/src/map/log.h b/src/map/log.h index 07606c8ef..b2cb92c20 100644 --- a/src/map/log.h +++ b/src/map/log.h @@ -2,8 +2,8 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _LOG_H_ -#define _LOG_H_ +#ifndef _MAP_LOG_H_ +#define _MAP_LOG_H_ #include "../common/cbasetypes.h" #include "../common/sql.h" @@ -60,6 +60,7 @@ typedef enum e_log_pick_type { LOG_TYPE_AUCTION = 0x04000, LOG_TYPE_BUYING_STORE = 0x08000, LOG_TYPE_OTHER = 0x10000, + LOG_TYPE_BANK = 0x20000, // combinations LOG_TYPE_LOOT = LOG_TYPE_PICKDROP_MONSTER|LOG_TYPE_CONSUME, // all @@ -133,4 +134,4 @@ struct log_interface *logs; void log_defaults(void); -#endif /* _LOG_H_ */ +#endif /* _MAP_LOG_H_ */ diff --git a/src/map/mail.c b/src/map/mail.c index 2378cbe2a..371aa892f 100644 --- a/src/map/mail.c +++ b/src/map/mail.c @@ -64,7 +64,7 @@ unsigned char mail_setitem(struct map_session_data *sd, int idx, int amount) { return 1; if( idx == 0 ) { // Zeny Transfer - if( amount < 0 || !pc->can_give_items(sd) ) + if( amount < 0 || !pc_can_give_items(sd) ) return 1; if( amount > sd->status.zeny ) @@ -81,8 +81,9 @@ unsigned char mail_setitem(struct map_session_data *sd, int idx, int amount) { return 1; if( amount < 0 || amount > sd->status.inventory[idx].amount ) return 1; - if( !pc->can_give_items(sd) || sd->status.inventory[idx].expire_time || - !itemdb_canmail(&sd->status.inventory[idx],pc->get_group_level(sd)) ) + if( !pc_can_give_items(sd) || sd->status.inventory[idx].expire_time || + !itemdb_canmail(&sd->status.inventory[idx],pc_get_group_level(sd)) || + (sd->status.inventory[idx].bound && !pc_can_give_bound_items(sd)) ) return 1; sd->mail.index = idx; diff --git a/src/map/mail.h b/src/map/mail.h index b2b9048cb..8df537ff3 100644 --- a/src/map/mail.h +++ b/src/map/mail.h @@ -2,8 +2,8 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _MAIL_H_ -#define _MAIL_H_ +#ifndef _MAP_MAIL_H_ +#define _MAP_MAIL_H_ #include "../common/mmo.h" @@ -23,4 +23,4 @@ struct mail_interface *mail; void mail_defaults(void); -#endif /* _MAIL_H_ */ +#endif /* _MAP_MAIL_H_ */ diff --git a/src/map/map.c b/src/map/map.c index d920875ee..838a88f01 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -76,6 +76,22 @@ int map_getusers(void) { return map->users; } +/** + * Expands map->bl_list on demand + **/ +static inline void map_bl_list_expand(void) { + map->bl_list_size += 250; + RECREATE(map->bl_list, struct block_list *, map->bl_list_size); +} + +/** + * Expands map->block_free on demand + **/ +static inline void map_block_free_expand(void) { + map->block_free_list_size += 100; + RECREATE(map->block_free, struct block_list *, map->block_free_list_size); +} + /*========================================== * server player count (this mapserver only) *------------------------------------------*/ @@ -88,13 +104,20 @@ int map_usercount(void) { *------------------------------------------*/ int map_freeblock (struct block_list *bl) { nullpo_retr(map->block_free_lock, bl); - if (map->block_free_lock == 0 || map->block_free_count >= block_free_max) { - aFree(bl); + + if (map->block_free_lock == 0) { + if( bl->type == BL_ITEM ) + ers_free(map->flooritem_ers, bl); + else + aFree(bl); bl = NULL; - if (map->block_free_count >= block_free_max) - ShowWarning("map_freeblock: too many free block! %d %d\n", map->block_free_count, map->block_free_lock); - } else + } else { + + if( map->block_free_count >= map->block_free_list_size ) + map_block_free_expand(); + map->block_free[map->block_free_count++] = bl; + } return map->block_free_lock; } @@ -109,11 +132,14 @@ int map_freeblock_lock (void) { * Remove the lock on map_bl *------------------------------------------*/ int map_freeblock_unlock (void) { + if ((--map->block_free_lock) == 0) { int i; - for (i = 0; i < map->block_free_count; i++) - { - aFree(map->block_free[i]); + for (i = 0; i < map->block_free_count; i++) { + if( map->block_free[i]->type == BL_ITEM ) + ers_free(map->flooritem_ers, map->block_free[i]); + else + aFree(map->block_free[i]); map->block_free[i] = NULL; } map->block_free_count = 0; @@ -127,7 +153,7 @@ int map_freeblock_unlock (void) { // Timer function to check if there some remaining lock and remove them if so. // Called each 1s -int map_freeblock_timer(int tid, unsigned int tick, int id, intptr_t data) { +int map_freeblock_timer(int tid, int64 tick, int id, intptr_t data) { if (map->block_free_lock > 0) { ShowError("map_freeblock_timer: block_free_lock(%d) is invalid.\n", map->block_free_lock); map->block_free_lock = 1; @@ -259,8 +285,7 @@ int map_delblock(struct block_list* bl) * Pass flag as 1 to prevent doing skill->unit_move checks * (which are executed by default on BL_CHAR types) *------------------------------------------*/ -int map_moveblock(struct block_list *bl, int x1, int y1, unsigned int tick) -{ +int map_moveblock(struct block_list *bl, int x1, int y1, int64 tick) { int x0 = bl->x, y0 = bl->y; struct status_change *sc = NULL; int moveblock = ( x0/BLOCK_SIZE != x1/BLOCK_SIZE || y0/BLOCK_SIZE != y1/BLOCK_SIZE); @@ -477,23 +502,22 @@ static int map_vforeachinmap(int (*func)(struct block_list*, va_list), int16 m, for (i = 0; i < bsize; i++) { if (type&~BL_MOB) { for (bl = map->list[m].block[i]; bl != NULL; bl = bl->next) { - if (bl->type&type && map->bl_list_count < BL_LIST_MAX) { + if (bl->type&type) { + if( map->bl_list_count >= map->bl_list_size ) + map_bl_list_expand(); map->bl_list[map->bl_list_count++] = bl; } } } if (type&BL_MOB) { for (bl = map->list[m].block_mob[i]; bl != NULL; bl = bl->next) { - if (map->bl_list_count < BL_LIST_MAX) { - map->bl_list[map->bl_list_count++] = bl; - } + if( map->bl_list_count >= map->bl_list_size ) + map_bl_list_expand(); + map->bl_list[map->bl_list_count++] = bl; } } } - if (map->bl_list_count >= BL_LIST_MAX) - ShowError("map.c:map_vforeachinmap: bl_list size (%d) exceeded\n", BL_LIST_MAX); - va_copy(argscopy, args); returnCount = bl_vforeach(func, blockcount, INT_MAX, argscopy); va_end(argscopy); @@ -601,52 +625,45 @@ static int bl_getall_area(int type, int m, int x0, int y0, int x1, int y1, int ( for (bx = x0 / BLOCK_SIZE; bx <= x1 / BLOCK_SIZE; bx++) { if (type&~BL_MOB) { for (bl = map->list[m].block[bx + by * map->list[m].bxs]; bl != NULL; bl = bl->next) { - if (map->bl_list_count < BL_LIST_MAX - && bl->type&type - && bl->x >= x0 && bl->x <= x1 - && bl->y >= y0 && bl->y <= y1) { - if (func) { - va_start(args, func); - if (func(bl, args)) { - map->bl_list[map->bl_list_count++] = bl; - found++; - } - va_end(args); - } - else { + if (bl->type&type && bl->x >= x0 && bl->x <= x1 && bl->y >= y0 && bl->y <= y1) { + if( map->bl_list_count >= map->bl_list_size ) + map_bl_list_expand(); + if (func) { + va_start(args, func); + if (func(bl, args)) { map->bl_list[map->bl_list_count++] = bl; found++; } + va_end(args); + } else { + map->bl_list[map->bl_list_count++] = bl; + found++; + } } } } if (type&BL_MOB) { // TODO: fix this code duplication for (bl = map->list[m].block_mob[bx + by * map->list[m].bxs]; bl != NULL; bl = bl->next) { - if (map->bl_list_count < BL_LIST_MAX - //&& bl->type&type // block_mob contains BL_MOBs only - && bl->x >= x0 && bl->x <= x1 - && bl->y >= y0 && bl->y <= y1) { - if (func) { - va_start(args, func); - if (func(bl, args)) { - map->bl_list[map->bl_list_count++] = bl; - found++; - } - va_end(args); - } - else { + if (bl->x >= x0 && bl->x <= x1 && bl->y >= y0 && bl->y <= y1) { + if( map->bl_list_count >= map->bl_list_size ) + map_bl_list_expand(); + if (func) { + va_start(args, func); + if (func(bl, args)) { map->bl_list[map->bl_list_count++] = bl; found++; } + va_end(args); + } else { + map->bl_list[map->bl_list_count++] = bl; + found++; + } } } } } } - if (map->bl_list_count >= BL_LIST_MAX) - ShowError("map.c:bl_getall_area: bl_list size (%d) exceeded\n", BL_LIST_MAX); - return found; } @@ -689,7 +706,7 @@ int map_vforeachinrange(int (*func)(struct block_list*, va_list), struct block_l va_copy(apcopy, ap); returnCount = bl_vforeach(func, blockcount, INT_MAX, apcopy); - va_end(ap); + va_end(apcopy); return returnCount; } @@ -1305,7 +1322,7 @@ int map_get_new_object_id(void) * Timered function to clear the floor (remove remaining item) * Called each flooritem_lifetime ms *------------------------------------------*/ -int map_clearflooritem_timer(int tid, unsigned int tick, int id, intptr_t data) { +int map_clearflooritem_timer(int tid, int64 tick, int id, intptr_t data) { struct flooritem_data* fitem = (struct flooritem_data*)idb_get(map->id_db, id); if (fitem == NULL || fitem->bl.type != BL_ITEM || (fitem->cleartimer != tid)) { @@ -1330,7 +1347,7 @@ int map_clearflooritem_timer(int tid, unsigned int tick, int id, intptr_t data) void map_clearflooritem(struct block_list *bl) { struct flooritem_data* fitem = (struct flooritem_data*)bl; - if( fitem->cleartimer ) + if( fitem->cleartimer != INVALID_TIMER ) timer->delete(fitem->cleartimer,map->clearflooritem_timer); clif->clearflooritem(fitem, 0); @@ -1470,15 +1487,16 @@ int map_addflooritem(struct item *item_data,int amount,int16 m,int16 x,int16 y,i return 0; r=rnd(); - CREATE(fitem, struct flooritem_data, 1); - fitem->bl.type=BL_ITEM; + fitem = ers_alloc(map->flooritem_ers, struct flooritem_data); + + fitem->bl.type = BL_ITEM; fitem->bl.prev = fitem->bl.next = NULL; - fitem->bl.m=m; - fitem->bl.x=x; - fitem->bl.y=y; + fitem->bl.m = m; + fitem->bl.x = x; + fitem->bl.y = y; fitem->bl.id = map->get_new_object_id(); if(fitem->bl.id==0){ - aFree(fitem); + ers_free(map->flooritem_ers, fitem); return 0; } @@ -1656,6 +1674,9 @@ int map_quit(struct map_session_data *sd) { //Non-active players should not have loaded any data yet (or it was cleared already) so no additional cleanups are needed. return 0; } + + if( sd->expiration_tid != INVALID_TIMER ) + timer->delete(sd->expiration_tid,pc->expiration_timer); if (sd->npc_timer_id != INVALID_TIMER) //Cancel the event timer. npc->timerevent_quit(sd); @@ -1666,6 +1687,9 @@ int map_quit(struct map_session_data *sd) { if( sd->bg_id && !sd->bg_queue.arena ) /* TODO: dump this chunk after bg_queue is fully enabled */ bg->team_leave(sd,1); + if( sd->state.autotrade && runflag != MAPSERVER_ST_SHUTDOWN && !hChSys.closing ) + pc->autotrade_update(sd,PAUC_REMOVE); + skill->cooldown_save(sd); pc->itemcd_do(sd,false); @@ -1715,8 +1739,6 @@ int map_quit(struct map_session_data *sd) { if( sd->state.storage_flag == 1 ) sd->state.storage_flag = 0; // No need to Double Save Storage on Quit. - if (sd->state.permanent_speed == 1) sd->state.permanent_speed = 0; // Remove lock so speed is set back to normal at login. - if( sd->ed ) { elemental->clean_effect(sd->ed); unit->remove_map(&sd->ed->bl,CLR_TELEPORT,ALC_MARK); @@ -2087,9 +2109,7 @@ struct s_mapiterator /// @param _bl_ block_list /// @return true if it matches #define MAPIT_MATCHES(_mapit_,_bl_) \ - ( \ - ( (_bl_)->type & (_mapit_)->types /* type matches */ ) \ - ) + ( (_bl_)->type & (_mapit_)->types /* type matches */ ) /// Allocates a new iterator. /// Returns the new iterator. @@ -2233,7 +2253,7 @@ bool map_addnpc(int16 m,struct npc_data *nd) { // Stores the spawn data entry in the mob list. // Returns the index of successful, or -1 if the list was full. int map_addmobtolist(unsigned short m, struct spawn_data *spawn) { - size_t i; + int i; ARR_FIND( 0, MAX_MOB_LIST_PER_MAP, i, map->list[m].moblist[i] == NULL ); if( i < MAX_MOB_LIST_PER_MAP ) { map->list[m].moblist[i] = spawn; @@ -2288,8 +2308,7 @@ int map_removemobs_sub(struct block_list *bl, va_list ap) return 1; } -int map_removemobs_timer(int tid, unsigned int tick, int id, intptr_t data) -{ +int map_removemobs_timer(int tid, int64 tick, int id, intptr_t data) { int count; const int16 m = id; @@ -2325,7 +2344,7 @@ void map_removemobs(int16 m) { *------------------------------------------*/ int16 map_mapname2mapid(const char* name) { unsigned short map_index; - map_index = mapindex_name2id(name); + map_index = mapindex->name2id(name); if (!map_index) return -1; return map->mapindex2mapid(map_index); @@ -2334,12 +2353,12 @@ int16 map_mapname2mapid(const char* name) { /*========================================== * Returns the map of the given mapindex. [Skotlex] *------------------------------------------*/ -int16 map_mapindex2mapid(unsigned short mapindex) { +int16 map_mapindex2mapid(unsigned short map_index) { - if (!mapindex || mapindex > MAX_MAPINDEX) + if (!map_index || map_index > MAX_MAPINDEX) return -1; - return map->index2mapid[mapindex]; + return map->index2mapid[map_index]; } /*========================================== @@ -2555,8 +2574,6 @@ int map_getcellp(struct map_data* m,int16 x,int16 y,cell_chk cellchk) { return (cell.novending); case CELL_CHKNOCHAT: return (cell.nochat); - case CELL_CHKMAELSTROM: - return (cell.maelstrom); case CELL_CHKICEWALL: return (cell.icewall); @@ -2617,7 +2634,6 @@ void map_setcell(int16 m, int16 x, int16 y, cell_t cell, bool flag) { case CELL_LANDPROTECTOR: map->list[m].cell[j].landprotector = flag; break; case CELL_NOVENDING: map->list[m].cell[j].novending = flag; break; case CELL_NOCHAT: map->list[m].cell[j].nochat = flag; break; - case CELL_MAELSTROM: map->list[m].cell[j].maelstrom = flag; break; case CELL_ICEWALL: map->list[m].cell[j].icewall = flag; break; default: ShowWarning("map_setcell: invalid cell type '%d'\n", (int)cell); @@ -2761,27 +2777,27 @@ void map_iwall_remove(const char *wall_name) DBData create_map_data_other_server(DBKey key, va_list args) { struct map_data_other_server *mdos; - unsigned short mapindex = (unsigned short)key.ui; + unsigned short map_index = (unsigned short)key.ui; mdos=(struct map_data_other_server *)aCalloc(1,sizeof(struct map_data_other_server)); - mdos->index = mapindex; - memcpy(mdos->name, mapindex_id2name(mapindex), MAP_NAME_LENGTH); + mdos->index = map_index; + memcpy(mdos->name, mapindex_id2name(map_index), MAP_NAME_LENGTH); return DB->ptr2data(mdos); } /*========================================== * Add mapindex to db of another map server *------------------------------------------*/ -int map_setipport(unsigned short mapindex, uint32 ip, uint16 port) +int map_setipport(unsigned short map_index, uint32 ip, uint16 port) { struct map_data_other_server *mdos; - mdos= uidb_ensure(map->map_db,(unsigned int)mapindex, map->create_map_data_other_server); + mdos= uidb_ensure(map->map_db,(unsigned int)map_index, map->create_map_data_other_server); if(mdos->cell) //Local map,Do nothing. Give priority to our own local maps over ones from another server. [Skotlex] return 0; if(ip == clif->map_ip && port == clif->map_port) { //That's odd, we received info that we are the ones with this map, but... we don't have it. - ShowFatalError("map_setipport : received info that this map-server SHOULD have map '%s', but it is not loaded.\n",mapindex_id2name(mapindex)); + ShowFatalError("map_setipport : received info that this map-server SHOULD have map '%s', but it is not loaded.\n",mapindex_id2name(map_index)); exit(EXIT_FAILURE); } mdos->ip = ip; @@ -2811,15 +2827,15 @@ int map_eraseallipport(void) { /*========================================== * Delete mapindex from db of another map server *------------------------------------------*/ -int map_eraseipport(unsigned short mapindex, uint32 ip, uint16 port) { +int map_eraseipport(unsigned short map_index, uint32 ip, uint16 port) { struct map_data_other_server *mdos; - mdos = (struct map_data_other_server*)uidb_get(map->map_db,(unsigned int)mapindex); + mdos = (struct map_data_other_server*)uidb_get(map->map_db,(unsigned int)map_index); if(!mdos || mdos->cell) //Map either does not exists or is a local map. return 0; if(mdos->ip==ip && mdos->port == port) { - uidb_remove(map->map_db,(unsigned int)mapindex); + uidb_remove(map->map_db,(unsigned int)map_index); aFree(mdos); return 1; } @@ -2901,14 +2917,14 @@ int map_readfromcache(struct map_data *m, char *buffer) { } -int map_addmap(char* mapname) { +int map_addmap(const char* mapname) { map->list[map->count].instance_id = -1; - mapindex_getmapname(mapname, map->list[map->count++].name); + mapindex->getmapname(mapname, map->list[map->count++].name); return 0; } void map_delmapid(int id) { - ShowNotice("Removing map [ %s ] from map->list"CL_CLL"\n",map->list[id].name); + ShowNotice("Removing map [ %s ] from maplist"CL_CLL"\n",map->list[id].name); memmove(map->list+id, map->list+id+1, sizeof(map->list[0])*(map->count-id-1)); map->count--; } @@ -2922,7 +2938,7 @@ int map_delmap(char* mapname) { return 0; } - mapindex_getmapname(mapname, map_name); + mapindex->getmapname(mapname, map_name); for(i = 0; i < map->count; i++) { if (strcmp(map->list[i].name, map_name) == 0) { map->delmapid(i); @@ -3104,6 +3120,18 @@ void do_final_maps(void) { if( map->list[i].channel ) clif->chsys_delete(map->list[i].channel); + + if( map->list[i].qi_data ) + aFree(map->list[i].qi_data); + + for( v = 0; v < map->list[i].hdatac; v++ ) { + if( map->list[i].hdata[v]->flag.free ) { + aFree(map->list[i].hdata[v]->data); + } + aFree(map->list[i].hdata[v]); + } + if( map->list[i].hdata ) + aFree(map->list[i].hdata); } map->zone_db_clear(); @@ -3169,6 +3197,12 @@ void map_flags_init(void) { map->list[i].misc_damage_rate = 100; map->list[i].short_damage_rate = 100; map->list[i].long_damage_rate = 100; + + if( map->list[i].qi_data ) + aFree(map->list[i].qi_data); + + map->list[i].qi_data = NULL; + map->list[i].qi_count = 0; } } @@ -3303,7 +3337,7 @@ int map_readallmaps (void) { continue; } - map->list[i].index = mapindex_name2id(map->list[i].name); + map->list[i].index = mapindex->name2id(map->list[i].name); if ( map->index2mapid[map_id2index(i)] != -1 ) { ShowWarning("Map %s already loaded!"CL_CLL"\n", map->list[i].name); @@ -3516,6 +3550,8 @@ void map_reloadnpc_sub(char *cfgName) npc->addsrcfile(w2); else if (strcmpi(w1, "import") == 0) map->reloadnpc_sub(w2); + else if (strcmpi(w1, "delnpc") == 0) + npc->delsrcfile(w2); else ShowWarning("Unknown setting '%s' in file %s\n", w1, cfgName); } @@ -3591,6 +3627,10 @@ int inter_config_read(char *cfgName) { map->db_use_sql_mob_skill_db = config_switch(w2); ShowStatus ("Using monster skill database as SQL: '%s'\n", w2); } + else if(strcmpi(w1,"autotrade_merchants_db")==0) + strcpy(map->autotrade_merchants_db, w2); + else if(strcmpi(w1,"autotrade_data_db")==0) + strcpy(map->autotrade_data_db, w2); /* sql log db */ else if(strcmpi(w1,"log_db_ip")==0) strcpy(logs->db_ip, w2); @@ -3645,14 +3685,115 @@ int map_sql_close(void) return 0; } +/** + * Merges two zones into a new one + * @param main the zone whose data must override the others upon conflict, + * e.g. enabling pvp on a town means that main is the pvp zone, while "other" is the towns previous zone + * + * @return the newly created zone from merging main and other + **/ +struct map_zone_data *map_merge_zone(struct map_zone_data *main, struct map_zone_data *other) { + char newzone[MAP_ZONE_NAME_LENGTH]; + struct map_zone_data *zone = NULL; + int cursor, i; + + sprintf(newzone, "%s+%s",main->name,other->name); + + if( (zone = strdb_get(map->zone_db, newzone)) ) + return zone;/* this zone has already been merged */ + + CREATE(zone, struct map_zone_data, 1); + + safestrncpy(zone->name, newzone, MAP_ZONE_NAME_LENGTH); + + zone->disabled_skills_count = main->disabled_skills_count + other->disabled_skills_count; + zone->disabled_items_count = main->disabled_items_count + other->disabled_items_count; + zone->mapflags_count = main->mapflags_count + other->mapflags_count; + zone->disabled_commands_count = main->disabled_commands_count + other->disabled_commands_count; + zone->capped_skills_count = main->capped_skills_count + other->capped_skills_count; + + CREATE(zone->disabled_skills, struct map_zone_disabled_skill_entry *, zone->disabled_skills_count ); + + for(i = 0, cursor = 0; i < main->disabled_skills_count; i++, cursor++ ) { + CREATE(zone->disabled_skills[cursor], struct map_zone_disabled_skill_entry, 1 ); + memcpy(zone->disabled_skills[cursor], main->disabled_skills[i], sizeof(struct map_zone_disabled_skill_entry)); + } + + for(i = 0; i < other->disabled_skills_count; i++, cursor++ ) { + CREATE(zone->disabled_skills[cursor], struct map_zone_disabled_skill_entry, 1 ); + memcpy(zone->disabled_skills[cursor], other->disabled_skills[i], sizeof(struct map_zone_disabled_skill_entry)); + } + + CREATE(zone->disabled_items, int, zone->disabled_items_count ); + + for(i = 0, cursor = 0; i < main->disabled_items_count; i++, cursor++ ) { + zone->disabled_items[cursor] = main->disabled_items[i]; + } + + for(i = 0; i < other->disabled_items_count; i++, cursor++ ) { + zone->disabled_items[cursor] = other->disabled_items[i]; + } + + CREATE(zone->mapflags, char *, zone->mapflags_count ); + + for(i = 0, cursor = 0; i < main->mapflags_count; i++, cursor++ ) { + CREATE(zone->mapflags[cursor], char, MAP_ZONE_MAPFLAG_LENGTH ); + safestrncpy(zone->mapflags[cursor], main->mapflags[i], MAP_ZONE_MAPFLAG_LENGTH); + } + + for(i = 0; i < other->mapflags_count; i++, cursor++ ) { + CREATE(zone->mapflags[cursor], char, MAP_ZONE_MAPFLAG_LENGTH ); + safestrncpy(zone->mapflags[cursor], other->mapflags[i], MAP_ZONE_MAPFLAG_LENGTH); + } + + CREATE(zone->disabled_commands, struct map_zone_disabled_command_entry *, zone->disabled_commands_count); + + for(i = 0, cursor = 0; i < main->disabled_commands_count; i++, cursor++ ) { + CREATE(zone->disabled_commands[cursor], struct map_zone_disabled_command_entry, 1); + memcpy(zone->disabled_commands[cursor], main->disabled_commands[i], sizeof(struct map_zone_disabled_command_entry)); + } + + for(i = 0; i < other->disabled_commands_count; i++, cursor++ ) { + CREATE(zone->disabled_commands[cursor], struct map_zone_disabled_command_entry, 1); + memcpy(zone->disabled_commands[cursor], other->disabled_commands[i], sizeof(struct map_zone_disabled_command_entry)); + } + + CREATE(zone->capped_skills, struct map_zone_skill_damage_cap_entry *, zone->capped_skills_count); + + + for(i = 0, cursor = 0; i < main->capped_skills_count; i++, cursor++ ) { + CREATE(zone->capped_skills[cursor], struct map_zone_skill_damage_cap_entry, 1); + memcpy(zone->capped_skills[cursor], main->disabled_commands[i], sizeof(struct map_zone_skill_damage_cap_entry)); + } + + for(i = 0; i < other->capped_skills_count; i++, cursor++ ) { + CREATE(zone->capped_skills[cursor], struct map_zone_skill_damage_cap_entry, 1); + memcpy(zone->capped_skills[cursor], other->capped_skills[i], sizeof(struct map_zone_skill_damage_cap_entry)); + } + + zone->info.special = 2; + + strdb_put(map->zone_db, newzone, zone); + + return zone; +} + void map_zone_change2(int m, struct map_zone_data *zone) { char empty[1] = "\0"; - map->list[m].prev_zone = map->list[m].zone; - + if( map->list[m].zone == zone ) + return; + + if( map->list[m].zone->info.special != 2 ) /* we don't update it for merged zones! */ + map->list[m].prev_zone = map->list[m].zone; + if( map->list[m].zone_mf_count ) map->zone_remove(m); + if( zone->info.special ) { + zone = map->merge_zone(zone,map->list[m].prev_zone); + } + map->zone_apply(m,zone,empty,empty,empty); } /* when changing from a mapflag to another during runtime */ @@ -3669,7 +3810,7 @@ void map_zone_remove(int m) { unsigned short k; char empty[1] = "\0"; for(k = 0; k < map->list[m].zone_mf_count; k++) { - int len = strlen(map->list[m].zone_mf[k]),j; + size_t len = strlen(map->list[m].zone_mf[k]),j; params[0] = '\0'; memcpy(flag, map->list[m].zone_mf[k], MAP_ZONE_MAPFLAG_LENGTH); for(j = 0; j < len; j++) { @@ -4221,7 +4362,7 @@ bool map_zone_mf_cache(int m, char *flag, char *params) { } else if (!strcmpi(flag,"adjust_unit_duration")) { int skill_id, k; char skill_name[MAP_ZONE_MAPFLAG_LENGTH], modifier[MAP_ZONE_MAPFLAG_LENGTH]; - int len = strlen(params); + size_t len = strlen(params); modifier[0] = '\0'; memcpy(skill_name, params, MAP_ZONE_MAPFLAG_LENGTH); @@ -4239,7 +4380,6 @@ bool map_zone_mf_cache(int m, char *flag, char *params) { } else { int idx = map->list[m].unit_count; - k = 0; ARR_FIND(0, idx, k, map->list[m].units[k]->skill_id == skill_id); if( k < idx ) { @@ -4255,7 +4395,7 @@ bool map_zone_mf_cache(int m, char *flag, char *params) { } else if (!strcmpi(flag,"adjust_skill_damage")) { int skill_id, k; char skill_name[MAP_ZONE_MAPFLAG_LENGTH], modifier[MAP_ZONE_MAPFLAG_LENGTH]; - int len = strlen(params); + size_t len = strlen(params); modifier[0] = '\0'; memcpy(skill_name, params, MAP_ZONE_MAPFLAG_LENGTH); @@ -4273,7 +4413,6 @@ bool map_zone_mf_cache(int m, char *flag, char *params) { } else { int idx = map->list[m].skill_count; - k = 0; ARR_FIND(0, idx, k, map->list[m].skills[k]->skill_id == skill_id); if( k < idx ) { @@ -4380,7 +4519,17 @@ bool map_zone_mf_cache(int m, char *flag, char *params) { map_zone_mf_cache_add(m,rflag); } } + } else if (!strcmpi(flag,"nocashshop")) { + if( state && map->list[m].flag.nocashshop ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"nocashshop\toff"); + else if( map->list[m].flag.nocashshop ) + map_zone_mf_cache_add(m,"nocashshop"); + } } + return false; } void map_zone_apply(int m, struct map_zone_data *zone, const char* start, const char* buffer, const char* filepath) { @@ -4389,7 +4538,7 @@ void map_zone_apply(int m, struct map_zone_data *zone, const char* start, const char flag[MAP_ZONE_MAPFLAG_LENGTH], params[MAP_ZONE_MAPFLAG_LENGTH]; map->list[m].zone = zone; for(i = 0; i < zone->mapflags_count; i++) { - int len = strlen(zone->mapflags[i]); + size_t len = strlen(zone->mapflags[i]); int k; params[0] = '\0'; memcpy(flag, zone->mapflags[i], MAP_ZONE_MAPFLAG_LENGTH); @@ -4417,7 +4566,7 @@ void map_zone_init(void) { zone = &map->zone_all; for(i = 0; i < zone->mapflags_count; i++) { - int len = strlen(zone->mapflags[i]); + size_t len = strlen(zone->mapflags[i]); params[0] = '\0'; memcpy(flag, zone->mapflags[i], MAP_ZONE_MAPFLAG_LENGTH); for(k = 0; k < len; k++) { @@ -4440,7 +4589,7 @@ void map_zone_init(void) { if( battle_config.pk_mode ) { zone = &map->zone_pk; for(i = 0; i < zone->mapflags_count; i++) { - int len = strlen(zone->mapflags[i]); + size_t len = strlen(zone->mapflags[i]); params[0] = '\0'; memcpy(flag, zone->mapflags[i], MAP_ZONE_MAPFLAG_LENGTH); for(k = 0; k < len; k++) { @@ -4547,10 +4696,10 @@ void read_map_zone_db(void) { #else const char *config_filename = "db/pre-re/map_zone_db.conf"; // FIXME hardcoded name #endif - if (conf_read_file(&map_zone_db, config_filename)) + if (libconfig->read_file(&map_zone_db, config_filename)) return; - zones = config_lookup(&map_zone_db, "zones"); + zones = libconfig->lookup(&map_zone_db, "zones"); if (zones != NULL) { struct map_zone_data *zone; @@ -4567,16 +4716,16 @@ void read_map_zone_db(void) { disabled_commands_count = 0, capped_skills_count = 0; enum map_zone_skill_subtype subtype; - zone_count = config_setting_length(zones); + zone_count = libconfig->setting_length(zones); for (i = 0; i < zone_count; ++i) { bool is_all = false; - zone_e = config_setting_get_elem(zones, i); + zone_e = libconfig->setting_get_elem(zones, i); - if (!config_setting_lookup_string(zone_e, "name", &zonename)) { + if (!libconfig->setting_lookup_string(zone_e, "name", &zonename)) { ShowError("map_zone_db: missing zone name, skipping... (%s:%d)\n", config_setting_source_file(zone_e), config_setting_source_line(zone_e)); - config_setting_remove_elem(zones,i);/* remove from the tree */ + libconfig->setting_remove_elem(zones,i);/* remove from the tree */ --zone_count; --i; continue; @@ -4584,7 +4733,7 @@ void read_map_zone_db(void) { if( strdb_exists(map->zone_db, zonename) ) { ShowError("map_zone_db: duplicate zone name '%s', skipping...\n",zonename); - config_setting_remove_elem(zones,i);/* remove from the tree */ + libconfig->setting_remove_elem(zones,i);/* remove from the tree */ --zone_count; --i; continue; @@ -4602,33 +4751,33 @@ void read_map_zone_db(void) { zone->disabled_skills_count = 0; zone->disabled_items_count = 0; } - safestrncpy(zone->name, zonename, MAP_ZONE_NAME_LENGTH); + safestrncpy(zone->name, zonename, MAP_ZONE_NAME_LENGTH/2); - if( (skills = config_setting_get_member(zone_e, "disabled_skills")) != NULL ) { - disabled_skills_count = config_setting_length(skills); + if( (skills = libconfig->setting_get_member(zone_e, "disabled_skills")) != NULL ) { + disabled_skills_count = libconfig->setting_length(skills); /* validate */ - for(h = 0; h < config_setting_length(skills); h++) { - config_setting_t *skillinfo = config_setting_get_elem(skills, h); + for(h = 0; h < libconfig->setting_length(skills); h++) { + config_setting_t *skillinfo = libconfig->setting_get_elem(skills, h); name = config_setting_name(skillinfo); if( !map->zone_str2skillid(name) ) { ShowError("map_zone_db: unknown skill (%s) in disabled_skills for zone '%s', skipping skill...\n",name,zone->name); - config_setting_remove_elem(skills,h); + libconfig->setting_remove_elem(skills,h); --disabled_skills_count; --h; continue; } - if( !map->zone_bl_type(config_setting_get_string_elem(skills,h),&subtype) )/* we dont remove it from the three due to inheritance */ + if( !map->zone_bl_type(libconfig->setting_get_string_elem(skills,h),&subtype) )/* we dont remove it from the three due to inheritance */ --disabled_skills_count; } /* all ok, process */ CREATE( zone->disabled_skills, struct map_zone_disabled_skill_entry *, disabled_skills_count ); - for(h = 0, v = 0; h < config_setting_length(skills); h++) { - config_setting_t *skillinfo = config_setting_get_elem(skills, h); + for(h = 0, v = 0; h < libconfig->setting_length(skills); h++) { + config_setting_t *skillinfo = libconfig->setting_get_elem(skills, h); struct map_zone_disabled_skill_entry * entry; enum bl_type type; name = config_setting_name(skillinfo); - if( (type = map->zone_bl_type(config_setting_get_string_elem(skills,h),&subtype)) ) { /* only add if enabled */ + if( (type = map->zone_bl_type(libconfig->setting_get_string_elem(skills,h),&subtype)) ) { /* only add if enabled */ CREATE( entry, struct map_zone_disabled_skill_entry, 1 ); entry->nameid = map->zone_str2skillid(name); @@ -4642,28 +4791,28 @@ void read_map_zone_db(void) { zone->disabled_skills_count = disabled_skills_count; } - if( (items = config_setting_get_member(zone_e, "disabled_items")) != NULL ) { - disabled_items_count = config_setting_length(items); + if( (items = libconfig->setting_get_member(zone_e, "disabled_items")) != NULL ) { + disabled_items_count = libconfig->setting_length(items); /* validate */ - for(h = 0; h < config_setting_length(items); h++) { - config_setting_t *item = config_setting_get_elem(items, h); + for(h = 0; h < libconfig->setting_length(items); h++) { + config_setting_t *item = libconfig->setting_get_elem(items, h); name = config_setting_name(item); if( !map->zone_str2itemid(name) ) { ShowError("map_zone_db: unknown item (%s) in disabled_items for zone '%s', skipping item...\n",name,zone->name); - config_setting_remove_elem(items,h); + libconfig->setting_remove_elem(items,h); --disabled_items_count; --h; continue; } - if( !config_setting_get_bool(item) )/* we dont remove it from the three due to inheritance */ + if( !libconfig->setting_get_bool(item) )/* we dont remove it from the three due to inheritance */ --disabled_items_count; } /* all ok, process */ CREATE( zone->disabled_items, int, disabled_items_count ); - for(h = 0, v = 0; h < config_setting_length(items); h++) { - config_setting_t *item = config_setting_get_elem(items, h); + for(h = 0, v = 0; h < libconfig->setting_length(items); h++) { + config_setting_t *item = libconfig->setting_get_elem(items, h); - if( config_setting_get_bool(item) ) { /* only add if enabled */ + if( libconfig->setting_get_bool(item) ) { /* only add if enabled */ name = config_setting_name(item); zone->disabled_items[v++] = map->zone_str2itemid(name); } @@ -4672,14 +4821,14 @@ void read_map_zone_db(void) { zone->disabled_items_count = disabled_items_count; } - if( (mapflags = config_setting_get_member(zone_e, "mapflags")) != NULL ) { - mapflags_count = config_setting_length(mapflags); + if( (mapflags = libconfig->setting_get_member(zone_e, "mapflags")) != NULL ) { + mapflags_count = libconfig->setting_length(mapflags); /* mapflags are not validated here, so we save all anyway */ CREATE( zone->mapflags, char *, mapflags_count ); for(h = 0; h < mapflags_count; h++) { CREATE( zone->mapflags[h], char, MAP_ZONE_MAPFLAG_LENGTH ); - name = config_setting_get_string_elem(mapflags, h); + name = libconfig->setting_get_string_elem(mapflags, h); safestrncpy(zone->mapflags[h], name, MAP_ZONE_MAPFLAG_LENGTH); @@ -4687,31 +4836,31 @@ void read_map_zone_db(void) { zone->mapflags_count = mapflags_count; } - if( (commands = config_setting_get_member(zone_e, "disabled_commands")) != NULL ) { - disabled_commands_count = config_setting_length(commands); + if( (commands = libconfig->setting_get_member(zone_e, "disabled_commands")) != NULL ) { + disabled_commands_count = libconfig->setting_length(commands); /* validate */ - for(h = 0; h < config_setting_length(commands); h++) { - config_setting_t *command = config_setting_get_elem(commands, h); + for(h = 0; h < libconfig->setting_length(commands); h++) { + config_setting_t *command = libconfig->setting_get_elem(commands, h); name = config_setting_name(command); if( !atcommand->exists(name) ) { ShowError("map_zone_db: unknown command '%s' in disabled_commands for zone '%s', skipping entry...\n",name,zone->name); - config_setting_remove_elem(commands,h); + libconfig->setting_remove_elem(commands,h); --disabled_commands_count; --h; continue; } - if( !config_setting_get_int(command) )/* we dont remove it from the three due to inheritance */ + if( !libconfig->setting_get_int(command) )/* we dont remove it from the three due to inheritance */ --disabled_commands_count; } /* all ok, process */ CREATE( zone->disabled_commands, struct map_zone_disabled_command_entry *, disabled_commands_count ); - for(h = 0, v = 0; h < config_setting_length(commands); h++) { - config_setting_t *command = config_setting_get_elem(commands, h); + for(h = 0, v = 0; h < libconfig->setting_length(commands); h++) { + config_setting_t *command = libconfig->setting_get_elem(commands, h); struct map_zone_disabled_command_entry * entry; int group_lv; name = config_setting_name(command); - if( (group_lv = config_setting_get_int(command)) ) { /* only add if enabled */ + if( (group_lv = libconfig->setting_get_int(command)) ) { /* only add if enabled */ CREATE( entry, struct map_zone_disabled_command_entry, 1 ); entry->cmd = atcommand->exists(name)->func; @@ -4723,35 +4872,35 @@ void read_map_zone_db(void) { zone->disabled_commands_count = disabled_commands_count; } - if( (caps = config_setting_get_member(zone_e, "skill_damage_cap")) != NULL ) { - capped_skills_count = config_setting_length(caps); + if( (caps = libconfig->setting_get_member(zone_e, "skill_damage_cap")) != NULL ) { + capped_skills_count = libconfig->setting_length(caps); /* validate */ - for(h = 0; h < config_setting_length(caps); h++) { - config_setting_t *cap = config_setting_get_elem(caps, h); + for(h = 0; h < libconfig->setting_length(caps); h++) { + config_setting_t *cap = libconfig->setting_get_elem(caps, h); name = config_setting_name(cap); if( !map->zone_str2skillid(name) ) { ShowError("map_zone_db: unknown skill (%s) in skill_damage_cap for zone '%s', skipping skill...\n",name,zone->name); - config_setting_remove_elem(caps,h); + libconfig->setting_remove_elem(caps,h); --capped_skills_count; --h; continue; } - if( !map->zone_bl_type(config_setting_get_string_elem(cap,1),&subtype) )/* we dont remove it from the three due to inheritance */ + if( !map->zone_bl_type(libconfig->setting_get_string_elem(cap,1),&subtype) )/* we dont remove it from the three due to inheritance */ --capped_skills_count; } /* all ok, process */ CREATE( zone->capped_skills, struct map_zone_skill_damage_cap_entry *, capped_skills_count ); - for(h = 0, v = 0; h < config_setting_length(caps); h++) { - config_setting_t *cap = config_setting_get_elem(caps, h); + for(h = 0, v = 0; h < libconfig->setting_length(caps); h++) { + config_setting_t *cap = libconfig->setting_get_elem(caps, h); struct map_zone_skill_damage_cap_entry * entry; enum bl_type type; name = config_setting_name(cap); - if( (type = map->zone_bl_type(config_setting_get_string_elem(cap,1),&subtype)) ) { /* only add if enabled */ + if( (type = map->zone_bl_type(libconfig->setting_get_string_elem(cap,1),&subtype)) ) { /* only add if enabled */ CREATE( entry, struct map_zone_skill_damage_cap_entry, 1 ); entry->nameid = map->zone_str2skillid(name); - entry->cap = config_setting_get_int_elem(cap,0); + entry->cap = libconfig->setting_get_int_elem(cap,0); entry->type = type; entry->subtype = subtype; zone->capped_skills[v++] = entry; @@ -4771,24 +4920,24 @@ void read_map_zone_db(void) { config_setting_t *new_entry = NULL; int inherit_count; - zone_e = config_setting_get_elem(zones, i); - config_setting_lookup_string(zone_e, "name", &zonename); + zone_e = libconfig->setting_get_elem(zones, i); + libconfig->setting_lookup_string(zone_e, "name", &zonename); if( strncmpi(zonename,MAP_ZONE_ALL_NAME,MAP_ZONE_NAME_LENGTH) == 0 ) { continue;/* all zone doesn't inherit anything (if it did, everything would link to each other and boom endless loop) */ } - if( (inherit_tree = config_setting_get_member(zone_e, "inherit")) != NULL ) { + if( (inherit_tree = libconfig->setting_get_member(zone_e, "inherit")) != NULL ) { /* append global zone to this */ - new_entry = config_setting_add(inherit_tree,MAP_ZONE_ALL_NAME,CONFIG_TYPE_STRING); - config_setting_set_string(new_entry,MAP_ZONE_ALL_NAME); + new_entry = libconfig->setting_add(inherit_tree,MAP_ZONE_ALL_NAME,CONFIG_TYPE_STRING); + libconfig->setting_set_string(new_entry,MAP_ZONE_ALL_NAME); } else { /* create inherit member and add global zone to it */ - inherit_tree = config_setting_add(zone_e, "inherit",CONFIG_TYPE_ARRAY); - new_entry = config_setting_add(inherit_tree,MAP_ZONE_ALL_NAME,CONFIG_TYPE_STRING); - config_setting_set_string(new_entry,MAP_ZONE_ALL_NAME); + inherit_tree = libconfig->setting_add(zone_e, "inherit",CONFIG_TYPE_ARRAY); + new_entry = libconfig->setting_add(inherit_tree,MAP_ZONE_ALL_NAME,CONFIG_TYPE_STRING); + libconfig->setting_set_string(new_entry,MAP_ZONE_ALL_NAME); } - inherit_count = config_setting_length(inherit_tree); + inherit_count = libconfig->setting_length(inherit_tree); for(h = 0; h < inherit_count; h++) { struct map_zone_data *izone; /* inherit zone */ int disabled_skills_count_i = 0; /* disabled skill count from inherit zone */ @@ -4798,8 +4947,8 @@ void read_map_zone_db(void) { int capped_skills_count_i = 0; /* skill capped count from inherit zone */ int j; - name = config_setting_get_string_elem(inherit_tree, h); - config_setting_lookup_string(zone_e, "name", &zonename);/* will succeed for we validated it earlier */ + name = libconfig->setting_get_string_elem(inherit_tree, h); + libconfig->setting_lookup_string(zone_e, "name", &zonename);/* will succeed for we validated it earlier */ if( !(izone = strdb_get(map->zone_db, name)) ) { ShowError("map_zone_db: Unknown zone '%s' being inherit by zone '%s', skipping...\n",name,zonename); @@ -4821,13 +4970,13 @@ void read_map_zone_db(void) { /* process everything to override, paying attention to config_setting_get_bool */ if( disabled_skills_count_i ) { - if( (skills = config_setting_get_member(zone_e, "disabled_skills")) == NULL ) - skills = config_setting_add(zone_e, "disabled_skills",CONFIG_TYPE_GROUP); - disabled_skills_count = config_setting_length(skills); + if( (skills = libconfig->setting_get_member(zone_e, "disabled_skills")) == NULL ) + skills = libconfig->setting_add(zone_e, "disabled_skills",CONFIG_TYPE_GROUP); + disabled_skills_count = libconfig->setting_length(skills); for(j = 0; j < disabled_skills_count_i; j++) { int k; for(k = 0; k < disabled_skills_count; k++) { - config_setting_t *skillinfo = config_setting_get_elem(skills, k); + config_setting_t *skillinfo = libconfig->setting_get_elem(skills, k); if( map->zone_str2skillid(config_setting_name(skillinfo)) == izone->disabled_skills[j]->nameid ) { break; } @@ -4844,18 +4993,18 @@ void read_map_zone_db(void) { } if( disabled_items_count_i ) { - if( (items = config_setting_get_member(zone_e, "disabled_items")) == NULL ) - items = config_setting_add(zone_e, "disabled_items",CONFIG_TYPE_GROUP); - disabled_items_count = config_setting_length(items); + if( (items = libconfig->setting_get_member(zone_e, "disabled_items")) == NULL ) + items = libconfig->setting_add(zone_e, "disabled_items",CONFIG_TYPE_GROUP); + disabled_items_count = libconfig->setting_length(items); for(j = 0; j < disabled_items_count_i; j++) { int k; for(k = 0; k < disabled_items_count; k++) { - config_setting_t *item = config_setting_get_elem(items, k); + config_setting_t *item = libconfig->setting_get_elem(items, k); name = config_setting_name(item); if( map->zone_str2itemid(name) == izone->disabled_items[j] ) { - if( config_setting_get_bool(item) ) + if( libconfig->setting_get_bool(item) ) continue; break; } @@ -4868,13 +5017,13 @@ void read_map_zone_db(void) { } if( mapflags_count_i ) { - if( (mapflags = config_setting_get_member(zone_e, "mapflags")) == NULL ) - mapflags = config_setting_add(zone_e, "mapflags",CONFIG_TYPE_ARRAY); - mapflags_count = config_setting_length(mapflags); + if( (mapflags = libconfig->setting_get_member(zone_e, "mapflags")) == NULL ) + mapflags = libconfig->setting_add(zone_e, "mapflags",CONFIG_TYPE_ARRAY); + mapflags_count = libconfig->setting_length(mapflags); for(j = 0; j < mapflags_count_i; j++) { int k; for(k = 0; k < mapflags_count; k++) { - name = config_setting_get_string_elem(mapflags, k); + name = libconfig->setting_get_string_elem(mapflags, k); if( strcmpi(name,izone->mapflags[j]) == 0 ) { break; @@ -4889,14 +5038,14 @@ void read_map_zone_db(void) { } if( disabled_commands_count_i ) { - if( (commands = config_setting_get_member(zone_e, "disabled_commands")) == NULL ) - commands = config_setting_add(zone_e, "disabled_commands",CONFIG_TYPE_GROUP); + if( (commands = libconfig->setting_get_member(zone_e, "disabled_commands")) == NULL ) + commands = libconfig->setting_add(zone_e, "disabled_commands",CONFIG_TYPE_GROUP); - disabled_commands_count = config_setting_length(commands); + disabled_commands_count = libconfig->setting_length(commands); for(j = 0; j < disabled_commands_count_i; j++) { int k; for(k = 0; k < disabled_commands_count; k++) { - config_setting_t *command = config_setting_get_elem(commands, k); + config_setting_t *command = libconfig->setting_get_elem(commands, k); if( atcommand->exists(config_setting_name(command))->func == izone->disabled_commands[j]->cmd ) { break; } @@ -4913,14 +5062,14 @@ void read_map_zone_db(void) { } if( capped_skills_count_i ) { - if( (caps = config_setting_get_member(zone_e, "skill_damage_cap")) == NULL ) - caps = config_setting_add(zone_e, "skill_damage_cap",CONFIG_TYPE_GROUP); + if( (caps = libconfig->setting_get_member(zone_e, "skill_damage_cap")) == NULL ) + caps = libconfig->setting_add(zone_e, "skill_damage_cap",CONFIG_TYPE_GROUP); - capped_skills_count = config_setting_length(caps); + capped_skills_count = libconfig->setting_length(caps); for(j = 0; j < capped_skills_count_i; j++) { int k; for(k = 0; k < capped_skills_count; k++) { - config_setting_t *cap = config_setting_get_elem(caps, k); + config_setting_t *cap = libconfig->setting_get_elem(caps, k); if( map->zone_str2skillid(config_setting_name(cap)) == izone->capped_skills[j]->nameid ) { break; } @@ -4942,8 +5091,52 @@ void read_map_zone_db(void) { ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' zones in '"CL_WHITE"%s"CL_RESET"'.\n", zone_count, config_filename); /* not supposed to go in here but in skill_final whatever */ - config_destroy(&map_zone_db); + libconfig->destroy(&map_zone_db); + + /* post-load processing */ + if( (zone = strdb_get(map->zone_db, MAP_ZONE_PVP_NAME)) ) + zone->info.special = 1; + if( (zone = strdb_get(map->zone_db, MAP_ZONE_GVG_NAME)) ) + zone->info.special = 1; + if( (zone = strdb_get(map->zone_db, MAP_ZONE_BG_NAME)) ) + zone->info.special = 1; + } +} + +int map_get_new_bonus_id (void) { + return map->bonus_id++; +} + +void map_add_questinfo(int m, struct questinfo *qi) { + unsigned short i; + + /* duplicate, override */ + for(i = 0; i < map->list[m].qi_count; i++) { + if( map->list[m].qi_data[i].nd == qi->nd ) + break; + } + + if( i == map->list[m].qi_count ) + RECREATE(map->list[m].qi_data, struct questinfo, ++map->list[m].qi_count); + + memcpy(&map->list[m].qi_data[i], qi, sizeof(struct questinfo)); +} + +bool map_remove_questinfo(int m, struct npc_data *nd) { + unsigned short i; + + for(i = 0; i < map->list[m].qi_count; i++) { + struct questinfo *qi = &map->list[m].qi_data[i]; + if( qi->nd == nd ) { + memset(&map->list[m].qi_data[i], 0, sizeof(struct questinfo)); + if( i != --map->list[m].qi_count ) { + memmove(&map->list[m].qi_data[i],&map->list[m].qi_data[i+1],sizeof(struct questinfo)*(map->list[m].qi_count-i)); + } + return true; + } } + + return false; } /** @@ -5047,7 +5240,7 @@ void do_final(void) map->id_db->foreach(map->id_db,map->cleanup_db_sub); chrif->char_reset_offline(); - chrif->flush_fifo(); + chrif->flush(); atcommand->final(); battle->final(); @@ -5055,6 +5248,7 @@ void do_final(void) ircbot->final();/* before clif. */ clif->final(); npc->final(); + quest->final(); script->final(); itemdb->final(); instance->final(); @@ -5075,9 +5269,11 @@ void do_final(void) map->list_final(); vending->final(); + HPM_map_do_final(); + map->map_db->destroy(map->map_db, map->db_final); - mapindex_final(); + mapindex->final(); if(map->enable_grf) grfio_final(); @@ -5092,9 +5288,16 @@ void do_final(void) map->sql_close(); ers_destroy(map->iterator_ers); + ers_destroy(map->flooritem_ers); aFree(map->list); + if( map->block_free ) + aFree(map->block_free); + if( map->bl_list ) + aFree(map->bl_list); + + if( !map->enable_grf ) aFree(map->cache_buffer); @@ -5130,7 +5333,7 @@ void do_abort(void) } ShowError("Server received crash signal! Attempting to save all online characters!\n"); map->foreachpc(map->abort_sub); - chrif->flush_fifo(); + chrif->flush(); } /*====================================================== @@ -5141,17 +5344,19 @@ void map_helpscreen(bool do_exit) ShowInfo("Usage: %s [options]\n", SERVER_NAME); ShowInfo("\n"); ShowInfo("Options:\n"); - ShowInfo(" -?, -h [--help]\t\tDisplays this help screen.\n"); - ShowInfo(" -v [--version]\t\tDisplays the server's version.\n"); - ShowInfo(" --run-once\t\t\tCloses server after loading (testing).\n"); - ShowInfo(" --map-config <file>\t\tAlternative map-server configuration.\n"); - ShowInfo(" --battle-config <file>\tAlternative battle configuration.\n"); - ShowInfo(" --atcommand-config <file>\tAlternative atcommand configuration.\n"); - ShowInfo(" --script-config <file>\tAlternative script configuration.\n"); - ShowInfo(" --msg-config <file>\t\tAlternative message configuration.\n"); - ShowInfo(" --grf-path <file>\t\tAlternative GRF path configuration.\n"); - ShowInfo(" --inter-config <file>\t\tAlternative inter-server configuration.\n"); - ShowInfo(" --log-config <file>\t\tAlternative logging configuration.\n"); + ShowInfo(" -?, -h [--help] Displays this help screen.\n"); + ShowInfo(" -v [--version] Displays the server's version.\n"); + ShowInfo(" --run-once Closes server after loading (testing).\n"); + ShowInfo(" --map-config <file> Alternative map-server configuration.\n"); + ShowInfo(" --battle-config <file> Alternative battle configuration.\n"); + ShowInfo(" --atcommand-config <file> Alternative atcommand configuration.\n"); + ShowInfo(" --script-config <file> Alternative script configuration.\n"); + ShowInfo(" --msg-config <file> Alternative message configuration.\n"); + ShowInfo(" --grf-path <file> Alternative GRF path configuration.\n"); + ShowInfo(" --inter-config <file> Alternative inter-server configuration.\n"); + ShowInfo(" --log-config <file> Alternative logging configuration.\n"); + ShowInfo(" --script-check <file> Tests a script for errors, without running the server.\n"); + HPM->arg_help();/* display help for commands implemented thru HPM */ if( do_exit ) exit(EXIT_SUCCESS); } @@ -5194,10 +5399,11 @@ void do_shutdown(void) } } -bool map_arg_next_value(const char* option, int i, int argc) +bool map_arg_next_value(const char* option, int i, int argc, bool must) { if( i >= argc-1 ) { - ShowWarning("Missing value for option '%s'.\n", option); + if( must ) + ShowWarning("Missing value for option '%s'.\n", option); return false; } @@ -5234,13 +5440,15 @@ CPCMD(gm_use) { ShowError("gm:use invalid syntax. use '"CL_WHITE"gm:use @command <optional params>"CL_RESET"'\n"); return; } - map->cpsd->fd = -2; - if( !atcommand->parse(map->cpsd->fd, map->cpsd, line, 0) ) + + map->cpsd_active = true; + + if( !atcommand->exec(map->cpsd->fd, map->cpsd, line, false) ) ShowInfo("HCP: '"CL_WHITE"%s"CL_RESET"' failed\n",line); else ShowInfo("HCP: '"CL_WHITE"%s"CL_RESET"' was used\n",line); - map->cpsd->fd = 0; - + + map->cpsd_active = false; } /* Hercules Console Parser */ void map_cp_defaults(void) { @@ -5279,6 +5487,7 @@ void map_hp_symbols(void) { HPM->share(skill,"skill"); HPM->share(vending,"vending"); HPM->share(pc,"pc"); + HPM->share(pcg,"pc_groups"); HPM->share(party,"party"); HPM->share(storage,"storage"); HPM->share(trade,"trade"); @@ -5297,22 +5506,22 @@ void map_hp_symbols(void) { HPM->share(quest,"quest"); #ifdef PCRE_SUPPORT HPM->share(npc_chat,"npc_chat"); + HPM->share(libpcre,"libpcre"); #endif - /* partial */ HPM->share(mapit,"mapit"); + HPM->share(mapindex,"mapindex"); /* sql link */ HPM->share(map->mysql_handle,"sql_handle"); /* specific */ HPM->share(atcommand->create,"addCommand"); HPM->share(script->addScript,"addScript"); - HPM->share(HPM_map_addToMSD,"addToMSD"); - HPM->share(HPM_map_getFromMSD,"getFromMSD"); - HPM->share(HPM_map_removeFromMSD,"removeFromMSD"); - /* vars */ - HPM->share(map->list,"map->list"); + HPM->share(HPM_map_add_group_permission,"addGroupPermission"); } void map_load_defaults(void) { + mapindex_defaults(); + map_defaults(); + /* */ atcommand_defaults(); battle_defaults(); battleground_defaults(); @@ -5333,6 +5542,7 @@ void map_load_defaults(void) { skill_defaults(); vending_defaults(); pc_defaults(); + pc_groups_defaults(); party_defaults(); storage_defaults(); trade_defaults(); @@ -5354,22 +5564,33 @@ void map_load_defaults(void) { } int do_init(int argc, char *argv[]) { + bool minimal = false; + char *scriptcheck = NULL; int i; #ifdef GCOLLECT GC_enable_incremental(); #endif + + map_load_defaults(); - map_defaults(); - - rnd_init(); - + HPM_map_do_init(); + HPM->DataCheck = HPM_map_DataCheck; + HPM->load_sub = HPM_map_plugin_load_sub; + HPM->symbol_defaults_sub = map_hp_symbols; + HPM->grabHPDataSub = HPM_map_grabHPData; + HPM->config_read(); + + HPM->event(HPET_PRE_INIT); + for( i = 1; i < argc ; i++ ) { const char* arg = argv[i]; if( arg[0] != '-' && ( arg[0] != '/' || arg[1] == '-' ) ) {// -, -- and / ShowError("Unknown option '%s'.\n", argv[i]); exit(EXIT_FAILURE); + } else if ( HPM->parse_arg(arg,&i,argv,map->arg_next_value(arg, i, argc, false)) ) { + continue; /* HPM Triggered */ } else if( (++arg)[0] == '-' ) {// long option arg++; @@ -5378,31 +5599,36 @@ int do_init(int argc, char *argv[]) } else if( strcmp(arg, "version") == 0 ) { map->versionscreen(true); } else if( strcmp(arg, "map-config") == 0 ) { - if( map->arg_next_value(arg, i, argc) ) + if( map->arg_next_value(arg, i, argc, true) ) map->MAP_CONF_NAME = argv[++i]; } else if( strcmp(arg, "battle-config") == 0 ) { - if( map->arg_next_value(arg, i, argc) ) + if( map->arg_next_value(arg, i, argc, true) ) map->BATTLE_CONF_FILENAME = argv[++i]; } else if( strcmp(arg, "atcommand-config") == 0 ) { - if( map->arg_next_value(arg, i, argc) ) + if( map->arg_next_value(arg, i, argc, true) ) map->ATCOMMAND_CONF_FILENAME = argv[++i]; } else if( strcmp(arg, "script-config") == 0 ) { - if( map->arg_next_value(arg, i, argc) ) + if( map->arg_next_value(arg, i, argc, true) ) map->SCRIPT_CONF_NAME = argv[++i]; } else if( strcmp(arg, "msg-config") == 0 ) { - if( map->arg_next_value(arg, i, argc) ) + if( map->arg_next_value(arg, i, argc, true) ) map->MSG_CONF_NAME = argv[++i]; } else if( strcmp(arg, "grf-path-file") == 0 ) { - if( map->arg_next_value(arg, i, argc) ) + if( map->arg_next_value(arg, i, argc, true) ) map->GRF_PATH_FILENAME = argv[++i]; } else if( strcmp(arg, "inter-config") == 0 ) { - if( map->arg_next_value(arg, i, argc) ) + if( map->arg_next_value(arg, i, argc, true) ) map->INTER_CONF_NAME = argv[++i]; } else if( strcmp(arg, "log-config") == 0 ) { - if( map->arg_next_value(arg, i, argc) ) + if( map->arg_next_value(arg, i, argc, true) ) map->LOG_CONF_NAME = argv[++i]; } else if( strcmp(arg, "run-once") == 0 ) { // close the map-server as soon as its done.. for testing [Celest] runflag = CORE_ST_STOP; + } else if( strcmp(arg, "script-check") == 0 ) { + map->minimal = true; + runflag = CORE_ST_STOP; + if( map->arg_next_value(arg, i, argc, true) ) + scriptcheck = argv[++i]; } else { ShowError("Unknown option '%s'.\n", argv[i]); exit(EXIT_FAILURE); @@ -5422,41 +5648,43 @@ int do_init(int argc, char *argv[]) } } } + minimal = map->minimal;/* temp (perhaps make minimal a mask with options of what to load? e.g. plugin 1 does minimal |= mob_db; */ + if (!minimal) { + map->config_read(map->MAP_CONF_NAME); + CREATE(map->list,struct map_data,map->count); + map->count = 0; + map->config_read_sub(map->MAP_CONF_NAME); - map_load_defaults(); - map->config_read(map->MAP_CONF_NAME); - CREATE(map->list,struct map_data,map->count); - map->count = 0; - map->config_read_sub(map->MAP_CONF_NAME); - // loads npcs - map->reloadnpc(false); + // loads npcs + map->reloadnpc(false); - chrif->checkdefaultlogin(); + chrif->checkdefaultlogin(); - if (!map->ip_set || !map->char_ip_set) { - char ip_str[16]; - ip2str(addr_[0], ip_str); + if (!map->ip_set || !map->char_ip_set) { + char ip_str[16]; + ip2str(sockt->addr_[0], ip_str); - ShowWarning("Not all IP addresses in /conf/map-server.conf configured, autodetecting...\n"); + ShowWarning("Not all IP addresses in /conf/map-server.conf configured, autodetecting...\n"); - if (naddr_ == 0) - ShowError("Unable to determine your IP address...\n"); - else if (naddr_ > 1) - ShowNotice("Multiple interfaces detected...\n"); + if (sockt->naddr_ == 0) + ShowError("Unable to determine your IP address...\n"); + else if (sockt->naddr_ > 1) + ShowNotice("Multiple interfaces detected...\n"); - ShowInfo("Defaulting to %s as our IP address\n", ip_str); + ShowInfo("Defaulting to %s as our IP address\n", ip_str); - if (!map->ip_set) - clif->setip(ip_str); - if (!map->char_ip_set) - chrif->setip(ip_str); - } + if (!map->ip_set) + clif->setip(ip_str); + if (!map->char_ip_set) + chrif->setip(ip_str); + } - battle->config_read(map->BATTLE_CONF_FILENAME); - atcommand->msg_read(map->MSG_CONF_NAME); + battle->config_read(map->BATTLE_CONF_FILENAME); + atcommand->msg_read(map->MSG_CONF_NAME); + map->inter_config_read(map->INTER_CONF_NAME); + logs->config_read(map->LOG_CONF_NAME); + } script->config_read(map->SCRIPT_CONF_NAME); - map->inter_config_read(map->INTER_CONF_NAME); - logs->config_read(map->LOG_CONF_NAME); map->id_db = idb_alloc(DB_OPT_BASE); map->pc_db = idb_alloc(DB_OPT_BASE); //Added for reliable map->id2sd() use. [Skotlex] @@ -5469,57 +5697,88 @@ int do_init(int argc, char *argv[]) map->iwall_db = strdb_alloc(DB_OPT_RELEASE_DATA,2*NAME_LENGTH+2+1); // [Zephyrus] Invisible Walls map->zone_db = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, MAP_ZONE_NAME_LENGTH); - map->iterator_ers = ers_new(sizeof(struct s_mapiterator),"map.c::map_iterator_ers",ERS_OPT_NONE); + map->iterator_ers = ers_new(sizeof(struct s_mapiterator),"map.c::map_iterator_ers",ERS_OPT_CLEAN|ERS_OPT_FLEX_CHUNK); + ers_chunk_size(map->iterator_ers, 25); - map->sql_init(); - if (logs->config.sql_logs) - logs->sql_init(); + map->flooritem_ers = ers_new(sizeof(struct flooritem_data),"map.c::map_flooritem_ers",ERS_OPT_CLEAN|ERS_OPT_FLEX_CHUNK); + ers_chunk_size(map->flooritem_ers, 100); + + if (!minimal) { + map->sql_init(); + if (logs->config.sql_logs) + logs->sql_init(); + } + + i = mapindex->init(); + + if (minimal) { + // Pretend all maps from the mapindex are on this mapserver + CREATE(map->list,struct map_data,i); + + for( i = 0; i < MAX_MAPINDEX; i++ ) { + if (mapindex_exists(i)) { + map->addmap(mapindex_id2name(i)); + } + } + } - mapindex_init(); if(map->enable_grf) grfio_init(map->GRF_PATH_FILENAME); map->readallmaps(); - timer->add_func_list(map->freeblock_timer, "map_freeblock_timer"); - timer->add_func_list(map->clearflooritem_timer, "map_clearflooritem_timer"); - timer->add_func_list(map->removemobs_timer, "map_removemobs_timer"); - timer->add_interval(timer->gettick()+1000, map->freeblock_timer, 0, 0, 60*1000); - HPM->load_sub = HPM_map_plugin_load_sub; - HPM->symbol_defaults_sub = map_hp_symbols; - HPM->config_read(); - HPM->event(HPET_INIT); - - atcommand->init(); - battle->init(); - instance->init(); - chrif->init(); - clif->init(); - ircbot->init(); - script->init(); - itemdb->init(); - skill->init(); - map->read_zone_db();/* read after item and skill initalization */ - mob->init(); - pc->init(); - status->init(); - party->init(); - guild->init(); - gstorage->init(); - pet->init(); - homun->init(); - mercenary->init(); - elemental->init(); - quest->init(); - npc->init(); - unit->init(); - bg->init(); - duel->init(); - vending->init(); + if (!minimal) { + timer->add_func_list(map->freeblock_timer, "map_freeblock_timer"); + timer->add_func_list(map->clearflooritem_timer, "map_clearflooritem_timer"); + timer->add_func_list(map->removemobs_timer, "map_removemobs_timer"); + timer->add_interval(timer->gettick()+1000, map->freeblock_timer, 0, 0, 60*1000); + + HPM->event(HPET_INIT); + } + + atcommand->init(minimal); + battle->init(minimal); + instance->init(minimal); + chrif->init(minimal); + clif->init(minimal); + ircbot->init(minimal); + script->init(minimal); + itemdb->init(minimal); + skill->init(minimal); + if (!minimal) + map->read_zone_db();/* read after item and skill initalization */ + mob->init(minimal); + pc->init(minimal); + status->init(minimal); + party->init(minimal); + guild->init(minimal); + gstorage->init(minimal); + pet->init(minimal); + homun->init(minimal); + mercenary->init(minimal); + elemental->init(minimal); + quest->init(minimal); + npc->init(minimal); + unit->init(minimal); + bg->init(minimal); + duel->init(minimal); + vending->init(minimal); + + if (scriptcheck) { + if (npc->parsesrcfile(scriptcheck, false) == 0) + exit(EXIT_SUCCESS); + exit(EXIT_FAILURE); + } + if( minimal ) { + HPM->event(HPET_READY); + exit(EXIT_SUCCESS); + } + npc->event_do_oninit(); // Init npcs (OnInit) - + npc->market_fromsql(); /* after OnInit */ + if (battle_config.pk_mode) ShowNotice("Server is running on '"CL_WHITE"PK Mode"CL_RESET"'.\n"); @@ -5552,6 +5811,7 @@ void map_defaults(void) { map = &map_s; /* */ + map->minimal = false; map->count = 0; sprintf(map->db_path ,"db"); @@ -5599,6 +5859,8 @@ void map_defaults(void) { sprintf(map->server_db,"ragnarok"); map->mysql_handle = NULL; + map->cpsd_active = false; + map->port = 0; map->users = 0; map->ip_set = 0; @@ -5618,22 +5880,29 @@ void map_defaults(void) { map->zone_db = NULL; map->iwall_db = NULL; + map->block_free = NULL; + map->block_free_count = 0; + map->block_free_lock = 0; + map->block_free_list_size = 0; + map->bl_list = NULL; + map->bl_list_count = 0; + map->bl_list_size = 0; + //all in a big chunk, respects order - memset(map->block_free,0,sizeof(map->block_free) - + sizeof(map->block_free_count) - + sizeof(map->block_free_lock) - + sizeof(map->bl_list) - + sizeof(map->bl_list_count) - + sizeof(map->bl_head) + memset(&map->bl_head,0,sizeof(map->bl_head) + sizeof(map->zone_all) + sizeof(map->zone_pk) ); - + map->cpsd = NULL; map->list = NULL; map->iterator_ers = NULL; map->cache_buffer = NULL; + + map->flooritem_ers = NULL; + /* */ + map->bonus_id = SP_LAST_KNOWN; /* funcs */ map->zone_init = map_zone_init; map->zone_remove = map_zone_remove; @@ -5800,7 +6069,14 @@ void map_defaults(void) { map->addblcell = map_addblcell; map->delblcell = map_delblcell; - + + map->get_new_bonus_id = map_get_new_bonus_id; + + map->add_questinfo = map_add_questinfo; + map->remove_questinfo = map_remove_questinfo; + + map->merge_zone = map_merge_zone; + /** * mapit interface **/ @@ -5814,4 +6090,5 @@ void map_defaults(void) { mapit->next = mapit_next; mapit->prev = mapit_prev; mapit->exists = mapit_exists; + } diff --git a/src/map/map.h b/src/map/map.h index 3a7990dcb..270931689 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -2,8 +2,8 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _MAP_H_ -#define _MAP_H_ +#ifndef _MAP_MAP_H_ +#define _MAP_MAP_H_ #include "../common/cbasetypes.h" #include "../common/core.h" // CORE_ST_LAST @@ -26,7 +26,7 @@ enum E_MAPSERVER_ST { }; #define MAX_NPC_PER_MAP 512 -#define AREA_SIZE battle_config.area_size +#define AREA_SIZE (battle_config.area_size) #define DAMAGELOG_SIZE 30 #define LOOTITEM_SIZE 10 #define MAX_MOBSKILL 50 @@ -39,7 +39,7 @@ enum E_MAPSERVER_ST { #define MAX_LEVEL 150 #define MAX_IGNORE_LIST 20 // official is 14 #define MAX_VENDING 12 -#define MAX_MAP_SIZE 512*512 // Wasn't there something like this already? Can't find it.. [Shinryo] +#define MAX_MAP_SIZE (512*512) // Wasn't there something like this already? Can't find it.. [Shinryo] #define BLOCK_SIZE 8 #define block_free_max 1048576 @@ -221,7 +221,7 @@ enum { #define CHAT_SIZE_MAX (255 + 1) // 24 for npc name + 24 for label + 2 for a "::" and 1 for EOS #define EVENT_NAME_LENGTH ( NAME_LENGTH * 2 + 3 ) -#define DEFAULT_AUTOSAVE_INTERVAL 5*60*1000 +#define DEFAULT_AUTOSAVE_INTERVAL (5*60*1000) // Specifies maps where players may hit each other #define map_flag_vs(m) (map->list[m].flag.pvp || map->list[m].flag.gvg_dungeon || map->list[m].flag.gvg || ((map->agit_flag || map->agit2_flag) && map->list[m].flag.gvg_castle) || map->list[m].flag.battleground) // Specifies maps that have special GvG/WoE restrictions @@ -339,7 +339,7 @@ struct flooritem_data { unsigned char subx,suby; int cleartimer; int first_get_charid,second_get_charid,third_get_charid; - unsigned int first_get_tick,second_get_tick,third_get_tick; + int64 first_get_tick,second_get_tick,third_get_tick; struct item item_data; }; @@ -360,6 +360,9 @@ enum _sp { SP_KILLEDRID=122, SP_SLOTCHANGE=123, SP_CHARRENAME=124, + SP_MOD_EXP=125, + SP_MOD_DROP=126, + SP_MOD_DEATH=127, // Mercenaries SP_MERCFLEE=165, SP_MERCKILLS=189, SP_MERCFAITH=190, @@ -406,7 +409,11 @@ enum _sp { SP_ADD_SKILL_BLOW, SP_SP_VANISH_RATE, SP_MAGIC_SP_GAIN_VALUE, SP_MAGIC_HP_GAIN_VALUE, SP_ADD_CLASS_DROP_ITEM, //2041-2045 SP_EMATK, SP_SP_GAIN_RACE_ATTACK, SP_HP_GAIN_RACE_ATTACK, SP_SKILL_USE_SP_RATE, //2046-2049 SP_SKILL_COOLDOWN,SP_SKILL_FIXEDCAST, SP_SKILL_VARIABLECAST, SP_FIXCASTRATE, SP_VARCASTRATE, //2050-2054 - SP_SKILL_USE_SP,SP_MAGIC_ATK_ELE, SP_ADD_FIXEDCAST, SP_ADD_VARIABLECAST //2055-2058 + SP_SKILL_USE_SP,SP_MAGIC_ATK_ELE, SP_ADD_FIXEDCAST, SP_ADD_VARIABLECAST, //2055-2058 + + + /* must be the last, plugins add bonuses from this value onwards */ + SP_LAST_KNOWN, }; enum _look { @@ -436,7 +443,6 @@ typedef enum { CELL_LANDPROTECTOR, CELL_NOVENDING, CELL_NOCHAT, - CELL_MAELSTROM, CELL_ICEWALL, } cell_t; @@ -460,7 +466,6 @@ typedef enum { CELL_CHKLANDPROTECTOR, CELL_CHKNOVENDING, CELL_CHKNOCHAT, - CELL_CHKMAELSTROM, CELL_CHKICEWALL, } cell_chk; @@ -479,7 +484,6 @@ struct mapcell { landprotector : 1, novending : 1, nochat : 1, - maelstrom : 1, icewall : 1; #ifdef CELL_NOSTACK @@ -524,7 +528,7 @@ struct map_zone_skill_damage_cap_entry { enum map_zone_skill_subtype subtype; }; -#define MAP_ZONE_NAME_LENGTH 30 +#define MAP_ZONE_NAME_LENGTH 60 #define MAP_ZONE_ALL_NAME "All" #define MAP_ZONE_NORMAL_NAME "Normal" #define MAP_ZONE_PVP_NAME "PvP" @@ -545,6 +549,9 @@ struct map_zone_data { int disabled_commands_count; struct map_zone_skill_damage_cap_entry **capped_skills; int capped_skills_count; + struct { + unsigned int special : 2;/* 1: whether this is a mergeable zone; 2: whether it is a merged zone */ + } info; }; struct map_drop_list { @@ -553,6 +560,17 @@ struct map_drop_list { int drop_per; }; + +struct questinfo { + struct npc_data *nd; + unsigned short icon; + unsigned char color; + int quest_id; + bool hasJob; + unsigned short job;/* perhaps a mapid mask would be most flexible? */ +}; + + struct map_data { char name[MAP_NAME_LENGTH]; uint16 index; // The map index used by the mapindex* functions. @@ -628,6 +646,7 @@ struct map_data { unsigned chsysnolocalaj : 1; unsigned noknockback : 1; unsigned notomb : 1; + unsigned nocashshop : 1; } flag; struct point save; struct npc_data *npc[MAX_NPC_PER_MAP]; @@ -686,6 +705,17 @@ struct map_data { int (*getcellp)(struct map_data* m,int16 x,int16 y,cell_chk cellchk); void (*setcell) (int16 m, int16 x, int16 y, cell_t cell, bool flag); char *cellPos; + + /* ShowEvent Data Cache */ + struct questinfo *qi_data; + unsigned short qi_count; + + /* speeds up clif_updatestatus processing by causing hpmeter to run only when someone with the permission can view it */ + unsigned short hpmeter_visible; + + /* HPM Custom Struct */ + struct HPluginData **hdata; + unsigned int hdatac; }; /// Stores information about a remote map (for multi-mapserver setups). @@ -698,7 +728,7 @@ struct map_data_other_server { uint16 port; }; -#define map_id2index(id) map->list[(id)].index +#define map_id2index(id) (map->list[(id)].index) /// Bitfield of flags for the iterator. enum e_mapitflags { @@ -721,11 +751,11 @@ struct mapit_interface { struct mapit_interface *mapit; -#define mapit_getallusers() mapit->alloc(MAPIT_NORMAL,BL_PC) -#define mapit_geteachpc() mapit->alloc(MAPIT_NORMAL,BL_PC) -#define mapit_geteachmob() mapit->alloc(MAPIT_NORMAL,BL_MOB) -#define mapit_geteachnpc() mapit->alloc(MAPIT_NORMAL,BL_NPC) -#define mapit_geteachiddb() mapit->alloc(MAPIT_NORMAL,BL_ALL) +#define mapit_getallusers() (mapit->alloc(MAPIT_NORMAL,BL_PC)) +#define mapit_geteachpc() (mapit->alloc(MAPIT_NORMAL,BL_PC)) +#define mapit_geteachmob() (mapit->alloc(MAPIT_NORMAL,BL_MOB)) +#define mapit_geteachnpc() (mapit->alloc(MAPIT_NORMAL,BL_NPC)) +#define mapit_geteachiddb() (mapit->alloc(MAPIT_NORMAL,BL_ALL)) //Useful typedefs from jA [Skotlex] typedef struct map_session_data TBL_PC; @@ -774,6 +804,7 @@ struct map_cache_map_info { struct map_interface { /* vars */ + bool minimal; int count; int autosave_interval; @@ -812,6 +843,8 @@ struct map_interface { char mob_skill_db_db[32]; char mob_skill_db2_db[32]; char interreg_db[32]; + char autotrade_merchants_db[32]; + char autotrade_data_db[32]; char default_codepage[32]; @@ -825,8 +858,8 @@ struct map_interface { int port; int users; int enable_grf; //To enable/disable reading maps from GRF files, bypassing mapcache [blackhole89] - int ip_set; - int char_ip_set; + bool ip_set; + bool char_ip_set; int16 index2mapid[MAX_MAPINDEX]; /* */ @@ -842,18 +875,25 @@ struct map_interface { DBMap* iwall_db; /* order respected by map_defaults() in order to zero */ /* from block_free until zone_pk */ - struct block_list *block_free[block_free_max]; - int block_free_count, block_free_lock; - struct block_list *bl_list[BL_LIST_MAX]; - int bl_list_count; + struct block_list **block_free; + int block_free_count, block_free_lock, block_free_list_size; + struct block_list **bl_list; + int bl_list_count, bl_list_size; struct block_list bl_head; struct map_zone_data zone_all;/* used as a base on all maps */ struct map_zone_data zone_pk;/* used for (pk_mode) */ + /* */ struct map_session_data *cpsd; struct map_data *list; /* [Ind/Hercules] */ struct eri *iterator_ers; char *cache_buffer; // Has the uncompressed gat data of all maps, so just one allocation has to be made + /* */ + struct eri *flooritem_ers; + /* */ + int bonus_id; + /* */ + bool cpsd_active; /* funcs */ void (*zone_init) (void); void (*zone_remove) (int m); @@ -876,7 +916,7 @@ struct map_interface { // blocklist manipulation int (*addblock) (struct block_list* bl); int (*delblock) (struct block_list* bl); - int (*moveblock) (struct block_list *bl, int x1, int y1, unsigned int tick); + int (*moveblock) (struct block_list *bl, int x1, int y1, int64 tick); //blocklist nb in one cell int (*count_oncell) (int16 m,int16 x,int16 y,int type); struct skill_unit * (*find_skill_unit_oncell) (struct block_list* target,int16 x,int16 y,uint16 skill_id,struct skill_unit* out_unit, int flag); @@ -888,8 +928,8 @@ struct map_interface { // npc bool (*addnpc) (int16 m,struct npc_data *nd); // map item - int (*clearflooritem_timer) (int tid, unsigned int tick, int id, intptr_t data); - int (*removemobs_timer) (int tid, unsigned int tick, int id, intptr_t data); + int (*clearflooritem_timer) (int tid, int64 tick, int id, intptr_t data); + int (*removemobs_timer) (int tid, int64 tick, int id, intptr_t data); void (*clearflooritem) (struct block_list* bl); int (*addflooritem) (struct item *item_data,int amount,int16 m,int16 x,int16 y,int first_charid,int second_charid,int third_charid,int flags); // player to map session @@ -939,11 +979,11 @@ struct map_interface { struct chat_data* (*id2cd) (int id); struct block_list * (*id2bl) (int id); bool (*blid_exists) (int id); - int16 (*mapindex2mapid) (unsigned short mapindex); + int16 (*mapindex2mapid) (unsigned short map_index); int16 (*mapname2mapid) (const char* name); int (*mapname2ipport) (unsigned short name, uint32* ip, uint16* port); - int (*setipport) (unsigned short mapindex, uint32 ip, uint16 port); - int (*eraseipport) (unsigned short mapindex, uint32 ip, uint16 port); + int (*setipport) (unsigned short map_index, uint32 ip, uint16 port); + int (*eraseipport) (unsigned short map_index, uint32 ip, uint16 port); int (*eraseallipport) (void); void (*addiddb) (struct block_list *bl); void (*deliddb) (struct block_list *bl); @@ -977,7 +1017,7 @@ struct map_interface { void (*do_shutdown) (void); - int (*freeblock_timer) (int tid, unsigned int tick, int id, intptr_t data); + int (*freeblock_timer) (int tid, int64 tick, int id, intptr_t data); int (*searchrandfreecell) (int16 m, int16 *x, int16 *y, int stack); int (*count_sub) (struct block_list *bl, va_list ap); DBData (*create_charid2nick) (DBKey key, va_list args); @@ -993,7 +1033,7 @@ struct map_interface { int (*eraseallipport_sub) (DBKey key, DBData *data, va_list va); char* (*init_mapcache) (FILE *fp); int (*readfromcache) (struct map_data *m, char *buffer); - int (*addmap) (char *mapname); + int (*addmap) (const char *mapname); void (*delmapid) (int id); void (*zone_db_clear) (void); void (*list_final) (void); @@ -1017,13 +1057,17 @@ struct map_interface { int (*abort_sub) (struct map_session_data *sd, va_list ap); void (*helpscreen) (bool do_exit); void (*versionscreen) (bool do_exit); - bool (*arg_next_value) (const char *option, int i, int argc); + bool (*arg_next_value) (const char *option, int i, int argc, bool must); void (*addblcell) (struct block_list *bl); void (*delblcell) (struct block_list *bl); + int (*get_new_bonus_id) (void); + void (*add_questinfo) (int m, struct questinfo *qi); + bool (*remove_questinfo) (int m, struct npc_data *nd); + struct map_zone_data *(*merge_zone) (struct map_zone_data *main, struct map_zone_data *other); }; struct map_interface *map; void map_defaults(void); -#endif /* _MAP_H_ */ +#endif /* _MAP_MAP_H_ */ diff --git a/src/map/mapreg.h b/src/map/mapreg.h index 3c1d0ba0e..c92b6f602 100644 --- a/src/map/mapreg.h +++ b/src/map/mapreg.h @@ -2,14 +2,14 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _MAPREG_H_ -#define _MAPREG_H_ +#ifndef _MAP_MAPREG_H_ +#define _MAP_MAPREG_H_ #include "../common/cbasetypes.h" #include "../common/db.h" struct mapreg_save { - int uid; + int64 uid; union { int i; char *str; @@ -19,22 +19,30 @@ struct mapreg_save { struct mapreg_interface { DBMap *db; // int var_id -> int value + /* TODO duck str_db, use same */ DBMap *str_db; // int var_id -> char* value + /* */ + DBMap *array_db; + /* */ + bool skip_insert; + /* */ struct eri *ers; //[Ind/Hercules] + /* */ char table[32]; + /* */ bool i_dirty; bool str_dirty; /* */ void (*init) (void); void (*final) (void); /* */ - int (*readreg) (int uid); - char* (*readregstr) (int uid); - bool (*setreg) (int uid, int val); - bool (*setregstr) (int uid, const char *str); + int (*readreg) (int64 uid); + char* (*readregstr) (int64 uid); + bool (*setreg) (int64 uid, int val); + bool (*setregstr) (int64 uid, const char *str); void (*load) (void); void (*save) (void); - int (*save_timer) (int tid, unsigned int tick, int id, intptr_t data); + int (*save_timer) (int tid, int64 tick, int id, intptr_t data); void (*reload) (void); bool (*config_read) (const char *w1, const char *w2); }; @@ -43,4 +51,4 @@ struct mapreg_interface *mapreg; void mapreg_defaults(void); -#endif /* _MAPREG_H_ */ +#endif /* _MAP_MAPREG_H_ */ diff --git a/src/map/mapreg_sql.c b/src/map/mapreg_sql.c index 902b7c39b..3cf92454d 100644 --- a/src/map/mapreg_sql.c +++ b/src/map/mapreg_sql.c @@ -21,51 +21,56 @@ struct mapreg_interface mapreg_s; #define MAPREG_AUTOSAVE_INTERVAL (300*1000) /// Looks up the value of an integer variable using its uid. -int mapreg_readreg(int uid) { - struct mapreg_save *m = idb_get(mapreg->db, uid); +int mapreg_readreg(int64 uid) { + struct mapreg_save *m = i64db_get(mapreg->db, uid); return m?m->u.i:0; } /// Looks up the value of a string variable using its uid. -char* mapreg_readregstr(int uid) { - struct mapreg_save *m = idb_get(mapreg->str_db, uid); +char* mapreg_readregstr(int64 uid) { + struct mapreg_save *m = i64db_get(mapreg->str_db, uid); return m?m->u.str:NULL; } /// Modifies the value of an integer variable. -bool mapreg_setreg(int uid, int val) { +bool mapreg_setreg(int64 uid, int val) { struct mapreg_save *m; - int num = (uid & 0x00ffffff); - int i = (uid & 0xff000000) >> 24; + int num = script_getvarid(uid); + unsigned int i = script_getvaridx(uid); const char* name = script->get_str(num); if( val != 0 ) { - if( (m = idb_get(mapreg->db,uid)) ) { + if( (m = i64db_get(mapreg->db,uid)) ) { m->u.i = val; if(name[1] != '@') { m->save = true; mapreg->i_dirty = true; } } else { + if( i ) + script->array_update(&mapreg->array_db,uid,false); + m = ers_alloc(mapreg->ers, struct mapreg_save); m->u.i = val; m->uid = uid; m->save = false; - if(name[1] != '@') {// write new variable to database + if(name[1] != '@' && !mapreg->skip_insert) {// write new variable to database char tmp_str[32*2+1]; SQL->EscapeStringLen(map->mysql_handle, tmp_str, name, strnlen(name, 32)); if( SQL_ERROR == SQL->Query(map->mysql_handle, "INSERT INTO `%s`(`varname`,`index`,`value`) VALUES ('%s','%d','%d')", mapreg->table, tmp_str, i, val) ) Sql_ShowDebug(map->mysql_handle); } - idb_put(mapreg->db, uid, m); + i64db_put(mapreg->db, uid, m); } } else { // val == 0 - if( (m = idb_get(mapreg->db,uid)) ) { + if( i ) + script->array_update(&mapreg->array_db,uid,true); + if( (m = i64db_get(mapreg->db,uid)) ) { ers_free(mapreg->ers, m); } - idb_remove(mapreg->db,uid); + i64db_remove(mapreg->db,uid); if( name[1] != '@' ) {// Remove from database because it is unused. if( SQL_ERROR == SQL->Query(map->mysql_handle, "DELETE FROM `%s` WHERE `varname`='%s' AND `index`='%d'", mapreg->table, name, i) ) @@ -77,25 +82,27 @@ bool mapreg_setreg(int uid, int val) { } /// Modifies the value of a string variable. -bool mapreg_setregstr(int uid, const char* str) { +bool mapreg_setregstr(int64 uid, const char* str) { struct mapreg_save *m; - int num = (uid & 0x00ffffff); - int i = (uid & 0xff000000) >> 24; + int num = script_getvarid(uid); + unsigned int i = script_getvaridx(uid); const char* name = script->get_str(num); if( str == NULL || *str == 0 ) { + if( i ) + script->array_update(&mapreg->array_db,uid,true); if(name[1] != '@') { if( SQL_ERROR == SQL->Query(map->mysql_handle, "DELETE FROM `%s` WHERE `varname`='%s' AND `index`='%d'", mapreg->table, name, i) ) Sql_ShowDebug(map->mysql_handle); } - if( (m = idb_get(mapreg->str_db,uid)) ) { + if( (m = i64db_get(mapreg->str_db,uid)) ) { if( m->u.str != NULL ) aFree(m->u.str); ers_free(mapreg->ers, m); } - idb_remove(mapreg->str_db,uid); + i64db_remove(mapreg->str_db,uid); } else { - if( (m = idb_get(mapreg->str_db,uid)) ) { + if( (m = i64db_get(mapreg->str_db,uid)) ) { if( m->u.str != NULL ) aFree(m->u.str); m->u.str = aStrdup(str); @@ -104,13 +111,16 @@ bool mapreg_setregstr(int uid, const char* str) { m->save = true; } } else { + if( i ) + script->array_update(&mapreg->array_db,uid,false); + m = ers_alloc(mapreg->ers, struct mapreg_save); m->uid = uid; m->u.str = aStrdup(str); m->save = false; - if(name[1] != '@') { //put returned null, so we must insert. + if(name[1] != '@' && !mapreg->skip_insert) { //put returned null, so we must insert. char tmp_str[32*2+1]; char tmp_str2[255*2+1]; SQL->EscapeStringLen(map->mysql_handle, tmp_str, name, strnlen(name, 32)); @@ -118,7 +128,7 @@ bool mapreg_setregstr(int uid, const char* str) { if( SQL_ERROR == SQL->Query(map->mysql_handle, "INSERT INTO `%s`(`varname`,`index`,`value`) VALUES ('%s','%d','%s')", mapreg->table, tmp_str, i, tmp_str2) ) Sql_ShowDebug(map->mysql_handle); } - idb_put(mapreg->str_db, uid, m); + i64db_put(mapreg->str_db, uid, m); } } @@ -147,41 +157,36 @@ void script_load_mapreg(void) { return; } + mapreg->skip_insert = true; + SQL->StmtBindColumn(stmt, 0, SQLDT_STRING, &varname[0], sizeof(varname), &length, NULL); SQL->StmtBindColumn(stmt, 1, SQLDT_INT, &index, 0, NULL, NULL); SQL->StmtBindColumn(stmt, 2, SQLDT_STRING, &value[0], sizeof(value), NULL, NULL); - + while ( SQL_SUCCESS == SQL->StmtNextRow(stmt) ) { - struct mapreg_save *m = NULL; int s = script->add_str(varname); int i = index; + if( varname[length-1] == '$' ) { - if( idb_exists(mapreg->str_db, (i<<24)|s) ) { + if( i64db_exists(mapreg->str_db, reference_uid(s, i)) ) { ShowWarning("load_mapreg: duplicate! '%s' => '%s' skipping...\n",varname,value); continue; } + mapreg->setregstr(reference_uid(s, i),value); } else { - if( idb_exists(mapreg->db, (i<<24)|s) ) { + if( i64db_exists(mapreg->db, reference_uid(s, i)) ) { ShowWarning("load_mapreg: duplicate! '%s' => '%s' skipping...\n",varname,value); continue; } - } - - m = ers_alloc(mapreg->ers, struct mapreg_save); - m->uid = (i<<24)|s; - m->save = false; - if( varname[length-1] == '$' ) { - m->u.str = aStrdup(value); - idb_put(mapreg->str_db, m->uid, m); - } else { - m->u.i = atoi(value); - idb_put(mapreg->db, m->uid, m); + mapreg->setreg(reference_uid(s, i),atoi(value)); } } SQL->StmtFree(stmt); + mapreg->skip_insert = false; + mapreg->i_dirty = false; mapreg->str_dirty = false; } @@ -195,8 +200,8 @@ void script_save_mapreg(void) { iter = db_iterator(mapreg->db); for( m = dbi_first(iter); dbi_exists(iter); m = dbi_next(iter) ) { if( m->save ) { - int num = (m->uid & 0x00ffffff); - int i = (m->uid & 0xff000000) >> 24; + int num = script_getvarid(m->uid); + int i = script_getvaridx(m->uid); const char* name = script->get_str(num); if( SQL_ERROR == SQL->Query(map->mysql_handle, "UPDATE `%s` SET `value`='%d' WHERE `varname`='%s' AND `index`='%d' LIMIT 1", mapreg->table, m->u.i, name, i) ) @@ -212,8 +217,8 @@ void script_save_mapreg(void) { iter = db_iterator(mapreg->str_db); for( m = dbi_first(iter); dbi_exists(iter); m = dbi_next(iter) ) { if( m->save ) { - int num = (m->uid & 0x00ffffff); - int i = (m->uid & 0xff000000) >> 24; + int num = script_getvarid(m->uid); + int i = script_getvaridx(m->uid); const char* name = script->get_str(num); char tmp_str2[2*255+1]; @@ -228,7 +233,7 @@ void script_save_mapreg(void) { } } -int script_autosave_mapreg(int tid, unsigned int tick, int id, intptr_t data) { +int script_autosave_mapreg(int tid, int64 tick, int id, intptr_t data) { mapreg->save(); return 0; } @@ -257,7 +262,13 @@ void mapreg_reload(void) { db_clear(mapreg->db); db_clear(mapreg->str_db); - + + if( mapreg->array_db ) { + mapreg->array_db->destroy(mapreg->array_db,script->array_free_db); + mapreg->array_db = NULL; + } + + mapreg->load(); } @@ -286,12 +297,15 @@ void mapreg_final(void) { db_destroy(mapreg->str_db); ers_destroy(mapreg->ers); + + if( mapreg->array_db ) + mapreg->array_db->destroy(mapreg->array_db,script->array_free_db); } void mapreg_init(void) { - mapreg->db = idb_alloc(DB_OPT_BASE); - mapreg->str_db = idb_alloc(DB_OPT_BASE); - mapreg->ers = ers_new(sizeof(struct mapreg_save), "mapreg_sql.c::mapreg_ers", ERS_OPT_NONE); + mapreg->db = i64db_alloc(DB_OPT_BASE); + mapreg->str_db = i64db_alloc(DB_OPT_BASE); + mapreg->ers = ers_new(sizeof(struct mapreg_save), "mapreg_sql.c::mapreg_ers", ERS_OPT_CLEAN); mapreg->load(); @@ -314,12 +328,16 @@ void mapreg_defaults(void) { mapreg->db = NULL; mapreg->str_db = NULL; mapreg->ers = NULL; + mapreg->skip_insert = false; safestrncpy(mapreg->table, "mapreg", sizeof(mapreg->table)); mapreg->i_dirty = false; mapreg->str_dirty = false; /* */ + mapreg->array_db = NULL; + + /* */ mapreg->init = mapreg_init; mapreg->final = mapreg_final; diff --git a/src/map/mercenary.c b/src/map/mercenary.c index 8b8353f46..495621014 100644 --- a/src/map/mercenary.c +++ b/src/map/mercenary.c @@ -94,7 +94,7 @@ int mercenary_get_lifetime(struct mercenary_data *md) return 0; td = timer->get(md->contract_timer); - return (td != NULL) ? DIFF_TICK(td->tick, timer->gettick()) : 0; + return (td != NULL) ? DIFF_TICK32(td->tick, timer->gettick()) : 0; } int mercenary_get_guild(struct mercenary_data *md) @@ -217,7 +217,7 @@ int mercenary_save(struct mercenary_data *md) return 1; } -int merc_contract_end_timer(int tid, unsigned int tick, int id, intptr_t data) { +int merc_contract_end_timer(int tid, int64 tick, int id, intptr_t data) { struct map_session_data *sd; struct mercenary_data *md; @@ -317,7 +317,7 @@ int merc_data_received(struct s_mercenary *merc, bool flag) { md->bl.y = md->ud.to_y; map->addiddb(&md->bl); - status_calc_mercenary(md,1); + status_calc_mercenary(md,SCO_FIRST); md->contract_timer = INVALID_TIMER; merc_contract_init(md); } @@ -360,7 +360,7 @@ int mercenary_killbonus(struct mercenary_data *md) const enum sc_type scs[] = { SC_MER_FLEE, SC_MER_ATK, SC_MER_HP, SC_MER_SP, SC_MER_HIT }; int index = rnd() % ARRAYLENGTH(scs); - sc_start(&md->bl, scs[index], 100, rnd() % 5, 600000); + sc_start(NULL,&md->bl, scs[index], 100, rnd() % 5, 600000); return 0; } @@ -490,7 +490,10 @@ int read_mercenary_skilldb(void) { return 0; } -void do_init_mercenary(void) { +void do_init_mercenary(bool minimal) { + if (minimal) + return; + mercenary->read_db(); mercenary->read_skilldb(); diff --git a/src/map/mercenary.h b/src/map/mercenary.h index 47f37ac66..dd9266b2e 100644 --- a/src/map/mercenary.h +++ b/src/map/mercenary.h @@ -1,8 +1,8 @@ // Copyright (c) Hercules Dev Team, licensed under GNU GPL. // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _MERCENARY_H_ -#define _MERCENARY_H_ +#ifndef _MAP_MERCENARY_H_ +#define _MAP_MERCENARY_H_ #include "status.h" // struct status_data, struct status_change #include "unit.h" // struct unit_data @@ -43,7 +43,7 @@ struct mercenary_data { int contract_timer; unsigned devotion_flag : 1; - unsigned int masterteleport_timer; + int64 masterteleport_timer; }; /*===================================== @@ -59,7 +59,7 @@ struct mercenary_interface { /* funcs */ - void (*init) (void); + void (*init) (bool minimal); bool (*class) (int class_); struct view_data * (*get_viewdata) (int class_); @@ -89,7 +89,7 @@ struct mercenary_interface { int (*killbonus) (struct mercenary_data *md); int (*search_index) (int class_); - int (*contract_end_timer) (int tid, unsigned int tick, int id, intptr_t data); + int (*contract_end_timer) (int tid, int64 tick, int id, intptr_t data); bool (*read_db_sub) (char* str[], int columns, int current); bool (*read_skill_db_sub) (char* str[], int columns, int current); }; @@ -98,4 +98,4 @@ struct mercenary_interface *mercenary; void mercenary_defaults(void); -#endif /* _MERCENARY_H_ */ +#endif /* _MAP_MERCENARY_H_ */ diff --git a/src/map/mob.c b/src/map/mob.c index 7023bcb9d..ff63048d1 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -52,7 +52,7 @@ struct mob_interface mob_s; #define MOB_LAZYSKILLPERC 0 // Probability for mobs far from players from doing their IDLE skill. (rate of 1000 minute) // Move probability for mobs away from players (rate of 1000 minute) // in Aegis, this is 100% for mobs that have been activated by players and none otherwise. -#define MOB_LAZYMOVEPERC(md) (md->state.spotted?1000:0) +#define MOB_LAZYMOVEPERC(md) ((md)->state.spotted?1000:0) #define MOB_MAX_DELAY (24*3600*1000) #define MAX_MINCHASE 30 //Max minimum chase value to use for mobs. #define RUDE_ATTACKED_COUNT 2 //After how many rude-attacks should the skill be used? @@ -95,7 +95,11 @@ int mobdb_searchname(const char *str) monster = mob->db(i); if(monster == mob->dummy) //Skip dummy mobs. continue; - if(strcmpi(monster->name,str)==0 || strcmpi(monster->jname,str)==0 || strcmpi(monster->sprite,str)==0) + if(strcmpi(monster->name,str)==0 || strcmpi(monster->jname,str)==0) + return i; + if(battle_config.case_sensitive_aegisnames && strcmp(monster->sprite,str)==0) + return i; + if(!battle_config.case_sensitive_aegisnames && strcasecmp(monster->sprite,str)==0) return i; } @@ -106,18 +110,20 @@ int mobdb_searchname_array_sub(struct mob_db* monster, const char *str, int flag return 1; if(!monster->base_exp && !monster->job_exp && monster->spawn[0].qty < 1) return 1; // Monsters with no base/job exp and no spawn point are, by this criteria, considered "slave mobs" and excluded from search results - if( !flag ){ + if( !flag ) { if(stristr(monster->jname,str)) return 0; if(stristr(monster->name,str)) return 0; - return strcmpi(monster->jname,str); + } else { + if(strcmpi(monster->jname,str) == 0) + return 0; + if(strcmpi(monster->name,str) == 0) + return 0; } - if(strcmp(monster->jname,str) == 0) - return 0; - if(strcmp(monster->name,str) == 0) - return 0; - return strcmp(monster->sprite,str); + if (battle_config.case_sensitive_aegisnames) + return strcmp(monster->sprite,str); + return strcasecmp(monster->sprite,str); } /*========================================== @@ -332,8 +338,7 @@ int mob_get_random_id(int type, int flag, int lv) /*========================================== * Kill Steal Protection [Zephyrus] *------------------------------------------*/ -bool mob_ksprotected (struct block_list *src, struct block_list *target) -{ +bool mob_ksprotected(struct block_list *src, struct block_list *target) { struct block_list *s_bl, *t_bl; struct map_session_data *sd, // Source @@ -341,7 +346,7 @@ bool mob_ksprotected (struct block_list *src, struct block_list *target) *t_sd; // Mob Target struct status_change_entry *sce; struct mob_data *md; - unsigned int tick = timer->gettick(); + int64 tick = timer->gettick(); char output[128]; if( !battle_config.ksprotection ) @@ -393,7 +398,7 @@ bool mob_ksprotected (struct block_list *src, struct block_list *target) if( DIFF_TICK(sd->ks_floodprotect_tick, tick) <= 0 ) { sprintf(output, "[KS Warning!! - Owner : %s]", pl_sd->status.name); - clif->disp_onlyself(sd, output, strlen(output)); + clif_disp_onlyself(sd, output, strlen(output)); sd->ks_floodprotect_tick = tick + 2000; } @@ -402,7 +407,7 @@ bool mob_ksprotected (struct block_list *src, struct block_list *target) if( DIFF_TICK(pl_sd->ks_floodprotect_tick, tick) <= 0 ) { sprintf(output, "[Watch out! %s is trying to KS you!]", sd->status.name); - clif->disp_onlyself(pl_sd, output, strlen(output)); + clif_disp_onlyself(pl_sd, output, strlen(output)); pl_sd->ks_floodprotect_tick = tick + 2000; } @@ -410,7 +415,7 @@ bool mob_ksprotected (struct block_list *src, struct block_list *target) return true; } while(0); - status->change_start(target, SC_KSPROTECTED, 10000, sd->bl.id, sd->state.noks, sd->status.party_id, sd->status.guild_id, battle_config.ksprotection, 0); + status->change_start(NULL, target, SC_KSPROTECTED, 10000, sd->bl.id, sd->state.noks, sd->status.party_id, sd->status.guild_id, battle_config.ksprotection, 0); return false; } @@ -442,7 +447,7 @@ struct mob_data *mob_once_spawn_sub(struct block_list *bl, int16 m, int16 x, int map->search_freecell(bl, m, &x, &y, 1, 1, 0); // if none found, pick random position on map - if (x <= 0 || y <= 0 || map->getcell(m,x,y,CELL_CHKNOREACH)) + if (x <= 0 || x >= map->list[m].xs || y <= 0 || y >= map->list[m].ys) map->search_freecell(NULL, m, &x, &y, -1, -1, 1); data.x = x; @@ -460,6 +465,12 @@ struct mob_data *mob_once_spawn_sub(struct block_list *bl, int16 m, int16 x, int int mob_once_spawn(struct map_session_data* sd, int16 m, int16 x, int16 y, const char* mobname, int class_, int amount, const char* event, unsigned int size, unsigned int ai) { struct mob_data* md = NULL; int count, lv; + bool no_guardian_data = false; + + if( ai && ai&0x200 ) { + no_guardian_data = true; + ai &=~ 0x200; + } if (m < 0 || amount <= 0) return 0; // invalid input @@ -473,7 +484,7 @@ int mob_once_spawn(struct map_session_data* sd, int16 m, int16 x, int16 y, const if (!md) continue; - if (class_ == MOBID_EMPERIUM) { + if (class_ == MOBID_EMPERIUM && !no_guardian_data) { struct guild_castle* gc = guild->mapindex2gc(map_id2index(m)); struct guild* g = (gc) ? guild->search(gc->guild_id) : NULL; if (gc) { @@ -495,7 +506,7 @@ int mob_once_spawn(struct map_session_data* sd, int16 m, int16 x, int16 y, const if (class_ < 0 && battle_config.dead_branch_active) { //Behold Aegis's masterful decisions yet again... //"I understand the "Aggressive" part, but the "Can Move" and "Can Attack" is just stupid" - Poki#3 - sc_start4(&md->bl, SC_MODECHANGE, 100, 1, 0, MD_AGGRESSIVE|MD_CANATTACK|MD_CANMOVE|MD_ANGRY, 0, 60000); + sc_start4(NULL, &md->bl, SC_MODECHANGE, 100, 1, 0, MD_AGGRESSIVE|MD_CANATTACK|MD_CANMOVE|MD_ANGRY, 0, 60000); } } @@ -559,8 +570,8 @@ int mob_once_spawn_area(struct map_session_data* sd, int16 m, int16 x0, int16 y0 /*========================================== * Set a Guardian's guild data [Skotlex] *------------------------------------------*/ -int mob_spawn_guardian_sub(int tid, unsigned int tick, int id, intptr_t data) -{ //Needed because the guild_data may not be available at guardian spawn time. +int mob_spawn_guardian_sub(int tid, int64 tick, int id, intptr_t data) { + //Needed because the guild_data may not be available at guardian spawn time. struct block_list* bl = map->id2bl(id); struct mob_data* md; struct guild* g; @@ -582,7 +593,7 @@ int mob_spawn_guardian_sub(int tid, unsigned int tick, int id, intptr_t data) if (g == NULL) { //Liberate castle, if the guild is not found this is an error! [Skotlex] ShowError("mob_spawn_guardian_sub: Couldn't load guild %d!\n", (int)data); - if (md->class_ == MOBID_EMPERIUM) + if (md->class_ == MOBID_EMPERIUM && md->guardian_data) { //Not sure this is the best way, but otherwise we'd be invoking this for ALL guardians spawned later on. md->guardian_data->guild_id = 0; if (md->guardian_data->castle->guild_id) //Free castle up. @@ -591,7 +602,7 @@ int mob_spawn_guardian_sub(int tid, unsigned int tick, int id, intptr_t data) guild->castledatasave(md->guardian_data->castle->castle_id, 1, 0); } } else { - if (md->guardian_data->number >= 0 && md->guardian_data->number < MAX_GUARDIANS && md->guardian_data->castle->guardian[md->guardian_data->number].visible) + if (md->guardian_data && md->guardian_data->number >= 0 && md->guardian_data->number < MAX_GUARDIANS && md->guardian_data->castle->guardian[md->guardian_data->number].visible) guild->castledatasave(md->guardian_data->castle->castle_id, 10+md->guardian_data->number,0); unit->free(&md->bl,CLR_OUTSIGHT); //Remove guardian. } @@ -602,7 +613,7 @@ int mob_spawn_guardian_sub(int tid, unsigned int tick, int id, intptr_t data) memcpy(md->guardian_data->guild_name, g->name, NAME_LENGTH); md->guardian_data->guardup_lv = guardup_lv; if( guardup_lv ) - status_calc_mob(md, 0); //Give bonuses. + status_calc_mob(md, SCO_NONE); //Give bonuses. return 0; } @@ -779,18 +790,17 @@ int mob_can_reach(struct mob_data *md,struct block_list *bl,int range, int state /*========================================== * Links nearby mobs (supportive mobs) *------------------------------------------*/ -int mob_linksearch(struct block_list *bl,va_list ap) -{ +int mob_linksearch(struct block_list *bl,va_list ap) { struct mob_data *md; int class_; struct block_list *target; - unsigned int tick; + int64 tick; nullpo_ret(bl); md=(struct mob_data *)bl; class_ = va_arg(ap, int); target = va_arg(ap, struct block_list *); - tick=va_arg(ap, unsigned int); + tick = va_arg(ap, int64); if (md->class_ == class_ && DIFF_TICK(md->last_linktime, tick) < MIN_MOBLINKTIME && !md->target_id) @@ -809,7 +819,7 @@ int mob_linksearch(struct block_list *bl,va_list ap) /*========================================== * mob spawn with delay (timer function) *------------------------------------------*/ -int mob_delayspawn(int tid, unsigned int tick, int id, intptr_t data) { +int mob_delayspawn(int tid, int64 tick, int id, intptr_t data) { struct block_list* bl = map->id2bl(id); struct mob_data* md = BL_CAST(BL_MOB, bl); @@ -868,14 +878,15 @@ int mob_setdelayspawn(struct mob_data *md) } int mob_count_sub(struct block_list *bl, va_list ap) { - int mobid[10], i; - ARR_FIND(0, 10, i, (mobid[i] = va_arg(ap, int)) == 0); //fetch till 0 - if (mobid[0]) { //if there one let's check it otherwise go backward - TBL_MOB *md = BL_CAST(BL_MOB, bl); - ARR_FIND(0, 10, i, md->class_ == mobid[i]); - return (i < 10) ? 1 : 0; - } - return 1; //backward compatibility + int mobid[10] = { 0 }, i; + ARR_FIND(0, 10, i, (mobid[i] = va_arg(ap, int)) == 0); //fetch till 0 + if (mobid[0]) { //if there one let's check it otherwise go backward + TBL_MOB *md = BL_CAST(BL_MOB, bl); + nullpo_ret(md); + ARR_FIND(0, 10, i, md->class_ == mobid[i]); + return (i < 10) ? 1 : 0; + } + return 1; //backward compatibility } /*========================================== @@ -884,8 +895,8 @@ int mob_count_sub(struct block_list *bl, va_list ap) { int mob_spawn (struct mob_data *md) { int i=0; - unsigned int tick = timer->gettick(); - int c =0; + int64 tick = timer->gettick(); + int64 c = 0; md->last_thinktime = tick; if (md->bl.prev != NULL) @@ -921,7 +932,7 @@ int mob_spawn (struct mob_data *md) } memset(&md->state, 0, sizeof(md->state)); - status_calc_mob(md, 1); + status_calc_mob(md, SCO_FIRST); md->attacked_id = 0; md->target_id = 0; md->move_fail_count = 0; @@ -1042,7 +1053,7 @@ int mob_ai_sub_hard_activesearch(struct block_list *bl,va_list ap) mode= va_arg(ap,int); //If can't seek yet, not an enemy, or you can't attack it, skip. - if ((*target) == bl || !status->check_skilluse(&md->bl, bl, 0, 0)) + if (md->bl.id == bl->id || (*target) == bl || !status->check_skilluse(&md->bl, bl, 0, 0)) return 0; if ((mode&MD_TARGETWEAK) && status->get_lv(bl) >= md->level-5) @@ -1051,39 +1062,38 @@ int mob_ai_sub_hard_activesearch(struct block_list *bl,va_list ap) if(battle->check_target(&md->bl,bl,BCT_ENEMY)<=0) return 0; - switch (bl->type) - { - case BL_PC: - if (((TBL_PC*)bl)->state.gangsterparadise && - !(status_get_mode(&md->bl)&MD_BOSS)) - return 0; //Gangster paradise protection. - default: - if (battle_config.hom_setting&0x4 && - (*target) && (*target)->type == BL_HOM && bl->type != BL_HOM) - return 0; //For some reason Homun targets are never overriden. + switch (bl->type) { + case BL_PC: + if (((TBL_PC*)bl)->state.gangsterparadise && + !(status_get_mode(&md->bl)&MD_BOSS)) + return 0; //Gangster paradise protection. + default: + if (battle_config.hom_setting&0x4 && + (*target) && (*target)->type == BL_HOM && bl->type != BL_HOM) + return 0; //For some reason Homun targets are never overriden. - dist = distance_bl(&md->bl, bl); - if( - ((*target) == NULL || !check_distance_bl(&md->bl, *target, dist)) && - battle->check_range(&md->bl,bl,md->db->range2) - ) { //Pick closest target? + dist = distance_bl(&md->bl, bl); + if( + ((*target) == NULL || !check_distance_bl(&md->bl, *target, dist)) && + battle->check_range(&md->bl,bl,md->db->range2) + ) { //Pick closest target? - if( map->list[bl->m].icewall_num && - !path->search_long(NULL,bl->m,md->bl.x,md->bl.y,bl->x,bl->y,CELL_CHKICEWALL) ) { + if( map->list[bl->m].icewall_num && + !path->search_long(NULL,bl->m,md->bl.x,md->bl.y,bl->x,bl->y,CELL_CHKICEWALL) ) { - if( !check_distance_bl(&md->bl, bl, status_get_range(&md->bl) ) ) - return 0; + if( !check_distance_bl(&md->bl, bl, status_get_range(&md->bl) ) ) + return 0; - } + } - (*target) = bl; - md->target_id=bl->id; - md->min_chase= dist + md->db->range3; - if(md->min_chase>MAX_MINCHASE) - md->min_chase=MAX_MINCHASE; - return 1; - } - break; + (*target) = bl; + md->target_id=bl->id; + md->min_chase= dist + md->db->range3; + if(md->min_chase>MAX_MINCHASE) + md->min_chase=MAX_MINCHASE; + return 1; + } + break; } return 0; } @@ -1100,7 +1110,7 @@ int mob_ai_sub_hard_changechase(struct block_list *bl,va_list ap) { target= va_arg(ap,struct block_list**); //If can't seek yet, not an enemy, or you can't attack it, skip. - if( *target == bl + if( md->bl.id == bl->id || *target == bl || battle->check_target(&md->bl,bl,BCT_ENEMY) <= 0 || !status->check_skilluse(&md->bl, bl, 0, 0) ) @@ -1185,7 +1195,7 @@ int mob_warpchase_sub(struct block_list *bl,va_list ap) { /*========================================== * Processing of slave monsters *------------------------------------------*/ -int mob_ai_sub_hard_slavemob(struct mob_data *md,unsigned int tick) { +int mob_ai_sub_hard_slavemob(struct mob_data *md, int64 tick) { struct block_list *bl; bl=map->id2bl(md->master_id); @@ -1268,8 +1278,7 @@ int mob_ai_sub_hard_slavemob(struct mob_data *md,unsigned int tick) { * when trying to pick new targets when the current chosen target is * unreachable. *------------------------------------------*/ -int mob_unlocktarget(struct mob_data *md, unsigned int tick) -{ +int mob_unlocktarget(struct mob_data *md, int64 tick) { nullpo_ret(md); switch (md->state.skillstate) { @@ -1308,8 +1317,7 @@ int mob_unlocktarget(struct mob_data *md, unsigned int tick) /*========================================== * Random walk *------------------------------------------*/ -int mob_randomwalk(struct mob_data *md,unsigned int tick) -{ +int mob_randomwalk(struct mob_data *md, int64 tick) { const int retrycount=20; int i,x,y,c,d; int speed; @@ -1383,8 +1391,7 @@ int mob_warpchase(struct mob_data *md, struct block_list *target) /*========================================== * AI of MOB whose is near a Player *------------------------------------------*/ -bool mob_ai_sub_hard(struct mob_data *md, unsigned int tick) -{ +bool mob_ai_sub_hard(struct mob_data *md, int64 tick) { struct block_list *tbl = NULL, *abl = NULL; int mode; int view_range, can_move; @@ -1405,7 +1412,8 @@ bool mob_ai_sub_hard(struct mob_data *md, unsigned int tick) // Abnormalities if(( md->sc.opt1 > 0 && md->sc.opt1 != OPT1_STONEWAIT && md->sc.opt1 != OPT1_BURNING && md->sc.opt1 != OPT1_CRYSTALIZE ) - || md->sc.data[SC_BLADESTOP] || md->sc.data[SC__MANHOLE] || md->sc.data[SC_CURSEDCIRCLE_TARGET]) {//Should reset targets. + || md->sc.data[SC_DEEP_SLEEP] || md->sc.data[SC_BLADESTOP] || md->sc.data[SC__MANHOLE] || md->sc.data[SC_CURSEDCIRCLE_TARGET]) { + //Should reset targets. md->target_id = md->attacked_id = 0; return false; } @@ -1458,7 +1466,7 @@ bool mob_ai_sub_hard(struct mob_data *md, unsigned int tick) } } else - if( (abl = map->id2bl(md->attacked_id)) && (!tbl || mob->can_changetarget(md, abl, mode)) ) { + if( (abl = map->id2bl(md->attacked_id)) && (!tbl || mob->can_changetarget(md, abl, mode) || (md->sc.count && md->sc.data[SC__CHAOS]))) { int dist; if( md->bl.m != abl->m || abl->prev == NULL || (dist = distance_bl(&md->bl, abl)) >= MAX_MINCHASE // Attacker longer than visual area @@ -1521,7 +1529,7 @@ bool mob_ai_sub_hard(struct mob_data *md, unsigned int tick) if ((!tbl && mode&MD_AGGRESSIVE) || md->state.skillstate == MSS_FOLLOW) { map->foreachinrange (mob->ai_sub_hard_activesearch, &md->bl, view_range, DEFAULT_ENEMY_TYPE(md), md, &tbl, mode); - } else if (mode&MD_CHANGECHASE && (md->state.skillstate == MSS_RUSH || md->state.skillstate == MSS_FOLLOW)) { + } else if ((mode&MD_CHANGECHASE && (md->state.skillstate == MSS_RUSH || md->state.skillstate == MSS_FOLLOW)) || (md->sc.count && md->sc.data[SC__CHAOS])) { int search_size; search_size = view_range<md->status.rhw.range ? view_range:md->status.rhw.range; map->foreachinrange (mob->ai_sub_hard_changechase, &md->bl, search_size, DEFAULT_ENEMY_TYPE(md), md, &tbl); @@ -1645,10 +1653,9 @@ bool mob_ai_sub_hard(struct mob_data *md, unsigned int tick) return true; } -int mob_ai_sub_hard_timer(struct block_list *bl,va_list ap) -{ +int mob_ai_sub_hard_timer(struct block_list *bl, va_list ap) { struct mob_data *md = (struct mob_data*)bl; - unsigned int tick = va_arg(ap, unsigned int); + int64 tick = va_arg(ap, int64); if (mob->ai_sub_hard(md, tick)) { //Hard AI triggered. if(!md->state.spotted) @@ -1661,9 +1668,9 @@ int mob_ai_sub_hard_timer(struct block_list *bl,va_list ap) /*========================================== * Serious processing for mob in PC field of view (foreachclient) *------------------------------------------*/ -int mob_ai_sub_foreachclient(struct map_session_data *sd,va_list ap) { - unsigned int tick; - tick=va_arg(ap,unsigned int); +int mob_ai_sub_foreachclient(struct map_session_data *sd, va_list ap) { + int64 tick; + tick=va_arg(ap, int64); map->foreachinrange(mob->ai_sub_hard_timer,&sd->bl, AREA_SIZE+ACTIVE_AI_RANGE, BL_MOB,tick); return 0; @@ -1672,16 +1679,15 @@ int mob_ai_sub_foreachclient(struct map_session_data *sd,va_list ap) { /*========================================== * Negligent mode MOB AI (PC is not in near) *------------------------------------------*/ -int mob_ai_sub_lazy(struct mob_data *md, va_list args) -{ - unsigned int tick; +int mob_ai_sub_lazy(struct mob_data *md, va_list args) { + int64 tick; nullpo_ret(md); if(md->bl.prev == NULL) return 0; - tick = va_arg(args,unsigned int); + tick = va_arg(args, int64); if (battle_config.mob_ai&0x20 && map->list[md->bl.m].users>0) return (int)mob->ai_sub_hard(md, tick); @@ -1715,7 +1721,7 @@ int mob_ai_sub_lazy(struct mob_data *md, va_list args) md->last_thinktime=tick; if (md->master_id) { - mob->ai_sub_hard_slavemob (md,tick); + mob->ai_sub_hard_slavemob(md,tick); return 0; } @@ -1740,7 +1746,7 @@ int mob_ai_sub_lazy(struct mob_data *md, va_list args) /*========================================== * Negligent processing for mob outside PC field of view (interval timer function) *------------------------------------------*/ -int mob_ai_lazy(int tid, unsigned int tick, int id, intptr_t data) { +int mob_ai_lazy(int tid, int64 tick, int id, intptr_t data) { map->foreachmob(mob->ai_sub_lazy,tick); return 0; } @@ -1748,7 +1754,7 @@ int mob_ai_lazy(int tid, unsigned int tick, int id, intptr_t data) { /*========================================== * Serious processing for mob in PC field of view (interval timer function) *------------------------------------------*/ -int mob_ai_hard(int tid, unsigned int tick, int id, intptr_t data) { +int mob_ai_hard(int tid, int64 tick, int id, intptr_t data) { if (battle_config.mob_ai&0x20) map->foreachmob(mob->ai_sub_lazy,tick); @@ -1763,7 +1769,6 @@ int mob_ai_hard(int tid, unsigned int tick, int id, intptr_t data) { *------------------------------------------*/ struct item_drop* mob_setdropitem(int nameid, int qty, struct item_data *data) { struct item_drop *drop = ers_alloc(item_drop_ers, struct item_drop); - memset(&drop->item_data, 0, sizeof(struct item)); drop->item_data.nameid = nameid; drop->item_data.amount = qty; drop->item_data.identify = data ? itemdb->isidentified2(data) : itemdb->isidentified(nameid); @@ -1785,8 +1790,7 @@ struct item_drop* mob_setlootitem(struct item* item) /*========================================== * item drop with delay (timer function) *------------------------------------------*/ -int mob_delay_item_drop(int tid, unsigned int tick, int id, intptr_t data) -{ +int mob_delay_item_drop(int tid, int64 tick, int id, intptr_t data) { struct item_drop_list *list; struct item_drop *ditem, *ditem_prev; list=(struct item_drop_list *)data; @@ -1822,7 +1826,7 @@ void mob_item_drop(struct mob_data *md, struct item_drop_list *dlist, struct ite if( sd && (drop_rate <= sd->state.autoloot || pc->isautolooting(sd, ditem->item_data.nameid)) - && (battle_config.idle_no_autoloot == 0 || DIFF_TICK(last_tick, sd->idletime) < battle_config.idle_no_autoloot) + && (battle_config.idle_no_autoloot == 0 || DIFF_TICK(sockt->last_tick, sd->idletime) < battle_config.idle_no_autoloot) && (battle_config.homunculus_autoloot?1:!flag) #ifdef AUTOLOOT_DISTANCE && sd->bl.m == md->bl.m @@ -1840,7 +1844,7 @@ void mob_item_drop(struct mob_data *md, struct item_drop_list *dlist, struct ite dlist->item = ditem; } -int mob_timer_delete(int tid, unsigned int tick, int id, intptr_t data) { +int mob_timer_delete(int tid, int64 tick, int id, intptr_t data) { struct block_list* bl = map->id2bl(id); struct mob_data* md = BL_CAST(BL_MOB, bl); @@ -1885,7 +1889,7 @@ int mob_deleteslave(struct mob_data *md) { return 0; } // Mob respawning through KAIZEL or NPC_REBIRTH [Skotlex] -int mob_respawn(int tid, unsigned int tick, int id, intptr_t data) { +int mob_respawn(int tid, int64 tick, int id, intptr_t data) { struct block_list *bl = map->id2bl(id); if(!bl) return 0; @@ -2069,7 +2073,8 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) { } pt[DAMAGELOG_SIZE]; int i, temp, count, m = md->bl.m, pnum = 0; int dmgbltypes = 0; // bitfield of all bl types, that caused damage to the mob and are elligible for exp distribution - unsigned int mvp_damage, tick = timer->gettick(); + unsigned int mvp_damage; + int64 tick = timer->gettick(); bool rebirth, homkillonly; mstatus = &md->status; @@ -2190,7 +2195,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) { // change experience for different sized monsters [Valaris] if (battle_config.mob_size_influence) { switch( md->special_state.size ) { - case SZ_MEDIUM: + case SZ_SMALL: per /= 2.; break; case SZ_BIG: @@ -2311,7 +2316,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) { // change drops depending on monsters size [Valaris] if (battle_config.mob_size_influence) { - if (md->special_state.size == SZ_MEDIUM && drop_rate >= 2) + if (md->special_state.size == SZ_SMALL && drop_rate >= 2) drop_rate /= 2; else if( md->special_state.size == SZ_BIG) drop_rate *= 2; @@ -2339,6 +2344,12 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) { drop_rate = 1; } #endif + if( sd && sd->status.mod_drop != 100 ) { + drop_rate = drop_rate * sd->status.mod_drop / 100; + if( drop_rate < 1 ) + drop_rate = 1; + } + // attempt to drop the item if (rnd() % 10000 >= drop_rate) continue; @@ -2357,6 +2368,14 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) { //MSG: "'%s' won %s's %s (chance: %0.02f%%)" intif->broadcast(message, strlen(message)+1, BC_DEFAULT); } + + /* heres the thing we got the feature set up however we're still discussing how to best define the ids, + * so while we discuss, for a small period of time, the list is hardcoded (yes officially only those 2 use it, + * thus why we're unsure on how to best place the setting) */ + /* temp, will not be hardcoded for long thudu. */ + if( it->nameid == 7782 || it->nameid == 7783 ) /* for when not hardcoded: add a check on mvp bonus drop as well */ + clif->item_drop_announce(mvp_sd, it->nameid, md->name); + // Announce first, or else ditem will be freed. [Lance] // By popular demand, use base drop rate for autoloot code. [Skotlex] mob->item_drop(md, dlist, ditem, 0, md->db->dropitem[i].p, homkillonly); @@ -2435,7 +2454,6 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) { if(mvp_sd && md->db->mexp > 0 && !md->special_state.ai) { int log_mvp[2] = {0}; unsigned int mexp; - struct item item; double exp; //mapflag: noexp check [Lorky] @@ -2458,6 +2476,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) { /* pose them randomly in the list -- so on 100% drop servers it wont always drop the same item */ int mdrop_id[MAX_MVP_DROP]; int mdrop_p[MAX_MVP_DROP]; + struct item item; memset(&mdrop_id,0,MAX_MVP_DROP*sizeof(int)); @@ -2513,7 +2532,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) { logs->mvpdrop(mvp_sd, md->class_, log_mvp); } - if (type&2 && !sd && md->class_ == MOBID_EMPERIUM) + if (type&2 && !sd && md->class_ == MOBID_EMPERIUM && md->guardian_data) //Emperium destroyed by script. Discard mvp character. [Skotlex] mvp_sd = NULL; @@ -2534,11 +2553,11 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) { if( ++sd->mission_count >= 100 && (temp = mob->get_random_id(0, 0xE, sd->status.base_level)) ) { pc->addfame(sd, 1); sd->mission_mobid = temp; - pc_setglobalreg(sd,"TK_MISSION_ID", temp); + pc_setglobalreg(sd,script->add_str("TK_MISSION_ID"), temp); sd->mission_count = 0; clif->mission_info(sd, temp, 0); } - pc_setglobalreg(sd,"TK_MISSION_COUNT", sd->mission_count); + pc_setglobalreg(sd,script->add_str("TK_MISSION_COUNT"), sd->mission_count); } if( sd->status.party_id ) @@ -2610,7 +2629,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) { void mob_revive(struct mob_data *md, unsigned int hp) { - unsigned int tick = timer->gettick(); + int64 tick = timer->gettick(); md->state.skillstate = MSS_IDLE; md->last_thinktime = tick; md->next_walktime = tick+rnd()%50+5000; @@ -2695,8 +2714,8 @@ int mob_random_class (int *value, size_t count) *------------------------------------------*/ int mob_class_change (struct mob_data *md, int class_) { - unsigned int tick = timer->gettick(); - int i, c, hp_rate; + int64 tick = timer->gettick(), c = 0; + int i, hp_rate; nullpo_ret(md); @@ -2732,7 +2751,7 @@ int mob_class_change (struct mob_data *md, int class_) unit->skillcastcancel(&md->bl, 0); status->set_viewdata(&md->bl, class_); clif->class_change(&md->bl, md->vd->class_, 1); - status_calc_mob(md, 1); + status_calc_mob(md, SCO_FIRST); md->ud.state.speed_changed = 1; //Speed change update. if (battle_config.monster_class_change_recover) { @@ -2765,6 +2784,19 @@ void mob_heal(struct mob_data *md,unsigned int heal) { if (battle_config.show_mob_info&3) clif->charnameack (0, &md->bl); + +#if PACKETVER >= 20120404 + if( !(md->status.mode&MD_BOSS) ){ + int i; + for(i = 0; i < DAMAGELOG_SIZE; i++){ // must show hp bar to all char who already hit the mob. + if( md->dmglog[i].id ) { + struct map_session_data *sd = map->charid2sd(md->dmglog[i].id); + if( sd && check_distance_bl(&md->bl, &sd->bl, AREA_SIZE) ) // check if in range + clif->monster_hp_bar(md,sd); + } + } + } +#endif } /*========================================== @@ -2896,17 +2928,17 @@ int mob_summonslave(struct mob_data *md2,int *value,int amount,uint16 skill_id) switch (battle_config.slaves_inherit_mode) { case 1: //Always aggressive if (!(md->status.mode&MD_AGGRESSIVE)) - sc_start4(&md->bl, SC_MODECHANGE, 100,1,0, MD_AGGRESSIVE, 0, 0); + sc_start4(NULL, &md->bl, SC_MODECHANGE, 100,1,0, MD_AGGRESSIVE, 0, 0); break; case 2: //Always passive if (md->status.mode&MD_AGGRESSIVE) - sc_start4(&md->bl, SC_MODECHANGE, 100,1,0, 0, MD_AGGRESSIVE, 0); + sc_start4(NULL, &md->bl, SC_MODECHANGE, 100,1,0, 0, MD_AGGRESSIVE, 0); break; default: //Copy master. if (md2->status.mode&MD_AGGRESSIVE) - sc_start4(&md->bl, SC_MODECHANGE, 100,1,0, MD_AGGRESSIVE, 0, 0); + sc_start4(NULL, &md->bl, SC_MODECHANGE, 100,1,0, MD_AGGRESSIVE, 0, 0); else - sc_start4(&md->bl, SC_MODECHANGE, 100,1,0, 0, MD_AGGRESSIVE, 0); + sc_start4(NULL, &md->bl, SC_MODECHANGE, 100,1,0, 0, MD_AGGRESSIVE, 0); break; } } @@ -3032,8 +3064,7 @@ struct mob_data *mob_getfriendstatus(struct mob_data *md,int cond1,int cond2) { /*========================================== * Skill use judging *------------------------------------------*/ -int mobskill_use(struct mob_data *md, unsigned int tick, int event) -{ +int mobskill_use(struct mob_data *md, int64 tick, int event) { struct mob_skill *ms; struct block_list *fbl = NULL; //Friend bl, which can either be a BL_PC or BL_MOB depending on the situation. [Skotlex] struct block_list *bl; @@ -3249,8 +3280,7 @@ int mobskill_use(struct mob_data *md, unsigned int tick, int event) /*========================================== * Skill use event processing *------------------------------------------*/ -int mobskill_event(struct mob_data *md, struct block_list *src, unsigned int tick, int flag) -{ +int mobskill_event(struct mob_data *md, struct block_list *src, int64 tick, int flag) { int target_id, res = 0; if(md->bl.prev == NULL || md->status.hp <= 0) @@ -3473,7 +3503,7 @@ int mob_clone_spawn(struct map_session_data *sd, int16 m, int16 x, int16 y, cons sd->fd = fd; //Finally, spawn it. - md = mob->once_spawn_sub(&sd->bl, m, x, y, "--en--", class_, event, SZ_SMALL, AI_NONE); + md = mob->once_spawn_sub(&sd->bl, m, x, y, "--en--", class_, event, SZ_MEDIUM, AI_NONE); if (!md) return 0; //Failed? md->special_state.clone = 1; @@ -3487,7 +3517,7 @@ int mob_clone_spawn(struct map_session_data *sd, int16 m, int16 x, int16 y, cons { if( md->deletetimer != INVALID_TIMER ) timer->delete(md->deletetimer, mob->timer_delete); - md->deletetimer = timer->add (timer->gettick() + duration, mob->timer_delete, md->bl.id, 0); + md->deletetimer = timer->add(timer->gettick() + duration, mob->timer_delete, md->bl.id, 0); } } @@ -3877,6 +3907,7 @@ void mob_readdb(void) { sv->readdb(map->db_path, filename[fi], ',', 31+2*MAX_MVP_DROP+2*MAX_MOB_DROP, 31+2*MAX_MVP_DROP+2*MAX_MOB_DROP, -1, mob->readdb_sub); } + mob->name_constants(); } /*========================================== @@ -3926,9 +3957,24 @@ int mob_read_sqldb(void) { ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, mob_db_name[fi]); } + mob->name_constants(); return 0; } +void mob_name_constants(void) { + int i; +#ifdef ENABLE_CASE_CHECK + script->parser_current_file = "Mob Database (Likely an invalid or conflicting SpriteName)"; +#endif // ENABLE_CASE_CHECK + for (i = 0; i < MAX_MOB_DB; i++) { + if (mob->db_data[i] && !mob->is_clone(i)) + script->set_constant2(mob->db_data[i]->sprite, i, 0); + } +#ifdef ENABLE_CASE_CHECK + script->parser_current_file = NULL; +#endif // ENABLE_CASE_CHECK +} + /*========================================== * MOB display graphic change data reading *------------------------------------------*/ @@ -4065,7 +4111,7 @@ bool mob_parse_row_chatdb(char** str, const char* source, int line, int* last_ms //MSG ID ms->msg_id=msg_id; //Color - ms->color=strtoul(str[1],NULL,0); + ms->color=(unsigned int)strtoul(str[1],NULL,0); //Message msg = str[2]; len = strlen(msg); @@ -4543,7 +4589,12 @@ bool mob_readdb_itemratio(char* str[], int columns, int current) /** * read all mob-related databases */ -void mob_load(void) { +void mob_load(bool minimal) { + if (minimal) { + // Only read the mob db in minimal mode + mob->readdb(); + return; + } sv->readdb(map->db_path, "mob_item_ratio.txt", ',', 2, 2+MAX_ITEMRATIO_MOBS, -1, mob->readdb_itemratio); // must be read before mobdb mob->readchatdb(); if (map->db_use_sql_mob_db) { @@ -4578,7 +4629,7 @@ void mob_reload(void) { } } - mob->load(); + mob->load(false); } void mob_clear_spawninfo() @@ -4592,15 +4643,18 @@ void mob_clear_spawninfo() /*========================================== * Circumference initialization of mob *------------------------------------------*/ -int do_init_mob(void) -{ //Initialize the mob database +int do_init_mob(bool minimal) { + // Initialize the mob database memset(mob->db_data,0,sizeof(mob->db_data)); //Clear the array - mob->db_data[0] = (struct mob_db*)aCalloc(1, sizeof (struct mob_db)); //This mob is used for random spawns + mob->db_data[0] = (struct mob_db*)aCalloc(1, sizeof (struct mob_db)); //This mob is used for random spawns mob->makedummymobdb(0); //The first time this is invoked, it creates the dummy mob - item_drop_ers = ers_new(sizeof(struct item_drop),"mob.c::item_drop_ers",ERS_OPT_NONE); + item_drop_ers = ers_new(sizeof(struct item_drop),"mob.c::item_drop_ers",ERS_OPT_CLEAN); item_drop_list_ers = ers_new(sizeof(struct item_drop_list),"mob.c::item_drop_list_ers",ERS_OPT_NONE); - mob->load(); + mob->load(minimal); + + if (minimal) + return 0; timer->add_func_list(mob->delayspawn,"mob_delayspawn"); timer->add_func_list(mob->delay_item_drop,"mob_delay_item_drop"); @@ -4754,6 +4808,7 @@ void mob_defaults(void) { mob->readdb_sub = mob_readdb_sub; mob->readdb = mob_readdb; mob->read_sqldb = mob_read_sqldb; + mob->name_constants = mob_name_constants; mob->readdb_mobavail = mob_readdb_mobavail; mob->read_randommonster = mob_read_randommonster; mob->parse_row_chatdb = mob_parse_row_chatdb; diff --git a/src/map/mob.h b/src/map/mob.h index 210983675..80175b1db 100644 --- a/src/map/mob.h +++ b/src/map/mob.h @@ -2,8 +2,8 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _MOB_H_ -#define _MOB_H_ +#ifndef _MAP_MOB_H_ +#define _MAP_MOB_H_ #include "../common/mmo.h" // struct item #include "guild.h" // struct guardian_data @@ -37,7 +37,7 @@ #define MOB_CLONE_END MAX_MOB_DB //Used to determine default enemy type of mobs (for use in eachinrange calls) -#define DEFAULT_ENEMY_TYPE(md) (md->special_state.ai?BL_CHAR:BL_MOB|BL_PC|BL_HOM|BL_MER) +#define DEFAULT_ENEMY_TYPE(md) ((md)->special_state.ai?BL_CHAR:BL_MOB|BL_PC|BL_HOM|BL_MER) #define MAX_MOB_CHAT 250 //Max Skill's messages @@ -63,8 +63,8 @@ enum MobDamageLogFlag }; enum size { - SZ_SMALL = 0, - SZ_MEDIUM, + SZ_MEDIUM = 0, + SZ_SMALL, SZ_BIG, }; @@ -91,7 +91,7 @@ struct mob_skill { struct mob_chat { unsigned short msg_id; - unsigned long color; + unsigned int color; char msg[CHAT_SIZE_MAX]; }; @@ -166,7 +166,7 @@ struct mob_data { int areanpc_id; //Required in OnTouchNPC (to avoid multiple area touchs) unsigned int bg_id; // BattleGround System - unsigned int next_walktime,last_thinktime,last_linktime,last_pcneartime,dmgtick; + int64 next_walktime, last_thinktime, last_linktime, last_pcneartime, dmgtick; short move_fail_count; short lootitem_count; short min_chase; @@ -175,7 +175,7 @@ struct mob_data { int master_id,master_dist; int8 skill_idx;// key of array - unsigned int skilldelay[MAX_MOBSKILL]; + int64 skilldelay[MAX_MOBSKILL]; char npc_event[EVENT_NAME_LENGTH]; /** * Did this monster summon something? @@ -243,8 +243,9 @@ struct item_drop_list { }; -#define mob_stop_walking(md, type) unit->stop_walking(&(md)->bl, type) -#define mob_stop_attack(md) unit->stop_attack(&(md)->bl) +#define mob_stop_walking(md, type) (unit->stop_walking(&(md)->bl, (type))) +#define mob_stop_attack(md) (unit->stop_attack(&(md)->bl)) + #define mob_is_battleground(md) ( map->list[(md)->bl.m].flag.battleground && ((md)->class_ == MOBID_BARRICADE2 || ((md)->class_ >= MOBID_FOOD_STOR && (md)->class_ <= MOBID_PINK_CRYST)) ) #define mob_is_gvg(md) (map->list[(md)->bl.m].flag.gvg_castle && ( (md)->class_ == MOBID_EMPERIUM || (md)->class_ == MOBID_BARRICADE1 || (md)->class_ == MOBID_GUARIDAN_STONE1 || (md)->class_ == MOBID_GUARIDAN_STONE2) ) #define mob_is_treasure(md) (((md)->class_ >= MOBID_TREAS01 && (md)->class_ <= MOBID_TREAS40) || ((md)->class_ >= MOBID_TREAS41 && (md)->class_ <= MOBID_TREAS49)) @@ -259,17 +260,17 @@ struct mob_interface { int manuk[8]; int splendide[5]; /* */ - int (*init) (void); + int (*init) (bool mimimal); int (*final) (void); void (*reload) (void); /* */ struct mob_db* (*db) (int index); struct mob_chat* (*chat) (short id); int (*makedummymobdb) (int); - int (*spawn_guardian_sub) (int tid, unsigned int tick, int id, intptr_t data); + int (*spawn_guardian_sub) (int tid, int64 tick, int id, intptr_t data); int (*skill_id2skill_idx) (int class_, uint16 skill_id); int (*db_searchname) (const char *str); - int (*db_searchname_array_sub) (struct mob_db *mob, const char *str, int flag); + int (*db_searchname_array_sub) (struct mob_db *monster, const char *str, int flag); // MvP Tomb System void (*mvptomb_create) (struct mob_data *md, char *killer, time_t time); void (*mvptomb_destroy) (struct mob_data *md); @@ -287,7 +288,7 @@ struct mob_interface { int (*spawn_bg) (const char *mapname, short x, short y, const char *mobname, int class_, const char *event, unsigned int bg_id); int (*can_reach) (struct mob_data *md, struct block_list *bl, int range, int state); int (*linksearch) (struct block_list *bl, va_list ap); - int (*delayspawn) (int tid, unsigned int tick, int id, intptr_t data); + int (*delayspawn) (int tid, int64 tick, int id, intptr_t data); int (*setdelayspawn) (struct mob_data *md); int (*count_sub) (struct block_list *bl, va_list ap); int (*spawn) (struct mob_data *md); @@ -298,24 +299,24 @@ struct mob_interface { int (*ai_sub_hard_bg_ally) (struct block_list *bl, va_list ap); int (*ai_sub_hard_lootsearch) (struct block_list *bl, va_list ap); int (*warpchase_sub) (struct block_list *bl, va_list ap); - int (*ai_sub_hard_slavemob) (struct mob_data *md, unsigned int tick); - int (*unlocktarget) (struct mob_data *md, unsigned int tick); - int (*randomwalk) (struct mob_data *md, unsigned int tick); + int (*ai_sub_hard_slavemob) (struct mob_data *md, int64 tick); + int (*unlocktarget) (struct mob_data *md, int64 tick); + int (*randomwalk) (struct mob_data *md, int64 tick); int (*warpchase) (struct mob_data *md, struct block_list *target); - bool (*ai_sub_hard) (struct mob_data *md, unsigned int tick); + bool (*ai_sub_hard) (struct mob_data *md, int64 tick); int (*ai_sub_hard_timer) (struct block_list *bl, va_list ap); int (*ai_sub_foreachclient) (struct map_session_data *sd, va_list ap); int (*ai_sub_lazy) (struct mob_data *md, va_list args); - int (*ai_lazy) (int tid, unsigned int tick, int id, intptr_t data); - int (*ai_hard) (int tid, unsigned int tick, int id, intptr_t data); + int (*ai_lazy) (int tid, int64 tick, int id, intptr_t data); + int (*ai_hard) (int tid, int64 tick, int id, intptr_t data); struct item_drop* (*setdropitem) (int nameid, int qty, struct item_data *data); struct item_drop* (*setlootitem) (struct item *item); - int (*delay_item_drop) (int tid, unsigned int tick, int id, intptr_t data); + int (*delay_item_drop) (int tid, int64 tick, int id, intptr_t data); void (*item_drop) (struct mob_data *md, struct item_drop_list *dlist, struct item_drop *ditem, int loot, int drop_rate, unsigned short flag); - int (*timer_delete) (int tid, unsigned int tick, int id, intptr_t data); + int (*timer_delete) (int tid, int64 tick, int id, intptr_t data); int (*deleteslave_sub) (struct block_list *bl, va_list ap); int (*deleteslave) (struct mob_data *md); - int (*respawn) (int tid, unsigned int tick, int id, intptr_t data); + int (*respawn) (int tid, int64 tick, int id, intptr_t data); void (*log_damage) (struct mob_data *md, struct block_list *src, int damage); void (*damage) (struct mob_data *md, struct block_list *src, int damage); int (*dead) (struct mob_data *md, struct block_list *src, int type); @@ -334,8 +335,8 @@ struct mob_interface { struct block_list* (*getmasterhpltmaxrate) (struct mob_data *md, int rate); int (*getfriendstatus_sub) (struct block_list *bl, va_list ap); struct mob_data* (*getfriendstatus) (struct mob_data *md, int cond1, int cond2); - int (*skill_use) (struct mob_data *md, unsigned int tick, int event); - int (*skill_event) (struct mob_data *md, struct block_list *src, unsigned int tick, int flag); + int (*skill_use) (struct mob_data *md, int64 tick, int event); + int (*skill_event) (struct mob_data *md, struct block_list *src, int64 tick, int flag); int (*is_clone) (int class_); int (*clone_spawn) (struct map_session_data *sd, int16 m, int16 x, int16 y, const char *event, int master_id, int mode, int flag, unsigned int duration); int (*clone_delete) (struct mob_data *md); @@ -345,6 +346,7 @@ struct mob_interface { bool (*readdb_sub) (char *fields[], int columns, int current); void (*readdb) (void); int (*read_sqldb) (void); + void (*name_constants) (void); bool (*readdb_mobavail) (char *str[], int columns, int current); int (*read_randommonster) (void); bool (*parse_row_chatdb) (char **str, const char *source, int line, int *last_msg_id); @@ -354,7 +356,7 @@ struct mob_interface { int (*read_sqlskilldb) (void); bool (*readdb_race2) (char *fields[], int columns, int current); bool (*readdb_itemratio) (char *str[], int columns, int current); - void (*load) (void); + void (*load) (bool minimal); void (*clear_spawninfo) (); }; @@ -362,4 +364,4 @@ struct mob_interface *mob; void mob_defaults(void); -#endif /* _MOB_H_ */ +#endif /* _MAP_MOB_H_ */ diff --git a/src/map/npc.c b/src/map/npc.c index c52dce325..36efc7267 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -12,6 +12,8 @@ #include "../common/ers.h" #include "../common/db.h" #include "../common/socket.h" +#include "../common/HPM.h" + #include "map.h" #include "log.h" #include "clif.h" @@ -54,6 +56,9 @@ struct npc_path_data *npc_last_npd; static struct view_data npc_viewdb[MAX_NPC_CLASS]; static struct view_data npc_viewdb2[MAX_NPC_CLASS2_END-MAX_NPC_CLASS2_START]; +/* for speedup */ +unsigned int npc_market_qty[MAX_INVENTORY]; + static struct script_event_s { //Holds pointers to the commonly executed scripts for speedup. [Skotlex] struct event_data *event[UCHAR_MAX]; @@ -215,7 +220,7 @@ struct npc_data* npc_name2id(const char* name) /** * Timer to check for idle time and timeout the dialog if necessary **/ -int npc_rr_secure_timeout_timer(int tid, unsigned int tick, int id, intptr_t data) { +int npc_rr_secure_timeout_timer(int tid, int64 tick, int id, intptr_t data) { #ifdef SECURE_NPCTIMEOUT struct map_session_data* sd = NULL; unsigned int timeout = NPC_SECURE_TIMEOUT_NEXT; @@ -394,8 +399,7 @@ int npc_event_doall(const char* name) * Clock event execution * OnMinute/OnClock/OnHour/OnDay/OnDDHHMM *------------------------------------------*/ -int npc_event_do_clock(int tid, unsigned int tick, int id, intptr_t data) -{ +int npc_event_do_clock(int tid, int64 tick, int id, intptr_t data) { static struct tm ev_tm_b; // tracks previous execution time time_t clock; struct tm* t; @@ -459,10 +463,10 @@ void npc_event_do_oninit(void) *------------------------------------------*/ int npc_timerevent_export(struct npc_data *nd, int i) { - int t = 0, k = 0; + int t = 0, len = 0; char *lname = nd->u.scr.label_list[i].name; int pos = nd->u.scr.label_list[i].pos; - if (sscanf(lname, "OnTimer%d%n", &t, &k) == 1 && lname[k] == '\0') { + if (sscanf(lname, "OnTimer%d%n", &t, &len) == 1 && lname[len] == '\0') { // Timer event struct npc_timerevent_list *te = nd->u.scr.timer_event; int j, k = nd->u.scr.timeramount; @@ -493,9 +497,9 @@ struct timer_event_data { /*========================================== * triger 'OnTimerXXXX' events *------------------------------------------*/ -int npc_timerevent(int tid, unsigned int tick, int id, intptr_t data) { +int npc_timerevent(int tid, int64 tick, int id, intptr_t data) { int old_rid, old_timer; - unsigned int old_tick; + int64 old_tick; struct npc_data* nd=(struct npc_data *)map->id2bl(id); struct npc_timerevent_list *te; struct timer_event_data *ted = (struct timer_event_data*)data; @@ -529,8 +533,7 @@ int npc_timerevent(int tid, unsigned int tick, int id, intptr_t data) { ted->next++; if( nd->u.scr.timeramount > ted->next ) { - int next; - next = nd->u.scr.timer_event[ ted->next ].timer - nd->u.scr.timer_event[ ted->next - 1 ].timer; + int next = nd->u.scr.timer_event[ ted->next ].timer - nd->u.scr.timer_event[ ted->next - 1 ].timer; ted->time += next; if( sd ) sd->npc_timer_id = timer->add(tick+next,npc->timerevent,id,(intptr_t)ted); @@ -564,7 +567,7 @@ int npc_timerevent(int tid, unsigned int tick, int id, intptr_t data) { *------------------------------------------*/ int npc_timerevent_start(struct npc_data* nd, int rid) { int j; - unsigned int tick = timer->gettick(); + int64 tick = timer->gettick(); struct map_session_data *sd = NULL; //Player to whom script is attached. nullpo_ret(nd); @@ -642,7 +645,7 @@ int npc_timerevent_stop(struct npc_data* nd) if( !sd && nd->u.scr.timertick ) { - nd->u.scr.timer += DIFF_TICK(timer->gettick(),nd->u.scr.timertick); // Set 'timer' to the time that has passed since the beginning of the timers + nd->u.scr.timer += DIFF_TICK32(timer->gettick(),nd->u.scr.timertick); // Set 'timer' to the time that has passed since the beginning of the timers nd->u.scr.timertick = 0; // Set 'tick' to zero so that we know it's off. } @@ -688,7 +691,7 @@ void npc_timerevent_quit(struct map_session_data* sd) if( ev ) { int old_rid,old_timer; - unsigned int old_tick; + int64 old_tick; //Set timer related info. old_rid = (nd->u.scr.rid == sd->bl.id ? 0 : nd->u.scr.rid); // Detach rid if the last attached player logged off. @@ -715,9 +718,8 @@ void npc_timerevent_quit(struct map_session_data* sd) * Get the tick value of an NPC timer * If it's stopped, return stopped time *------------------------------------------*/ -int npc_gettimerevent_tick(struct npc_data* nd) -{ - int tick; +int64 npc_gettimerevent_tick(struct npc_data* nd) { + int64 tick; nullpo_ret(nd); // TODO: Get player attached timer's tick. Now we can just get it by using 'getnpctimer' inside OnTimer event. @@ -1151,8 +1153,10 @@ int npc_click(struct map_session_data* sd, struct npc_data* nd) } if(!nd) return 1; + if ((nd = npc->checknear(sd,&nd->bl)) == NULL) return 1; + //Hidden/Disabled npc. if (nd->class_ < 0 || nd->option&(OPTION_INVISIBLE|OPTION_HIDE)) return 1; @@ -1165,7 +1169,11 @@ int npc_click(struct map_session_data* sd, struct npc_data* nd) clif->cashshop_show(sd,nd); break; case SCRIPT: - script->run(nd->u.scr.script,0,sd->bl.id,nd->bl.id); + if( nd->u.scr.shop && nd->u.scr.shop->items && nd->u.scr.trader ) { + if( !npc->trader_open(sd,nd) ) + return 1; + } else + script->run(nd->u.scr.script,0,sd->bl.id,nd->bl.id); break; case TOMB: npc->run_tomb(sd,nd); @@ -1232,16 +1240,22 @@ int npc_buysellsel(struct map_session_data* sd, int id, int type) { if ((nd = npc->checknear(sd,map->id2bl(id))) == NULL) return 1; - if (nd->subtype!=SHOP) { - ShowError("no such shop npc : %d\n",id); + if ( nd->subtype != SHOP && !(nd->subtype == SCRIPT && nd->u.scr.shop && nd->u.scr.shop->items) ) { + + if( nd->subtype == SCRIPT ) + ShowError("npc_buysellsel: trader '%s' has no shop list!\n",nd->exname); + else + ShowError("npc_buysellsel: no such shop npc %d (%s)\n",id,nd->exname); + if (sd->npc_id == id) - sd->npc_id=0; + sd->npc_id = 0; return 1; } - if (nd->option & OPTION_INVISIBLE) // can't buy if npc is not visible (hack?) + + if (nd->option & OPTION_INVISIBLE) // can't buy if npc is not visible (hack?) return 1; - if( nd->class_ < 0 && !sd->state.callshop ) - {// not called through a script and is not a visible NPC so an invalid call + + if( nd->class_ < 0 && !sd->state.callshop ) {// not called through a script and is not a visible NPC so an invalid call return 1; } @@ -1254,21 +1268,42 @@ int npc_buysellsel(struct map_session_data* sd, int id, int type) { } else { clif->selllist(sd); } + return 0; } + /*========================================== * Cash Shop Buy List *------------------------------------------*/ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, unsigned short* item_list) { int i, j, nameid, amount, new_, w, vt; - struct npc_data *nd = (struct npc_data *)map->id2bl(sd->npc_shopid); - - if( !nd || nd->subtype != CASHSHOP ) - return 1; + struct npc_data *nd = NULL; + struct npc_item_list *shop = NULL; + unsigned short shop_size = 0; if( sd->state.trading ) return 4; + if( count <= 0 ) + return 5; + + if( points < 0 ) + return 6; + + if( !(nd = (struct npc_data *)map->id2bl(sd->npc_shopid)) ) + return 1; + + 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; + } else { + shop = nd->u.shop.shop_item; + shop_size = nd->u.shop.count; + } + new_ = 0; w = 0; vt = 0; // Global Value @@ -1281,12 +1316,13 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns if( !itemdb->exists(nameid) || amount <= 0 ) return 5; - ARR_FIND(0,nd->u.shop.count,j,nd->u.shop.shop_item[j].nameid == nameid); - if( j == nd->u.shop.count || nd->u.shop.shop_item[j].value <= 0 ) + ARR_FIND(0,shop_size,j,shop[j].nameid == nameid); + if( j == shop_size || shop[j].value <= 0 ) return 5; if( !itemdb->isstackable(nameid) && amount > 1 ) { - ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %d!\n", sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid); + ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %d!\n", + sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid); amount = item_list[i*2+0] = 1; } @@ -1298,21 +1334,27 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns return 3; } - vt += nd->u.shop.shop_item[j].value * amount; + vt += shop[j].value * amount; w += itemdb_weight(nameid) * amount; } if( w + sd->weight > sd->max_weight ) return 3; + if( pc->inventoryblank(sd) < new_ ) return 3; + if( points > vt ) points = vt; // Payment Process ---------------------------------------------------- - if( sd->kafraPoints < points || sd->cashPoints < (vt - points) ) - return 6; - pc->paycash(sd,vt,points); - + if( nd->subtype == SCRIPT && nd->u.scr.shop->type == NST_CUSTOM ) { + if( !npc->trader_pay(nd,sd,vt,points) ) + return 6; + } else { + if( sd->kafraPoints < points || sd->cashPoints < (vt - points) ) + return 6; + pc->paycash(sd,vt,points); + } // Delivery Process ---------------------------------------------------- for( i = 0; i < count; i++ ) { struct item item_tmp; @@ -1356,45 +1398,263 @@ int npc_buylist_sub(struct map_session_data* sd, int n, unsigned short* item_lis return 0; } +/** + * Loads persistent NPC Market Data from SQL + **/ +void npc_market_fromsql(void) { + SqlStmt* stmt = SQL->StmtMalloc(map->mysql_handle); + char name[NAME_LENGTH+1]; + 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`") + || SQL_ERROR == SQL->StmtExecute(stmt) + ) { + SqlStmt_ShowDebug(stmt); + SQL->StmtFree(stmt); + return; + } + + SQL->StmtBindColumn(stmt, 0, SQLDT_STRING, &name[0], sizeof(name), NULL, NULL); + SQL->StmtBindColumn(stmt, 1, SQLDT_INT, &itemid, 0, NULL, NULL); + SQL->StmtBindColumn(stmt, 2, SQLDT_INT, &amount, 0, NULL, NULL); + + while ( SQL_SUCCESS == SQL->StmtNextRow(stmt) ) { + struct npc_data *nd = NULL; + unsigned short i; + + if( !(nd = npc->name2id(name)) ) { + ShowError("npc_market_fromsql: NPC '%s' not found! skipping...\n",name); + npc->market_delfromsql_sub(name, USHRT_MAX); + continue; + } else if ( nd->subtype != SCRIPT || !nd->u.scr.shop || !nd->u.scr.shop->items || nd->u.scr.shop->type != NST_MARKET ) { + ShowError("npc_market_fromsql: NPC '%s' is not proper for market, skipping...\n",name); + npc->market_delfromsql_sub(name, USHRT_MAX); + continue; + } + + for(i = 0; i < nd->u.scr.shop->items; i++) { + if( nd->u.scr.shop->item[i].nameid == itemid ) { + nd->u.scr.shop->item[i].qty = amount; + break; + } + } + + if( i == nd->u.scr.shop->items ) { + ShowError("npc_market_fromsql: NPC '%s' does not sell item %d (qty %d), deleting...\n",name,itemid,amount); + npc->market_delfromsql_sub(name, itemid); + continue; + } + + } + + SQL->StmtFree(stmt); +} +/** + * 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) ) + 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) ) + 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) ) + Sql_ShowDebug(map->mysql_handle); + } +} +/** + * Removes persistent NPC Market Data from SQL + **/ +void npc_market_delfromsql(struct npc_data *nd, unsigned short index) { + npc->market_delfromsql_sub(nd->exname, index == USHRT_MAX ? index : nd->u.scr.shop->item[index].nameid); +} +/** + * Judges whether to allow and spawn a trader's window. + **/ +bool npc_trader_open(struct map_session_data *sd, struct npc_data *nd) { + + if( !nd->u.scr.shop || !nd->u.scr.shop->items ) + return false; + + switch( nd->u.scr.shop->type ) { + case NST_ZENY: + sd->state.callshop = 1; + clif->npcbuysell(sd,nd->bl.id); + return true;/* we skip sd->npc_shopid, npc->buysell will set it then when the player selects */ + case NST_MARKET: { + unsigned short i; + + for(i = 0; i < nd->u.scr.shop->items; i++) { + if( nd->u.scr.shop->item[i].qty ) + break; + } + + /* 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 */ + return false; + } + clif->npc_market_open(sd,nd); + } + break; + default: + clif->cashshop_show(sd,nd); + break; + } + + sd->npc_shopid = nd->bl.id; + + return true; +} +/** + * Creates (npc_data)->u.scr.shop and updates all duplicates across the server to match the created pointer + * + * @param master id of the original npc + **/ +void npc_trader_update(int master) { + DBIterator* iter; + struct block_list* bl; + struct npc_data *master_nd = map->id2nd(master); + + CREATE(master_nd->u.scr.shop,struct npc_shop_data,1); + + iter = db_iterator(map->id_db); + + for( bl = (struct block_list*)dbi_first(iter); dbi_exists(iter); bl = (struct block_list*)dbi_next(iter) ) { + if( bl->type == BL_NPC ) { + struct npc_data* nd = (struct npc_data*)bl; + + if( nd->src_id == master ) { + nd->u.scr.shop = master_nd->u.scr.shop; + } + } + } + + dbi_destroy(iter); +} +/** + * Tries to issue a CountFunds event to the shop. + * + * @param nd shop + * @param sd player + **/ +void npc_trader_count_funds(struct npc_data *nd, struct map_session_data *sd) { + char evname[EVENT_NAME_LENGTH]; + struct event_data *ev = NULL; + + npc->trader_funds[0] = npc->trader_funds[1] = 0;/* clear */ + + switch( nd->u.scr.shop->type ) { + case NST_CASH: + npc->trader_funds[0] = sd->cashPoints; + npc->trader_funds[1] = sd->kafraPoints; + return; + case NST_CUSTOM: + break; + default: + ShowError("npc_trader_count_funds: unsupported shop type %d\n",nd->u.scr.shop->type); + return; + } + + snprintf(evname, EVENT_NAME_LENGTH, "%s::OnCountFunds",nd->exname); + + if ( (ev = strdb_get(npc->ev_db, evname)) ) + script->run(ev->nd->u.scr.script, ev->pos, sd->bl.id, ev->nd->bl.id); + else + ShowError("npc_trader_count_funds: '%s' event '%s' not found, operation failed\n",nd->exname,evname); + + /* the callee will rely on npc->trader_funds, upon success script->run updates them */ +} +/** + * Tries to issue a payment to the NPC Event capable of handling it + * + * @param nd shop + * @param sd player + * @param price total cost + * @param points the amount input in the shop by the user to use from the secondary currency (if any is being employed) + * + * @return bool whether it was successful (if the script does not respond it will fail) + **/ +bool npc_trader_pay(struct npc_data *nd, struct map_session_data *sd, int price, int points) { + char evname[EVENT_NAME_LENGTH]; + struct event_data *ev = NULL; + + npc->trader_ok = false;/* clear */ + + snprintf(evname, EVENT_NAME_LENGTH, "%s::OnPayFunds",nd->exname); + + if ( (ev = strdb_get(npc->ev_db, evname)) ) { + pc->setreg(sd,script->add_str("@price"),price); + pc->setreg(sd,script->add_str("@points"),points); + + script->run(ev->nd->u.scr.script, ev->pos, sd->bl.id, ev->nd->bl.id); + } else + ShowError("npc_trader_pay: '%s' event '%s' not found, operation failed\n",nd->exname,evname); + + return npc->trader_ok;/* run script will deal with it */ +} /*========================================== * Cash Shop Buy *------------------------------------------*/ int npc_cashshop_buy(struct map_session_data *sd, int nameid, int amount, int points) { - struct npc_data *nd = (struct npc_data *)map->id2bl(sd->npc_shopid); + struct npc_data *nd = NULL; struct item_data *item; + struct npc_item_list *shop = NULL; int i, price, w; - + unsigned short shop_size = 0; + if( amount <= 0 ) return 5; if( points < 0 ) return 6; - if( !nd || nd->subtype != CASHSHOP ) - return 1; - if( sd->state.trading ) return 4; + + if( !(nd = (struct npc_data *)map->id2bl(sd->npc_shopid)) ) + return 1; if( (item = itemdb->exists(nameid)) == NULL ) return 5; // Invalid Item - ARR_FIND(0, nd->u.shop.count, i, nd->u.shop.shop_item[i].nameid == nameid); - if( i == nd->u.shop.count ) + 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; + } else { + shop = nd->u.shop.shop_item; + shop_size = nd->u.shop.count; + } + + ARR_FIND(0, shop_size, i, shop[i].nameid == nameid); + + if( i == shop_size ) return 5; - if( nd->u.shop.shop_item[i].value <= 0 ) + + if( shop[i].value <= 0 ) return 5; - if(!itemdb->isstackable(nameid) && amount > 1) - { + if(!itemdb->isstackable(nameid) && amount > 1) { ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %d!\n", sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid); amount = 1; } - switch( pc->checkadditem(sd, nameid, amount) ) - { + switch( pc->checkadditem(sd, nameid, amount) ) { case ADDITEM_NEW: if( pc->inventoryblank(sd) == 0 ) return 3; @@ -1407,26 +1667,31 @@ int npc_cashshop_buy(struct map_session_data *sd, int nameid, int amount, int po if( w + sd->weight > sd->max_weight ) return 3; - if( (double)nd->u.shop.shop_item[i].value * amount > INT_MAX ) { + if( (double)shop[i].value * amount > INT_MAX ) { ShowWarning("npc_cashshop_buy: Item '%s' (%d) price overflow attempt!\n", item->name, nameid); ShowDebug("(NPC:'%s' (%s,%d,%d), player:'%s' (%d/%d), value:%d, amount:%d)\n", 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, - nd->u.shop.shop_item[i].value, amount); + shop[i].value, amount); return 5; } - price = nd->u.shop.shop_item[i].value * amount; + price = shop[i].value * amount; + if( points > price ) points = price; - if( (sd->kafraPoints < points) || (sd->cashPoints < price - points) ) - return 6; - - pc->paycash(sd, price, points); + if( nd->subtype == SCRIPT && nd->u.scr.shop->type == NST_CUSTOM ) { + if( !npc->trader_pay(nd,sd,price,points) ) + return 6; + } else { + if( (sd->kafraPoints < points) || (sd->cashPoints < price - points) ) + return 6; + + pc->paycash(sd, price, points); + } - if( !pet->create_egg(sd, nameid) ) - { + if( !pet->create_egg(sd, nameid) ) { struct item item_tmp; memset(&item_tmp, 0, sizeof(struct item)); item_tmp.nameid = nameid; @@ -1444,104 +1709,115 @@ int npc_cashshop_buy(struct map_session_data *sd, int nameid, int amount, int po /// @return result code for clif->parse_NpcBuyListSend int npc_buylist(struct map_session_data* sd, int n, unsigned short* item_list) { struct npc_data* nd; + struct npc_item_list *shop = NULL; double z; int i,j,w,skill_t,new_, idx = skill->get_index(MC_DISCOUNT); - + unsigned short shop_size = 0; + nullpo_retr(3, sd); nullpo_retr(3, item_list); - + nd = npc->checknear(sd,map->id2bl(sd->npc_shopid)); if( nd == NULL ) return 3; - if( nd->subtype != SHOP ) - return 3; - + + if( nd->subtype != SHOP ) { + if( nd->subtype == SCRIPT && nd->u.scr.shop && nd->u.scr.shop->type == NST_ZENY ) { + shop = nd->u.scr.shop->item; + shop_size = nd->u.scr.shop->items; + } else + return 3; + } else { + shop = nd->u.shop.shop_item; + shop_size = nd->u.shop.count; + } + z = 0; w = 0; new_ = 0; // process entries in buy list, one by one for( i = 0; i < n; ++i ) { int nameid, amount, value; - + // find this entry in the shop's sell list - ARR_FIND( 0, nd->u.shop.count, j, - item_list[i*2+1] == nd->u.shop.shop_item[j].nameid || //Normal items - item_list[i*2+1] == itemdb_viewid(nd->u.shop.shop_item[j].nameid) //item_avail replacement - ); - - if( j == nd->u.shop.count ) + ARR_FIND( 0, shop_size, j, + item_list[i*2+1] == shop[j].nameid || //Normal items + item_list[i*2+1] == itemdb_viewid(shop[j].nameid) //item_avail replacement + ); + + if( j == shop_size ) return 3; // no such item in shop - + amount = item_list[i*2+0]; - nameid = item_list[i*2+1] = nd->u.shop.shop_item[j].nameid; //item_avail replacement - value = nd->u.shop.shop_item[j].value; - + nameid = item_list[i*2+1] = shop[j].nameid; //item_avail replacement + value = shop[j].value; + if( !itemdb->exists(nameid) ) return 3; // item no longer in itemdb - + if( !itemdb->isstackable(nameid) && amount > 1 ) { //Exploit? You can't buy more than 1 of equipment types o.O ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %d!\n", - sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid); + sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid); amount = item_list[i*2+0] = 1; } - + if( nd->master_nd ) { // Script-controlled shops decide by themselves, what can be bought and for what price. continue; } - + switch( pc->checkadditem(sd,nameid,amount) ) { case ADDITEM_EXIST: break; - + case ADDITEM_NEW: new_++; break; - + case ADDITEM_OVERAMOUNT: return 2; } - + value = pc->modifybuyvalue(sd,value); - + z += (double)value * amount; w += itemdb_weight(nameid) * amount; } - + if( nd->master_nd != NULL ) //Script-based shops. return npc->buylist_sub(sd,n,item_list,nd->master_nd); - + if( z > (double)sd->status.zeny ) return 1; // Not enough Zeny if( w + sd->weight > sd->max_weight ) return 2; // Too heavy if( pc->inventoryblank(sd) < new_ ) return 3; // Not enough space to store items - + pc->payzeny(sd,(int)z,LOG_TYPE_NPC, NULL); - + for( i = 0; i < n; ++i ) { int nameid = item_list[i*2+1]; int amount = item_list[i*2+0]; struct item item_tmp; - + if (itemdb_type(nameid) == IT_PETEGG) pet->create_egg(sd, nameid); else { memset(&item_tmp,0,sizeof(item_tmp)); item_tmp.nameid = nameid; item_tmp.identify = 1; - + pc->additem(sd,&item_tmp,amount,LOG_TYPE_NPC); } } - + // custom merchant shop exp bonus if( battle_config.shop_exp > 0 && z > 0 && (skill_t = pc->checkskill2(sd,idx)) > 0 ) { if( sd->status.skill[idx].flag >= SKILL_FLAG_REPLACED_LV_0 ) skill_t = sd->status.skill[idx].flag - SKILL_FLAG_REPLACED_LV_0; - + if( skill_t > 0 ) { z = z * (double)skill_t * (double)battle_config.shop_exp/10000.; if( z < 1 ) @@ -1549,10 +1825,120 @@ int npc_buylist(struct map_session_data* sd, int n, unsigned short* item_list) { pc->gainexp(sd,NULL,0,(int)z, false); } } - + return 0; } +/** + * parses incoming npc market purchase list + **/ +int npc_market_buylist(struct map_session_data* sd, unsigned short list_size, struct packet_npc_market_purchase *p) { + struct npc_data* nd; + struct npc_item_list *shop = NULL; + double z; + int i,j,w,new_; + unsigned short shop_size = 0; + + nullpo_retr(1, sd); + nullpo_retr(1, p); + + nd = npc->checknear(sd,map->id2bl(sd->npc_shopid)); + + if( nd == NULL || nd->subtype != SCRIPT || !list_size || !nd->u.scr.shop || nd->u.scr.shop->type != NST_MARKET ) + return 1; + + shop = nd->u.scr.shop->item; + shop_size = nd->u.scr.shop->items; + + z = 0; + w = 0; + new_ = 0; + + // process entries in buy list, one by one + for( i = 0; i < list_size; ++i ) { + int nameid, amount, value; + + // find this entry in the shop's sell list + ARR_FIND( 0, shop_size, j, + p->list[i].ITID == shop[j].nameid || //Normal items + p->list[i].ITID == itemdb_viewid(shop[j].nameid) //item_avail replacement + ); + + if( j == shop_size ) /* TODO find official response for this */ + return 1; // no such item in shop + + if( p->list[i].qty > shop[j].qty ) + return 1; + + amount = p->list[i].qty; + nameid = p->list[i].ITID = shop[j].nameid; //item_avail replacement + value = shop[j].value; + npc_market_qty[i] = j; + + if( !itemdb->exists(nameid) ) /* TODO find official response for this */ + return 1; // item no longer in itemdb + + if( !itemdb->isstackable(nameid) && amount > 1 ) { + //Exploit? You can't buy more than 1 of equipment types o.O + ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable item %d!\n", + sd->status.name, sd->status.account_id, sd->status.char_id, amount, nameid); + amount = p->list[i].qty = 1; + } + + switch( pc->checkadditem(sd,nameid,amount) ) { + case ADDITEM_EXIST: + break; + + case ADDITEM_NEW: + new_++; + break; + + case ADDITEM_OVERAMOUNT: /* TODO find official response for this */ + return 1; + } + + z += (double)value * amount; + w += itemdb_weight(nameid) * amount; + } + + if( z > (double)sd->status.zeny ) /* TODO find official response for this */ + return 1; // Not enough Zeny + + if( w + sd->weight > sd->max_weight ) /* TODO find official response for this */ + return 1; // Too heavy + + if( pc->inventoryblank(sd) < new_ ) /* TODO find official response for this */ + return 1; // Not enough space to store items + + pc->payzeny(sd,(int)z,LOG_TYPE_NPC, NULL); + + for( i = 0; i < list_size; ++i ) { + int nameid = p->list[i].ITID; + int amount = p->list[i].qty; + struct item item_tmp; + + j = npc_market_qty[i]; + + if( p->list[i].qty > shop[j].qty ) /* wohoo someone tampered with the packet. */ + return 1; + + shop[j].qty -= amount; + + npc->market_tosql(nd,j); + + if (itemdb_type(nameid) == IT_PETEGG) + pet->create_egg(sd, nameid); + else { + memset(&item_tmp,0,sizeof(item_tmp)); + item_tmp.nameid = nameid; + item_tmp.identify = 1; + + pc->additem(sd,&item_tmp,amount,LOG_TYPE_NPC); + } + } + + return 0; +} /// npc_selllist for script-controlled shops int npc_selllist_sub(struct map_session_data* sd, int n, unsigned short* item_list, struct npc_data* nd) @@ -1616,16 +2002,22 @@ int npc_selllist_sub(struct map_session_data* sd, int n, unsigned short* item_li /// @return result code for clif->parse_NpcSellListSend int npc_selllist(struct map_session_data* sd, int n, unsigned short* item_list) { double z; - int i,skill_t, idx = skill->get_index(MC_OVERCHARGE); + int i,skill_t, skill_idx = skill->get_index(MC_OVERCHARGE); struct npc_data *nd; nullpo_retr(1, sd); nullpo_retr(1, item_list); - if( ( nd = npc->checknear(sd, map->id2bl(sd->npc_shopid)) ) == NULL || nd->subtype != SHOP ) { + if( ( nd = npc->checknear(sd, map->id2bl(sd->npc_shopid)) ) == NULL ) { return 1; } + if( nd->subtype != SHOP ) { + if( !(nd->subtype == SCRIPT && nd->u.scr.shop && nd->u.scr.shop->type == NST_ZENY) ) + return 1; + } + + z = 0; // verify the sell list @@ -1680,9 +2072,9 @@ int npc_selllist(struct map_session_data* sd, int n, unsigned short* item_list) pc->getzeny(sd, (int)z, LOG_TYPE_NPC, NULL); // custom merchant shop exp bonus - if( battle_config.shop_exp > 0 && z > 0 && ( skill_t = pc->checkskill2(sd,idx) ) > 0) { - if( sd->status.skill[idx].flag >= SKILL_FLAG_REPLACED_LV_0 ) - skill_t = sd->status.skill[idx].flag - SKILL_FLAG_REPLACED_LV_0; + if( battle_config.shop_exp > 0 && z > 0 && ( skill_t = pc->checkskill2(sd,skill_idx) ) > 0) { + if( sd->status.skill[skill_idx].flag >= SKILL_FLAG_REPLACED_LV_0 ) + skill_t = sd->status.skill[skill_idx].flag - SKILL_FLAG_REPLACED_LV_0; if( skill_t > 0 ) { z = z * (double)skill_t * (double)battle_config.shop_exp/10000.; @@ -1765,6 +2157,8 @@ void npc_unload_duplicates(struct npc_data* nd) { //Removes an npc from map and db. //Single is to free name (for duplicates). int npc_unload(struct npc_data* nd, bool single) { + unsigned int i; + nullpo_ret(nd); npc->remove_map(nd); @@ -1790,8 +2184,11 @@ int npc_unload(struct npc_data* nd, bool single) { aFree(nd->path);/* remove now that no other instances exist */ } } + + if( single && nd->bl.m != -1 ) + map->remove_questinfo(nd->bl.m,nd); - if( (nd->subtype == SHOP || nd->subtype == CASHSHOP) && nd->src_id == 0) //src check for duplicate shops [Orcao] + if( nd->src_id == 0 && ( nd->subtype == SHOP || nd->subtype == CASHSHOP ) ) //src check for duplicate shops [Orcao] aFree(nd->u.shop.shop_item); else if( nd->subtype == SCRIPT ) { struct s_mapiterator* iter; @@ -1839,6 +2236,11 @@ int npc_unload(struct npc_data* nd, bool single) { nd->u.scr.label_list = NULL; nd->u.scr.label_list_num = 0; } + if(nd->u.scr.shop) { + if(nd->u.scr.shop->item) + aFree(nd->u.scr.shop->item); + aFree(nd->u.scr.shop); + } } if( nd->u.scr.guild_id ) guild->flag_remove(nd); @@ -1849,6 +2251,15 @@ int npc_unload(struct npc_data* nd, bool single) { nd->ud = NULL; } + for( i = 0; i < nd->hdatac; i++ ) { + if( nd->hdata[i]->flag.free ) { + aFree(nd->hdata[i]->data); + } + aFree(nd->hdata[i]); + } + if( nd->hdata ) + aFree(nd->hdata); + aFree(nd); return 0; @@ -1944,7 +2355,7 @@ void npc_parsename(struct npc_data* nd, const char* name, const char* start, con if( p ) { // <Display name>::<Unique name> size_t len = p-name; if( len > NAME_LENGTH ) { - ShowWarning("npc_parsename: Display name of '%s' is too long (len=%u) in file '%s', line'%d'. Truncating to %u characters.\n", name, (unsigned int)len, filepath, strline(buffer,start-buffer), NAME_LENGTH); + ShowWarning("npc_parsename: Display name of '%s' is too long (len=%u) in file '%s', line '%d'. Truncating to %u characters.\n", name, (unsigned int)len, filepath, strline(buffer,start-buffer), NAME_LENGTH); safestrncpy(nd->name, name, sizeof(nd->name)); } else { memcpy(nd->name, name, len); @@ -1952,19 +2363,19 @@ void npc_parsename(struct npc_data* nd, const char* name, const char* start, con } len = strlen(p+2); if( len > NAME_LENGTH ) - ShowWarning("npc_parsename: Unique name of '%s' is too long (len=%u) in file '%s', line'%d'. Truncating to %u characters.\n", name, (unsigned int)len, filepath, strline(buffer,start-buffer), NAME_LENGTH); + ShowWarning("npc_parsename: Unique name of '%s' is too long (len=%u) in file '%s', line '%d'. Truncating to %u characters.\n", name, (unsigned int)len, filepath, strline(buffer,start-buffer), NAME_LENGTH); safestrncpy(nd->exname, p+2, sizeof(nd->exname)); } else {// <Display name> size_t len = strlen(name); if( len > NAME_LENGTH ) - ShowWarning("npc_parsename: Name '%s' is too long (len=%u) in file '%s', line'%d'. Truncating to %u characters.\n", name, (unsigned int)len, filepath, strline(buffer,start-buffer), NAME_LENGTH); + ShowWarning("npc_parsename: Name '%s' is too long (len=%u) in file '%s', line '%d'. Truncating to %u characters.\n", name, (unsigned int)len, filepath, strline(buffer,start-buffer), NAME_LENGTH); safestrncpy(nd->name, name, sizeof(nd->name)); safestrncpy(nd->exname, name, sizeof(nd->exname)); } if( *nd->exname == '\0' || strstr(nd->exname,"::") != NULL ) {// invalid snprintf(newname, ARRAYLENGTH(newname), "0_%d_%d_%d", nd->bl.m, nd->bl.x, nd->bl.y); - ShowWarning("npc_parsename: Invalid unique name in file '%s', line'%d'. Renaming '%s' to '%s'.\n", filepath, strline(buffer,start-buffer), nd->exname, newname); + ShowWarning("npc_parsename: Invalid unique name in file '%s', line '%d'. Renaming '%s' to '%s'.\n", filepath, strline(buffer,start-buffer), nd->exname, newname); safestrncpy(nd->exname, newname, sizeof(nd->exname)); } @@ -1981,7 +2392,7 @@ void npc_parsename(struct npc_data* nd, const char* name, const char* start, con strcpy(this_mapname, (nd->bl.m == -1 ? "(not on a map)" : mapindex_id2name(map_id2index(nd->bl.m)))); strcpy(other_mapname, (dnd->bl.m == -1 ? "(not on a map)" : mapindex_id2name(map_id2index(dnd->bl.m)))); - ShowWarning("npc_parsename: Duplicate unique name in file '%s', line'%d'. Renaming '%s' to '%s'.\n", filepath, strline(buffer,start-buffer), nd->exname, newname); + ShowWarning("npc_parsename: Duplicate unique name in file '%s', line '%d'. Renaming '%s' to '%s'.\n", filepath, strline(buffer,start-buffer), nd->exname, newname); ShowDebug("this npc:\n display name '%s'\n unique name '%s'\n map=%s, x=%d, y=%d\n", nd->name, nd->exname, this_mapname, nd->bl.x, nd->bl.y); ShowDebug("other npc in '%s' :\n display name '%s'\n unique name '%s'\n map=%s, x=%d, y=%d\n",dnd->path, dnd->name, dnd->exname, other_mapname, dnd->bl.x, dnd->bl.y); safestrncpy(nd->exname, newname, sizeof(nd->exname)); @@ -2013,6 +2424,53 @@ void npc_parsename(struct npc_data* nd, const char* name, const char* start, con } } +// Parse View +// Support for using Constants in place of NPC View IDs. +int npc_parseview(const char* w4, const char* start, const char* buffer, const char* filepath) { + int val = -1, i = 0; + char viewid[1024]; // Max size of name from const.txt, see script->read_constdb. + + // Extract view ID / constant + while (w4[i] != '\0') { + if (ISSPACE(w4[i]) || w4[i] == '/' || w4[i] == ',') + break; + + i++; + } + + safestrncpy(viewid, w4, i+=1); + + // Check if view id is not an ID (only numbers). + if(!npc->viewisid(viewid)) + { + // Check if constant exists and get its value. + if(!script->get_constant(viewid, &val)) { + ShowWarning("npc_parseview: Invalid NPC constant '%s' specified in file '%s', line'%d'. Defaulting to INVISIBLE_CLASS. \n", viewid, filepath, strline(buffer,start-buffer)); + val = INVISIBLE_CLASS; + } + } else { + // NPC has an ID specified for view id. + val = atoi(w4); + } + + return val; +} + +// View is ID +// Checks if given view is an ID or constant. +bool npc_viewisid(const char * viewid) +{ + if(atoi(viewid) != -1) + { + // Loop through view, looking for non-numeric character. + while (*viewid) { + if (ISDIGIT(*viewid++) == 0) return false; + } + } + + return true; +} + //Add then display an npc warp on map struct npc_data* npc_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) { int i, flag = 0; @@ -2079,7 +2537,7 @@ const char* npc_parse_warp(char* w1, char* w2, char* w3, char* w4, const char* s } m = map->mapname2mapid(mapname); - i = mapindex_name2id(to_mapname); + i = mapindex->name2id(to_mapname); if( i == 0 ) { ShowError("npc_parse_warp: Unknown destination map in file '%s', line '%d' : %s\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), to_mapname, w1, w2, w3, w4); @@ -2157,7 +2615,7 @@ const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const char* s return strchr(start,'\n');;//try next } - if( !strcasecmp(w2,"cashshop") ) + if( strcmp(w2,"cashshop") == 0 ) type = CASHSHOP; else type = SHOP; @@ -2193,7 +2651,7 @@ const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const char* s } if( type == SHOP && value*0.75 < id->value_sell*1.24 ) {// Exploit possible: you can buy and sell back with profit - ShowWarning("npc_parse_shop: Item %s [%d] discounted buying price (%d->%d) is less than overcharged selling price (%d->%d) at file '%s', line '%d'.\n", + ShowWarning("npc_parse_shop: Item %s [%d] discounted buying price (%d->%d) is less than overcharged selling price (%d->%d) in file '%s', line '%d'.\n", id->name, nameid, value, (int)(value*0.75), id->value_sell, (int)(id->value_sell*1.24), filepath, strline(buffer,start-buffer)); } //for logs filters, atcommands and iteminfo script command @@ -2220,7 +2678,7 @@ const char* npc_parse_shop(char* w1, char* w2, char* w3, char* w4, const char* s nd->bl.y = y; nd->bl.id = npc->get_new_npc_id(); npc->parsename(nd, w3, start, buffer, filepath); - nd->class_ = m==-1?-1:atoi(w4); + nd->class_ = m == -1 ? -1 : npc->parseview(w4, start, buffer, filepath); nd->speed = 200; ++npc_shop; @@ -2250,7 +2708,7 @@ void npc_convertlabel_db(struct npc_label_list* label_list, const char *filepath int lpos = script->labels[i].pos; struct npc_label_list* label; const char *p; - int len; + size_t len; // In case of labels not terminated with ':', for user defined function support p = lname; @@ -2261,7 +2719,7 @@ void npc_convertlabel_db(struct npc_label_list* label_list, const char *filepath // here we check if the label fit into the buffer if( len > 23 ) { - ShowError("npc_parse_script: label name longer than 23 chars! '%s'\n (%s)", lname, filepath); + ShowError("npc_parse_script: label name longer than 23 chars! (%s) in file '%s'.\n", lname, filepath); return; } @@ -2285,7 +2743,7 @@ const char* npc_skip_script(const char* start, const char* buffer, const char* f p = strchr(start,'{'); if( p == NULL ) { - ShowError("npc_skip_script: Missing left curly in file '%s', line'%d'.", filepath, strline(buffer,start-buffer)); + ShowError("npc_skip_script: Missing left curly in file '%s', line '%d'.\n", filepath, strline(buffer,start-buffer)); return NULL;// can't continue } @@ -2321,7 +2779,7 @@ const char* npc_skip_script(const char* start, const char* buffer, const char* f } else if( *p == '\0' ) {// end of buffer - ShowError("Missing %d right curlys at file '%s', line '%d'.\n", curly_count, filepath, strline(buffer,p-buffer)); + ShowError("Missing %d right curlys in file '%s', line '%d'.\n", curly_count, filepath, strline(buffer,p-buffer)); return NULL;// can't continue } } @@ -2334,8 +2792,8 @@ const char* npc_skip_script(const char* start, const char* buffer, const char* f /// -%TAB%script%TAB%<NPC Name>%TAB%-1,{<code>} /// <map name>,<x>,<y>,<facing>%TAB%script%TAB%<NPC Name>%TAB%<sprite id>,{<code>} /// <map name>,<x>,<y>,<facing>%TAB%script%TAB%<NPC Name>%TAB%<sprite id>,<triggerX>,<triggerY>,{<code>} -const char* npc_parse_script(char* w1, char* w2, char* w3, char* w4, const char* start, const char* buffer, const char* filepath, bool runOnInit) { - int x, y, dir = 0, m, xs = 0, ys = 0, class_ = 0; // [Valaris] thanks to fov +const char* npc_parse_script(char* w1, char* w2, char* w3, char* w4, const char* start, const char* buffer, const char* filepath, int options) { + int x, y, dir = 0, m, xs = 0, ys = 0; // [Valaris] thanks to fov char mapname[32]; struct script_code *scriptroot; int i; @@ -2383,14 +2841,13 @@ const char* npc_parse_script(char* w1, char* w2, char* w3, char* w4, const char* CREATE(nd, struct npc_data, 1); - if( sscanf(w4, "%d,%d,%d", &class_, &xs, &ys) == 3 ) + if( sscanf(w4, "%*[^,],%d,%d", &xs, &ys) == 2 ) {// OnTouch area defined nd->u.scr.xs = xs; nd->u.scr.ys = ys; } else {// no OnTouch area - class_ = atoi(w4); nd->u.scr.xs = -1; nd->u.scr.ys = -1; } @@ -2401,12 +2858,15 @@ const char* npc_parse_script(char* w1, char* w2, char* w3, char* w4, const char* nd->bl.y = y; npc->parsename(nd, w3, start, buffer, filepath); nd->bl.id = npc->get_new_npc_id(); - nd->class_ = class_; + nd->class_ = m == -1 ? -1 : npc->parseview(w4, start, buffer, filepath); nd->speed = 200; nd->u.scr.script = scriptroot; nd->u.scr.label_list = label_list; nd->u.scr.label_list_num = label_list_num; - + if( options&NPO_TRADER ) + nd->u.scr.trader = true; + nd->u.scr.shop = NULL; + ++npc_script; nd->bl.type = BL_NPC; nd->subtype = SCRIPT; @@ -2417,7 +2877,7 @@ const char* npc_parse_script(char* w1, char* w2, char* w3, char* w4, const char* nd->dir = dir; npc->setcells(nd); map->addblock(&nd->bl); - if( class_ >= 0 ) { + if( nd->class_ >= 0 ) { status->set_viewdata(&nd->bl, nd->class_); if( map->list[nd->bl.m].users ) clif->spawn(&nd->bl); @@ -2432,7 +2892,7 @@ const char* npc_parse_script(char* w1, char* w2, char* w3, char* w4, const char* // Loop through labels to export them as necessary for (i = 0; i < nd->u.scr.label_list_num; i++) { if (npc->event_export(nd, i)) { - ShowWarning("npc_parse_script : duplicate event %s::%s (%s)\n", + ShowWarning("npc_parse_script: duplicate event %s::%s in file '%s'.\n", nd->exname, nd->u.scr.label_list[i].name, filepath); } npc->timerevent_export(nd, i); @@ -2440,7 +2900,7 @@ const char* npc_parse_script(char* w1, char* w2, char* w3, char* w4, const char* nd->u.scr.timerid = INVALID_TIMER; - if( runOnInit ) { + if( options&NPO_ONINIT ) { char evname[EVENT_NAME_LENGTH]; struct event_data *ev; @@ -2465,7 +2925,7 @@ const char* npc_parse_script(char* w1, char* w2, char* w3, char* w4, const char* /// npc: <map name>,<x>,<y>,<facing>%TAB%duplicate(<name of target>)%TAB%<NPC Name>%TAB%<sprite id>,<triggerX>,<triggerY> const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const char* start, const char* buffer, const char* filepath) { - int x, y, dir, m, xs = -1, ys = -1, class_ = 0; + int x, y, dir, m, xs = -1, ys = -1; char mapname[32]; char srcname[128]; int i; @@ -2483,14 +2943,14 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch // get the npc being duplicated if( w2[length-1] != ')' || length <= 11 || length-11 >= sizeof(srcname) ) {// does not match 'duplicate(%127s)', name is empty or too long - ShowError("npc_parse_script: bad duplicate name in file '%s', line '%d' : %s\n", filepath, strline(buffer,start-buffer), w2); + ShowError("npc_parse_script: bad duplicate name in file '%s', line '%d': %s\n", filepath, strline(buffer,start-buffer), w2); return end;// next line, try to continue } safestrncpy(srcname, w2+10, length-10); dnd = npc->name2id(srcname); if( dnd == NULL) { - ShowError("npc_parse_script: original npc not found for duplicate in file '%s', line '%d' : %s\n", filepath, strline(buffer,start-buffer), srcname); + ShowError("npc_parse_script: original npc not found for duplicate in file '%s', line '%d': %s\n", filepath, strline(buffer,start-buffer), srcname); return end;// next line, try to continue } src_id = dnd->bl.id; @@ -2501,8 +2961,10 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch x = y = dir = 0; m = -1; } else { - if( sscanf(w1, "%31[^,],%d,%d,%d", mapname, &x, &y, &dir) != 4 )// <map name>,<x>,<y>,<facing> - { + int fields = sscanf(w1, "%31[^,],%d,%d,%d", mapname, &x, &y, &dir); + if( type == WARP && fields == 3 ) { // <map name>,<x>,<y> + dir = 0; + } else if( fields != 4 ) {// <map name>,<x>,<y>,<facing> ShowError("npc_parse_duplicate: Invalid placement format for duplicate in file '%s', line '%d'. Skipping line...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4); return end;// next line, try to continue } @@ -2515,9 +2977,8 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch } if( type == WARP && sscanf(w4, "%d,%d", &xs, &ys) == 2 );// <spanx>,<spany> - else if( type == SCRIPT && sscanf(w4, "%d,%d,%d", &class_, &xs, &ys) == 3);// <sprite id>,<triggerX>,<triggerY> - else if( type != WARP ) class_ = atoi(w4);// <sprite id> - else { + else if( type == SCRIPT && sscanf(w4, "%*[^,],%d,%d", &xs, &ys) == 2);// <sprite id>,<triggerX>,<triggerY> + else if( type == WARP ) { ShowError("npc_parse_duplicate: Invalid span format for duplicate warp in file '%s', line '%d'. Skipping line...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4); return end;// next line, try to continue } @@ -2530,7 +2991,7 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch nd->bl.y = y; npc->parsename(nd, w3, start, buffer, filepath); nd->bl.id = npc->get_new_npc_id(); - nd->class_ = class_; + nd->class_ = m == -1 ? -1 : npc->parseview(w4, start, buffer, filepath); nd->speed = 200; nd->src_id = src_id; nd->bl.type = BL_NPC; @@ -2543,6 +3004,8 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch nd->u.scr.script = dnd->u.scr.script; nd->u.scr.label_list = dnd->u.scr.label_list; nd->u.scr.label_list_num = dnd->u.scr.label_list_num; + nd->u.scr.shop = dnd->u.scr.shop; + nd->u.scr.trader = dnd->u.scr.trader; break; case SHOP: @@ -2573,7 +3036,7 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch nd->dir = dir; npc->setcells(nd); map->addblock(&nd->bl); - if( class_ >= 0 ) { + if( nd->class_ >= 0 ) { status->set_viewdata(&nd->bl, nd->class_); if( map->list[nd->bl.m].users ) clif->spawn(&nd->bl); @@ -2591,7 +3054,7 @@ const char* npc_parse_duplicate(char* w1, char* w2, char* w3, char* w4, const ch // Loop through labels to export them as necessary for (i = 0; i < nd->u.scr.label_list_num; i++) { if (npc->event_export(nd, i)) { - ShowWarning("npc_parse_duplicate : duplicate event %s::%s (%s)\n", + ShowWarning("npc_parse_duplicate: duplicate event %s::%s in file '%s'.\n", nd->exname, nd->u.scr.label_list[i].name, filepath); } npc->timerevent_export(nd, i); @@ -2710,12 +3173,17 @@ void npc_unsetcells(struct npc_data* nd) { int16 m = nd->bl.m, x = nd->bl.x, y = nd->bl.y, xs, ys; int i,j, x0, x1, y0, y1; - if (nd->subtype == WARP) { - xs = nd->u.warp.xs; - ys = nd->u.warp.ys; - } else { - xs = nd->u.scr.xs; - ys = nd->u.scr.ys; + switch(nd->subtype) { + case WARP: + xs = nd->u.warp.xs; + ys = nd->u.warp.ys; + break; + case SCRIPT: + xs = nd->u.scr.xs; + ys = nd->u.scr.ys; + break; + default: + return; // Other types doesn't have touch area } if (m < 0 || xs < 0 || ys < 0 || map->list[m].cell == (struct mapcell *)0xdeadbeaf) @@ -2798,7 +3266,6 @@ int npc_do_atcmd_event(struct map_session_data* sd, const char* command, const c } if( sd->npc_id != 0 ) { // Enqueue the event trigger. - int i; ARR_FIND( 0, MAX_EVENTQUEUE, i, sd->eventqueue[i][0] == '\0' ); if( i < MAX_EVENTQUEUE ) { safestrncpy(sd->eventqueue[i],eventname,50); //Event enqueued. @@ -2874,7 +3341,7 @@ const char* npc_parse_function(char* w1, char* w2, char* w3, char* w4, const cha if (func_db->put(func_db, DB->str2key(w3), DB->ptr2data(scriptroot), &old_data)) { struct script_code *oldscript = (struct script_code*)DB->data2ptr(&old_data); - ShowInfo("npc_parse_function: Overwriting user function [%s] (%s:%d)\n", w3, filepath, strline(buffer,start-buffer)); + ShowWarning("npc_parse_function: Overwriting user function [%s] in file '%s', line '%d'.\n", w3, filepath, strline(buffer,start-buffer)); script->free_vars(oldscript->script_vars); aFree(oldscript->script_buf); aFree(oldscript); @@ -2910,7 +3377,7 @@ const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const char* st memset(&mobspawn, 0, sizeof(struct spawn_data)); - mobspawn.state.boss = !strcmpi(w2,"boss_monster"); + mobspawn.state.boss = (strcmp(w2,"boss_monster") == 0 ? 1 : 0); // w1=<map name>,<x>,<y>,<xs>,<ys> // w3=<mob name>{,<mob level>} @@ -2922,7 +3389,7 @@ const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const char* st ShowError("npc_parse_mob: Invalid mob definition in file '%s', line '%d'.\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4); return strchr(start,'\n');// skip and continue } - if( mapindex_name2id(mapname) == 0 ) { + if( mapindex->name2id(mapname) == 0 ) { ShowError("npc_parse_mob: Unknown map '%s' in file '%s', line '%d'.\n", mapname, filepath, strline(buffer,start-buffer)); return strchr(start,'\n');// skip and continue } @@ -2932,33 +3399,33 @@ const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const char* st mobspawn.m = (unsigned short)m; if( x < 0 || x >= map->list[mobspawn.m].xs || y < 0 || y >= map->list[mobspawn.m].ys ) { - ShowError("npc_parse_mob: Spawn coordinates out of range: %s (%d,%d), map size is (%d,%d) - %s %s (file '%s', line '%d').\n", map->list[mobspawn.m].name, x, y, (map->list[mobspawn.m].xs-1), (map->list[mobspawn.m].ys-1), w1, w3, filepath, strline(buffer,start-buffer)); + ShowError("npc_parse_mob: Spawn coordinates out of range: %s (%d,%d), map size is (%d,%d) - %s %s in file '%s', line '%d'.\n", map->list[mobspawn.m].name, x, y, (map->list[mobspawn.m].xs-1), (map->list[mobspawn.m].ys-1), w1, w3, filepath, strline(buffer,start-buffer)); return strchr(start,'\n');// skip and continue } // check monster ID if exists! if( mob->db_checkid(class_) == 0 ) { - ShowError("npc_parse_mob: Unknown mob ID %d (file '%s', line '%d').\n", class_, filepath, strline(buffer,start-buffer)); + ShowError("npc_parse_mob: Unknown mob ID %d in file '%s', line '%d'.\n", class_, filepath, strline(buffer,start-buffer)); return strchr(start,'\n');// skip and continue } if( num < 1 || num > 1000 ) { - ShowError("npc_parse_mob: Invalid number of monsters %d, must be inside the range [1,1000] (file '%s', line '%d').\n", num, filepath, strline(buffer,start-buffer)); + ShowError("npc_parse_mob: Invalid number of monsters %d, must be inside the range [1,1000] in file '%s', line '%d'.\n", num, filepath, strline(buffer,start-buffer)); return strchr(start,'\n');// skip and continue } if( (mobspawn.state.size < 0 || mobspawn.state.size > 2) && size != -1 ) { - ShowError("npc_parse_mob: Invalid size number %d for mob ID %d (file '%s', line '%d').\n", mobspawn.state.size, class_, filepath, strline(buffer, start - buffer)); + ShowError("npc_parse_mob: Invalid size number %d for mob ID %d in file '%s', line '%d'.\n", mobspawn.state.size, class_, filepath, strline(buffer, start - buffer)); return strchr(start, '\n'); } if( (mobspawn.state.ai < 0 || mobspawn.state.ai > 4) && ai != -1 ) { - ShowError("npc_parse_mob: Invalid ai %d for mob ID %d (file '%s', line '%d').\n", mobspawn.state.ai, class_, filepath, strline(buffer, start - buffer)); + ShowError("npc_parse_mob: Invalid ai %d for mob ID %d in file '%s', line '%d'.\n", mobspawn.state.ai, class_, filepath, strline(buffer, start - buffer)); return strchr(start, '\n'); } if( (mob_lv == 0 || mob_lv > MAX_LEVEL) && mob_lv != -1 ) { - ShowError("npc_parse_mob: Invalid level %d for mob ID %d (file '%s', line '%d').\n", mob_lv, class_, filepath, strline(buffer, start - buffer)); + ShowError("npc_parse_mob: Invalid level %d for mob ID %d in file '%s', line '%d'.\n", mob_lv, class_, filepath, strline(buffer, start - buffer)); return strchr(start, '\n'); } @@ -2988,7 +3455,7 @@ const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const char* st } if(mobspawn.delay1>0xfffffff || mobspawn.delay2>0xfffffff) { - ShowError("npc_parse_mob: Invalid spawn delays %u %u (file '%s', line '%d').\n", mobspawn.delay1, mobspawn.delay2, filepath, strline(buffer,start-buffer)); + ShowError("npc_parse_mob: Invalid spawn delays %u %u in file '%s', line '%d'.\n", mobspawn.delay1, mobspawn.delay2, filepath, strline(buffer,start-buffer)); return strchr(start,'\n');// skip and continue } @@ -3002,7 +3469,7 @@ const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const char* st //Verify dataset. if( !mob->parse_dataset(&mobspawn) ) { - ShowError("npc_parse_mob: Invalid dataset for monster ID %d (file '%s', line '%d').\n", class_, filepath, strline(buffer,start-buffer)); + ShowError("npc_parse_mob: Invalid dataset for monster ID %d in file '%s', line '%d'.\n", class_, filepath, strline(buffer,start-buffer)); return strchr(start,'\n');// skip and continue } @@ -3087,16 +3554,16 @@ const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, const char int savex, savey; if (state == 0) ; //Map flag disabled. - else if (!strcmpi(w4, "SavePoint")) { + else if (w4 && !strcmpi(w4, "SavePoint")) { map->list[m].save.map = 0; map->list[m].save.x = -1; map->list[m].save.y = -1; } else if (sscanf(w4, "%31[^,],%d,%d", savemap, &savex, &savey) == 3) { - map->list[m].save.map = mapindex_name2id(savemap); + map->list[m].save.map = mapindex->name2id(savemap); map->list[m].save.x = savex; map->list[m].save.y = savey; if (!map->list[m].save.map) { - ShowWarning("npc_parse_mapflag: Specified save point map '%s' for mapflag 'nosave' not found (file '%s', line '%d'), using 'SavePoint'.\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", savemap, filepath, strline(buffer,start-buffer), w1, w2, w3, w4); + ShowWarning("npc_parse_mapflag: Specified save point map '%s' for mapflag 'nosave' not found in file '%s', line '%d', using 'SavePoint'.\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", savemap, filepath, strline(buffer,start-buffer), w1, w2, w3, w4); map->list[m].save.x = -1; map->list[m].save.y = -1; } @@ -3134,11 +3601,11 @@ const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, const char map->list[m].flag.gvg = 0; map->list[m].flag.gvg_dungeon = 0; map->list[m].flag.gvg_castle = 0; - ShowWarning("npc_parse_mapflag: You can't set PvP and GvG flags for the same map! Removing GvG flags from %s (file '%s', line '%d').\n", map->list[m].name, filepath, strline(buffer,start-buffer)); + ShowWarning("npc_parse_mapflag: You can't set PvP and GvG flags for the same map! Removing GvG flags from %s in file '%s', line '%d'.\n", map->list[m].name, filepath, strline(buffer,start-buffer)); } if( state && map->list[m].flag.battleground ) { map->list[m].flag.battleground = 0; - ShowWarning("npc_parse_mapflag: You can't set PvP and BattleGround flags for the same map! Removing BattleGround flag from %s (file '%s', line '%d').\n", map->list[m].name, filepath, strline(buffer,start-buffer)); + ShowWarning("npc_parse_mapflag: You can't set PvP and BattleGround flags for the same map! Removing BattleGround flag from %s in file '%s', line '%d'.\n", map->list[m].name, filepath, strline(buffer,start-buffer)); } if( state && (zone = strdb_get(map->zone_db, MAP_ZONE_PVP_NAME)) && map->list[m].zone != zone ) { map->zone_change(m,zone,start,buffer,filepath); @@ -3184,11 +3651,11 @@ const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, const char map->list[m].flag.gvg = state; if( state && map->list[m].flag.pvp ) { map->list[m].flag.pvp = 0; - ShowWarning("npc_parse_mapflag: You can't set PvP and GvG flags for the same map! Removing PvP flag from %s (file '%s', line '%d').\n", map->list[m].name, filepath, strline(buffer,start-buffer)); + ShowWarning("npc_parse_mapflag: You can't set PvP and GvG flags for the same map! Removing PvP flag from %s in file '%s', line '%d'.\n", map->list[m].name, filepath, strline(buffer,start-buffer)); } if( state && map->list[m].flag.battleground ) { map->list[m].flag.battleground = 0; - ShowWarning("npc_parse_mapflag: You can't set GvG and BattleGround flags for the same map! Removing BattleGround flag from %s (file '%s', line '%d').\n", map->list[m].name, filepath, strline(buffer,start-buffer)); + ShowWarning("npc_parse_mapflag: You can't set GvG and BattleGround flags for the same map! Removing BattleGround flag from %s in file '%s', line '%d'.\n", map->list[m].name, filepath, strline(buffer,start-buffer)); } if( state && (zone = strdb_get(map->zone_db, MAP_ZONE_GVG_NAME)) && map->list[m].zone != zone ) { map->zone_change(m,zone,start,buffer,filepath); @@ -3216,13 +3683,13 @@ const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, const char if( map->list[m].flag.battleground && map->list[m].flag.pvp ) { map->list[m].flag.pvp = 0; - ShowWarning("npc_parse_mapflag: You can't set PvP and BattleGround flags for the same map! Removing PvP flag from %s (file '%s', line '%d').\n", map->list[m].name, filepath, strline(buffer,start-buffer)); + ShowWarning("npc_parse_mapflag: You can't set PvP and BattleGround flags for the same map! Removing PvP flag from %s in file '%s', line '%d'.\n", map->list[m].name, filepath, strline(buffer,start-buffer)); } if( map->list[m].flag.battleground && (map->list[m].flag.gvg || map->list[m].flag.gvg_dungeon || map->list[m].flag.gvg_castle) ) { map->list[m].flag.gvg = 0; map->list[m].flag.gvg_dungeon = 0; map->list[m].flag.gvg_castle = 0; - ShowWarning("npc_parse_mapflag: You can't set GvG and BattleGround flags for the same map! Removing GvG flag from %s (file '%s', line '%d').\n", map->list[m].name, filepath, strline(buffer,start-buffer)); + ShowWarning("npc_parse_mapflag: You can't set GvG and BattleGround flags for the same map! Removing GvG flag from %s in file '%s', line '%d'.\n", map->list[m].name, filepath, strline(buffer,start-buffer)); } if( state && (zone = strdb_get(map->zone_db, MAP_ZONE_BG_NAME)) && map->list[m].zone != zone ) { @@ -3309,10 +3776,11 @@ const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, const char else if (!strcmpi(w3,"adjust_unit_duration")) { int skill_id, k; char skill_name[MAP_ZONE_MAPFLAG_LENGTH], modifier[MAP_ZONE_MAPFLAG_LENGTH]; - int len = strlen(w4); + size_t len = w4 ? strlen(w4) : 0; modifier[0] = '\0'; - memcpy(skill_name, w4, MAP_ZONE_MAPFLAG_LENGTH); + if( w4 ) + memcpy(skill_name, w4, MAP_ZONE_MAPFLAG_LENGTH); for(k = 0; k < len; k++) { if( skill_name[k] == '\t' ) { @@ -3323,11 +3791,11 @@ const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, const char } if( modifier[0] == '\0' ) { - ShowWarning("npc_parse_mapflag: Missing 5th param for 'adjust_unit_duration' flag! removing flag from %s (file '%s', line '%d').\n", map->list[m].name, filepath, strline(buffer,start-buffer)); + ShowWarning("npc_parse_mapflag: Missing 5th param for 'adjust_unit_duration' flag! removing flag from %s in file '%s', line '%d'.\n", map->list[m].name, filepath, strline(buffer,start-buffer)); } else if( !( skill_id = skill->name2id(skill_name) ) || !skill->get_unit_id( skill->name2id(skill_name), 0) ) { - ShowWarning("npc_parse_mapflag: Unknown skill (%s) for 'adjust_unit_duration' flag! removing flag from %s (file '%s', line '%d').\n",skill_name, map->list[m].name, filepath, strline(buffer,start-buffer)); + ShowWarning("npc_parse_mapflag: Unknown skill (%s) for 'adjust_unit_duration' flag! removing flag from %s in file '%s', line '%d'.\n",skill_name, map->list[m].name, filepath, strline(buffer,start-buffer)); } else if ( atoi(modifier) < 1 || atoi(modifier) > USHRT_MAX ) { - ShowWarning("npc_parse_mapflag: Invalid modifier '%d' for skill '%s' for 'adjust_unit_duration' flag! removing flag from %s (file '%s', line '%d').\n", atoi(modifier), skill_name, map->list[m].name, filepath, strline(buffer,start-buffer)); + ShowWarning("npc_parse_mapflag: Invalid modifier '%d' for skill '%s' for 'adjust_unit_duration' flag! removing flag from %s in file '%s', line '%d'.\n", atoi(modifier), skill_name, map->list[m].name, filepath, strline(buffer,start-buffer)); } else { int idx = map->list[m].unit_count; @@ -3363,10 +3831,12 @@ const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, const char } else if (!strcmpi(w3,"adjust_skill_damage")) { int skill_id, k; char skill_name[MAP_ZONE_MAPFLAG_LENGTH], modifier[MAP_ZONE_MAPFLAG_LENGTH]; - int len = strlen(w4); + size_t len = w4 ? strlen(w4) : 0; modifier[0] = '\0'; - memcpy(skill_name, w4, MAP_ZONE_MAPFLAG_LENGTH); + + if( w4 ) + memcpy(skill_name, w4, MAP_ZONE_MAPFLAG_LENGTH); for(k = 0; k < len; k++) { if( skill_name[k] == '\t' ) { @@ -3377,11 +3847,11 @@ const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, const char } if( modifier[0] == '\0' ) { - ShowWarning("npc_parse_mapflag: Missing 5th param for 'adjust_skill_damage' flag! removing flag from %s (file '%s', line '%d').\n", map->list[m].name, filepath, strline(buffer,start-buffer)); + ShowWarning("npc_parse_mapflag: Missing 5th param for 'adjust_skill_damage' flag! removing flag from %s in file '%s', line '%d'.\n", map->list[m].name, filepath, strline(buffer,start-buffer)); } else if( !( skill_id = skill->name2id(skill_name) ) ) { - ShowWarning("npc_parse_mapflag: Unknown skill (%s) for 'adjust_skill_damage' flag! removing flag from %s (file '%s', line '%d').\n", skill_name, map->list[m].name, filepath, strline(buffer,start-buffer)); + ShowWarning("npc_parse_mapflag: Unknown skill (%s) for 'adjust_skill_damage' flag! removing flag from %s in file '%s', line '%d'.\n", skill_name, map->list[m].name, filepath, strline(buffer,start-buffer)); } else if ( atoi(modifier) < 1 || atoi(modifier) > USHRT_MAX ) { - ShowWarning("npc_parse_mapflag: Invalid modifier '%d' for skill '%s' for 'adjust_skill_damage' flag! removing flag from %s (file '%s', line '%d').\n", atoi(modifier), skill_name, map->list[m].name, filepath, strline(buffer,start-buffer)); + ShowWarning("npc_parse_mapflag: Invalid modifier '%d' for skill '%s' for 'adjust_skill_damage' flag! removing flag from %s in file '%s', line '%d'.\n", atoi(modifier), skill_name, map->list[m].name, filepath, strline(buffer,start-buffer)); } else { int idx = map->list[m].skill_count; @@ -3419,7 +3889,7 @@ const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, const char struct map_zone_data *zone; if( !(zone = strdb_get(map->zone_db, w4)) ) { - ShowWarning("npc_parse_mapflag: Invalid zone '%s'! removing flag from %s (file '%s', line '%d').\n", w4, map->list[m].name, filepath, strline(buffer,start-buffer)); + ShowWarning("npc_parse_mapflag: Invalid zone '%s'! removing flag from %s in file '%s', line '%d'.\n", w4, map->list[m].name, filepath, strline(buffer,start-buffer)); } else if( map->list[m].zone != zone ) { map->zone_change(m,zone,start,buffer,filepath); } @@ -3439,16 +3909,19 @@ const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, const char map->list[m].short_damage_rate = (state) ? atoi(w4) : 100; } else if ( !strcmpi(w3,"long_damage_rate") ) { map->list[m].long_damage_rate = (state) ? atoi(w4) : 100; + } else if ( !strcmpi(w3,"src4instance") ) { + map->list[m].flag.src4instance = (state) ? 1 : 0; + } else if ( !strcmpi(w3,"nocashshop") ) { + map->list[m].flag.nocashshop = (state) ? 1 : 0; } else - ShowError("npc_parse_mapflag: unrecognized mapflag '%s' (file '%s', line '%d').\n", w3, filepath, strline(buffer,start-buffer)); + ShowError("npc_parse_mapflag: unrecognized mapflag '%s' in file '%s', line '%d'.\n", w3, filepath, strline(buffer,start-buffer)); return strchr(start,'\n');// continue } //Read file and create npc/func/mapflag/monster... accordingly. //@runOnInit should we exec OnInit when it's done ? -void npc_parsesrcfile(const char* filepath, bool runOnInit) -{ +int npc_parsesrcfile(const char* filepath, bool runOnInit) { int16 m, x, y; int lines = 0; FILE* fp; @@ -3461,7 +3934,7 @@ void npc_parsesrcfile(const char* filepath, bool runOnInit) if( fp == NULL ) { ShowError("npc_parsesrcfile: File not found '%s'.\n", filepath); - return; + return -1; } fseek(fp, 0, SEEK_END); len = ftell(fp); @@ -3474,7 +3947,7 @@ void npc_parsesrcfile(const char* filepath, bool runOnInit) ShowError("npc_parsesrcfile: Failed to read file '%s' - %s\n", filepath, strerror(errno)); aFree(buffer); fclose(fp); - return; + return -1; } fclose(fp); @@ -3487,7 +3960,7 @@ void npc_parsesrcfile(const char* filepath, bool runOnInit) lines++; // w1<TAB>w2<TAB>w3<TAB>w4 - count = sv->parse(p, len+buffer-p, 0, '\t', pos, ARRAYLENGTH(pos), (e_svopt)(SV_TERMINATE_LF|SV_TERMINATE_CRLF)); + count = sv->parse(p, (int)(len+buffer-p), 0, '\t', pos, ARRAYLENGTH(pos), (e_svopt)(SV_TERMINATE_LF|SV_TERMINATE_CRLF)); if( count < 0 ) { ShowError("npc_parsesrcfile: Parse error in file '%s', line '%d'. Stopping...\n", filepath, strline(buffer,p-buffer)); @@ -3529,15 +4002,15 @@ void npc_parsesrcfile(const char* filepath, bool runOnInit) break; } - if( strcmp(w1,"-") !=0 && strcasecmp(w1,"function") != 0 ) + if( strcmp(w1,"-") != 0 && strcmp(w1,"function") != 0 ) {// w1 = <map name>,<x>,<y>,<facing> char mapname[MAP_NAME_LENGTH*2]; x = y = 0; sscanf(w1,"%23[^,],%hd,%hd[^,]",mapname,&x,&y); - if( !mapindex_name2id(mapname) ) + if( !mapindex->name2id(mapname) ) {// Incorrect map, we must skip the script info... ShowError("npc_parsesrcfile: Unknown map '%s' in file '%s', line '%d'. Skipping line...\n", mapname, filepath, strline(buffer,p-buffer)); - if( strcasecmp(w2,"script") == 0 && count > 3 ) + if( strcmp(w2,"script") == 0 && count > 3 ) { if((p = npc->skip_script(p,buffer,filepath)) == NULL) { @@ -3550,7 +4023,7 @@ void npc_parsesrcfile(const char* filepath, bool runOnInit) m = map->mapname2mapid(mapname); if( m < 0 ) { // "mapname" is not assigned to this server, we must skip the script info... - if( strcasecmp(w2,"script") == 0 && count > 3 ) + if( strcmp(w2,"script") == 0 && count > 3 ) { if((p = npc->skip_script(p,buffer,filepath)) == NULL) { @@ -3562,7 +4035,7 @@ void npc_parsesrcfile(const char* filepath, bool runOnInit) } if (x < 0 || x >= map->list[m].xs || y < 0 || y >= map->list[m].ys) { ShowError("npc_parsesrcfile: Unknown coordinates ('%d', '%d') for map '%s' in file '%s', line '%d'. Skipping line...\n", x, y, mapname, filepath, strline(buffer,p-buffer)); - if( strcasecmp(w2,"script") == 0 && count > 3 ) + if( strcmp(w2,"script") == 0 && count > 3 ) { if((p = npc->skip_script(p,buffer,filepath)) == NULL) { @@ -3574,42 +4047,65 @@ void npc_parsesrcfile(const char* filepath, bool runOnInit) } } - if( strcasecmp(w2,"warp") == 0 && count > 3 ) + if( strcmp(w2,"warp") == 0 && count > 3 ) { p = npc->parse_warp(w1,w2,w3,w4, p, buffer, filepath); } - else if( (!strcasecmp(w2,"shop") || !strcasecmp(w2,"cashshop")) && count > 3 ) + else if( (strcmp(w2,"shop") == 0 || strcmp(w2,"cashshop") == 0) && count > 3 ) { p = npc->parse_shop(w1,w2,w3,w4, p, buffer, filepath); } - else if( strcasecmp(w2,"script") == 0 && count > 3 ) + else if( strcmp(w2,"script") == 0 && count > 3 ) { - if( strcasecmp(w1,"function") == 0 ) + if( strcmp(w1,"function") == 0 ) { p = npc->parse_function(w1, w2, w3, w4, p, buffer, filepath); - else - p = npc->parse_script(w1,w2,w3,w4, p, buffer, filepath,runOnInit); + } else { +#ifdef ENABLE_CASE_CHECK + if( strcasecmp(w1, "function") == 0 ) DeprecationWarning("npc_parsesrcfile", w1, "function", filepath, strline(buffer, p-buffer)); // TODO +#endif // ENABLE_CASE_CHECK + p = npc->parse_script(w1,w2,w3,w4, p, buffer, filepath,runOnInit?NPO_ONINIT:NPO_NONE); + } + } + else if( strcmp(w2,"trader") == 0 && count > 3 ) { + p = npc->parse_script(w1,w2,w3,w4, p, buffer, filepath,(runOnInit?NPO_ONINIT:NPO_NONE)|NPO_TRADER); } else if( (i=0, sscanf(w2,"duplicate%n",&i), (i > 0 && w2[i] == '(')) && count > 3 ) { p = npc->parse_duplicate(w1,w2,w3,w4, p, buffer, filepath); } - else if( (strcmpi(w2,"monster") == 0 || strcmpi(w2,"boss_monster") == 0) && count > 3 ) + else if( (strcmp(w2,"monster") == 0 || strcmp(w2,"boss_monster") == 0) && count > 3 ) { p = npc->parse_mob(w1, w2, w3, w4, p, buffer, filepath); } - else if( strcmpi(w2,"mapflag") == 0 && count >= 3 ) + else if( strcmp(w2,"mapflag") == 0 && count >= 3 ) { p = npc->parse_mapflag(w1, w2, trim(w3), trim(w4), p, buffer, filepath); } else { +#ifdef ENABLE_CASE_CHECK + if( strcasecmp(w2, "warp") == 0 ) { DeprecationWarning("npc_parsesrcfile", w2, "warp", filepath, strline(buffer, p-buffer)); } // TODO + else if( strcasecmp(w2,"shop") == 0 ) { DeprecationWarning("npc_parsesrcfile", w2, "shop", filepath, strline(buffer, p-buffer)); } // TODO + else if( strcasecmp(w2,"cashshop") == 0 ) { DeprecationWarning("npc_parsesrcfile", w2, "cashshop", filepath, strline(buffer, p-buffer)); } // TODO + else if( strcasecmp(w2, "script") == 0 ) { DeprecationWarning("npc_parsesrcfile", w2, "script", filepath, strline(buffer, p-buffer)); } // TODO + else if( strcasecmp(w2,"trader") == 0 ) DeprecationWarning("npc_parsesrcfile", w2, "trader", filepath, strline(buffer, p-buffer)) // TODO + else if( strncasecmp(w2, "duplicate", 9) == 0 ) { + char temp[10]; + safestrncpy(temp, w2, 10); + DeprecationWarning("npc_parsesrcfile", temp, "duplicate", filepath, strline(buffer, p-buffer)); // TODO + } + else if( strcasecmp(w2,"monster") == 0 ) { DeprecationWarning("npc_parsesrcfile", w2, "monster", filepath, strline(buffer, p-buffer)); } // TODO: + else if( strcasecmp(w2,"boss_monster") == 0 ) { DeprecationWarning("npc_parsesrcfile", w2, "boss_monster", filepath, strline(buffer, p-buffer)); } // TODO + else if( strcasecmp(w2, "mapflag") == 0 ) { DeprecationWarning("npc_parsesrcfile", w2, "mapflag", filepath, strline(buffer, p-buffer)); } // TODO + else +#endif // ENABLE_CASE_CHECK ShowError("npc_parsesrcfile: Unable to parse, probably a missing or extra TAB in file '%s', line '%d'. Skipping line...\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,p-buffer), w1, w2, w3, w4); p = strchr(p,'\n');// skip and continue } } aFree(buffer); - return; + return 0; } int npc_script_event(struct map_session_data* sd, enum npce_event type) @@ -3666,11 +4162,15 @@ void npc_read_event_script(void) break; } - if( (p=strchr(p,':')) && p && strcmpi(name,p)==0 ) + if( (p=strchr(p,':')) && strcmp(name,p) == 0 ) { script_event[i].event[count] = ed; script_event[i].event_name[count] = key.str; script_event[i].event_count++; +#ifdef ENABLE_CASE_CHECK + } else if( p && strcasecmp(name, p) == 0 ) { + DeprecationWarning2("npc_read_event_script", p, name, config[i].event_name); // TODO +#endif // ENABLE_CASE_CHECK } } dbi_destroy(iter); @@ -3782,12 +4282,10 @@ int npc_reload(void) { "\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); - + itemdb->name_constants(); - - for(i = 0; i < instance->instances; i++) { - instance->destroy(i); - } + + instance->reload(); map->zone_init(); @@ -3803,6 +4301,8 @@ int npc_reload(void) { //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 rest of the startup events if connected to char-server. [Lance] if(!intif->CheckForCharServer()){ ShowStatus("Event '"CL_WHITE"OnInterIfInit"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n", npc->event_doall("OnInterIfInit")); @@ -3818,7 +4318,7 @@ bool npc_unloadfile( const char* filepath ) { bool found = false; for( nd = dbi_first(iter); dbi_exists(iter); nd = dbi_next(iter) ) { - if( nd->path && strcasecmp(nd->path,filepath) == 0 ) { + if( nd->path && strcasecmp(nd->path,filepath) == 0 ) { // FIXME: This can break in case-sensitive file systems found = true; npc->unload_duplicates(nd);/* unload any npcs which could duplicate this but be in a different file */ npc->unload(nd, true); @@ -3888,8 +4388,7 @@ static void npc_debug_warps(void) { /*========================================== * npc initialization *------------------------------------------*/ -int do_init_npc(void) -{ +int do_init_npc(bool minimal) { struct npc_src_list *file; int i; @@ -3911,48 +4410,52 @@ int do_init_npc(void) for( i = MAX_NPC_CLASS2_START; i < MAX_NPC_CLASS2_END; i++ ) npc_viewdb2[i - MAX_NPC_CLASS2_START].class_ = i; - npc->ev_db = stridb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, EVENT_NAME_LENGTH); - npc->ev_label_db = stridb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, NAME_LENGTH); + npc->ev_db = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, EVENT_NAME_LENGTH); + npc->ev_label_db = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, NAME_LENGTH); npc->name_db = strdb_alloc(DB_OPT_BASE, NAME_LENGTH); npc->path_db = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, 0); - npc->timer_event_ers = ers_new(sizeof(struct timer_event_data),"clif.c::timer_event_ers",ERS_OPT_NONE); - npc_last_npd = NULL; npc_last_path = NULL; npc_last_ref = NULL; - // 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); + 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); } - 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); - - itemdb->name_constants(); - map->zone_init(); + itemdb->name_constants(); + + if (!minimal) { + map->zone_init(); - npc->motd = npc->name2id("HerculesMOTD"); /* [Ind/Hercules] */ + npc->motd = npc->name2id("HerculesMOTD"); /* [Ind/Hercules] */ - // set up the events cache - memset(script_event, 0, sizeof(script_event)); - npc->read_event_script(); + // set up the events cache + memset(script_event, 0, sizeof(script_event)); + npc->read_event_script(); - //Debug function to locate all endless loop warps. - if (battle_config.warp_point_debug) - npc->debug_warps(); + //Debug function to locate all endless loop warps. + if (battle_config.warp_point_debug) + npc->debug_warps(); - timer->add_func_list(npc->event_do_clock,"npc_event_do_clock"); - timer->add_func_list(npc->timerevent,"npc_timerevent"); + timer->add_func_list(npc->event_do_clock,"npc_event_do_clock"); + timer->add_func_list(npc->timerevent,"npc_timerevent"); + } // Init dummy NPC npc->fake_nd = (struct npc_data *)aCalloc(1,sizeof(struct npc_data)); @@ -3986,6 +4489,9 @@ void npc_defaults(void) { npc->fake_nd = NULL; npc->src_files = NULL; /* */ + npc->trader_ok = false; + npc->trader_funds[0] = npc->trader_funds[1] = 0; + /* */ npc->init = do_init_npc; npc->final = do_final_npc; /* */ @@ -4043,6 +4549,8 @@ void npc_defaults(void) { npc->addsrcfile = npc_addsrcfile; npc->delsrcfile = npc_delsrcfile; npc->parsename = npc_parsename; + npc->parseview = npc_parseview; + npc->viewisid = npc_viewisid; npc->add_warp = npc_add_warp; npc->parse_warp = npc_parse_warp; npc->parse_shop = npc_parse_shop; @@ -4073,4 +4581,14 @@ void npc_defaults(void) { npc->debug_warps_sub = npc_debug_warps_sub; npc->debug_warps = npc_debug_warps; npc->secure_timeout_timer = npc_rr_secure_timeout_timer; + /* */ + npc->trader_count_funds = npc_trader_count_funds; + npc->trader_pay = npc_trader_pay; + npc->trader_update = npc_trader_update; + npc->market_buylist = npc_market_buylist; + npc->trader_open = npc_trader_open; + npc->market_fromsql = npc_market_fromsql; + npc->market_tosql = npc_market_tosql; + npc->market_delfromsql = npc_market_delfromsql; + npc->market_delfromsql_sub = npc_market_delfromsql_sub; } diff --git a/src/map/npc.h b/src/map/npc.h index f809cb19c..346a9f8c0 100644 --- a/src/map/npc.h +++ b/src/map/npc.h @@ -2,16 +2,33 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _NPC_H_ -#define _NPC_H_ +#ifndef _MAP_NPC_H_ +#define _MAP_NPC_H_ #include "map.h" // struct block_list #include "status.h" // struct status_change #include "unit.h" // struct unit_data + +struct HPluginData; struct block_list; struct npc_data; struct view_data; +enum npc_parse_options { + NPO_NONE = 0x0, + NPO_ONINIT = 0x1, + NPO_TRADER = 0x2, +}; + +enum npc_shop_types { + NST_ZENY,/* default */ + NST_CASH,/* official npc cash shop */ + NST_MARKET,/* official npc market type */ + NST_CUSTOM, + /* */ + NST_MAX, +}; + struct npc_timerevent_list { int timer,pos; }; @@ -20,9 +37,16 @@ struct npc_label_list { int pos; }; struct npc_item_list { - unsigned int nameid,value; + unsigned short nameid; + unsigned int value; + unsigned int qty; }; - +struct npc_shop_data { + unsigned char type;/* what am i */ + struct npc_item_list *item;/* list */ + unsigned short items;/* total */ +}; +struct npc_parse; struct npc_data { struct block_list bl; struct unit_data *ud; @@ -35,7 +59,7 @@ struct npc_data { char exname[NAME_LENGTH+1];// unique npc name int chat_id; int touching_id; - unsigned int next_walktime; + int64 next_walktime; uint8 dir; unsigned size : 2; @@ -44,7 +68,7 @@ struct npc_data { unsigned short level; unsigned short stat_point; - void* chatdb; // pointer to a npc_parse struct (see npc_chat.c) + struct npc_parse *chatdb; char* path;/* path dir */ enum npc_subtype subtype; int src_id; @@ -54,14 +78,17 @@ struct npc_data { short xs,ys; // OnTouch area radius int guild_id; int timer,timerid,timeramount,rid; - unsigned int timertick; + int64 timertick; struct npc_timerevent_list *timer_event; int label_list_num; struct npc_label_list *label_list; + /* */ + struct npc_shop_data *shop; + bool trader; } scr; - struct { + struct { /* TODO duck this as soon as the new shop formatting is deemed stable */ struct npc_item_list* shop_item; - int count; + unsigned short count; } shop; struct { short xs,ys; // OnTouch area radius @@ -74,10 +101,12 @@ struct npc_data { char killer_name[NAME_LENGTH]; } tomb; } u; + /* HPData Support for npc_data */ + struct HPluginData **hdata; + unsigned int hdatac; }; - #define START_NPC_NUM 110000000 enum actor_classes { @@ -92,7 +121,7 @@ enum actor_classes { #define MAX_NPC_CLASS 1000 // New NPC range #define MAX_NPC_CLASS2_START 10000 -#define MAX_NPC_CLASS2_END 10049 +#define MAX_NPC_CLASS2_END 10070 //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) @@ -139,8 +168,11 @@ struct npc_interface { struct npc_data *fake_nd; struct npc_src_list *src_files; struct unit_data base_ud; + /* npc trader global data, for ease of transition between the script, cleared on every usage */ + bool trader_ok; + int trader_funds[2]; /* */ - int (*init) (void); + int (*init) (bool minimal); int (*final) (void); /* */ int (*get_new_npc_id) (void); @@ -160,14 +192,14 @@ struct npc_interface { 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, unsigned int tick, int id, intptr_t data); + 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, unsigned int tick, int id, intptr_t data); + 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); - int (*gettimerevent_tick) (struct npc_data *nd); + 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); @@ -197,12 +229,14 @@ struct npc_interface { 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); + int (*parseview) (const char *w4, const char *start, const char *buffer, const char *filepath); + bool (*viewisid) (const char *viewid); 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_script) (char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath, int options); 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); @@ -216,7 +250,7 @@ struct npc_interface { 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 (*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); @@ -226,10 +260,20 @@ struct npc_interface { void (*do_clear_npc) (void); void (*debug_warps_sub) (struct npc_data *nd); void (*debug_warps) (void); + /* */ + void (*trader_count_funds) (struct npc_data *nd, struct map_session_data *sd); + bool (*trader_pay) (struct npc_data *nd, struct map_session_data *sd, int price, int points); + void (*trader_update) (int master); + int (*market_buylist) (struct map_session_data* sd, unsigned short list_size, struct packet_npc_market_purchase *p); + bool (*trader_open) (struct map_session_data *sd, struct npc_data *nd); + void (*market_fromsql) (void); + void (*market_tosql) (struct npc_data *nd, unsigned short index); + void (*market_delfromsql) (struct npc_data *nd, unsigned short index); + void (*market_delfromsql_sub) (const char *npcname, unsigned short index); /** * For the Secure NPC Timeout option (check config/Secure.h) [RR] **/ - int (*secure_timeout_timer) (int tid, unsigned int tick, int id, intptr_t data); + int (*secure_timeout_timer) (int tid, int64 tick, int id, intptr_t data); }; struct npc_interface *npc; @@ -259,12 +303,6 @@ struct pcrematch_set { /* * 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; @@ -285,7 +323,28 @@ struct npc_chat_interface { struct npc_chat_interface *npc_chat; +/** + * pcre interface (libpcre) + * so that plugins may share and take advantage of the core's pcre + * should be moved into core/perhaps its own file once hpm is enhanced for login/char + **/ +struct pcre_interface { + pcre *(*compile) (const char *pattern, int options, const char **errptr, int *erroffset, const unsigned char *tableptr); + pcre_extra *(*study) (const pcre *code, int options, const char **errptr); + int (*exec) (const pcre *code, const pcre_extra *extra, PCRE_SPTR subject, int length, int startoffset, int options, int *ovector, int ovecsize); + void (*free) (void *ptr); + int (*copy_substring) (const char *subject, int *ovector, int stringcount, int stringnumber, char *buffer, int buffersize); + void (*free_substring) (const char *stringptr); + int (*copy_named_substring) (const pcre *code, const char *subject, int *ovector, int stringcount, const char *stringname, char *buffer, int buffersize); + int (*get_substring) (const char *subject, int *ovector, int stringcount, int stringnumber, const char **stringptr); +}; + +struct pcre_interface *libpcre; + +/** + * Also defaults libpcre + **/ void npc_chat_defaults(void); #endif -#endif /* _NPC_H_ */ +#endif /* _MAP_NPC_H_ */ diff --git a/src/map/npc_chat.c b/src/map/npc_chat.c index 1372fff21..9d5639efc 100644 --- a/src/map/npc_chat.c +++ b/src/map/npc_chat.c @@ -22,7 +22,12 @@ #include <string.h> #include <stdarg.h> +/** + * interface sources + **/ struct npc_chat_interface npc_chat_s; +struct pcre_interface libpcre_s; + /** * Written by MouseJstr in a vision... (2/21/2005) @@ -79,8 +84,8 @@ struct npc_chat_interface npc_chat_s; */ void finalize_pcrematch_entry(struct pcrematch_entry* e) { - pcre_free(e->pcre_); - pcre_free(e->pcre_extra_); + libpcre->free(e->pcre_); + libpcre->free(e->pcre_extra_); aFree(e->pattern); aFree(e->label); } @@ -91,9 +96,9 @@ void finalize_pcrematch_entry(struct pcrematch_entry* e) struct pcrematch_set* lookup_pcreset(struct npc_data* nd, int setid) { struct pcrematch_set *pcreset; - struct npc_parse *npcParse = (struct npc_parse *) nd->chatdb; + struct npc_parse *npcParse = nd->chatdb; if (npcParse == NULL) - nd->chatdb = npcParse = (struct npc_parse *) aCalloc(sizeof(struct npc_parse), 1); + nd->chatdb = npcParse = (struct npc_parse *)aCalloc(sizeof(struct npc_parse), 1); pcreset = npcParse->active; @@ -112,7 +117,7 @@ struct pcrematch_set* lookup_pcreset(struct npc_data* nd, int setid) } if (pcreset == NULL) { - pcreset = (struct pcrematch_set *) aCalloc(sizeof(struct pcrematch_set), 1); + pcreset = (struct pcrematch_set *)aCalloc(sizeof(struct pcrematch_set), 1); pcreset->next = npcParse->inactive; if (pcreset->next != NULL) pcreset->next->prev = pcreset; @@ -132,7 +137,7 @@ struct pcrematch_set* lookup_pcreset(struct npc_data* nd, int setid) void activate_pcreset(struct npc_data* nd, int setid) { struct pcrematch_set *pcreset; - struct npc_parse *npcParse = (struct npc_parse *) nd->chatdb; + struct npc_parse *npcParse = nd->chatdb; if (npcParse == NULL) return; // Nothing to activate... pcreset = npcParse->inactive; @@ -165,7 +170,7 @@ void activate_pcreset(struct npc_data* nd, int setid) void deactivate_pcreset(struct npc_data* nd, int setid) { struct pcrematch_set *pcreset; - struct npc_parse *npcParse = (struct npc_parse *) nd->chatdb; + struct npc_parse *npcParse = nd->chatdb; if (npcParse == NULL) return; // Nothing to deactivate... if (setid == -1) { @@ -202,7 +207,7 @@ void delete_pcreset(struct npc_data* nd, int setid) { int active = 1; struct pcrematch_set *pcreset; - struct npc_parse *npcParse = (struct npc_parse *) nd->chatdb; + struct npc_parse *npcParse = nd->chatdb; if (npcParse == NULL) return; // Nothing to deactivate... pcreset = npcParse->active; @@ -287,8 +292,8 @@ void npc_chat_def_pattern(struct npc_data* nd, int setid, const char* pattern, c struct pcrematch_entry *e = npc_chat->create_pcrematch_entry(s); e->pattern = aStrdup(pattern); e->label = aStrdup(label); - e->pcre_ = pcre_compile(pattern, PCRE_CASELESS, &err, &erroff, NULL); - e->pcre_extra_ = pcre_study(e->pcre_, 0, &err); + e->pcre_ = libpcre->compile(pattern, PCRE_CASELESS, &err, &erroff, NULL); + e->pcre_extra_ = libpcre->study(e->pcre_, 0, &err); } /** @@ -299,7 +304,7 @@ void npc_chat_def_pattern(struct npc_data* nd, int setid, const char* pattern, c */ void npc_chat_finalize(struct npc_data* nd) { - struct npc_parse *npcParse = (struct npc_parse *) nd->chatdb; + struct npc_parse *npcParse = nd->chatdb; if (npcParse == NULL) return; @@ -318,8 +323,8 @@ void npc_chat_finalize(struct npc_data* nd) */ int npc_chat_sub(struct block_list* bl, va_list ap) { - struct npc_data* nd = (struct npc_data *) bl; - struct npc_parse* npcParse = (struct npc_parse *) nd->chatdb; + struct npc_data *nd = (struct npc_data *) bl; + struct npc_parse *npcParse = nd->chatdb; char* msg; int len, i; struct map_session_data* sd; @@ -344,7 +349,7 @@ int npc_chat_sub(struct block_list* bl, va_list ap) int offsets[2*10 + 10]; // 1/3 reserved for temp space requred by pcre_exec // perform pattern match - int r = pcre_exec(e->pcre_, e->pcre_extra_, msg, len, 0, 0, offsets, ARRAYLENGTH(offsets)); + int r = libpcre->exec(e->pcre_, e->pcre_extra_, msg, len, 0, 0, offsets, ARRAYLENGTH(offsets)); if (r > 0) { // save out the matched strings @@ -352,7 +357,7 @@ int npc_chat_sub(struct block_list* bl, va_list ap) { char var[6], val[255]; snprintf(var, sizeof(var), "$@p%i$", i); - pcre_copy_substring(msg, offsets, r, i, val, sizeof(val)); + libpcre->copy_substring(msg, offsets, r, i, val, sizeof(val)); script->set_var(sd, var, val); } @@ -425,6 +430,17 @@ void npc_chat_defaults(void) { npc_chat->activate_pcreset = activate_pcreset; npc_chat->lookup_pcreset = lookup_pcreset; npc_chat->finalize_pcrematch_entry = finalize_pcrematch_entry; + + libpcre = &libpcre_s; + + libpcre->compile = pcre_compile; + libpcre->study = pcre_study; + libpcre->exec = pcre_exec; + libpcre->free = pcre_free; + libpcre->copy_substring = pcre_copy_substring; + libpcre->free_substring = pcre_free_substring; + libpcre->copy_named_substring = pcre_copy_named_substring; + libpcre->get_substring = pcre_get_substring; } #endif //PCRE_SUPPORT diff --git a/src/map/packets.h b/src/map/packets.h index c91b5d50c..3ff202bae 100644 --- a/src/map/packets.h +++ b/src/map/packets.h @@ -3,8 +3,8 @@ //Included directly by clif.h in packet_loaddb() -#ifndef _PACKETS_H_ -#define _PACKETS_H_ +#ifndef _MAP_PACKETS_H_ +#define _MAP_PACKETS_H_ #ifndef packet #define packet(a,b,...) @@ -1613,7 +1613,7 @@ packet(0x020d,-1); //2009-10-27aRagexeRE #if PACKETVER >= 20091027 - packet(0x07f5,6,clif->pGMReqAccountName,2); + packet(0x07f5,6,clif->pGMFullStrip,2); packet(0x07f6,14); #endif @@ -2375,6 +2375,21 @@ packet(0x020d,-1); packet(0x0930,36,clif->pStoragePassword,0); #endif +/* Bank System [Yommy/Hercules] */ +#if PACKETVER >= 20130724 + packet(0x09A6,12); // ZC_BANKING_CHECK + packet(0x09A7,10,clif->pBankDeposit,2,4,6); + packet(0x09A8,16); // ZC_ACK_BANKING_DEPOSIT + packet(0x09A9,10,clif->pBankWithdraw,2,4,6); + packet(0x09AA,16); // ZC_ACK_BANKING_WITHDRAW + packet(0x09AB,6,clif->pBankCheck,2,4); + //// + packet(0x09B6,6,clif->pBankOpen,2,4); + packet(0x09B7,4); // ZC_ACK_OPEN_BANKING + packet(0x09B8,6,clif->pBankClose,2,4); + packet(0x09B9,4); // ZC_ACK_CLOSE_BANKING +#endif + //2013-07-03Ragexe (Shakto) #if PACKETVER >= 20130703 packet(0x0930,5,clif->pChangeDir,2,4); @@ -2400,7 +2415,7 @@ packet(0x020d,-1); packet(0x0873,36,clif->pStoragePassword,0); packet(0x097C,4,clif->pRanklist); #endif - + //2013-08-07Ragexe (Shakto) #if PACKETVER >= 20130807 packet(0x0369,7,clif->pActionRequest,2,6); @@ -2438,6 +2453,46 @@ packet(0x020d,-1); packet(0x0887,36,clif->pStoragePassword,0); #endif +// 2013-12-23cRagexe - Yommy +#if PACKETVER >= 20131223 + packet(0x0369,7,clif->pActionRequest,2,6); + packet(0x083C,10,clif->pUseSkillToId,2,4,6); + packet(0x0437,5,clif->pWalkToXY,2); + packet(0x035F,6,clif->pTickSend,2); + packet(0x0202,5,clif->pChangeDir,2,4); + packet(0x07E4,6,clif->pTakeItem,2); + packet(0x0362,6,clif->pDropItem,2,4); + packet(0x07EC,8,clif->pMoveToKafra,2,4); + packet(0x0364,8,clif->pMoveFromKafra,2,4); + packet(0x0438,10,clif->pUseSkillToPos,2,4,6,8); + packet(0x0366,90,clif->pUseSkillToPosMoreInfo,2,4,6,8,10); + packet(0x096A,6,clif->pGetCharNameRequest,2); + packet(0x0368,6,clif->pSolveCharName,2); + packet(0x0838,12,clif->pSearchStoreInfoListItemClick,2,6,10); + packet(0x0835,2,clif->pSearchStoreInfoNextPage,0); + packet(0x0819,-1,clif->pSearchStoreInfo,2,4,5,9,13,14,15); + packet(0x0811,-1,clif->pReqTradeBuyingStore,2,4,8,12); + packet(0x0360,6,clif->pReqClickBuyingStore,2); + packet(0x0817,2,clif->pReqCloseBuyingStore,0); + packet(0x0815,-1,clif->pReqOpenBuyingStore,2,4,8,9,89); + packet(0x0365,18,clif->pPartyBookingRegisterReq,2,4); + // packet(0x0363,8); // CZ_JOIN_BATTLE_FIELD + packet(0x0281,-1,clif->pItemListWindowSelected,2,4,8); + packet(0x022d,19,clif->pWantToConnection,2,6,10,14,18); + packet(0x0802,26,clif->pPartyInvite2,2); + // packet(0x0436,4); // CZ_GANGSI_RANK + packet(0x023B,26,clif->pFriendsListAdd,2); + packet(0x0361,5,clif->pHomMenu,2,4); + packet(0x08A4,36,clif->pStoragePassword,0); + /* New */ + packet(0x09d4,2,clif->pNPCShopClosed); + packet(0x09ce,102,clif->pGM_Monster_Item,2); + /* NPC Market */ + packet(0x09d8,2,clif->pNPCMarketClosed); + packet(0x09d6,-1,clif->pNPCMarketPurchase); + packet(0x09df,7); +#endif + /* PacketKeys: http://hercules.ws/board/topic/1105-hercules-wpe-free-june-14th-patch/ */ #if PACKETVER >= 20110817 packetKeys(0x053D5CED,0x3DED6DED,0x6DED6DED); /* Thanks to Shakto */ @@ -2631,4 +2686,12 @@ packet(0x020d,-1); packetKeys(0x7E241DE0,0x5E805580,0x3D807D80); /* Thanks to Shakto */ #endif -#endif /* _PACKETS_H_ */ +#if PACKETVER >= 20131223 + packetKeys(0x631C511C, 0x111C111C,0x111C111C); +#endif + +#if defined(OBFUSCATIONKEY1) && defined(OBFUSCATIONKEY2) && defined(OBFUSCATIONKEY3) + packetKeys(OBFUSCATIONKEY1,OBFUSCATIONKEY2,OBFUSCATIONKEY3); +#endif + +#endif /* _MAP_PACKETS_H_ */ diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h index f39b4a55b..a150ef6e2 100644 --- a/src/map/packets_struct.h +++ b/src/map/packets_struct.h @@ -3,21 +3,18 @@ /* Hercules Renewal: Phase Two http://hercules.ws/board/topic/383-hercules-renewal-phase-two/ */ -#ifndef _PACKETS_STRUCT_H_ -#define _PACKETS_STRUCT_H_ +#ifndef _MAP_PACKETS_STRUCT_H_ +#define _MAP_PACKETS_STRUCT_H_ #include "../common/mmo.h" /** - * structs for data - */ -struct EQUIPSLOTINFO { - unsigned short card[4]; -}; -/** * **/ enum packet_headers { + banking_withdraw_ackType = 0x9aa, + banking_deposit_ackType = 0x9a8, + banking_checkType = 0x9a6, cart_additem_ackType = 0x12c, sc_notickType = 0x196, #if PACKETVER < 20061218 @@ -39,7 +36,7 @@ enum packet_headers { idle_unitType = 0x2ee, #elif PACKETVER < 20101124 idle_unitType = 0x7f9, -#elif PACKETVER < 20140000 //actual 20120221 +#elif PACKETVER < 20150000 //actual 20120221 idle_unitType = 0x857, #else idle_unitType = 0x915, @@ -57,6 +54,11 @@ enum packet_headers { spawn_unit2Type = 0x7c, idle_unit2Type = 0x78, #endif +#if PACKETVER < 20071113 + damageType = 0x8a, +#else + damageType = 0x2e1, +#endif #if PACKETVER < 4 spawn_unitType = 0x79, #elif PACKETVER < 7 @@ -67,7 +69,7 @@ enum packet_headers { spawn_unitType = 0x2ed, #elif PACKETVER < 20101124 spawn_unitType = 0x7f8, -#elif PACKETVER < 20140000 //actual 20120221 +#elif PACKETVER < 20150000 //actual 20120221 spawn_unitType = 0x858, #else spawn_unitType = 0x90f, @@ -79,6 +81,7 @@ enum packet_headers { #endif script_clearType = 0x8d6, package_item_announceType = 0x7fd, + item_drop_announceType = 0x7fd, #if PACKETVER < 4 unit_walkingType = 0x7b, #elif PACKETVER < 7 @@ -89,7 +92,7 @@ enum packet_headers { unit_walkingType = 0x2ec, #elif PACKETVER < 20101124 unit_walkingType = 0x7f7, -#elif PACKETVER < 20140000 //actual 20120221 +#elif PACKETVER < 20150000 //actual 20120221 unit_walkingType = 0x856, #else unit_walkingType = 0x914, @@ -102,17 +105,182 @@ enum packet_headers { bgqueue_revokereqType = 0x8da, bgqueue_battlebeginackType = 0x8e0, bgqueue_notify_entryType = 0x8d9, - bgqueue_battlebegins = 0x8df, + bgqueue_battlebeginsType = 0x8df, + notify_bounditemType = 0x2d3, +#if PACKETVER < 3 + skill_entryType = 0x11f, +#elif PACKETVER < 20121212 + skill_entryType = 0x8c7, +#elif PACKETVER < 20130731 + skill_entryType = 0x99f, +#else + skill_entryType = 0x9ca, +#endif + graffiti_entryType = 0x1c9, #if PACKETVER > 20130000 /* not sure date */ dropflooritemType = 0x84b, #else dropflooritemType = 0x9e, #endif +#if PACKETVER >= 20120925 + inventorylistnormalType = 0x991, +#elif PACKETVER >= 20080102 + inventorylistnormalType = 0x2e8, +#elif PACKETVER >= 20071002 + inventorylistnormalType = 0x1ee, +#else + inventorylistnormalType = 0xa3, +#endif +#if PACKETVER >= 20120925 + inventorylistequipType = 0x992, +#elif PACKETVER >= 20080102 + inventorylistequipType = 0x2d0, +#elif PACKETVER >= 20071002 + inventorylistequipType = 0x295, +#else + inventorylistequipType = 0xa4, +#endif +#if PACKETVER >= 20120925 + storagelistnormalType = 0x995, +#elif PACKETVER >= 20080102 + storagelistnormalType = 0x2ea, +#elif PACKETVER >= 20071002 + storagelistnormalType = 0x295, +#else + storagelistnormalType = 0xa5, +#endif +#if PACKETVER >= 20120925 + storagelistequipType = 0x996, +#elif PACKETVER >= 20080102 + storagelistequipType = 0x2d1, +#elif PACKETVER >= 20071002 + storagelistequipType = 0x296, +#else + storagelistequipType = 0xa6, +#endif +#if PACKETVER >= 20120925 + cartlistnormalType = 0x993, +#elif PACKETVER >= 20080102 + cartlistnormalType = 0x2e9, +#elif PACKETVER >= 20071002 + cartlistnormalType = 0x1ef, +#else + cartlistnormalType = 0x123, +#endif +#if PACKETVER >= 20120925 + cartlistequipType = 0x994, +#elif PACKETVER >= 20080102 + cartlistequipType = 0x2d2, +#elif PACKETVER >= 20071002 + cartlistequipType = 0x297, +#else + cartlistequipType = 0x122, +#endif +#if PACKETVER >= 20120925 + equipitemType = 0x998, +#else + equipitemType = 0xa9, +#endif +#if PACKETVER >= 20120925 + equipitemackType = 0x999, +#else + equipitemackType = 0xaa, +#endif +#if PACKETVER >= 20120925 + unequipitemackType = 0x99a, +#else + unequipitemackType = 0xac, +#endif +#if PACKETVER >= 20120925 + viewequipackType = 0x997, +#elif PACKETVER >= 20101124 + viewequipackType = 0x859, +#else + viewequipackType = 0x2d7, +#endif + notifybindonequip = 0x2d3, monsterhpType = 0x977, maptypeproperty2Type = 0x99b, + npcmarketresultackType = 0x9d7, + npcmarketopenType = 0x9d5, }; +#if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute #pragma pack(push, 1) +#endif // not NetBSD < 6 / Solaris + +/** + * structs for data + */ +struct EQUIPSLOTINFO { + unsigned short card[4]; +} __attribute__((packed)); + +struct NORMALITEM_INFO { + short index; + unsigned short ITID; + unsigned char type; +#if PACKETVER < 20120925 + uint8 IsIdentified; +#endif + short count; +#if PACKETVER >= 20120925 + unsigned int WearState; +#else + unsigned short WearState; +#endif +#if PACKETVER >= 5 + struct EQUIPSLOTINFO slot; +#endif +#if PACKETVER >= 20080102 + int HireExpireDate; +#endif +#if PACKETVER >= 20120925 + struct { + unsigned char IsIdentified : 1; + unsigned char PlaceETCTab : 1; + unsigned char SpareBits : 6; + } Flag; +#endif +} __attribute__((packed)); + +struct EQUIPITEM_INFO { + short index; + unsigned short ITID; + unsigned char type; +#if PACKETVER < 20120925 + uint8 IsIdentified; +#endif +#if PACKETVER >= 20120925 + unsigned int location; + unsigned int WearState; +#else + unsigned short location; + unsigned short WearState; +#endif +#if PACKETVER < 20120925 + uint8 IsDamaged; +#endif + unsigned char RefiningLevel; + struct EQUIPSLOTINFO slot; +#if PACKETVER >= 20071002 + int HireExpireDate; +#endif +#if PACKETVER >= 20080102 + unsigned short bindOnEquipType; +#endif +#if PACKETVER >= 20100629 + unsigned short wItemSpriteNumber; +#endif +#if PACKETVER >= 20120925 + struct { + unsigned char IsIdentified : 1; + unsigned char IsDamaged : 1; + unsigned char PlaceETCTab : 1; + unsigned char SpareBits : 5; + } Flag; +#endif +} __attribute__((packed)); struct packet_authok { short PacketType; @@ -144,8 +312,8 @@ struct packet_additem { unsigned short Index; unsigned short count; unsigned short nameid; - bool IsIdentified; - bool IsDamaged; + uint8 IsIdentified; + uint8 IsDamaged; unsigned char refiningLevel; struct EQUIPSLOTINFO slot; #if PACKETVER >= 20120925 @@ -170,7 +338,7 @@ struct packet_dropflooritem { #if PACKETVER >= 20130000 /* not sure date */ unsigned short type; #endif - bool IsIdentified; + uint8 IsIdentified; short xPos; short yPos; unsigned char subX; @@ -202,7 +370,7 @@ struct packet_idle_unit2 { short GEmblemVer; short honor; short virtue; - bool isPKModeON; + uint8 isPKModeON; unsigned char sex; unsigned char PosDir[3]; unsigned char xSize; @@ -230,7 +398,7 @@ struct packet_spawn_unit2 { short headpalette; short bodypalette; short headDir; - bool isPKModeON; + uint8 isPKModeON; unsigned char sex; unsigned char PosDir[3]; unsigned char xSize; @@ -279,7 +447,7 @@ struct packet_spawn_unit { #else short virtue; #endif - bool isPKModeON; + uint8 isPKModeON; unsigned char sex; unsigned char PosDir[3]; unsigned char xSize; @@ -288,7 +456,7 @@ struct packet_spawn_unit { #if PACKETVER >= 20080102 short font; #endif -#if PACKETVER >= 20140000 //actual 20120221 +#if PACKETVER >= 20150000 //actual 20120221 int maxHP; int HP; unsigned char isBoss; @@ -340,7 +508,7 @@ struct packet_unit_walking { #else short virtue; #endif - bool isPKModeON; + uint8 isPKModeON; unsigned char sex; unsigned char MoveData[6]; unsigned char xSize; @@ -349,7 +517,7 @@ struct packet_unit_walking { #if PACKETVER >= 20080102 short font; #endif -#if PACKETVER >= 20140000 //actual 20120221 +#if PACKETVER >= 20150000 //actual 20120221 int maxHP; int HP; unsigned char isBoss; @@ -398,7 +566,7 @@ struct packet_idle_unit { #else short virtue; #endif - bool isPKModeON; + uint8 isPKModeON; unsigned char sex; unsigned char PosDir[3]; unsigned char xSize; @@ -408,7 +576,7 @@ struct packet_idle_unit { #if PACKETVER >= 20080102 short font; #endif -#if PACKETVER >= 20140000 //actual 20120221 +#if PACKETVER >= 20150000 //actual 20120221 int maxHP; int HP; unsigned char isBoss; @@ -538,11 +706,243 @@ struct packet_package_item_announce { unsigned short BoxItemID; } __attribute__((packed)); +/* made possible thanks to Yommy!! */ +struct packet_item_drop_announce { + short PacketType; + short PacketLength; + unsigned char type; + unsigned short ItemID; + char len; + char Name[NAME_LENGTH]; + char monsterNameLen; + char monsterName[NAME_LENGTH]; +} __attribute__((packed)); + struct packet_cart_additem_ack { short PacketType; char result; } __attribute__((packed)); +struct packet_banking_check { + short PacketType; + int64 Money; + short Reason; +} __attribute__((packed)); + +struct packet_banking_deposit_req { + short PacketType; + unsigned int AID; + int Money; +} __attribute__((packed)); + +struct packet_banking_withdraw_req { + short PacketType; + unsigned int AID; + int Money; +} __attribute__((packed)); + +struct packet_banking_deposit_ack { + short PacketType; + short Reason; + int64 Money; + int Balance; +} __attribute__((packed)); + +struct packet_banking_withdraw_ack { + short PacketType; + short Reason; + int64 Money; + int Balance; +} __attribute__((packed)); + +struct packet_itemlist_normal { + short PacketType; + short PacketLength; + struct NORMALITEM_INFO list[MAX_ITEMLIST]; +} __attribute__((packed)); + +struct packet_itemlist_equip { + short PacketType; + short PacketLength; + struct EQUIPITEM_INFO list[MAX_ITEMLIST]; +} __attribute__((packed)); + +struct packet_storelist_normal { + short PacketType; + short PacketLength; +#if PACKETVER >= 20120925 + char name[NAME_LENGTH]; +#endif + struct NORMALITEM_INFO list[MAX_ITEMLIST]; +} __attribute__((packed)); + +struct packet_storelist_equip { + short PacketType; + short PacketLength; +#if PACKETVER >= 20120925 + char name[NAME_LENGTH]; +#endif + struct EQUIPITEM_INFO list[MAX_ITEMLIST]; +} __attribute__((packed)); + +struct packet_equip_item { + short PacketType; + unsigned short index; +#if PACKETVER >= 20120925 + unsigned int wearLocation; +#else + unsigned short wearLocation; +#endif +} __attribute__((packed)); + +struct packet_equipitem_ack { + short PacketType; + unsigned short index; +#if PACKETVER >= 20120925 + unsigned int wearLocation; +#else + unsigned short wearLocation; +#endif +#if PACKETVER >= 20100629 + unsigned short wItemSpriteNumber; +#endif + unsigned char result; +} __attribute__((packed)); + +struct packet_unequipitem_ack { + short PacketType; + unsigned short index; +#if PACKETVER >= 20120925 + unsigned int wearLocation; +#else + unsigned short wearLocation; +#endif + unsigned char result; +} __attribute__((packed)); + +struct packet_viewequip_ack { + short PacketType; + short PacketLength; + char characterName[NAME_LENGTH]; + short job; + short head; + short accessory; + short accessory2; + short accessory3; +#if PACKETVER >= 20101124 + short robe; +#endif + short headpalette; + short bodypalette; + unsigned char sex; + struct EQUIPITEM_INFO list[MAX_INVENTORY]; +} __attribute__((packed)); + +struct packet_notify_bounditem { + short PacketType; + unsigned short index; +} __attribute__((packed)); + +struct packet_skill_entry { + short PacketType; +#if PACKETVER >= 20110718 + short PacketLength; +#endif + unsigned int AID; + unsigned int creatorAID; + short xPos; + short yPos; +#if PACKETVER >= 20121212 + int job; +#else + unsigned char job; +#endif +#if PACKETVER >= 20110718 + char RadiusRange; +#endif + unsigned char isVisible; +#if PACKETVER >= 20130731 + unsigned char level; +#endif +} __attribute__((packed)); + +struct packet_graffiti_entry { + short PacketType; + unsigned int AID; + unsigned int creatorAID; + short xPos; + short yPos; + unsigned char job; + unsigned char isVisible; + unsigned char isContens; + char msg[80]; +} __attribute__((packed)); + +struct packet_damage { + short PacketType; + unsigned int GID; + unsigned int targetGID; + unsigned int startTime; + int attackMT; + int attackedMT; +#if PACKETVER < 20071113 + short damage; +#else + int damage; +#endif + short count; + unsigned char action; +#if PACKETVER < 20071113 + short leftDamage; +#else + int leftDamage; +#endif +} __attribute__((packed)); + +struct packet_gm_monster_item { + short PacketType; +#if PACKETVER >= 20131218 + char str[100]; +#else + char str[24]; +#endif +} __attribute__((packed)); + +struct packet_npc_market_purchase { + short PacketType; + short PacketLength; + struct { + unsigned short ITID; + int qty; + } list[MAX_INVENTORY];/* assuming MAX_INVENTORY is max since you can't hold more than MAX_INVENTORY items thus cant buy that many at once. */ +} __attribute__((packed)); + +struct packet_npc_market_result_ack { + short PacketType; + short PacketLength; + unsigned char result; + struct { + unsigned short ITID; + unsigned short qty; + unsigned int price; + } list[MAX_INVENTORY];/* assuming MAX_INVENTORY is max since you can't hold more than MAX_INVENTORY items thus cant buy that many at once. */ +} __attribute__((packed)); + +struct packet_npc_market_open { + short PacketType; + short PacketLength; + /* inner struct figured by Ind after some annoying hour of debugging (data Thanks to Yommy) */ + struct { + unsigned short nameid; + unsigned char type; + unsigned int price; + unsigned int qty; + unsigned short view; + } list[1000];/* TODO: whats the actual max of this? */ +} __attribute__((packed)); + +#if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute #pragma pack(pop) +#endif // not NetBSD < 6 / Solaris -#endif /* _PACKETS_STRUCT_H_ */ +#endif /* _MAP_PACKETS_STRUCT_H_ */ diff --git a/src/map/party.c b/src/map/party.c index 904110452..cf5e7bbe3 100644 --- a/src/map/party.c +++ b/src/map/party.c @@ -11,6 +11,7 @@ #include "../common/showmsg.h" #include "../common/utils.h" #include "../common/strlib.h" +#include "../common/HPM.h" #include "party.h" #include "atcommand.h" //msg_txt() @@ -94,8 +95,21 @@ TBL_PC* party_sd_check(int party_id, int account_id, int char_id) { int party_db_final(DBKey key, DBData *data, va_list ap) { struct party_data *p; - if( ( p = DB->data2ptr(data) ) && p->instance ) - aFree(p->instance); + if( ( p = DB->data2ptr(data) ) ) { + int j; + + if( p->instance ) + aFree(p->instance); + + for( j = 0; j < p->hdatac; j++ ) { + if( p->hdata[j]->flag.free ) { + aFree(p->hdata[j]->data); + } + aFree(p->hdata[j]); + } + if( p->hdata ) + aFree(p->hdata); + } return 0; } @@ -333,7 +347,7 @@ int party_invite(struct map_session_data *sd,struct map_session_data *tsd) } // confirm whether the account has the ability to invite before checking the player - if( !pc->has_permission(sd, PC_PERM_PARTY) || (tsd && !pc->has_permission(tsd, PC_PERM_PARTY)) ) { + if( !pc_has_permission(sd, PC_PERM_PARTY) || (tsd && !pc_has_permission(tsd, PC_PERM_PARTY)) ) { clif->message(sd->fd, msg_txt(81)); // "Your GM level doesn't authorize you to preform this action on the specified player." return 0; } @@ -547,10 +561,13 @@ int party_member_withdraw(int party_id, int account_id, int char_id) } if( sd && sd->status.party_id == party_id && sd->status.char_id == char_id ) { +#ifdef GP_BOUND_ITEMS + pc->bound_clear(sd,IBT_PARTY); +#endif sd->status.party_id = 0; clif->charnameupdate(sd); //Update name display [Skotlex] //TODO: hp bars should be cleared too - if( p->instances ) + if( p && p->instances ) instance->check_kick(sd); } if (sd && sd->sc.data[SC_DANCING]) { @@ -586,6 +603,18 @@ int party_broken(int party_id) } } + if( p->instance ) + aFree(p->instance); + + for( j = 0; j < p->hdatac; j++ ) { + if( p->hdata[j]->flag.free ) { + aFree(p->hdata[j]->data); + } + aFree(p->hdata[j]); + } + if( p->hdata ) + aFree(p->hdata); + idb_remove(party->db,party_id); return 0; } @@ -812,7 +841,7 @@ int party_skill_check(struct map_session_data *sd, int party_id, uint16 skill_id case TK_COUNTER: //Increase Triple Attack rate of Monks. if((p_sd->class_&MAPID_UPPERMASK) == MAPID_MONK && pc->checkskill(p_sd,MO_TRIPLEATTACK)) { - sc_start4(&p_sd->bl,SC_SKILLRATE_UP,100,MO_TRIPLEATTACK, + sc_start4(&p_sd->bl,&p_sd->bl,SC_SKILLRATE_UP,100,MO_TRIPLEATTACK, 50+50*skill_lv, //+100/150/200% rate 0,0,skill->get_time(SG_FRIEND, 1)); } @@ -821,7 +850,7 @@ int party_skill_check(struct map_session_data *sd, int party_id, uint16 skill_id if((p_sd->class_&MAPID_UPPERMASK) == MAPID_STAR_GLADIATOR && sd->sc.data[SC_COUNTERKICK_READY] && pc->checkskill(p_sd,SG_FRIEND)) { - sc_start4(&p_sd->bl,SC_SKILLRATE_UP,100,TK_COUNTER, + sc_start4(&p_sd->bl,&p_sd->bl,SC_SKILLRATE_UP,100,TK_COUNTER, 50+50*pc->checkskill(p_sd,SG_FRIEND), //+100/150/200% rate 0,0,skill->get_time(SG_FRIEND, 1)); } @@ -831,8 +860,7 @@ int party_skill_check(struct map_session_data *sd, int party_id, uint16 skill_id return 0; } -int party_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data) -{ +int party_send_xy_timer(int tid, int64 tick, int id, intptr_t data) { struct party_data* p; DBIterator *iter = db_iterator(party->db); @@ -850,7 +878,7 @@ int party_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data) for( i = 0; i < MAX_PARTY; i++ ) { struct map_session_data* sd = p->data[i].sd; - if( !sd ) continue; + if( !sd || sd->bg_id ) continue; if( p->data[i].x != sd->bl.x || p->data[i].y != sd->bl.y ) {// perform position update @@ -1080,6 +1108,22 @@ int party_vforeachsamemap(int (*func)(struct block_list*,va_list), struct map_se return total; } +// Special check for Minstrel's and Wanderer's chorus skills. +int party_sub_count_chorus(struct block_list *bl, va_list ap) { + struct map_session_data *sd = (TBL_PC *)bl; + + if (sd->state.autotrade) + return 0; + + if (battle_config.idle_no_share && pc_isidle(sd)) + return 0; + + if ( (sd->class_&MAPID_THIRDMASK) != MAPID_MINSTRELWANDERER ) + return 0; + + return 1; +} + /** * Executes 'func' for each party member on the same map and within a 'range' cells area * @param func Function to execute @@ -1307,7 +1351,10 @@ void do_final_party(void) { db_destroy(party->booking_db); // Party Booking [Spiria] } // Constructor, init vars -void do_init_party(void) { +void do_init_party(bool minimal) { + if (minimal) + return; + party->db = idb_alloc(DB_OPT_RELEASE_DATA); party->booking_db = idb_alloc(DB_OPT_RELEASE_DATA); // Party Booking [Spiria] timer->add_func_list(party->send_xy_timer, "party_send_xy_timer"); @@ -1362,6 +1409,7 @@ void party_defaults(void) { party->share_loot = party_share_loot; party->send_dot_remove = party_send_dot_remove; party->sub_count = party_sub_count; + party->sub_count_chorus = party_sub_count_chorus; party->booking_register = party_booking_register; party->booking_update = party_booking_update; party->booking_search = party_booking_search; diff --git a/src/map/party.h b/src/map/party.h index 208edb846..ed8289af6 100644 --- a/src/map/party.h +++ b/src/map/party.h @@ -2,8 +2,8 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _PARTY_H_ -#define _PARTY_H_ +#ifndef _MAP_PARTY_H_ +#define _MAP_PARTY_H_ #include "../common/mmo.h" // struct party #include "../config/core.h" @@ -14,6 +14,8 @@ #define PARTY_BOOKING_JOBS 6 #define PARTY_BOOKING_RESULTS 10 +struct HPluginData; + struct party_member_data { struct map_session_data *sd; unsigned int hp; //For HP,x,y refreshing. @@ -32,6 +34,10 @@ struct party_data { unsigned snovice :1; //There's a Super Novice unsigned tk : 1; //There's a taekwon } state; + + /* HPM Custom Struct */ + struct HPluginData **hdata; + unsigned int hdatac; }; #define PB_NOTICE_LENGTH (36 + 1) @@ -44,9 +50,9 @@ struct party_booking_detail { }; struct party_booking_ad_info { - unsigned long index; + unsigned int index; char charname[NAME_LENGTH]; - long expiretime; + int expiretime; struct party_booking_detail p_detail; }; #else /* PARTY_RECRUIT */ @@ -56,8 +62,8 @@ struct party_booking_detail { }; struct party_booking_ad_info { - unsigned long index; - long expiretime; + unsigned int index; + int expiretime; char charname[NAME_LENGTH]; struct party_booking_detail p_detail; }; @@ -71,9 +77,9 @@ struct party_booking_ad_info { struct party_interface { DBMap* db; // int party_id -> struct party_data* (releases data) DBMap* booking_db; // int char_id -> struct party_booking_ad_info* (releases data) // Party Booking [Spiria] - unsigned long booking_nextid; + unsigned int booking_nextid; /* funcs */ - void (*init) (void); + void (*init) (bool minimal); void (*final) (void); /* */ struct party_data* (*search) (int party_id); @@ -109,6 +115,7 @@ struct party_interface { int (*share_loot) (struct party_data* p, struct map_session_data* sd, struct item* item_data, int first_charid); int (*send_dot_remove) (struct map_session_data *sd); int (*sub_count) (struct block_list *bl, va_list ap); + int (*sub_count_chorus) (struct block_list *bl, va_list ap); /*========================================== * Party Booking in KRO [Spiria] *------------------------------------------*/ @@ -123,7 +130,7 @@ struct party_interface { /* */ int (*vforeachsamemap) (int (*func)(struct block_list *,va_list),struct map_session_data *sd,int range, va_list ap); int (*foreachsamemap) (int (*func)(struct block_list *,va_list),struct map_session_data *sd,int range,...); - int (*send_xy_timer) (int tid, unsigned int tick, int id, intptr_t data); + int (*send_xy_timer) (int tid, int64 tick, int id, intptr_t data); void (*fill_member) (struct party_member* member, struct map_session_data* sd, unsigned int leader); TBL_PC* (*sd_check) (int party_id, int account_id, int char_id); void (*check_state) (struct party_data *p); @@ -135,4 +142,4 @@ struct party_interface *party; void party_defaults(void); -#endif /* _PARTY_H_ */ +#endif /* _MAP_PARTY_H_ */ diff --git a/src/map/path.c b/src/map/path.c index a47677cf5..21d14c815 100644 --- a/src/map/path.c +++ b/src/map/path.c @@ -184,8 +184,10 @@ bool path_search_long(struct shootpath_data *spd,int16 m,int16 x0,int16 y0,int16 /// Ensures there is enough space in array to store new element. static void heap_push_node(struct node_heap *heap, struct path_node *node) { +#ifndef __clang_analyzer__ // TODO: Figure out why clang's static analyzer doesn't like this BHEAP_ENSURE(*heap, 1, 256); BHEAP_PUSH(*heap, node, NODE_MINTOPCMP, swap_ptr); +#endif // __clang_analyzer__ } /// Updates path_node in the binary node_heap. diff --git a/src/map/path.h b/src/map/path.h index e872c8877..0b67a0120 100644 --- a/src/map/path.h +++ b/src/map/path.h @@ -2,8 +2,8 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _PATH_H_ -#define _PATH_H_ +#ifndef _MAP_PATH_H_ +#define _MAP_PATH_H_ #include "map.h" // enum cell_chk @@ -23,13 +23,13 @@ struct shootpath_data { int y[MAX_WALKPATH]; }; -#define check_distance_bl(bl1, bl2, distance) path->check_distance((bl1)->x - (bl2)->x, (bl1)->y - (bl2)->y, distance) -#define check_distance_blxy(bl, x1, y1, distance) path->check_distance((bl)->x-(x1), (bl)->y-(y1), distance) -#define check_distance_xy(x0, y0, x1, y1, distance) path->check_distance((x0)-(x1), (y0)-(y1), distance) +#define check_distance_bl(bl1, bl2, distance) (path->check_distance((bl1)->x - (bl2)->x, (bl1)->y - (bl2)->y, distance)) +#define check_distance_blxy(bl, x1, y1, distance) (path->check_distance((bl)->x - (x1), (bl)->y - (y1), distance)) +#define check_distance_xy(x0, y0, x1, y1, distance) (path->check_distance((x0) - (x1), (y0) - (y1), distance)) -#define distance_bl(bl1, bl2) path->distance((bl1)->x - (bl2)->x, (bl1)->y - (bl2)->y) -#define distance_blxy(bl, x1, y1) path->distance((bl)->x-(x1), (bl)->y-(y1)) -#define distance_xy(x0, y0, x1, y1) path->distance((x0)-(x1), (y0)-(y1)) +#define distance_bl(bl1, bl2) (path->distance((bl1)->x - (bl2)->x, (bl1)->y - (bl2)->y)) +#define distance_blxy(bl, x1, y1) (path->distance((bl)->x - (x1), (bl)->y - (y1))) +#define distance_xy(x0, y0, x1, y1) (path->distance((x0) - (x1), (y0) - (y1))) struct path_interface { // calculates destination cell for knockback @@ -46,4 +46,4 @@ struct path_interface *path; void path_defaults(void); -#endif /* _PATH_H_ */ +#endif /* _MAP_PATH_H_ */ diff --git a/src/map/pc.c b/src/map/pc.c index 6b7d6c735..284a459e7 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -72,20 +72,11 @@ struct map_session_data* pc_get_dummy_sd(void) { struct map_session_data *dummy_sd; CREATE(dummy_sd, struct map_session_data, 1); - dummy_sd->group = pc_group_get_dummy_group(); // map_session_data.group is expected to be non-NULL at all times + dummy_sd->group = pcg->get_dummy_group(); // map_session_data.group is expected to be non-NULL at all times return dummy_sd; } /** - * Gets player's group level. - * @see pc_group_get_level() - */ -int pc_get_group_level(struct map_session_data *sd) -{ - return pc_group_get_level(sd->group); -} - -/** * Sets player's group. * Caller should handle error (preferably display message and disconnect). * @param group_id Group ID @@ -93,7 +84,7 @@ int pc_get_group_level(struct map_session_data *sd) */ int pc_set_group(struct map_session_data *sd, int group_id) { - GroupSettings *group = pc_group_id2group(group_id); + GroupSettings *group = pcg->id2group(group_id); if (group == NULL) return 1; sd->group_id = group_id; @@ -102,22 +93,14 @@ int pc_set_group(struct map_session_data *sd, int group_id) } /** - * Checks if player has permission to perform action. - */ -bool pc_has_permission(struct map_session_data *sd, enum e_pc_permission permission) -{ - return ((sd->extra_temp_permissions&permission) != 0 || pc_group_has_permission(sd->group, permission)); -} - -/** * Checks if commands used by player should be logged. */ bool pc_should_log_commands(struct map_session_data *sd) { - return pc_group_should_log_commands(sd->group); + return pcg->should_log_commands(sd->group); } -int pc_invincible_timer(int tid, unsigned int tick, int id, intptr_t data) { +int pc_invincible_timer(int tid, int64 tick, int id, intptr_t data) { struct map_session_data *sd; if( (sd=(struct map_session_data *)map->id2sd(id)) == NULL || sd->bl.type!=BL_PC ) @@ -155,7 +138,7 @@ void pc_delinvincibletimer(struct map_session_data* sd) } } -int pc_spiritball_timer(int tid, unsigned int tick, int id, intptr_t data) { +int pc_spiritball_timer(int tid, int64 tick, int id, intptr_t data) { struct map_session_data *sd; int i; @@ -213,7 +196,7 @@ int pc_addspiritball(struct map_session_data *sd,int interval,int max) sd->spirit_timer[i] = tid; sd->spiritball++; if( (sd->class_&MAPID_THIRDMASK) == MAPID_ROYAL_GUARD ) - clif->millenniumshield(sd,sd->spiritball); + clif->millenniumshield(&sd->bl,sd->spiritball); else clif->spiritball(&sd->bl); @@ -252,7 +235,7 @@ int pc_delspiritball(struct map_session_data *sd,int count,int type) if(!type) { if( (sd->class_&MAPID_THIRDMASK) == MAPID_ROYAL_GUARD ) - clif->millenniumshield(sd,sd->spiritball); + clif->millenniumshield(&sd->bl,sd->spiritball); else clif->spiritball(&sd->bl); } @@ -419,7 +402,7 @@ int pc_setrestartvalue(struct map_session_data *sd,int type) { /*========================================== Rental System *------------------------------------------*/ -int pc_inventory_rental_end(int tid, unsigned int tick, int id, intptr_t data) { +int pc_inventory_rental_end(int tid, int64 tick, int id, intptr_t data) { struct map_session_data *sd = map->id2sd(id); if( sd == NULL ) return 0; @@ -443,11 +426,78 @@ int pc_inventory_rental_clear(struct map_session_data *sd) return 1; } +/* assumes i is valid (from default areas where it is called, it is) */ +void pc_rental_expire(struct map_session_data *sd, int i) { + short nameid = sd->status.inventory[i].nameid; + /* Soon to be dropped, we got plans to integrate it with item db */ + switch( nameid ) { + case ITEMID_REINS_OF_MOUNT: + status_change_end(&sd->bl,SC_ALL_RIDING,INVALID_TIMER); + break; + case ITEMID_LOVE_ANGEL: + if( sd->status.font == 1 ) { + sd->status.font = 0; + clif->font(sd); + } + break; + case ITEMID_SQUIRREL: + if( sd->status.font == 2 ) { + sd->status.font = 0; + clif->font(sd); + } + break; + case ITEMID_GOGO: + if( sd->status.font == 3 ) { + sd->status.font = 0; + clif->font(sd); + } + break; + case ITEMID_PICTURE_DIARY: + if( sd->status.font == 4 ) { + sd->status.font = 0; + clif->font(sd); + } + break; + case ITEMID_MINI_HEART: + if( sd->status.font == 5 ) { + sd->status.font = 0; + clif->font(sd); + } + break; + case ITEMID_NEWCOMER: + if( sd->status.font == 6 ) { + sd->status.font = 0; + clif->font(sd); + } + break; + case ITEMID_KID: + if( sd->status.font == 7 ) { + sd->status.font = 0; + clif->font(sd); + } + break; + case ITEMID_MAGIC_CASTLE: + if( sd->status.font == 8 ) { + sd->status.font = 0; + clif->font(sd); + } + break; + case ITEMID_BULGING_HEAD: + if( sd->status.font == 9 ) { + sd->status.font = 0; + clif->font(sd); + } + break; + } + + clif->rental_expired(sd->fd, i, sd->status.inventory[i].nameid); + pc->delitem(sd, i, sd->status.inventory[i].amount, 0, 0, LOG_TYPE_OTHER); +} void pc_inventory_rentals(struct map_session_data *sd) { int i, c = 0; - unsigned int expire_tick, next_tick = UINT_MAX; + int64 expire_tick, next_tick = INT64_MAX; for( i = 0; i < MAX_INVENTORY; i++ ) { // Check for Rentals on Inventory @@ -457,14 +507,9 @@ void pc_inventory_rentals(struct map_session_data *sd) continue; if( sd->status.inventory[i].expire_time <= time(NULL) ) { - if( sd->status.inventory[i].nameid == ITEMID_REINS_OF_MOUNT - && sd->sc.data[SC_ALL_RIDING] ) { - status_change_end(&sd->bl,SC_ALL_RIDING,INVALID_TIMER); - } - clif->rental_expired(sd->fd, i, sd->status.inventory[i].nameid); - pc->delitem(sd, i, sd->status.inventory[i].amount, 0, 0, LOG_TYPE_OTHER); + pc->rental_expire(sd,i); } else { - expire_tick = (unsigned int)(sd->status.inventory[i].expire_time - time(NULL)) * 1000; + expire_tick = (int64)(sd->status.inventory[i].expire_time - time(NULL)) * 1000; clif->rental_time(sd->fd, sd->status.inventory[i].nameid, (int)(expire_tick / 1000)); next_tick = min(expire_tick, next_tick); c++; @@ -498,14 +543,6 @@ void pc_inventory_rental_add(struct map_session_data *sd, int seconds) sd->rental_timer = timer->add(timer->gettick() + min(tick,3600000), pc->inventory_rental_end, sd->bl.id, 0); } -/** - * Determines if player can give / drop / trade / vend items - */ -bool pc_can_give_items(struct map_session_data *sd) -{ - return pc->has_permission(sd, PC_PERM_TRADE); -} - /*========================================== * prepares character for saving. *------------------------------------------*/ @@ -608,9 +645,14 @@ int pc_equippoint(struct map_session_data *sd,int n) if(sd->inventory_data[n]->look == W_DAGGER || sd->inventory_data[n]->look == W_1HSWORD || sd->inventory_data[n]->look == W_1HAXE) { - if(ep == EQP_HAND_R && (pc->checkskill(sd,AS_LEFT) > 0 || (sd->class_&MAPID_UPPERMASK) == MAPID_ASSASSIN || - (sd->class_&MAPID_UPPERMASK) == MAPID_KAGEROUOBORO))//Kagerou and Oboro can dual wield daggers. [Rytech] - return EQP_ARMS; + if( (pc->checkskill(sd,AS_LEFT) > 0 || + (sd->class_&MAPID_UPPERMASK) == MAPID_ASSASSIN || + (sd->class_&MAPID_UPPERMASK) == MAPID_KAGEROUOBORO) ) { //Kagerou and Oboro can dual wield daggers. [Rytech] + if( ep == EQP_HAND_R ) + return EQP_ARMS; + if( ep == EQP_SHADOW_WEAPON ) + return EQP_SHADOW_ARMS; + } } return ep; } @@ -857,7 +899,7 @@ int pc_isequip(struct map_session_data *sd,int n) item = sd->inventory_data[n]; - if(pc->has_permission(sd, PC_PERM_USE_ALL_EQUIPMENT)) + if(pc_has_permission(sd, PC_PERM_USE_ALL_EQUIPMENT)) return 1; if(item == NULL) @@ -866,12 +908,10 @@ int pc_isequip(struct map_session_data *sd,int n) clif->msg(sd, 0x6ED); return 0; } -#ifdef RENEWAL if(item->elvmax && sd->status.base_level > (unsigned int)item->elvmax){ clif->msg(sd, 0x6ED); return 0; } -#endif if(item->sex != 2 && sd->status.sex != item->sex) return 0; @@ -911,10 +951,10 @@ int pc_isequip(struct map_session_data *sd,int n) return 0; //Not usable by upper class. [Inkfish] while( 1 ) { - if( item->class_upper&1 && !(sd->class_&(JOBL_UPPER|JOBL_THIRD|JOBL_BABY)) ) break; - if( item->class_upper&2 && sd->class_&(JOBL_UPPER|JOBL_THIRD) ) break; - if( item->class_upper&4 && sd->class_&JOBL_BABY ) break; - if( item->class_upper&8 && sd->class_&JOBL_THIRD ) break; + if( item->class_upper&ITEMUPPER_NORMAL && !(sd->class_&(JOBL_UPPER|JOBL_THIRD|JOBL_BABY)) ) break; + if( item->class_upper&ITEMUPPER_UPPER && sd->class_&(JOBL_UPPER|JOBL_THIRD) ) break; + if( item->class_upper&ITEMUPPER_BABY && sd->class_&JOBL_BABY ) break; + if( item->class_upper&ITEMUPPER_THIRD && sd->class_&JOBL_THIRD ) break; return 0; } @@ -927,11 +967,11 @@ int pc_isequip(struct map_session_data *sd,int n) *------------------------------------------*/ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_time, int group_id, struct mmo_charstatus *st, bool changing_mapservers) { int i; - unsigned long tick = timer->gettick(); + int64 tick = timer->gettick(); uint32 ip = session[sd->fd]->client_addr; sd->login_id2 = login_id2; - + if (pc->set_group(sd, group_id) != 0) { ShowWarning("pc_authok: %s (AID:%d) logged in with unknown group id (%d)! kicking...\n", st->name, sd->status.account_id, group_id); @@ -977,6 +1017,7 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim sd->npc_timer_id = INVALID_TIMER; sd->pvp_timer = INVALID_TIMER; sd->fontcolor_tid = INVALID_TIMER; + sd->expiration_tid = INVALID_TIMER; /** * For the Secure NPC Timeout option (check config/Secure.h) [RR] **/ @@ -997,7 +1038,7 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim sd->cansendmail_tick = tick; sd->hchsysch_tick = tick; - sd->idletime = last_tick; + sd->idletime = sockt->last_tick; for(i = 0; i < MAX_SPIRITBALL; i++) sd->spirit_timer[i] = INVALID_TIMER; @@ -1053,6 +1094,9 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim sd->delayed_damage = 0; + if( battle_config.item_check ) + sd->state.itemcheck = 1; + // Event Timers for( i = 0; i < MAX_EVENTTIMER; i++ ) sd->eventtimer[i] = INVALID_TIMER; @@ -1062,12 +1106,22 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim for( i = 0; i < 3; i++ ) sd->hate_mob[i] = -1; - //warp player + sd->quest_log = NULL; + sd->num_quests = 0; + sd->avail_quests = 0; + sd->save_quest = false; + + sd->var_db = i64db_alloc(DB_OPT_BASE); + sd->vars_dirty = false; + sd->vars_ok = false; + sd->vars_received = 0x0; + + //warp player if ((i=pc->setpos(sd,sd->status.last_point.map, sd->status.last_point.x, sd->status.last_point.y, CLR_OUTSIGHT)) != 0) { ShowError ("Last_point_map %s - id %d not found (error code %d)\n", mapindex_id2name(sd->status.last_point.map), sd->status.last_point.map, i); // try warping to a default map instead (church graveyard) - if (pc->setpos(sd, mapindex_name2id(MAP_PRONTERA), 273, 354, CLR_OUTSIGHT) != 0) { + if (pc->setpos(sd, mapindex->name2id(MAP_PRONTERA), 273, 354, CLR_OUTSIGHT) != 0) { // if we fail again clif->authfail_fd(sd->fd, 0); return false; @@ -1104,11 +1158,8 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim clif->message(sd->fd, buf); } - // message of the limited time of the account - if (expiration_time != 0) { // don't display if it's unlimited or unknow value - char tmpstr[1024]; - strftime(tmpstr, sizeof(tmpstr) - 1, msg_txt(501), localtime(&expiration_time)); // "Your account time limit is: %d-%m-%Y %H:%M:%S." - clif->wis_message(sd->fd, map->wisp_server_name, tmpstr, strlen(tmpstr)+1); + if (expiration_time != 0) { + sd->expiration_time = expiration_time; } /** @@ -1126,7 +1177,12 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim * Check if player have any item cooldowns on **/ pc->itemcd_do(sd,true); - + +#ifdef GP_BOUND_ITEMS + if( sd->status.party_id == 0 ) + pc->bound_clear(sd,IBT_PARTY); +#endif + /* [Ind/Hercules] */ sd->sc_display = NULL; sd->sc_display_count = 0; @@ -1166,7 +1222,7 @@ int pc_set_hate_mob(struct map_session_data *sd, int pos, struct block_list *bl) return 0; //Wrong size } sd->hate_mob[pos] = class_; - pc_setglobalreg(sd,pc->sg_info[pos].hate_var,class_+1); + pc_setglobalreg(sd,script->add_str(pc->sg_info[pos].hate_var),class_+1); clif->hate_info(sd, pos, class_, 1); return 1; } @@ -1178,55 +1234,58 @@ int pc_reg_received(struct map_session_data *sd) { int i,j, idx = 0; - sd->change_level_2nd = pc_readglobalreg(sd,"jobchange_level"); - sd->change_level_3rd = pc_readglobalreg(sd,"jobchange_level_3rd"); - sd->die_counter = pc_readglobalreg(sd,"PC_DIE_COUNTER"); + sd->vars_ok = true; + + sd->change_level_2nd = pc_readglobalreg(sd,script->add_str("jobchange_level")); + sd->change_level_3rd = pc_readglobalreg(sd,script->add_str("jobchange_level_3rd")); + sd->die_counter = pc_readglobalreg(sd,script->add_str("PC_DIE_COUNTER")); // Cash shop - sd->cashPoints = pc_readaccountreg(sd,"#CASHPOINTS"); - sd->kafraPoints = pc_readaccountreg(sd,"#KAFRAPOINTS"); + sd->cashPoints = pc_readaccountreg(sd,script->add_str("#CASHPOINTS")); + sd->kafraPoints = pc_readaccountreg(sd,script->add_str("#KAFRAPOINTS")); // Cooking Exp - sd->cook_mastery = pc_readglobalreg(sd,"COOK_MASTERY"); + sd->cook_mastery = pc_readglobalreg(sd,script->add_str("COOK_MASTERY")); if( (sd->class_&MAPID_BASEMASK) == MAPID_TAEKWON ) { // Better check for class rather than skill to prevent "skill resets" from unsetting this - sd->mission_mobid = pc_readglobalreg(sd,"TK_MISSION_ID"); - sd->mission_count = pc_readglobalreg(sd,"TK_MISSION_COUNT"); + sd->mission_mobid = pc_readglobalreg(sd,script->add_str("TK_MISSION_ID")); + sd->mission_count = pc_readglobalreg(sd,script->add_str("TK_MISSION_COUNT")); } //SG map and mob read [Komurka] for(i=0;i<MAX_PC_FEELHATE;i++) { //for now - someone need to make reading from txt/sql - if ((j = pc_readglobalreg(sd,pc->sg_info[i].feel_var))!=0) { + if ((j = pc_readglobalreg(sd,script->add_str(pc->sg_info[i].feel_var)))!=0) { sd->feel_map[i].index = j; sd->feel_map[i].m = map->mapindex2mapid(j); } else { sd->feel_map[i].index = 0; sd->feel_map[i].m = -1; } - sd->hate_mob[i] = pc_readglobalreg(sd,pc->sg_info[i].hate_var)-1; + sd->hate_mob[i] = pc_readglobalreg(sd,script->add_str(pc->sg_info[i].hate_var))-1; } if ((i = pc->checkskill(sd,RG_PLAGIARISM)) > 0) { - sd->cloneskill_id = pc_readglobalreg(sd,"CLONE_SKILL"); + sd->cloneskill_id = pc_readglobalreg(sd,script->add_str("CLONE_SKILL")); if (sd->cloneskill_id > 0 && (idx = skill->get_index(sd->cloneskill_id))) { sd->status.skill[idx].id = sd->cloneskill_id; - sd->status.skill[idx].lv = pc_readglobalreg(sd,"CLONE_SKILL_LV"); + sd->status.skill[idx].lv = pc_readglobalreg(sd,script->add_str("CLONE_SKILL_LV")); if (sd->status.skill[idx].lv > i) sd->status.skill[idx].lv = i; sd->status.skill[idx].flag = SKILL_FLAG_PLAGIARIZED; } } if ((i = pc->checkskill(sd,SC_REPRODUCE)) > 0) { - sd->reproduceskill_id = pc_readglobalreg(sd,"REPRODUCE_SKILL"); + sd->reproduceskill_id = pc_readglobalreg(sd,script->add_str("REPRODUCE_SKILL")); if( sd->reproduceskill_id > 0 && (idx = skill->get_index(sd->reproduceskill_id))) { sd->status.skill[idx].id = sd->reproduceskill_id; - sd->status.skill[idx].lv = pc_readglobalreg(sd,"REPRODUCE_SKILL_LV"); + sd->status.skill[idx].lv = pc_readglobalreg(sd,script->add_str("REPRODUCE_SKILL_LV")); if( i < sd->status.skill[idx].lv) sd->status.skill[idx].lv = i; sd->status.skill[idx].flag = SKILL_FLAG_PLAGIARIZED; } } + //Weird... maybe registries were reloaded? if (sd->state.active) return 0; @@ -1256,7 +1315,7 @@ int pc_reg_received(struct map_session_data *sd) pc->load_combo(sd); - status_calc_pc(sd,1); + status_calc_pc(sd,SCO_FIRST|SCO_FORCE); chrif->scdata_request(sd->status.account_id, sd->status.char_id); intif->Mail_requestinbox(sd->status.char_id, 0); // MAIL SYSTEM - Request Mail Inbox @@ -1267,8 +1326,6 @@ int pc_reg_received(struct map_session_data *sd) clif->pLoadEndAck(sd->fd, sd); } - pc->inventory_rentals(sd); - if( sd->sc.option & OPTION_INVISIBLE ) { sd->vd.class_ = INVISIBLE_CLASS; clif->message(sd->fd, msg_txt(11)); // Invisible: On @@ -1284,7 +1341,7 @@ int pc_reg_received(struct map_session_data *sd) if( npc->motd ) /* [Ind/Hercules] */ script->run(npc->motd->u.scr.script, 0, sd->bl.id, npc->fake_nd->bl.id); - + return 1; } @@ -1372,7 +1429,7 @@ int pc_calc_skilltree(struct map_session_data *sd) } } - if( pc->has_permission(sd, PC_PERM_ALL_SKILL) ) { + if( pc_has_permission(sd, PC_PERM_ALL_SKILL) ) { for( i = 0; i < MAX_SKILL; i++ ) { switch(skill->db[i].nameid) { /** @@ -1393,7 +1450,6 @@ int pc_calc_skilltree(struct map_session_data *sd) case WL_SUMMON_ATK_GROUND: case LG_OVERBRAND_BRANDISH: case LG_OVERBRAND_PLUSATK: - case WM_SEVERE_RAINSTORM_MELEE: continue; default: break; @@ -1568,7 +1624,7 @@ int pc_calc_skilltree_normalize_job(struct map_session_data *sd) int skill_point, novice_skills; int c = sd->class_; - if (!battle_config.skillup_limit || pc->has_permission(sd, PC_PERM_ALL_SKILL)) + if (!battle_config.skillup_limit || pc_has_permission(sd, PC_PERM_ALL_SKILL)) return c; skill_point = pc->calc_skillpoint(sd); @@ -1606,7 +1662,7 @@ int pc_calc_skilltree_normalize_job(struct map_session_data *sd) } - pc_setglobalreg (sd, "jobchange_level", sd->change_level_2nd); + pc_setglobalreg (sd, script->add_str("jobchange_level"), sd->change_level_2nd); } if (skill_point < novice_skills + (sd->change_level_2nd - 1)) { @@ -1619,7 +1675,7 @@ int pc_calc_skilltree_normalize_job(struct map_session_data *sd) - (sd->status.job_level - 1) - (sd->change_level_2nd - 1) - novice_skills; - pc_setglobalreg (sd, "jobchange_level_3rd", sd->change_level_3rd); + pc_setglobalreg (sd, script->add_str("jobchange_level_3rd"), sd->change_level_3rd); } if (skill_point < novice_skills + (sd->change_level_2nd - 1) + (sd->change_level_3rd - 1)) { @@ -1663,9 +1719,9 @@ int pc_updateweightstatus(struct map_session_data *sd) // start new status change if( new_overweight == 1 ) - sc_start(&sd->bl, SC_WEIGHTOVER50, 100, 0, 0); + sc_start(NULL,&sd->bl, SC_WEIGHTOVER50, 100, 0, 0); else if( new_overweight == 2 ) - sc_start(&sd->bl, SC_WEIGHTOVER90, 100, 0, 0); + sc_start(NULL,&sd->bl, SC_WEIGHTOVER90, 100, 0, 0); // update overweight status sd->regen.state.overweight = new_overweight; @@ -1711,9 +1767,8 @@ int pc_disguise(struct map_session_data *sd, int class_) { } if (sd->chatID) { struct chat_data* cd; - nullpo_retr(1, sd); - cd = (struct chat_data*)map->id2bl(sd->chatID); - if( cd != NULL || (struct block_list*)sd == cd->owner ) + + if( (cd = (struct chat_data*)map->id2bl(sd->chatID)) ) clif->dispchat(cd,0); } } @@ -1928,8 +1983,8 @@ int pc_delautobonus(struct map_session_data* sd, struct s_autobonus *autobonus,c if( autobonus[i].bonus_script ) { int j; - ARR_FIND( 0, EQI_MAX-1, j, sd->equip_index[j] >= 0 && sd->status.inventory[sd->equip_index[j]].equip == autobonus[i].pos ); - if( j < EQI_MAX-1 ) + ARR_FIND( 0, EQI_MAX, j, sd->equip_index[j] >= 0 && sd->status.inventory[sd->equip_index[j]].equip == autobonus[i].pos ); + if( j < EQI_MAX ) script->run_autobonus(autobonus[i].bonus_script,sd->bl.id,sd->equip_index[j]); } continue; @@ -1959,19 +2014,19 @@ int pc_exeautobonus(struct map_session_data *sd,struct s_autobonus *autobonus) if( autobonus->other_script ) { int j; - ARR_FIND( 0, EQI_MAX-1, j, sd->equip_index[j] >= 0 && sd->status.inventory[sd->equip_index[j]].equip == autobonus->pos ); - if( j < EQI_MAX-1 ) + ARR_FIND( 0, EQI_MAX, j, sd->equip_index[j] >= 0 && sd->status.inventory[sd->equip_index[j]].equip == autobonus->pos ); + if( j < EQI_MAX ) script->run_autobonus(autobonus->other_script,sd->bl.id,sd->equip_index[j]); } autobonus->active = timer->add(timer->gettick()+autobonus->duration, pc->endautobonus, sd->bl.id, (intptr_t)autobonus); sd->state.autobonus |= autobonus->pos; - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_NONE); return 0; } -int pc_endautobonus(int tid, unsigned int tick, int id, intptr_t data) { +int pc_endautobonus(int tid, int64 tick, int id, intptr_t data) { struct map_session_data *sd = map->id2sd(id); struct s_autobonus *autobonus = (struct s_autobonus *)data; @@ -1980,7 +2035,7 @@ int pc_endautobonus(int tid, unsigned int tick, int id, intptr_t data) { autobonus->active = INVALID_TIMER; sd->state.autobonus &= ~autobonus->pos; - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_NONE); return 0; } @@ -3487,7 +3542,7 @@ int pc_skill(TBL_PC* sd, int id, int level, int flag) { } else clif->addskill(sd,id); if( !skill->db[index].inf ) //Only recalculate for passive skills. - status_calc_pc(sd, 0); + status_calc_pc(sd, SCO_NONE); break; case 1: //Item bonus skill. if( sd->status.skill[index].id == id ) { @@ -3521,7 +3576,7 @@ int pc_skill(TBL_PC* sd, int id, int level, int flag) { } else clif->addskill(sd,id); if( !skill->db[index].inf ) //Only recalculate for passive skills. - status_calc_pc(sd, 0); + status_calc_pc(sd, SCO_NONE); break; default: //Unknown flag? return 0; @@ -3697,7 +3752,7 @@ int pc_payzeny(struct map_session_data *sd,int zeny, enum e_log_pick_type type, if( zeny > 0 && sd->state.showzeny ) { char output[255]; sprintf(output, "Removed %dz.", zeny); - clif->disp_onlyself(sd,output,strlen(output)); + clif_disp_onlyself(sd,output,strlen(output)); } return 0; @@ -3732,14 +3787,14 @@ int pc_paycash(struct map_session_data *sd, int price, int points) return -1; } - pc_setaccountreg(sd, "#CASHPOINTS", sd->cashPoints-cash); - pc_setaccountreg(sd, "#KAFRAPOINTS", sd->kafraPoints-points); + pc_setaccountreg(sd, script->add_str("#CASHPOINTS"), sd->cashPoints-cash); + pc_setaccountreg(sd, script->add_str("#KAFRAPOINTS"), sd->kafraPoints-points); if( battle_config.cashshop_show_points ) { char output[128]; sprintf(output, msg_txt(504), points, cash, sd->kafraPoints, sd->cashPoints); - clif->disp_onlyself(sd, output, strlen(output)); + clif_disp_onlyself(sd, output, strlen(output)); } return cash+points; } @@ -3759,12 +3814,12 @@ int pc_getcash(struct map_session_data *sd, int cash, int points) cash = MAX_ZENY-sd->cashPoints; } - pc_setaccountreg(sd, "#CASHPOINTS", sd->cashPoints+cash); + pc_setaccountreg(sd, script->add_str("#CASHPOINTS"), sd->cashPoints+cash); if( battle_config.cashshop_show_points ) { sprintf(output, msg_txt(505), cash, sd->cashPoints); - clif->disp_onlyself(sd, output, strlen(output)); + clif_disp_onlyself(sd, output, strlen(output)); } return cash; } @@ -3782,12 +3837,12 @@ int pc_getcash(struct map_session_data *sd, int cash, int points) points = MAX_ZENY-sd->kafraPoints; } - pc_setaccountreg(sd, "#KAFRAPOINTS", sd->kafraPoints+points); + pc_setaccountreg(sd, script->add_str("#KAFRAPOINTS"), sd->kafraPoints+points); if( battle_config.cashshop_show_points ) { sprintf(output, msg_txt(506), points, sd->kafraPoints); - clif->disp_onlyself(sd, output, strlen(output)); + clif_disp_onlyself(sd, output, strlen(output)); } return points; } @@ -3825,7 +3880,7 @@ int pc_getzeny(struct map_session_data *sd,int zeny, enum e_log_pick_type type, if( zeny > 0 && sd->state.showzeny ) { char output[255]; sprintf(output, "Gained %dz.", zeny); - clif->disp_onlyself(sd,output,strlen(output)); + clif_disp_onlyself(sd,output,strlen(output)); } return 0; @@ -3880,14 +3935,37 @@ int pc_additem(struct map_session_data *sd,struct item *item_data,int amount,e_l if(sd->weight + w > sd->max_weight) return 2; + if( item_data->bound ) { + switch( (enum e_item_bound_type)item_data->bound ) { + case IBT_CHARACTER: + case IBT_ACCOUNT: + break; /* no restrictions */ + case IBT_PARTY: + if( !sd->status.party_id ) { + ShowError("pc_additem: can't add party_bound item to character without party!\n"); + ShowError("pc_additem: %s - x%d %s (%d)\n",sd->status.name,amount,data->jname,data->nameid); + return 7;/* need proper code? */ + } + break; + case IBT_GUILD: + if( !sd->status.guild_id ) { + ShowError("pc_additem: can't add guild_bound item to character without guild!\n"); + ShowError("pc_additem: %s - x%d %s (%d)\n",sd->status.name,amount,data->jname,data->nameid); + return 7;/* need proper code? */ + } + break; + } + } + i = MAX_INVENTORY; - if( itemdb->isstackable2(data) && item_data->expire_time == 0 ) - { // Stackable | Non Rental - for( i = 0; i < MAX_INVENTORY; i++ ) - { - if( sd->status.inventory[i].nameid == item_data->nameid && memcmp(&sd->status.inventory[i].card, &item_data->card, sizeof(item_data->card)) == 0 ) - { + // Stackable | Non Rental + if( itemdb->isstackable2(data) && item_data->expire_time == 0 ) { + for( i = 0; i < MAX_INVENTORY; i++ ) { + if( sd->status.inventory[i].nameid == item_data->nameid && + sd->status.inventory[i].bound == item_data->bound && + sd->status.inventory[i].expire_time == 0 && + memcmp(&sd->status.inventory[i].card, &item_data->card, sizeof(item_data->card)) == 0 ) { if( amount > MAX_AMOUNT - sd->status.inventory[i].amount || ( data->stack.inventory && amount > data->stack.amount - sd->status.inventory[i].amount ) ) return 5; sd->status.inventory[i].amount += amount; @@ -3904,9 +3982,11 @@ int pc_additem(struct map_session_data *sd,struct item *item_data,int amount,e_l return 4; memcpy(&sd->status.inventory[i], item_data, sizeof(sd->status.inventory[0])); - // clear equips field first, just in case + // clear equip and favorite fields first, just in case if( item_data->equip ) sd->status.inventory[i].equip = 0; + if( item_data->favorite ) + sd->status.inventory[i].favorite = 0; sd->status.inventory[i].amount = amount; sd->inventory_data[i] = data; @@ -3927,8 +4007,7 @@ int pc_additem(struct map_session_data *sd,struct item *item_data,int amount,e_l /* rental item check */ if( item_data->expire_time ) { if( time(NULL) > item_data->expire_time ) { - clif->rental_expired(sd->fd, i, sd->status.inventory[i].nameid); - pc->delitem(sd, i, sd->status.inventory[i].amount, 1, 0, LOG_TYPE_OTHER); + pc->rental_expire(sd,i); } else { int seconds = (int)( item_data->expire_time - time(NULL) ); clif->rental_time(sd->fd, sd->status.inventory[i].nameid, seconds); @@ -4026,7 +4105,7 @@ int pc_dropitem(struct map_session_data *sd,int n,int amount) int pc_takeitem(struct map_session_data *sd,struct flooritem_data *fitem) { int flag=0; - unsigned int tick = timer->gettick(); + int64 tick = timer->gettick(); struct map_session_data *first_sd = NULL,*second_sd = NULL,*third_sd = NULL; struct party_data *p=NULL; @@ -4109,95 +4188,98 @@ int pc_isUseitem(struct map_session_data *sd,int n) if( !item->script ) //if it has no script, you can't really consume it! return 0; - if( (item->item_usage.flag&NOUSE_SITTING) && (pc_issit(sd) == 1) && (pc->get_group_level(sd) < item->item_usage.override) ) { + if( (item->item_usage.flag&NOUSE_SITTING) && (pc_issit(sd) == 1) && (pc_get_group_level(sd) < item->item_usage.override) ) { clif->msgtable(sd->fd,0x297); //clif->colormes(sd->fd,COLOR_WHITE,msg_txt(1474)); return 0; // You cannot use this item while sitting. } - switch( nameid ) //@TODO, lot oh harcoded nameid here - { - case 605: // Anodyne + if (sd->state.storage_flag && item->type != IT_CASH) { + clif->colormes(sd->fd, COLOR_RED, msg_txt(1475)); + return 0; // You cannot use this item while storage is open. + } + + switch( nameid ) { // TODO: Is there no better way to handle this, other than hardcoding item IDs? + case ITEMID_ANODYNE: if( map_flag_gvg2(sd->bl.m) ) return 0; - case 606: + case ITEMID_ALOEBERA: if( pc_issit(sd) ) return 0; break; - case 601: // Fly Wing - case 12212: // Giant Fly Wing + case ITEMID_WING_OF_FLY: + case ITEMID_GIANT_FLY_WING: if( map->list[sd->bl.m].flag.noteleport || map_flag_gvg2(sd->bl.m) ) { clif->skill_mapinfomessage(sd,0); return 0; } - case 602: // ButterFly Wing - case 14527: // Dungeon Teleport Scroll - case 14581: // Dungeon Teleport Scroll - case 14582: // Yellow Butterfly Wing - case 14583: // Green Butterfly Wing - case 14584: // Red Butterfly Wing - case 14585: // Blue Butterfly Wing - case 14591: // Siege Teleport Scroll + case ITEMID_WING_OF_BUTTERFLY: + case ITEMID_DUN_TELE_SCROLL1: + case ITEMID_DUN_TELE_SCROLL2: + case ITEMID_WOB_RUNE: // Yellow Butterfly Wing + case ITEMID_WOB_SCHWALTZ: // Green Butterfly Wing + case ITEMID_WOB_RACHEL: // Red Butterfly Wing + case ITEMID_WOB_LOCAL: // Blue Butterfly Wing + case ITEMID_SIEGE_TELEPORT_SCROLL: if( sd->duel_group && !battle_config.duel_allow_teleport ) { clif->message(sd->fd, msg_txt(663)); return 0; } - if( nameid != 601 && nameid != 12212 && map->list[sd->bl.m].flag.noreturn ) + if( nameid != ITEMID_WING_OF_FLY && nameid != ITEMID_GIANT_FLY_WING && map->list[sd->bl.m].flag.noreturn ) return 0; break; - case 604: // Dead Branch - case 12024: // Red Pouch - case 12103: // Bloody Branch - case 12109: // Poring Box + case ITEMID_BRANCH_OF_DEAD_TREE: + case ITEMID_RED_POUCH_OF_SURPRISE: + case ITEMID_BLOODY_DEAD_BRANCH: + case ITEMID_PORING_BOX: if( map->list[sd->bl.m].flag.nobranch || map_flag_gvg2(sd->bl.m) ) return 0; break; - case 12210: // Bubble Gum - case 12264: // Comp Bubble Gum + case ITEMID_BUBBLE_GUM: + case ITEMID_COMP_BUBBLE_GUM: if( sd->sc.data[SC_CASH_RECEIVEITEM] ) return 0; break; - case 12208: // Battle Manual - case 12263: // Comp Battle Manual - case 12312: // Thick Battle Manual - case 12705: // Noble Nameplate - case 14532: // Battle_Manual25 - case 14533: // Battle_Manual100 - case 14545: // Battle_Manual300 + case ITEMID_BATTLE_MANUAL: + case ITEMID_COMP_BATTLE_MANUAL: + case ITEMID_THICK_MANUAL50: + case ITEMID_NOBLE_NAMEPLATE: + case ITEMID_BATTLE_MANUAL25: + case ITEMIDBATTLE_MANUAL100: + case ITEMID_BATTLE_MANUAL_X3: if( sd->sc.data[SC_CASH_PLUSEXP] ) return 0; break; - case 14592: // JOB_Battle_Manual + case ITEMID_JOB_MANUAL50: if( sd->sc.data[SC_CASH_PLUSONLYJOBEXP] ) return 0; break; // Mercenary Items - - case 12184: // Mercenary's Red Potion - case 12185: // Mercenary's Blue Potion - case 12241: // Mercenary's Concentration Potion - case 12242: // Mercenary's Awakening Potion - case 12243: // Mercenary's Berserk Potion + case ITEMID_MERCENARY_RED_POTION: + case ITEMID_MERCENARY_BLUE_POTION: + case ITEMID_M_CENTER_POTION: + case ITEMID_M_AWAKENING_POTION: + case ITEMID_M_BERSERK_POTION: if( sd->md == NULL || sd->md->db == NULL ) return 0; - if (sd->md->sc.data[SC_BERSERK] || sd->md->sc.data[SC_SATURDAY_NIGHT_FEVER]) + if (sd->md->sc.data[SC_BERSERK]) return 0; - if( nameid == 12242 && sd->md->db->lv < 40 ) + if( nameid == ITEMID_M_AWAKENING_POTION && sd->md->db->lv < 40 ) return 0; - if( nameid == 12243 && sd->md->db->lv < 80 ) + if( nameid == ITEMID_M_BERSERK_POTION && sd->md->db->lv < 80 ) return 0; break; - case 12213: //Neuralizer + case ITEMID_NEURALIZER: if( !map->list[sd->bl.m].flag.reset ) return 0; break; } - if( nameid >= 12153 && nameid <= 12182 && sd->md != NULL ) - return 0; // Mercenary Scrolls + if( nameid >= ITEMID_BOW_MERCENARY_SCROLL1 && nameid <= ITEMID_SPEARMERCENARY_SCROLL10 && sd->md != NULL ) // Mercenary Scrolls + return 0; /** * Only Rune Knights may use runes @@ -4210,10 +4292,15 @@ int pc_isUseitem(struct map_session_data *sd,int n) else if( itemdb_is_poison(nameid) && (sd->class_&MAPID_THIRDMASK) != MAPID_GUILLOTINE_CROSS ) return 0; - if( (item->package || item->group) && pc_is90overweight(sd) ) { - //##TODO## find official response to this - clif->colormes(sd->fd,COLOR_RED,msg_txt(1477));// Item cannot be open when overweight by 90% - return 0; + if( item->package || item->group ) { + if( pc_is90overweight(sd) ) { + clif->msgtable(sd->fd,ITEM_CANT_OBTAIN_WEIGHT); + return 0; + } + if( !pc->inventoryblank(sd) ) { + clif->colormes(sd->fd,COLOR_RED,msg_txt(1477)); + return 0; + } } //Gender check @@ -4225,12 +4312,10 @@ int pc_isUseitem(struct map_session_data *sd,int n) return 0; } -#ifdef RENEWAL if(item->elvmax && sd->status.base_level > (unsigned int)item->elvmax){ clif->msg(sd, 0x6EE); return 0; } -#endif //Not equipable by class. [Skotlex] if (!( @@ -4242,30 +4327,25 @@ int pc_isUseitem(struct map_session_data *sd,int n) //Not usable by upper class. [Haru] while( 1 ) { // Normal classes (no upper, no baby, no third classes) - if( item->class_upper&0x01 && !(sd->class_&(JOBL_UPPER|JOBL_THIRD|JOBL_BABY)) ) break; + if( item->class_upper&ITEMUPPER_NORMAL && !(sd->class_&(JOBL_UPPER|JOBL_THIRD|JOBL_BABY)) ) break; #ifdef RENEWAL // Upper classes (no third classes) - if( item->class_upper&0x02 && sd->class_&JOBL_UPPER && !(sd->class_&JOBL_THIRD) ) break; + if( item->class_upper&ITEMUPPER_UPPER && sd->class_&JOBL_UPPER && !(sd->class_&JOBL_THIRD) ) break; #else //pre-re has no use for the extra, so we maintain the previous for backwards compatibility - if( item->class_upper&0x02 && sd->class_&(JOBL_UPPER|JOBL_THIRD) ) break; + if( item->class_upper&ITEMUPPER_UPPER && sd->class_&(JOBL_UPPER|JOBL_THIRD) ) break; #endif // Baby classes (no third classes) - if( item->class_upper&0x04 && sd->class_&JOBL_BABY && !(sd->class_&JOBL_THIRD) ) break; + if( item->class_upper&ITEMUPPER_BABY && sd->class_&JOBL_BABY && !(sd->class_&JOBL_THIRD) ) break; // Third classes (no upper, no baby classes) - if( item->class_upper&0x08 && sd->class_&JOBL_THIRD && !(sd->class_&(JOBL_UPPER|JOBL_BABY)) ) break; + if( item->class_upper&ITEMUPPER_THIRD && sd->class_&JOBL_THIRD && !(sd->class_&(JOBL_UPPER|JOBL_BABY)) ) break; // Upper third classes - if( item->class_upper&0x10 && sd->class_&JOBL_THIRD && sd->class_&JOBL_UPPER ) break; + if( item->class_upper&ITEMUPPER_THURDUPPER && sd->class_&JOBL_THIRD && sd->class_&JOBL_UPPER ) break; // Baby third classes - if( item->class_upper&0x20 && sd->class_&JOBL_THIRD && sd->class_&JOBL_BABY ) break; + if( item->class_upper&ITEMUPPER_THIRDBABY && sd->class_&JOBL_THIRD && sd->class_&JOBL_BABY ) break; return 0; } - //Dead Branch & Bloody Branch & Porings Box - // FIXME: outdated, use constants or database - if( nameid == 604 || nameid == 12103 || nameid == 12109 ) - logs->branch(sd); - return 1; } @@ -4276,7 +4356,7 @@ int pc_isUseitem(struct map_session_data *sd,int n) * 1 = success *------------------------------------------*/ int pc_useitem(struct map_session_data *sd,int n) { - unsigned int tick = timer->gettick(); + int64 tick = timer->gettick(); int amount, nameid, i; struct script_code *item_script; @@ -4308,9 +4388,12 @@ int pc_useitem(struct map_session_data *sd,int n) { sd->sc.data[SC_TRICKDEAD] || sd->sc.data[SC_HIDING] || sd->sc.data[SC__SHADOWFORM] || + sd->sc.data[SC__INVISIBILITY] || sd->sc.data[SC__MANHOLE] || sd->sc.data[SC_KG_KAGEHUMI] || sd->sc.data[SC_WHITEIMPRISON] || + sd->sc.data[SC_DEEP_SLEEP] || + sd->sc.data[SC_SATURDAY_NIGHT_FEVER] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOITEM) )) return 0; @@ -4336,14 +4419,13 @@ int pc_useitem(struct map_session_data *sd,int n) { return 0; if( sd->inventory_data[n]->delay > 0 ) { - int i; ARR_FIND(0, MAX_ITEMDELAYS, i, sd->item_delay[i].nameid == nameid ); if( i == MAX_ITEMDELAYS ) /* item not found. try first empty now */ ARR_FIND(0, MAX_ITEMDELAYS, i, !sd->item_delay[i].nameid ); if( i < MAX_ITEMDELAYS ) { if( sd->item_delay[i].nameid ) {// found if( DIFF_TICK(sd->item_delay[i].tick, tick) > 0 ) { - int e_tick = DIFF_TICK(sd->item_delay[i].tick, tick)/1000; + int e_tick = (int)(DIFF_TICK(sd->item_delay[i].tick, tick)/1000); clif->msgtable_num(sd->fd, 0x746, e_tick + 1); // [%d] seconds left until you can use return 0; // Delay has not expired yet } @@ -4376,6 +4458,10 @@ int pc_useitem(struct map_session_data *sd,int n) { } } + //Dead Branch & Bloody Branch & Porings Box + if( nameid == ITEMID_BRANCH_OF_DEAD_TREE || nameid == ITEMID_BLOODY_DEAD_BRANCH || nameid == ITEMID_PORING_BOX ) + logs->branch(sd); + sd->itemid = sd->status.inventory[n].nameid; sd->itemindex = n; if(sd->catch_target_class != -1) //Abort pet catching. @@ -4439,8 +4525,8 @@ int pc_cart_additem(struct map_session_data *sd,struct item *item_data,int amoun return 1; } - if( !itemdb_cancartstore(item_data, pc->get_group_level(sd)) ) - { // Check item trade restrictions [Skotlex] + if( !itemdb_cancartstore(item_data, pc_get_group_level(sd)) || (item_data->bound > IBT_ACCOUNT && !pc_can_give_bound_items(sd))) + { // Check item trade restrictions [Skotlex] clif->message (sd->fd, msg_txt(264)); return 1;/* TODO: there is no official response to this? */ } @@ -4452,8 +4538,8 @@ int pc_cart_additem(struct map_session_data *sd,struct item *item_data,int amoun if( itemdb->isstackable2(data) && !item_data->expire_time ) { ARR_FIND( 0, MAX_CART, i, - sd->status.cart[i].nameid == item_data->nameid && - sd->status.cart[i].card[0] == item_data->card[0] && sd->status.cart[i].card[1] == item_data->card[1] && + sd->status.cart[i].nameid == item_data->nameid && sd->status.cart[i].bound == item_data->bound && + sd->status.cart[i].card[0] == item_data->card[0] && sd->status.cart[i].card[1] == item_data->card[1] && sd->status.cart[i].card[2] == item_data->card[2] && sd->status.cart[i].card[3] == item_data->card[3] ); }; @@ -4586,7 +4672,39 @@ int pc_getitemfromcart(struct map_session_data *sd,int idx,int amount) return flag; } - +void pc_bound_clear(struct map_session_data *sd, enum e_item_bound_type type) { + int i; + + switch( type ) { + /* both restricted to inventory */ + case IBT_PARTY: + case IBT_CHARACTER: + for( i = 0; i < MAX_INVENTORY; i++ ){ + if( sd->status.inventory[i].bound == type ) { + pc->delitem(sd,i,sd->status.inventory[i].amount,0,1,LOG_TYPE_OTHER); + } + } + break; + case IBT_ACCOUNT: + ShowError("Helllo! You reached pc_bound_clear for IBT_ACCOUNT, unfortunately no scenario was expected for this!\n"); + break; + case IBT_GUILD: { + struct guild_storage *gstor = gstorage->id2storage(sd->status.guild_id); + + for( i = 0; i < MAX_INVENTORY; i++ ){ + if(sd->status.inventory[i].bound == type) { + if( gstor ) + gstorage->additem(sd,gstor,&sd->status.inventory[i],sd->status.inventory[i].amount); + pc->delitem(sd,i,sd->status.inventory[i].amount,0,1,gstor?LOG_TYPE_GSTORAGE:LOG_TYPE_OTHER); + } + } + if( gstor ) + gstorage->close(sd); + } + break; + } + +} /*========================================== * Display item stolen msg to player sd *------------------------------------------*/ @@ -4690,14 +4808,16 @@ int pc_steal_item(struct map_session_data *sd,struct block_list *bl, uint16 skil return 1; } -/*========================================== - * Stole zeny from bl (mob) - * return - * 0 = fail - * 1 = success - *------------------------------------------*/ -int pc_steal_coin(struct map_session_data *sd,struct block_list *target) { - int rate,skill_lv; +/** + * Steals zeny from a monster through the RG_STEALCOIN skill. + * + * @param sd Source character + * @param target Target monster + * + * @return Amount of stolen zeny (0 in case of failure) + **/ +int pc_steal_coin(struct map_session_data *sd, struct block_list *target) { + int rate, skill_lv; struct mob_data *md; if(!sd || !target || target->type != BL_MOB) return 0; @@ -4709,15 +4829,14 @@ int pc_steal_coin(struct map_session_data *sd,struct block_list *target) { if( mob_is_treasure(md) ) return 0; - // FIXME: This formula is either custom or outdated. - skill_lv = pc->checkskill(sd,RG_STEALCOIN)*10; - rate = skill_lv + (sd->status.base_level - md->level)*3 + sd->battle_status.dex*2 + sd->battle_status.luk*2; + skill_lv = pc->checkskill(sd, RG_STEALCOIN); + rate = skill_lv*10 + (sd->status.base_level - md->level)*2 + sd->battle_status.dex/2 + sd->battle_status.luk/2; if(rnd()%1000 < rate) { - int amount = md->level*10 + rnd()%100; + int amount = md->level * skill_lv / 10 + md->level*8 + rnd()%(md->level*2 + 1); // mob_lv * skill_lv / 10 + random [mob_lv*8; mob_lv*10] pc->getzeny(sd, amount, LOG_TYPE_STEAL, NULL); md->state.steal_coin_flag = 1; - return 1; + return amount; } return 0; } @@ -4729,13 +4848,13 @@ int pc_steal_coin(struct map_session_data *sd,struct block_list *target) { * 1 - Invalid map index. * 2 - Map not in this map-server, and failed to locate alternate map-server. *------------------------------------------*/ -int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y, clr_type clrtype) { +int pc_setpos(struct map_session_data* sd, unsigned short map_index, int x, int y, clr_type clrtype) { int16 m; nullpo_ret(sd); - if( !mapindex || !mapindex_id2name(mapindex) || ( m = map->mapindex2mapid(mapindex) ) == -1 ) { - ShowDebug("pc_setpos: Passed mapindex(%d) is invalid!\n", mapindex); + if( !map_index || !mapindex_id2name(map_index) || ( m = map->mapindex2mapid(map_index) ) == -1 ) { + ShowDebug("pc_setpos: Passed mapindex(%d) is invalid!\n", map_index); return 1; } @@ -4759,7 +4878,7 @@ int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y } if( i != sd->instances ) { m = instance->list[sd->instance[i]].map[j]; - mapindex = map_id2index(m); + map_index = map_id2index(m); stop = true; } } @@ -4773,7 +4892,7 @@ int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y } if( i != p->instances ) { m = instance->list[p->instance[i]].map[j]; - mapindex = map_id2index(m); + map_index = map_id2index(m); stop = true; } } @@ -4787,13 +4906,22 @@ int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y } if( i != sd->guild->instances ) { m = instance->list[sd->guild->instance[i]].map[j]; - mapindex = map_id2index(m); - stop = true; + map_index = map_id2index(m); + //stop = true; Uncomment if adding new checks } } + + /* we hit a instance, if empty we populate the spawn data */ + if( map->list[m].instance_id >= 0 && instance->list[map->list[m].instance_id].respawn.map == 0 && + instance->list[map->list[m].instance_id].respawn.x == 0 && + instance->list[map->list[m].instance_id].respawn.y == 0) { + instance->list[map->list[m].instance_id].respawn.map = map_index; + instance->list[map->list[m].instance_id].respawn.x = x; + instance->list[map->list[m].instance_id].respawn.y = y; + } } - sd->state.changemap = (sd->mapindex != mapindex); + sd->state.changemap = (sd->mapindex != map_index); sd->state.warping = 1; sd->state.workinprogress = 0; if( sd->state.changemap ) { // Misc map-changing settings @@ -4819,6 +4947,10 @@ int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y status_change_end(&sd->bl, SC_MOON_COMFORT, INVALID_TIMER); status_change_end(&sd->bl, SC_STAR_COMFORT, INVALID_TIMER); status_change_end(&sd->bl, SC_MIRACLE, INVALID_TIMER); + status_change_end(&sd->bl, SC_NEUTRALBARRIER_MASTER, INVALID_TIMER);//Will later check if this is needed. [Rytech] + status_change_end(&sd->bl, SC_NEUTRALBARRIER, INVALID_TIMER); + status_change_end(&sd->bl, SC_STEALTHFIELD_MASTER, INVALID_TIMER); + status_change_end(&sd->bl, SC_STEALTHFIELD, INVALID_TIMER); if (sd->sc.data[SC_KNOWLEDGE]) { struct status_change_entry *sce = sd->sc.data[SC_KNOWLEDGE]; if (sce->timer != INVALID_TIMER) @@ -4856,7 +4988,7 @@ int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y uint32 ip; uint16 port; //if can't find any map-servers, just abort setting position. - if(!sd->mapindex || map->mapname2ipport(mapindex,&ip,&port)) + if(!sd->mapindex || map->mapname2ipport(map_index,&ip,&port)) return 2; if (sd->npc_id) @@ -4864,7 +4996,7 @@ int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y npc->script_event(sd, NPCE_LOGOUT); //remove from map, THEN change x/y coordinates unit->remove_map_pc(sd,clrtype); - sd->mapindex = mapindex; + sd->mapindex = map_index; sd->bl.x=x; sd->bl.y=y; pc->clean_skilltree(sd); @@ -4878,7 +5010,7 @@ int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y } if( x < 0 || x >= map->list[m].xs || y < 0 || y >= map->list[m].ys ) { - ShowError("pc_setpos: attempt to place player %s (%d:%d) on invalid coordinates (%s-%d,%d)\n", sd->status.name, sd->status.account_id, sd->status.char_id, mapindex_id2name(mapindex),x,y); + ShowError("pc_setpos: attempt to place player %s (%d:%d) on invalid coordinates (%s-%d,%d)\n", sd->status.name, sd->status.account_id, sd->status.char_id, mapindex_id2name(map_index),x,y); x = y = 0; // make it random } @@ -4901,7 +5033,7 @@ int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y //Tag player for rewarping after map-loading is done. [Skotlex] sd->state.rewarp = 1; - sd->mapindex = mapindex; + sd->mapindex = map_index; sd->bl.m = m; sd->bl.x = sd->ud.to_x = x; sd->bl.y = sd->ud.to_y = y; @@ -4932,6 +5064,10 @@ int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y sd->md->bl.y = sd->md->ud.to_y = y; sd->md->ud.dir = sd->ud.dir; } + + /* given autotrades have no clients you have to trigger this manually otherwise they get stuck in memory limbo bugreport:7495 */ + if( sd->state.autotrade ) + clif->pLoadEndAck(0,sd); return 0; } @@ -4975,7 +5111,7 @@ int pc_memo(struct map_session_data* sd, int pos) { nullpo_ret(sd); // check mapflags - if( sd->bl.m >= 0 && (map->list[sd->bl.m].flag.nomemo || map->list[sd->bl.m].flag.nowarpto) && !pc->has_permission(sd, PC_PERM_WARP_ANYWHERE) ) { + if( sd->bl.m >= 0 && (map->list[sd->bl.m].flag.nomemo || map->list[sd->bl.m].flag.nowarpto) && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE) ) { clif->skill_mapinfomessage(sd, 1); // "Saved point cannot be memorized." return 0; } @@ -5079,7 +5215,8 @@ int pc_checkallowskill(struct map_session_data *sd) SC_LKCONCENTRATION, SC_EDP, #endif - SC_FEARBREEZE + SC_FEARBREEZE, + SC_EXEEDBREAK, }; const enum sc_type scs_list[] = { SC_AUTOGUARD, @@ -5626,15 +5763,16 @@ const char* job_name(int class_) case JOB_KAGEROU: case JOB_OBORO: return msg_txt(653 - JOB_KAGEROU+class_); + case JOB_REBELLION: - return msg_txt(694); + return msg_txt(655); default: - return msg_txt(655); + return msg_txt(656); } } -int pc_follow_timer(int tid, unsigned int tick, int id, intptr_t data) { +int pc_follow_timer(int tid, int64 tick, int id, intptr_t data) { struct map_session_data *sd; struct block_list *tbl; @@ -5720,26 +5858,26 @@ int pc_checkbaselevelup(struct map_session_data *sd) { } while ((next=pc->nextbaseexp(sd)) > 0 && sd->status.base_exp >= next); if (battle_config.pet_lv_rate && sd->pd) //<Skotlex> update pet's level - status_calc_pet(sd->pd,0); + status_calc_pet(sd->pd,SCO_NONE); clif->updatestatus(sd,SP_STATUSPOINT); clif->updatestatus(sd,SP_BASELEVEL); clif->updatestatus(sd,SP_BASEEXP); clif->updatestatus(sd,SP_NEXTBASEEXP); - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_FORCE); status_percent_heal(&sd->bl,100,100); if((sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE) { - sc_start(&sd->bl,status->skill2sc(PR_KYRIE),100,1,skill->get_time(PR_KYRIE,1)); - sc_start(&sd->bl,status->skill2sc(PR_IMPOSITIO),100,1,skill->get_time(PR_IMPOSITIO,1)); - sc_start(&sd->bl,status->skill2sc(PR_MAGNIFICAT),100,1,skill->get_time(PR_MAGNIFICAT,1)); - sc_start(&sd->bl,status->skill2sc(PR_GLORIA),100,1,skill->get_time(PR_GLORIA,1)); - sc_start(&sd->bl,status->skill2sc(PR_SUFFRAGIUM),100,1,skill->get_time(PR_SUFFRAGIUM,1)); + sc_start(NULL,&sd->bl,status->skill2sc(PR_KYRIE),100,1,skill->get_time(PR_KYRIE,1)); + sc_start(NULL,&sd->bl,status->skill2sc(PR_IMPOSITIO),100,1,skill->get_time(PR_IMPOSITIO,1)); + sc_start(NULL,&sd->bl,status->skill2sc(PR_MAGNIFICAT),100,1,skill->get_time(PR_MAGNIFICAT,1)); + sc_start(NULL,&sd->bl,status->skill2sc(PR_GLORIA),100,1,skill->get_time(PR_GLORIA,1)); + sc_start(NULL,&sd->bl,status->skill2sc(PR_SUFFRAGIUM),100,1,skill->get_time(PR_SUFFRAGIUM,1)); if (sd->state.snovice_dead_flag) sd->state.snovice_dead_flag = 0; //Reenable steelbody resurrection on dead. } else if( (sd->class_&MAPID_BASEMASK) == MAPID_TAEKWON ) { - sc_start(&sd->bl,status->skill2sc(AL_INCAGI),100,10,600000); - sc_start(&sd->bl,status->skill2sc(AL_BLESSING),100,10,600000); + sc_start(NULL,&sd->bl,status->skill2sc(AL_INCAGI),100,10,600000); + sc_start(NULL,&sd->bl,status->skill2sc(AL_BLESSING),100,10,600000); } clif->misceffect(&sd->bl,0); npc->script_event(sd, NPCE_BASELVUP); //LORDALFA - LVLUPEVENT @@ -5752,7 +5890,6 @@ int pc_checkbaselevelup(struct map_session_data *sd) { } void pc_baselevelchanged(struct map_session_data *sd) { -#ifdef RENEWAL int i; for( i = 0; i < EQI_MAX; i++ ) { if( sd->equip_index[i] >= 0 ) { @@ -5760,9 +5897,8 @@ void pc_baselevelchanged(struct map_session_data *sd) { pc->unequipitem(sd, sd->equip_index[i], 3); } } -#endif - } + int pc_checkjoblevelup(struct map_session_data *sd) { unsigned int next = pc->nextjobexp(sd); @@ -5786,7 +5922,7 @@ int pc_checkjoblevelup(struct map_session_data *sd) clif->updatestatus(sd,SP_JOBEXP); clif->updatestatus(sd,SP_NEXTJOBEXP); clif->updatestatus(sd,SP_SKILLPOINT); - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_FORCE); clif->misceffect(&sd->bl,1); if (pc->checkskill(sd, SG_DEVIL) && !pc->nextjobexp(sd)) clif->status_change(&sd->bl,SI_DEVIL1, 1, 0, 0, 0, 1); //Permanent blind effect from SG_DEVIL. @@ -5820,6 +5956,12 @@ void pc_calcexp(struct map_session_data *sd, unsigned int *base_exp, unsigned in *job_exp = (unsigned int) cap_value(*job_exp + (double)*job_exp * bonus/100., 1, UINT_MAX); + if( sd->status.mod_exp != 100 ) { + *base_exp = (unsigned int) cap_value((double)*base_exp * sd->status.mod_exp/100., 1, UINT_MAX); + *job_exp = (unsigned int) cap_value((double)*job_exp * sd->status.mod_exp/100., 1, UINT_MAX); + + } + return; } /*========================================== @@ -5898,7 +6040,7 @@ int pc_gainexp(struct map_session_data *sd, struct block_list *src, unsigned int char output[256]; sprintf(output, "Experience Gained Base:%u (%.2f%%) Job:%u (%.2f%%)",base_exp,nextbp*(float)100,job_exp,nextjp*(float)100); - clif->disp_onlyself(sd,output,strlen(output)); + clif_disp_onlyself(sd,output,strlen(output)); } return 1; @@ -6043,52 +6185,88 @@ int pc_need_status_point(struct map_session_data* sd, int type, int val) return sp; } -/// Raises a stat by 1. -/// Obeys max_parameter limits. -/// Subtracts stat points. -/// -/// @param type The stat to change (see enum _sp) -int pc_statusup(struct map_session_data* sd, int type) -{ - int max, need, val; +/** + * Returns the value the specified stat can be increased by with the current + * amount of available status points for the current character's class. + * + * @param sd The target character. + * @param type Stat to verify. + * @return Maximum value the stat could grow by. + */ +int pc_maxparameterincrease(struct map_session_data* sd, int type) { + int base, final, status_points = sd->status.status_point; + + base = final = pc->getstat(sd, type); + + while (final <= pc_maxparameter(sd) && status_points >= 0) { +#ifdef RENEWAL // renewal status point cost formula + status_points -= (final < 100) ? (2 + (final - 1) / 10) : (16 + 4 * ((final - 100) / 5)); +#else + status_points -= ( 1 + (final + 9) / 10 ); +#endif + final++; + } + final--; + + return final > base ? final-base : 0; +} + +/** + * Raises a stat by the specified amount. + * Obeys max_parameter limits. + * Subtracts stat points. + * + * @param sd The target character. + * @param type The stat to change (see enum _sp) + * @param increase The stat increase amount. + * @return true if the stat was increased by any amount, false if there were no + * changes. + */ +bool pc_statusup(struct map_session_data* sd, int type, int increase) { + int max_increase = 0, current = 0, needed_points = 0, final_value = 0; nullpo_ret(sd); // check conditions - need = pc->need_status_point(sd,type,1); - if( type < SP_STR || type > SP_LUK || need < 0 || need > sd->status.status_point ) - { - clif->statusupack(sd,type,0,0); - return 1; + if (type < SP_STR || type > SP_LUK || increase <= 0) { + clif->statusupack(sd, type, 0, 0); + return false; } // check limits - max = pc_maxparameter(sd); - if( pc->getstat(sd,type) >= max ) - { - clif->statusupack(sd,type,0,0); - return 1; + current = pc->getstat(sd, type); + max_increase = pc->maxparameterincrease(sd, type); + increase = cap_value(increase, 0, max_increase); // cap to the maximum status points available + if (increase <= 0 || current + increase > pc_maxparameter(sd)) { + clif->statusupack(sd, type, 0, 0); + return false; + } + + // check status points + needed_points = pc->need_status_point(sd, type, increase); + if (needed_points < 0 || needed_points > sd->status.status_point) { // Sanity check + clif->statusupack(sd, type, 0, 0); + return false; } // set new values - val = pc->setstat(sd, type, pc->getstat(sd,type) + 1); - sd->status.status_point -= need; + final_value = pc->setstat(sd, type, current + increase); + sd->status.status_point -= needed_points; - status_calc_pc(sd,0); + status_calc_pc(sd, SCO_NONE); // update increase cost indicator - if( need != pc->need_status_point(sd,type,1) ) - clif->updatestatus(sd, SP_USTR + type-SP_STR); + clif->updatestatus(sd, SP_USTR + type-SP_STR); // update statpoint count - clif->updatestatus(sd,SP_STATUSPOINT); + clif->updatestatus(sd, SP_STATUSPOINT); // update stat value - clif->statusupack(sd,type,1,val); // required - if( val > 255 ) - clif->updatestatus(sd,type); // send after the 'ack' to override the truncated value + clif->statusupack(sd, type, 1, final_value); // required + if (final_value > 255) + clif->updatestatus(sd, type); // send after the 'ack' to override the truncated value - return 0; + return true; } /// Raises a stat by the specified amount. @@ -6114,7 +6292,7 @@ int pc_statusup2(struct map_session_data* sd, int type, int val) max = pc_maxparameter(sd); val = pc->setstat(sd, type, cap_value(pc->getstat(sd,type) + val, 1, max)); - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_NONE); // update increase cost indicator if( need != pc->need_status_point(sd,type,1) ) @@ -6157,17 +6335,17 @@ int pc_skillup(struct map_session_data *sd,uint16 skill_id) { sd->status.skill[index].lv++; sd->status.skill_point--; if( !skill->db[index].inf ) - status_calc_pc(sd,0); // Only recalculate for passive skills. + status_calc_pc(sd,SCO_NONE); // Only recalculate for passive skills. else if( sd->status.skill_point == 0 && (sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc->famerank(sd->status.char_id, MAPID_TAEKWON) ) pc->calc_skilltree(sd); // Required to grant all TK Ranger skills. else pc->check_skilltree(sd, skill_id); // Check if a new skill can Lvlup - clif->skillup(sd,skill_id); + clif->skillup(sd,skill_id, sd->status.skill[index].lv, 1); clif->updatestatus(sd,SP_SKILLPOINT); if( skill_id == GN_REMODELING_CART ) /* cart weight info was updated by status_calc_pc */ clif->updatestatus(sd,SP_CARTINFO); - if (!pc->has_permission(sd, PC_PERM_ALL_SKILL)) // may skill everything at any time anyways, and this would cause a huge slowdown + if (!pc_has_permission(sd, PC_PERM_ALL_SKILL)) // may skill everything at any time anyways, and this would cause a huge slowdown clif->skillinfoblock(sd); } else if( battle_config.skillup_limit ){ if( sd->sktree.second ) @@ -6200,7 +6378,7 @@ int pc_allskillup(struct map_session_data *sd) } } - if (pc->has_permission(sd, PC_PERM_ALL_SKILL)) { //Get ALL skills except npc/guild ones. [Skotlex] + if (pc_has_permission(sd, PC_PERM_ALL_SKILL)) { //Get ALL skills except npc/guild ones. [Skotlex] //and except SG_DEVIL [Komurka] and MO_TRIPLEATTACK and RG_SNATCHER [ultramage] for(i=0;i<MAX_SKILL;i++){ switch( skill->db[i].nameid ) { @@ -6230,7 +6408,7 @@ int pc_allskillup(struct map_session_data *sd) sd->status.skill[idx].lv = skill->tree_get_max(id, sd->status.class_); // celest } } - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_NONE); //Required because if you could level up all skills previously, //the update will not be sent as only the lv variable changes. clif->skillinfoblock(sd); @@ -6320,7 +6498,7 @@ int pc_resetlvl(struct map_session_data* sd,int type) if ((type == 1 || type == 2 || type == 3) && sd->status.party_id) party->send_levelup(sd); - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_FORCE); clif->skillinfoblock(sd); return 0; @@ -6382,10 +6560,10 @@ int pc_resetstate(struct map_session_data* sd) if( sd->mission_mobid ) { //bugreport:2200 sd->mission_mobid = 0; sd->mission_count = 0; - pc_setglobalreg(sd,"TK_MISSION_ID", 0); + pc_setglobalreg(sd,script->add_str("TK_MISSION_ID"), 0); } - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_NONE); return 1; } @@ -6438,7 +6616,7 @@ int pc_resetskill(struct map_session_data* sd, int flag) pc->setoption(sd, i); if( homun_alive(sd->hd) && pc->checkskill(sd, AM_CALLHOMUN) ) - homun->vaporize(sd, 0); + homun->vaporize(sd, HOM_ST_REST); } for( i = 1; i < MAX_SKILL; i++ ) { @@ -6496,7 +6674,7 @@ int pc_resetskill(struct map_session_data* sd, int flag) if( flag&1 ) { clif->updatestatus(sd,SP_SKILLPOINT); clif->skillinfoblock(sd); - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_FORCE); } return skill_point; @@ -6514,7 +6692,7 @@ int pc_resetfeel(struct map_session_data* sd) { sd->feel_map[i].m = -1; sd->feel_map[i].index = 0; - pc_setglobalreg(sd,pc->sg_info[i].feel_var,0); + pc_setglobalreg(sd,script->add_str(pc->sg_info[i].feel_var),0); } return 0; @@ -6528,7 +6706,7 @@ int pc_resethate(struct map_session_data* sd) for (i=0; i<3; i++) { sd->hate_mob[i] = -1; - pc_setglobalreg(sd,pc->sg_info[i].hate_var,0); + pc_setglobalreg(sd,script->add_str(pc->sg_info[i].hate_var),0); } return 0; } @@ -6592,7 +6770,7 @@ void pc_respawn(struct map_session_data* sd, clr_type clrtype) clif->resurrection(&sd->bl, 1); //If warping fails, send a normal stand up packet. } -int pc_respawn_timer(int tid, unsigned int tick, int id, intptr_t data) { +int pc_respawn_timer(int tid, int64 tick, int id, intptr_t data) { struct map_session_data *sd = map->id2sd(id); if( sd != NULL ) { @@ -6638,15 +6816,15 @@ void pc_damage(struct map_session_data *sd,struct block_list *src,unsigned int h * Invoked when a player has negative current hp *------------------------------------------*/ int pc_dead(struct map_session_data *sd,struct block_list *src) { - int i=0,j=0,k=0; - unsigned int tick = timer->gettick(); + int i=0,j=0; + int64 tick = timer->gettick(); - for(k = 0; k < 5; k++) - if (sd->devotion[k]){ - struct map_session_data *devsd = map->id2sd(sd->devotion[k]); + for(j = 0; j < 5; j++) + if (sd->devotion[j]){ + struct map_session_data *devsd = map->id2sd(sd->devotion[j]); if (devsd) status_change_end(&devsd->bl, SC_DEVOTION, INVALID_TIMER); - sd->devotion[k] = 0; + sd->devotion[j] = 0; } if(sd->status.pet_id > 0 && sd->pd) { @@ -6663,7 +6841,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) { if (sd->status.hom_id > 0){ if(battle_config.homunculus_auto_vapor && sd->hd && !sd->hd->sc.data[SC_LIGHT_OF_REGENE]) - homun->vaporize(sd, 0); + homun->vaporize(sd, HOM_ST_REST); } if( sd->md ) @@ -6683,7 +6861,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) { if (sd->npc_id && sd->st && sd->st->state != RUN) npc->event_dequeue(sd); - pc_setglobalreg(sd,"PC_DIE_COUNTER",sd->die_counter+1); + pc_setglobalreg(sd,script->add_str("PC_DIE_COUNTER"),sd->die_counter+1); pc->setparam(sd, SP_KILLERRID, src?src->id:0); if( sd->bg_id ) {/* TODO: purge when bgqueue is deemed ok */ @@ -6750,7 +6928,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) { ) { // monster level up [Valaris] clif->misceffect(&md->bl,0); md->level++; - status_calc_mob(md, 0); + status_calc_mob(md, SCO_NONE); status_percent_heal(src,10,0); if( battle_config.show_mob_info&4 ) @@ -6781,7 +6959,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) { if (battle_config.pk_mode&2) { ssd->status.manner -= 5; if(ssd->status.manner < 0) - sc_start(src,SC_NOCHAT,100,0,0); + sc_start(NULL,src,SC_NOCHAT,100,0,0); #if 0 // PK/Karma system code (not enabled yet) [celest] // originally from Kade Online, so i don't know if any of these is correct ^^; @@ -6833,7 +7011,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) { clif->resurrection(&sd->bl, 1); if(battle_config.pc_invincible_time) pc->setinvincibletimer(sd, battle_config.pc_invincible_time); - sc_start(&sd->bl,status->skill2sc(MO_STEELBODY),100,1,skill->get_time(MO_STEELBODY,1)); + sc_start(NULL,&sd->bl,status->skill2sc(MO_STEELBODY),100,1,skill->get_time(MO_STEELBODY,1)); if(map_flag_gvg2(sd->bl.m)) pc->respawn_timer(INVALID_TIMER, timer->gettick(), sd->bl.id, 0); return 0; @@ -6842,47 +7020,55 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) { // changed penalty options, added death by player if pk_mode [Valaris] if( battle_config.death_penalty_type - && (sd->class_&MAPID_UPPERMASK) != MAPID_NOVICE // only novices will receive no penalty - && !map->list[sd->bl.m].flag.noexppenalty && !map_flag_gvg2(sd->bl.m) - && !sd->sc.data[SC_BABY] && !sd->sc.data[SC_CASH_DEATHPENALTY] - ) { - unsigned int base_penalty =0; + && (sd->class_&MAPID_UPPERMASK) != MAPID_NOVICE // only novices will receive no penalty + && !map->list[sd->bl.m].flag.noexppenalty && !map_flag_gvg2(sd->bl.m) + && !sd->sc.data[SC_BABY] && !sd->sc.data[SC_CASH_DEATHPENALTY] + ) { + unsigned int base_penalty = 0; if (battle_config.death_penalty_base > 0) { + switch (battle_config.death_penalty_type) { case 1: base_penalty = (unsigned int) ((double)pc->nextbaseexp(sd) * (double)battle_config.death_penalty_base/10000); - break; + break; case 2: base_penalty = (unsigned int) ((double)sd->status.base_exp * (double)battle_config.death_penalty_base/10000); - break; + break; } + if(base_penalty) { if (battle_config.pk_mode && src && src->type==BL_PC) base_penalty*=2; + if( sd->status.mod_death != 100 ) + base_penalty = base_penalty * sd->status.mod_death / 100; sd->status.base_exp -= min(sd->status.base_exp, base_penalty); clif->updatestatus(sd,SP_BASEEXP); } } - if(battle_config.death_penalty_job > 0) - { + + if(battle_config.death_penalty_job > 0) { base_penalty = 0; + switch (battle_config.death_penalty_type) { case 1: base_penalty = (unsigned int) ((double)pc->nextjobexp(sd) * (double)battle_config.death_penalty_job/10000); - break; + break; case 2: base_penalty = (unsigned int) ((double)sd->status.job_exp * (double)battle_config.death_penalty_job/10000); - break; + break; } + if(base_penalty) { if (battle_config.pk_mode && src && src->type==BL_PC) base_penalty*=2; + if( sd->status.mod_death != 100 ) + base_penalty = base_penalty * sd->status.mod_death / 100; sd->status.job_exp -= min(sd->status.job_exp, base_penalty); clif->updatestatus(sd,SP_JOBEXP); } } - if(battle_config.zeny_penalty > 0 && !map->list[sd->bl.m].flag.nozenypenalty) - { + + if(battle_config.zeny_penalty > 0 && !map->list[sd->bl.m].flag.nozenypenalty) { base_penalty = (unsigned int)((double)sd->status.zeny * (double)battle_config.zeny_penalty / 10000.); if(base_penalty) pc->payzeny(sd, base_penalty, LOG_TYPE_PICKDROP_PLAYER, NULL); @@ -6898,14 +7084,13 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) { if(id == 0) continue; if(id == -1){ - int eq_num=0,eq_n[MAX_INVENTORY]; + int eq_num=0,eq_n[MAX_INVENTORY],k; memset(eq_n,0,sizeof(eq_n)); for(i=0;i<MAX_INVENTORY;i++){ if( (type == 1 && !sd->status.inventory[i].equip) || (type == 2 && sd->status.inventory[i].equip) || type == 3) { - int k; ARR_FIND( 0, MAX_INVENTORY, k, eq_n[k] <= 0 ); if( k < MAX_INVENTORY ) eq_n[k] = i; @@ -7034,6 +7219,9 @@ int pc_readparam(struct map_session_data* sd,int type) case SP_KILLEDRID: val = sd->killedrid; break; case SP_SLOTCHANGE: val = sd->status.slotchange; break; case SP_CHARRENAME: val = sd->status.rename; break; + case SP_MOD_EXP: val = sd->status.mod_exp; break; + case SP_MOD_DROP: val = sd->status.mod_drop; break; + case SP_MOD_DEATH: val = sd->status.mod_death; break; case SP_CRITICAL: val = sd->battle_status.cri/10; break; case SP_ASPD: val = (2000-sd->battle_status.amotion)/10; break; case SP_BASE_ATK: val = sd->battle_status.batk; break; @@ -7166,7 +7354,7 @@ int pc_setparam(struct map_session_data *sd,int type,int val) clif->updatestatus(sd, SP_NEXTBASEEXP); clif->updatestatus(sd, SP_STATUSPOINT); clif->updatestatus(sd, SP_BASEEXP); - status_calc_pc(sd, 0); + status_calc_pc(sd, SCO_FORCE); if(sd->status.party_id) { party->send_levelup(sd); @@ -7183,7 +7371,7 @@ int pc_setparam(struct map_session_data *sd,int type,int val) // clif->updatestatus(sd, SP_JOBLEVEL); // Gets updated at the bottom clif->updatestatus(sd, SP_NEXTJOBEXP); clif->updatestatus(sd, SP_JOBEXP); - status_calc_pc(sd, 0); + status_calc_pc(sd, SCO_FORCE); break; case SP_SKILLPOINT: sd->status.skill_point = val; @@ -7281,6 +7469,15 @@ int pc_setparam(struct map_session_data *sd,int type,int val) case SP_CHARRENAME: sd->status.rename = val; return 1; + case SP_MOD_EXP: + sd->status.mod_exp = val; + return 1; + case SP_MOD_DROP: + sd->status.mod_drop = val; + return 1; + case SP_MOD_DEATH: + sd->status.mod_death = val; + return 1; default: ShowError("pc_setparam: Attempted to set unknown parameter '%d'.\n", type); return 0; @@ -7358,6 +7555,11 @@ int pc_itemheal(struct map_session_data *sd,int itemid, int hp,int sp) sp -= sp * sd->sc.data[SC_CRITICALWOUND]->val2 / 100; } + if( sd->sc.data[SC_VITALITYACTIVATION] ){ + hp += hp / 2; // 1.5 times + sp -= sp / 2; + } + if ( sd->sc.data[SC_DEATHHURT] ) { hp -= hp * 20 / 100; sp -= sp * 20 / 100; @@ -7466,12 +7668,12 @@ int pc_jobchange(struct map_session_data *sd,int job, int upper) // changing from 1st to 2nd job if ((b_class&JOBL_2) && !(sd->class_&JOBL_2) && (b_class&MAPID_UPPERMASK) != MAPID_SUPER_NOVICE) { sd->change_level_2nd = sd->status.job_level; - pc_setglobalreg (sd, "jobchange_level", sd->change_level_2nd); + pc_setglobalreg (sd, script->add_str("jobchange_level"), sd->change_level_2nd); } // changing from 2nd to 3rd job else if((b_class&JOBL_THIRD) && !(sd->class_&JOBL_THIRD)) { sd->change_level_3rd = sd->status.job_level; - pc_setglobalreg (sd, "jobchange_level_3rd", sd->change_level_3rd); + pc_setglobalreg (sd, script->add_str("jobchange_level_3rd"), sd->change_level_3rd); } if(sd->cloneskill_id) { @@ -7483,8 +7685,8 @@ int pc_jobchange(struct map_session_data *sd,int job, int upper) clif->deleteskill(sd,sd->cloneskill_id); } sd->cloneskill_id = 0; - pc_setglobalreg(sd, "CLONE_SKILL", 0); - pc_setglobalreg(sd, "CLONE_SKILL_LV", 0); + pc_setglobalreg(sd, script->add_str("CLONE_SKILL"), 0); + pc_setglobalreg(sd, script->add_str("CLONE_SKILL_LV"), 0); } if(sd->reproduceskill_id) { @@ -7496,8 +7698,8 @@ int pc_jobchange(struct map_session_data *sd,int job, int upper) clif->deleteskill(sd,sd->reproduceskill_id); } sd->reproduceskill_id = 0; - pc_setglobalreg(sd, "REPRODUCE_SKILL",0); - pc_setglobalreg(sd, "REPRODUCE_SKILL_LV",0); + pc_setglobalreg(sd, script->add_str("REPRODUCE_SKILL"),0); + pc_setglobalreg(sd, script->add_str("REPRODUCE_SKILL_LV"),0); } if ( (b_class&MAPID_UPPERMASK) != (sd->class_&MAPID_UPPERMASK) ) { //Things to remove when changing class tree. @@ -7588,12 +7790,12 @@ int pc_jobchange(struct map_session_data *sd,int job, int upper) pc->setoption(sd, i); if(homun_alive(sd->hd) && !pc->checkskill(sd, AM_CALLHOMUN)) - homun->vaporize(sd, 0); + homun->vaporize(sd, HOM_ST_REST); if(sd->status.manner < 0) clif->changestatus(sd,SP_MANNER,sd->status.manner); - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_FORCE); pc->checkallowskill(sd); pc->equiplookall(sd); @@ -7716,11 +7918,11 @@ int pc_setoption(struct map_session_data *sd,int type) if( (type&OPTION_RIDING && !(p_type&OPTION_RIDING)) || (type&OPTION_DRAGON && !(p_type&OPTION_DRAGON) && pc->checkskill(sd,RK_DRAGONTRAINING) > 0) ) { // Mounting clif->sc_load(&sd->bl,sd->bl.id,AREA,SI_RIDING, 0, 0, 0); - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_NONE); } else if( (!(type&OPTION_RIDING) && p_type&OPTION_RIDING) || (!(type&OPTION_DRAGON) && p_type&OPTION_DRAGON) ) { // Dismount clif->sc_end(&sd->bl,sd->bl.id,AREA,SI_RIDING); - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_NONE); } #ifndef NEW_CARTS @@ -7728,11 +7930,11 @@ int pc_setoption(struct map_session_data *sd,int type) clif->cartlist(sd); clif->updatestatus(sd, SP_CARTINFO); if(pc->checkskill(sd, MC_PUSHCART) < 10) - status_calc_pc(sd,0); //Apply speed penalty. + status_calc_pc(sd,SCO_NONE); //Apply speed penalty. } else if( !( type&OPTION_CART ) && p_type&OPTION_CART ){ //Cart Off clif->clearcart(sd->fd); if(pc->checkskill(sd, MC_PUSHCART) < 10) - status_calc_pc(sd,0); //Remove speed penalty. + status_calc_pc(sd,SCO_NONE); //Remove speed penalty. } #endif @@ -7744,18 +7946,18 @@ int pc_setoption(struct map_session_data *sd,int type) if( (sd->class_&MAPID_THIRDMASK) == MAPID_RANGER ) { if( type&OPTION_WUGRIDER && !(p_type&OPTION_WUGRIDER) ) { // Mounting clif->sc_load(&sd->bl,sd->bl.id,AREA,SI_WUGRIDER, 0, 0, 0); - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_NONE); } else if( !(type&OPTION_WUGRIDER) && p_type&OPTION_WUGRIDER ) { // Dismount clif->sc_end(&sd->bl,sd->bl.id,AREA,SI_WUGRIDER); - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_NONE); } } if( (sd->class_&MAPID_THIRDMASK) == MAPID_MECHANIC ) { int i; if( type&OPTION_MADOGEAR && !(p_type&OPTION_MADOGEAR) ) - status_calc_pc(sd, 0); + status_calc_pc(sd, SCO_NONE); else if( !(type&OPTION_MADOGEAR) && p_type&OPTION_MADOGEAR ) - status_calc_pc(sd, 0); + status_calc_pc(sd, SCO_NONE); for( i = 0; i < SC_MAX; i++ ){ if ( !sd->sc.data[i] || !status->get_sc_type(i) ) continue; @@ -7826,7 +8028,7 @@ int pc_setcart(struct map_session_data *sd,int type) { if( !sd->sc.data[SC_PUSH_CART] ) /* first time, so fill cart data */ clif->cartlist(sd); clif->updatestatus(sd, SP_CARTINFO); - sc_start(&sd->bl, SC_PUSH_CART, 100, type, 0); + sc_start(NULL,&sd->bl, SC_PUSH_CART, 100, type, 0); clif->sc_load(&sd->bl, sd->bl.id, AREA, SI_ON_PUSH_CART, type, 0, 0); if( sd->sc.data[SC_PUSH_CART] )/* forcefully update */ sd->sc.data[SC_PUSH_CART]->val1 = type; @@ -7834,7 +8036,7 @@ int pc_setcart(struct map_session_data *sd,int type) { } if(pc->checkskill(sd, MC_PUSHCART) < 10) - status_calc_pc(sd,0); //Recalc speed penalty. + status_calc_pc(sd,SCO_NONE); //Recalc speed penalty. #else // Update option option = sd->sc.option; @@ -7896,353 +8098,258 @@ int pc_setmadogear(TBL_PC* sd, int flag) *------------------------------------------*/ int pc_candrop(struct map_session_data *sd, struct item *item) { - if( item && item->expire_time ) + if( item && (item->expire_time || (item->bound && !pc_can_give_bound_items(sd))) ) + return 0; + if( !pc_can_give_items(sd) ) //check if this GM level can drop items return 0; - if( !pc->can_give_items(sd) ) //check if this GM level can drop items - return 0; - return (itemdb_isdropable(item, pc->get_group_level(sd))); + return (itemdb_isdropable(item, pc_get_group_level(sd))); } - -/*========================================== - * Read ram register for player sd - * get val (int) from reg for player sd - *------------------------------------------*/ -int pc_readreg(struct map_session_data* sd, int reg) -{ - int i; - - nullpo_ret(sd); - - ARR_FIND( 0, sd->reg_num, i, sd->reg[i].index == reg ); - return ( i < sd->reg_num ) ? sd->reg[i].data : 0; +/** + * For '@type' variables (temporary numeric char reg) + **/ +int pc_readreg(struct map_session_data* sd, int64 reg) { + return i64db_iget(sd->var_db, reg); } -/*========================================== - * Set ram register for player sd - * memo val(int) at reg for player sd - *------------------------------------------*/ -int pc_setreg(struct map_session_data* sd, int reg, int val) -{ - int i; - - nullpo_ret(sd); - - ARR_FIND( 0, sd->reg_num, i, sd->reg[i].index == reg ); - if( i < sd->reg_num ) - {// overwrite existing entry - sd->reg[i].data = val; - return 1; - } - - ARR_FIND( 0, sd->reg_num, i, sd->reg[i].data == 0 ); - if( i == sd->reg_num ) - {// nothing free, increase size - sd->reg_num++; - RECREATE(sd->reg, struct script_reg, sd->reg_num); +/** + * For '@type' variables (temporary numeric char reg) + **/ +void pc_setreg(struct map_session_data* sd, int64 reg, int val) { + unsigned int index = script_getvaridx(reg); + + if( val ) { + i64db_iput(sd->var_db, reg, val); + if( index ) + script->array_update(&sd->array_db,reg,false); + } else { + i64db_remove(sd->var_db, reg); + if( index ) + script->array_update(&sd->array_db,reg,true); } - sd->reg[i].index = reg; - sd->reg[i].data = val; - - return 1; } -/*========================================== - * Read ram register for player sd - * get val (str) from reg for player sd - *------------------------------------------*/ -char* pc_readregstr(struct map_session_data* sd, int reg) -{ - int i; - - nullpo_ret(sd); +/** + * For '@type$' variables (temporary string char reg) + **/ +char* pc_readregstr(struct map_session_data* sd, int64 reg) { + struct script_reg_str *p = NULL; - ARR_FIND( 0, sd->regstr_num, i, sd->regstr[i].index == reg ); - return ( i < sd->regstr_num ) ? sd->regstr[i].data : NULL; + p = i64db_get(sd->var_db, reg); + + return p ? p->value : NULL; } -/*========================================== - * Set ram register for player sd - * memo val(str) at reg for player sd - *------------------------------------------*/ -int pc_setregstr(struct map_session_data* sd, int reg, const char* str) -{ - int i; - - nullpo_ret(sd); +/** + * For '@type$' variables (temporary string char reg) + **/ +void pc_setregstr(struct map_session_data* sd, int64 reg, const char* str) { + struct script_reg_str *p = NULL; + unsigned int index = script_getvaridx(reg); + DBData prev; - ARR_FIND( 0, sd->regstr_num, i, sd->regstr[i].index == reg ); - if( i < sd->regstr_num ) - {// found entry, update - if( str == NULL || *str == '\0' ) - {// empty string - if( sd->regstr[i].data != NULL ) - aFree(sd->regstr[i].data); - sd->regstr[i].data = NULL; - } - else if( sd->regstr[i].data ) - {// recreate - size_t len = strlen(str)+1; - RECREATE(sd->regstr[i].data, char, len); - memcpy(sd->regstr[i].data, str, len*sizeof(char)); + if( str[0] ) { + p = ers_alloc(pc->str_reg_ers, struct script_reg_str); + + p->value = aStrdup(str); + p->flag.type = 1; + + if( sd->var_db->put(sd->var_db,DB->i642key(reg),DB->ptr2data(p),&prev) ) { + p = DB->data2ptr(&prev); + if( p->value ) + aFree(p->value); + ers_free(pc->str_reg_ers, p); + } else { + if( index ) + script->array_update(&sd->array_db,reg,false); } - else - {// create - sd->regstr[i].data = aStrdup(str); + } else { + if( sd->var_db->remove(sd->var_db,DB->i642key(reg),&prev) ) { + p = DB->data2ptr(&prev); + if( p->value ) + aFree(p->value); + ers_free(pc->str_reg_ers, p); + if( index ) + script->array_update(&sd->array_db,reg,true); } - return 1; - } - - if( str == NULL || *str == '\0' ) - return 1;// nothing to add, empty string - - ARR_FIND( 0, sd->regstr_num, i, sd->regstr[i].data == NULL ); - if( i == sd->regstr_num ) - {// nothing free, increase size - sd->regstr_num++; - RECREATE(sd->regstr, struct script_regstr, sd->regstr_num); } - sd->regstr[i].index = reg; - sd->regstr[i].data = aStrdup(str); - - return 1; } - -int pc_readregistry(struct map_session_data *sd,const char *reg,int type) -{ - struct global_reg *sd_reg; - int i,max; - - nullpo_ret(sd); - switch (type) { - case 3: //Char reg - sd_reg = sd->save_reg.global; - max = sd->save_reg.global_num; - break; - case 2: //Account reg - sd_reg = sd->save_reg.account; - max = sd->save_reg.account_num; - break; - case 1: //Account2 reg - sd_reg = sd->save_reg.account2; - max = sd->save_reg.account2_num; - break; - default: - return 0; - } - if (max == -1) { - ShowError("pc_readregistry: Trying to read reg value %s (type %d) before it's been loaded!\n", reg, type); +/** + * Serves the following variable types: + * - 'type' (permanent nuneric char reg) + * - '#type' (permanent numeric account reg) + * - '##type' (permanent numeric account reg2) + **/ +int pc_readregistry(struct map_session_data *sd, int64 reg) { + struct script_reg_num *p = NULL; + + if (!sd->vars_ok) { + ShowError("pc_readregistry: Trying to read reg %s before it's been loaded!\n", script->get_str(script_getvarid(reg))); //This really shouldn't happen, so it's possible the data was lost somewhere, we should request it again. - intif->request_registry(sd,type==3?4:type); + //intif->request_registry(sd,type==3?4:type); + set_eof(sd->fd); return 0; } + + p = i64db_get(sd->var_db, reg); - ARR_FIND( 0, max, i, strcmp(sd_reg[i].str,reg) == 0 ); - return ( i < max ) ? atoi(sd_reg[i].value) : 0; + return p ? p->value : 0; } - -char* pc_readregistry_str(struct map_session_data *sd,const char *reg,int type) -{ - struct global_reg *sd_reg; - int i,max; - - nullpo_ret(sd); - switch (type) { - case 3: //Char reg - sd_reg = sd->save_reg.global; - max = sd->save_reg.global_num; - break; - case 2: //Account reg - sd_reg = sd->save_reg.account; - max = sd->save_reg.account_num; - break; - case 1: //Account2 reg - sd_reg = sd->save_reg.account2; - max = sd->save_reg.account2_num; - break; - default: - return NULL; - } - if (max == -1) { - ShowError("pc_readregistry: Trying to read reg value %s (type %d) before it's been loaded!\n", reg, type); +/** + * Serves the following variable types: + * - 'type$' (permanent str char reg) + * - '#type$' (permanent str account reg) + * - '##type$' (permanent str account reg2) + **/ +char* pc_readregistry_str(struct map_session_data *sd, int64 reg) { + struct script_reg_str *p = NULL; + + if (!sd->vars_ok) { + ShowError("pc_readregistry_str: Trying to read reg %s before it's been loaded!\n", script->get_str(script_getvarid(reg))); //This really shouldn't happen, so it's possible the data was lost somewhere, we should request it again. - intif->request_registry(sd,type==3?4:type); + //intif->request_registry(sd,type==3?4:type); + set_eof(sd->fd); return NULL; } - ARR_FIND( 0, max, i, strcmp(sd_reg[i].str,reg) == 0 ); - return ( i < max ) ? sd_reg[i].value : NULL; + p = i64db_get(sd->var_db, reg); + + return p ? p->value : NULL; } +/** + * Serves the following variable types: + * - 'type' (permanent nuneric char reg) + * - '#type' (permanent numeric account reg) + * - '##type' (permanent numeric account reg2) + **/ +int pc_setregistry(struct map_session_data *sd, int64 reg, int val) { + struct script_reg_num *p = NULL; + int i; + const char *regname = script->get_str( script_getvarid(reg) ); + unsigned int index = script_getvaridx(reg); -int pc_setregistry(struct map_session_data *sd,const char *reg,int val,int type) -{ - struct global_reg *sd_reg; - int i,*max, regmax; - - nullpo_ret(sd); - - switch( type ) - { - case 3: //Char reg - if( !strcmp(reg,"PC_DIE_COUNTER") && sd->die_counter != val ) - { - i = (!sd->die_counter && (sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE); - sd->die_counter = val; - if( i ) - status_calc_pc(sd,0); // Lost the bonus. - } - else if( !strcmp(reg,"COOK_MASTERY") && sd->cook_mastery != val ) - { - val = cap_value(val, 0, 1999); - sd->cook_mastery = val; - } - sd_reg = sd->save_reg.global; - max = &sd->save_reg.global_num; - regmax = GLOBAL_REG_NUM; - break; - case 2: //Account reg - if( !strcmp(reg,"#CASHPOINTS") && sd->cashPoints != val ) - { - val = cap_value(val, 0, MAX_ZENY); - sd->cashPoints = val; - } - else if( !strcmp(reg,"#KAFRAPOINTS") && sd->kafraPoints != val ) - { - val = cap_value(val, 0, MAX_ZENY); - sd->kafraPoints = val; - } - sd_reg = sd->save_reg.account; - max = &sd->save_reg.account_num; - regmax = ACCOUNT_REG_NUM; - break; - case 1: //Account2 reg - sd_reg = sd->save_reg.account2; - max = &sd->save_reg.account2_num; - regmax = ACCOUNT_REG2_NUM; - break; - default: - return 0; + /* SAAD! those things should be stored elsewhere e.g. char ones in char table, the cash ones in account_data table! */ + switch( regname[0] ) { + default: //Char reg + if( !strcmp(regname,"PC_DIE_COUNTER") && sd->die_counter != val ) { + i = (!sd->die_counter && (sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE); + sd->die_counter = val; + if( i ) + status_calc_pc(sd,SCO_NONE); // Lost the bonus. + } else if( !strcmp(regname,"COOK_MASTERY") && sd->cook_mastery != val ) { + val = cap_value(val, 0, 1999); + sd->cook_mastery = val; + } + break; + case '#': + if( !strcmp(regname,"#CASHPOINTS") && sd->cashPoints != val ) { + val = cap_value(val, 0, MAX_ZENY); + sd->cashPoints = val; + } else if( !strcmp(regname,"#KAFRAPOINTS") && sd->kafraPoints != val ) { + val = cap_value(val, 0, MAX_ZENY); + sd->kafraPoints = val; + } + break; } - if (*max == -1) { - ShowError("pc_setregistry : refusing to set %s (type %d) until vars are received.\n", reg, type); - return 1; + + if ( !pc->reg_load && !sd->vars_ok ) { + ShowError("pc_setregistry : refusing to set %s until vars are received.\n", regname); + return 0; } - - // delete reg - if (val == 0) { - ARR_FIND( 0, *max, i, strcmp(sd_reg[i].str, reg) == 0 ); - if( i < *max ) - { - if (i != *max - 1) - memcpy(&sd_reg[i], &sd_reg[*max - 1], sizeof(struct global_reg)); - memset(&sd_reg[*max - 1], 0, sizeof(struct global_reg)); - (*max)--; - sd->state.reg_dirty |= 1<<(type-1); //Mark this registry as "need to be saved" + + if( (p = i64db_get(sd->var_db, reg) ) ) { + if( val ) { + if( !p->value && index ) /* its a entry that was deleted, so we reset array */ + script->array_update(&sd->array_db,reg,false); + p->value = val; + } else { + p->value = 0; + if( index ) + script->array_update(&sd->array_db,reg,true); + } + if( !pc->reg_load ) + p->flag.update = 1;/* either way, it will require either delete or replace */ + } else if( val ) { + DBData prev; + + if( index ) + script->array_update(&sd->array_db,reg,false); + + p = ers_alloc(pc->num_reg_ers, struct script_reg_num); + + p->value = val; + if( !pc->reg_load ) + p->flag.update = 1; + + if( sd->var_db->put(sd->var_db,DB->i642key(reg),DB->ptr2data(p),&prev) ) { + p = DB->data2ptr(&prev); + ers_free(pc->num_reg_ers, p); } - return 1; } - // change value if found - ARR_FIND( 0, *max, i, strcmp(sd_reg[i].str, reg) == 0 ); - if( i < *max ) - { - safesnprintf(sd_reg[i].value, sizeof(sd_reg[i].value), "%d", val); - sd->state.reg_dirty |= 1<<(type-1); - return 1; - } - - // add value if not found - if (i < regmax) { - memset(&sd_reg[i], 0, sizeof(struct global_reg)); - safestrncpy(sd_reg[i].str, reg, sizeof(sd_reg[i].str)); - safesnprintf(sd_reg[i].value, sizeof(sd_reg[i].value), "%d", val); - (*max)++; - sd->state.reg_dirty |= 1<<(type-1); - return 1; - } - - ShowError("pc_setregistry : couldn't set %s, limit of registries reached (%d)\n", reg, regmax); + + if( !pc->reg_load && p ) + sd->vars_dirty = true; - return 0; + return 1; } +/** + * Serves the following variable types: + * - 'type$' (permanent str char reg) + * - '#type$' (permanent str account reg) + * - '##type$' (permanent str account reg2) + **/ +int pc_setregistry_str(struct map_session_data *sd, int64 reg, const char *val) { + struct script_reg_str *p = NULL; + const char *regname = script->get_str( script_getvarid(reg) ); + unsigned int index = script_getvaridx(reg); -int pc_setregistry_str(struct map_session_data *sd,const char *reg,const char *val,int type) -{ - struct global_reg *sd_reg; - int i,*max, regmax; - - nullpo_ret(sd); - if (reg[strlen(reg)-1] != '$') { - ShowError("pc_setregistry_str : reg %s must be string (end in '$') to use this!\n", reg); - return 0; - } - - switch (type) { - case 3: //Char reg - sd_reg = sd->save_reg.global; - max = &sd->save_reg.global_num; - regmax = GLOBAL_REG_NUM; - break; - case 2: //Account reg - sd_reg = sd->save_reg.account; - max = &sd->save_reg.account_num; - regmax = ACCOUNT_REG_NUM; - break; - case 1: //Account2 reg - sd_reg = sd->save_reg.account2; - max = &sd->save_reg.account2_num; - regmax = ACCOUNT_REG2_NUM; - break; - default: - return 0; - } - if (*max == -1) { - ShowError("pc_setregistry_str : refusing to set %s (type %d) until vars are received.\n", reg, type); + if ( !pc->reg_load && !sd->vars_ok ) { + ShowError("pc_setregistry_str : refusing to set %s until vars are received.\n", regname); return 0; } - // delete reg - if (!val || strcmp(val,"")==0) - { - ARR_FIND( 0, *max, i, strcmp(sd_reg[i].str, reg) == 0 ); - if( i < *max ) - { - if (i != *max - 1) - memcpy(&sd_reg[i], &sd_reg[*max - 1], sizeof(struct global_reg)); - memset(&sd_reg[*max - 1], 0, sizeof(struct global_reg)); - (*max)--; - sd->state.reg_dirty |= 1<<(type-1); //Mark this registry as "need to be saved" - if (type!=3) intif->saveregistry(sd,type); + if( (p = i64db_get(sd->var_db, reg) ) ) { + if( val[0] ) { + if( p->value ) + aFree(p->value); + else if ( index ) /* a entry that was deleted, so we reset */ + script->array_update(&sd->array_db,reg,false); + p->value = aStrdup(val); + } else { + p->value = NULL; + if( index ) + script->array_update(&sd->array_db,reg,true); } - return 1; - } + if( !pc->reg_load ) + p->flag.update = 1;/* either way, it will require either delete or replace */ + } else if( val[0] ) { + DBData prev; - // change value if found - ARR_FIND( 0, *max, i, strcmp(sd_reg[i].str, reg) == 0 ); - if( i < *max ) - { - safestrncpy(sd_reg[i].value, val, sizeof(sd_reg[i].value)); - sd->state.reg_dirty |= 1<<(type-1); //Mark this registry as "need to be saved" - if (type!=3) intif->saveregistry(sd,type); - return 1; - } + if( index ) + script->array_update(&sd->array_db,reg,false); - // add value if not found - if (i < regmax) { - memset(&sd_reg[i], 0, sizeof(struct global_reg)); - safestrncpy(sd_reg[i].str, reg, sizeof(sd_reg[i].str)); - safestrncpy(sd_reg[i].value, val, sizeof(sd_reg[i].value)); - (*max)++; - sd->state.reg_dirty |= 1<<(type-1); //Mark this registry as "need to be saved" - if (type!=3) intif->saveregistry(sd,type); - return 1; + p = ers_alloc(pc->str_reg_ers, struct script_reg_str); + + p->value = aStrdup(val); + if( !pc->reg_load ) + p->flag.update = 1; + p->flag.type = 1; + + if( sd->var_db->put(sd->var_db,DB->i642key(reg),DB->ptr2data(p),&prev) ) { + p = DB->data2ptr(&prev); + if( p->value ) + aFree(p->value); + ers_free(pc->str_reg_ers, p); + } } - - ShowError("pc_setregistry : couldn't set %s, limit of registries reached (%d)\n", reg, regmax); - - return 0; + + if( !pc->reg_load && p ) + sd->vars_dirty = true; + + return 1; } /*========================================== * Exec eventtimer for player sd (retrieved from map_session (id)) *------------------------------------------*/ -int pc_eventtimer(int tid, unsigned int tick, int id, intptr_t data) { +int pc_eventtimer(int tid, int64 tick, int id, intptr_t data) { struct map_session_data *sd=map->id2sd(id); char *p = (char *)data; int i; @@ -8355,17 +8462,19 @@ int pc_cleareventtimer(struct map_session_data *sd) /* called when a item with combo is worn */ int pc_checkcombo(struct map_session_data *sd, struct item_data *data ) { int i, j, k, z; - int index, idx, success = 0; + int index, success = 0; + struct pc_combos *combo; for( i = 0; i < data->combos_count; i++ ) { /* ensure this isn't a duplicate combo */ - if( sd->combos.bonus != NULL ) { + if( sd->combos != NULL ) { int x; - ARR_FIND( 0, sd->combos.count, x, sd->combos.id[x] == data->combos[i]->id ); + + ARR_FIND( 0, sd->combo_count, x, sd->combos[x].id == data->combos[i]->id ); /* found a match, skip this combo */ - if( x < sd->combos.count ) + if( x < sd->combo_count ) continue; } @@ -8382,7 +8491,7 @@ int pc_checkcombo(struct map_session_data *sd, struct item_data *data ) { if(!sd->inventory_data[index]) continue; - + if ( itemdb_type(id) != IT_CARD ) { if ( sd->inventory_data[index]->nameid != id ) continue; @@ -8416,24 +8525,16 @@ int pc_checkcombo(struct map_session_data *sd, struct item_data *data ) { /* we got here, means all items in the combo are matching */ - idx = sd->combos.count; - - if( sd->combos.bonus == NULL ) { - CREATE(sd->combos.bonus, struct script_code *, 1); - CREATE(sd->combos.id, unsigned short, 1); - sd->combos.count = 1; - } else { - RECREATE(sd->combos.bonus, struct script_code *, ++sd->combos.count); - RECREATE(sd->combos.id, unsigned short, sd->combos.count); - } - - /* we simply copy the pointer */ - sd->combos.bonus[idx] = data->combos[i]->script; - /* save this combo's id */ - sd->combos.id[idx] = data->combos[i]->id; - + RECREATE(sd->combos, struct pc_combos, ++sd->combo_count); + + combo = &sd->combos[sd->combo_count - 1]; + + combo->bonus = data->combos[i]->script; + combo->id = data->combos[i]->id; + success++; } + return success; } @@ -8441,45 +8542,45 @@ int pc_checkcombo(struct map_session_data *sd, struct item_data *data ) { int pc_removecombo(struct map_session_data *sd, struct item_data *data ) { int i, retval = 0; - if( sd->combos.bonus == NULL ) + if( !sd->combos ) return 0;/* nothing to do here, player has no combos */ + for( i = 0; i < data->combos_count; i++ ) { /* check if this combo exists in this user */ int x = 0, cursor = 0, j; - ARR_FIND( 0, sd->combos.count, x, sd->combos.id[x] == data->combos[i]->id ); + + ARR_FIND( 0, sd->combo_count, x, sd->combos[x].id == data->combos[i]->id ); /* no match, skip this combo */ - if( !(x < sd->combos.count) ) + if( x == sd->combo_count ) continue; - sd->combos.bonus[x] = NULL; - sd->combos.id[x] = 0; + sd->combos[x].bonus = NULL; + sd->combos[x].id = 0; + retval++; - for( j = 0, cursor = 0; j < sd->combos.count; j++ ) { - if( sd->combos.bonus[j] == NULL ) + + for( j = 0, cursor = 0; j < sd->combo_count; j++ ) { + if( sd->combos[j].bonus == NULL ) continue; if( cursor != j ) { - sd->combos.bonus[cursor] = sd->combos.bonus[j]; - sd->combos.id[cursor] = sd->combos.id[j]; + sd->combos[cursor].bonus = sd->combos[j].bonus; + sd->combos[cursor].id = sd->combos[j].id; } cursor++; } - /* check if combo requirements still fit */ - if( pc->checkcombo( sd, data ) ) - continue; - /* it's empty, we can clear all the memory */ - if( (sd->combos.count = cursor) == 0 ) { - aFree(sd->combos.bonus); - aFree(sd->combos.id); - sd->combos.bonus = NULL; - sd->combos.id = NULL; - return retval; /* we also can return at this point for we have no more combos to check */ + if( (sd->combo_count = cursor) == 0 ) { + aFree(sd->combos); + sd->combos = NULL; + break; } - } + + /* check if combo requirements still fit -- don't touch retval! */ + pc->checkcombo( sd, data ); return retval; } @@ -8518,13 +8619,13 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos) nullpo_ret(sd); if( n < 0 || n >= MAX_INVENTORY ) { - clif->equipitemack(sd,0,0,0); + clif->equipitemack(sd,0,0,EIA_FAIL); return 0; } if( DIFF_TICK(sd->canequip_tick,timer->gettick()) > 0 ) { - clif->equipitemack(sd,n,0,0); + clif->equipitemack(sd,n,0,EIA_FAIL); return 0; } @@ -8535,27 +8636,38 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos) ShowInfo("equip %d(%d) %x:%x\n",sd->status.inventory[n].nameid,n,id?id->equip:0,req_pos); if(!pc->isequip(sd,n) || !(pos&req_pos) || sd->status.inventory[n].equip != 0 || sd->status.inventory[n].attribute==1 ) { // [Valaris] // FIXME: pc->isequip: equip level failure uses 2 instead of 0 - clif->equipitemack(sd,n,0,0); // fail + clif->equipitemack(sd,n,0,EIA_FAIL); // fail return 0; } - if (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_SATURDAY_NIGHT_FEVER]) + if (sd->sc.data[SC_BERSERK]) { - clif->equipitemack(sd,n,0,0); // fail + clif->equipitemack(sd,n,0,EIA_FAIL); // fail return 0; } + /* won't fail from this point onwards */ + if( id->flag.bindonequip && !sd->status.inventory[n].bound ) { + sd->status.inventory[n].bound = (unsigned char)IBT_CHARACTER; + clif->notify_bounditem(sd,n); + } + if(pos == EQP_ACC) { //Accesories should only go in one of the two, pos = req_pos&EQP_ACC; if (pos == EQP_ACC) //User specified both slots.. pos = sd->equip_index[EQI_ACC_R] >= 0 ? EQP_ACC_L : EQP_ACC_R; - } - - if(pos == EQP_ARMS && id->equip == EQP_HAND_R) - { //Dual wield capable weapon. + } else if(pos == EQP_ARMS && id->equip == EQP_HAND_R) { //Dual wield capable weapon. pos = (req_pos&EQP_ARMS); if (pos == EQP_ARMS) //User specified both slots, pick one for them. pos = sd->equip_index[EQI_HAND_R] >= 0 ? EQP_HAND_L : EQP_HAND_R; + } else if(pos == EQP_SHADOW_ACC) { //Accesories should only go in one of the two, + pos = req_pos&EQP_SHADOW_ACC; + if (pos == EQP_SHADOW_ACC) //User specified both slots.. + pos = sd->equip_index[EQI_SHADOW_ACC_R] >= 0 ? EQP_SHADOW_ACC_L : EQP_SHADOW_ACC_R; + } else if( pos == EQP_SHADOW_ARMS && id->equip == EQP_SHADOW_WEAPON) { //Dual wield capable weapon. + pos = (req_pos&EQP_SHADOW_ARMS); + if (pos == EQP_SHADOW_ARMS) //User specified both slots, pick one for them. + pos = sd->equip_index[EQI_SHADOW_WEAPON] >= 0 ? EQP_SHADOW_SHIELD : EQP_SHADOW_WEAPON; } if (pos&EQP_HAND_R && battle_config.use_weapon_skill_range&BL_PC) @@ -8581,11 +8693,11 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos) clif->arrow_fail(sd,3); } else - clif->equipitemack(sd,n,pos,1); + clif->equipitemack(sd,n,pos,EIA_SUCCESS); sd->status.inventory[n].equip=pos; - if(pos & EQP_HAND_R) { + if(pos & (EQP_HAND_R|EQP_SHADOW_WEAPON)) { if(id) sd->weapontype1 = id->look; else @@ -8593,19 +8705,16 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos) pc->calcweapontype(sd); clif->changelook(&sd->bl,LOOK_WEAPON,sd->status.weapon); } - if(pos & EQP_HAND_L) { + if(pos & (EQP_HAND_L|EQP_SHADOW_SHIELD)) { if(id) { if(id->type == IT_WEAPON) { sd->status.shield = 0; sd->weapontype2 = id->look; - } - else - if(id->type == IT_ARMOR) { + } else if(id->type == IT_ARMOR) { sd->status.shield = id->look; sd->weapontype2 = 0; } - } - else + } else sd->status.shield = sd->weapontype2 = 0; pc->calcweapontype(sd); clif->changelook(&sd->bl,LOOK_SHIELD,sd->status.shield); @@ -8690,7 +8799,7 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos) } } - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_NONE); if (flag) //Update skill data clif->skillinfoblock(sd); @@ -8730,20 +8839,20 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag) { nullpo_ret(sd); if( n < 0 || n >= MAX_INVENTORY ) { - clif->unequipitemack(sd,0,0,0); + clif->unequipitemack(sd,0,0,UIA_FAIL); return 0; } // if player is berserk then cannot unequip - if (!(flag & 2) && sd->sc.count && (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_SATURDAY_NIGHT_FEVER])) + if (!(flag & 2) && sd->sc.count && (sd->sc.data[SC_BERSERK])) { - clif->unequipitemack(sd,n,0,0); + clif->unequipitemack(sd,n,0,UIA_FAIL); return 0; } if( !(flag&2) && sd->sc.count && sd->sc.data[SC_KYOUGAKU] ) { - clif->unequipitemack(sd,n,0,0); + clif->unequipitemack(sd,n,0,UIA_FAIL); return 0; } @@ -8751,7 +8860,7 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag) { ShowInfo("unequip %d %x:%x\n",n,pc->equippoint(sd,n),sd->status.inventory[n].equip); if(!sd->status.inventory[n].equip){ //Nothing to unequip - clif->unequipitemack(sd,n,0,0); + clif->unequipitemack(sd,n,0,UIA_FAIL); return 0; } for(i=0;i<EQI_MAX;i++) { @@ -8813,7 +8922,7 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag) { clif->changelook(&sd->bl,LOOK_ROBE,sd->status.robe); } - clif->unequipitemack(sd,n,sd->status.inventory[n].equip,1); + clif->unequipitemack(sd,n,sd->status.inventory[n].equip,UIA_SUCCESS); if((sd->status.inventory[n].equip & EQP_ARMS) && sd->weapontype1 == 0 && sd->weapontype2 == 0 && (!sd->sc.data[SC_TK_SEVENWIND] || sd->sc.data[SC_ASPERSIO])) //Check for seven wind (but not level seven!) @@ -8855,7 +8964,7 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag) { if(flag&1 || status_cacl) { pc->checkallowskill(sd); - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_NONE); } if(sd->sc.data[SC_CRUCIS] && !battle->check_undead(sd->battle_status.race,sd->battle_status.def_ele)) @@ -8892,14 +9001,14 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag) { *------------------------------------------*/ int pc_checkitem(struct map_session_data *sd) { - int i,id,calc_flag = 0; + int i, id, calc_flag = 0; nullpo_ret(sd); if( sd->state.vending ) //Avoid reorganizing items when we are vending, as that leads to exploits (pointed out by End of Exam) return 0; - if( battle_config.item_check ) { // check for invalid(ated) items + if( sd->state.itemcheck ) { // check for invalid(ated) items for( i = 0; i < MAX_INVENTORY; i++ ) { id = sd->status.inventory[i].nameid; @@ -8927,7 +9036,7 @@ int pc_checkitem(struct map_session_data *sd) } } - if (sd->state.gmaster_flag) { + if (sd->guild) { struct guild_storage *guild_storage = gstorage->id2storage2(sd->guild->guild_id); if (guild_storage) { for( i = 0; i < MAX_GUILD_STORAGE; i++ ) { @@ -8940,6 +9049,7 @@ int pc_checkitem(struct map_session_data *sd) } } } + sd->state.itemcheck = 0; } for( i = 0; i < MAX_INVENTORY; i++) { @@ -8957,10 +9067,10 @@ int pc_checkitem(struct map_session_data *sd) } } - + if( calc_flag && sd->state.active ) { pc->checkallowskill(sd); - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_NONE); } return 0; @@ -9003,7 +9113,7 @@ int pc_calc_pvprank(struct map_session_data *sd) { /*========================================== * Calculate next sd ranking calculation from config *------------------------------------------*/ -int pc_calc_pvprank_timer(int tid, unsigned int tick, int id, intptr_t data) { +int pc_calc_pvprank_timer(int tid, int64 tick, int id, intptr_t data) { struct map_session_data *sd; sd=map->id2sd(id); @@ -9204,11 +9314,10 @@ void pc_regen (struct map_session_data *sd, unsigned int diff_tick) { /*========================================== * Memo player sd savepoint. (map,x,y) *------------------------------------------*/ -int pc_setsavepoint(struct map_session_data *sd, short mapindex,int x,int y) -{ +int pc_setsavepoint(struct map_session_data *sd, short map_index, int x, int y) { nullpo_ret(sd); - sd->status.save_point.map = mapindex; + sd->status.save_point.map = map_index; sd->status.save_point.x = x; sd->status.save_point.y = y; @@ -9216,10 +9325,9 @@ int pc_setsavepoint(struct map_session_data *sd, short mapindex,int x,int y) } /*========================================== - * Save 1 player data at autosave intervalle + * Save 1 player data at autosave intervall *------------------------------------------*/ -int pc_autosave(int tid, unsigned int tick, int id, intptr_t data) -{ +int pc_autosave(int tid, int64 tick, int id, intptr_t data) { int interval; struct s_mapiterator* iter; struct map_session_data* sd; @@ -9270,7 +9378,7 @@ int pc_daynight_timer_sub(struct map_session_data *sd,va_list ap) { * timer to do the day [Yor] * data: 0 = called by timer, 1 = gmcommand/script *------------------------------------------------*/ -int map_day_timer(int tid, unsigned int tick, int id, intptr_t data) { +int map_day_timer(int tid, int64 tick, int id, intptr_t data) { char tmp_soutput[1024]; if (data == 0 && battle_config.day_duration <= 0) // if we want a day @@ -9290,7 +9398,7 @@ int map_day_timer(int tid, unsigned int tick, int id, intptr_t data) { * timer to do the night [Yor] * data: 0 = called by timer, 1 = gmcommand/script *------------------------------------------------*/ -int map_night_timer(int tid, unsigned int tick, int id, intptr_t data) { +int map_night_timer(int tid, int64 tick, int id, intptr_t data) { char tmp_soutput[1024]; if (data == 0 && battle_config.night_duration <= 0) // if we want a night @@ -9334,9 +9442,9 @@ void pc_overheat(struct map_session_data *sd, int val) { heat = max(0,heat); // Avoid negative HEAT if( heat >= limit[skill_lv] ) - sc_start(&sd->bl,SC_OVERHEAT,100,0,1000); + sc_start(NULL,&sd->bl,SC_OVERHEAT,100,0,1000); else - sc_start(&sd->bl,SC_OVERHEAT_LIMITPOINT,100,heat,30000); + sc_start(NULL,&sd->bl,SC_OVERHEAT_LIMITPOINT,100,heat,30000); return; } @@ -9346,10 +9454,16 @@ void pc_overheat(struct map_session_data *sd, int val) { */ bool pc_isautolooting(struct map_session_data *sd, int nameid) { - int i; - if( !sd->state.autolooting ) + int i = 0; + + if (sd->state.autoloottype && sd->state.autoloottype&(1<<itemdb_type(nameid))) + return true; + + if (!sd->state.autolooting) return false; + ARR_FIND(0, AUTOLOOTITEM_SIZE, i, sd->state.autolootid[i] == nameid); + return (i != AUTOLOOTITEM_SIZE); } @@ -9362,7 +9476,7 @@ bool pc_can_use_command(struct map_session_data *sd, const char *command) { return atcommand->can_use(sd,command); } -int pc_charm_timer(int tid, unsigned int tick, int id, intptr_t data) { +int pc_charm_timer(int tid, int64 tick, int id, intptr_t data) { struct map_session_data *sd; int i, type; @@ -9680,14 +9794,14 @@ void pc_read_skill_tree(void) { { "Rebellion", JOB_REBELLION }, }; - if (conf_read_file(&skill_tree_conf, config_filename)) { + if (libconfig->read_file(&skill_tree_conf, config_filename)) { ShowError("can't read %s\n", config_filename); return; } jnamelen = ARRAYLENGTH(jnames); - while( (skt = config_setting_get_elem(skill_tree_conf.root,i++)) ) { + while( (skt = libconfig->setting_get_elem(skill_tree_conf.root,i++)) ) { int k, idx; const char *name = config_setting_name(skt); @@ -9699,12 +9813,12 @@ void pc_read_skill_tree(void) { } - if( ( skills = config_setting_get_member(skt,"skills") ) ) { + if( ( skills = libconfig->setting_get_member(skt,"skills") ) ) { int c = 0; idx = pc->class2idx(jnames[k].id); - while( ( sk = config_setting_get_elem(skills,c++) ) ) { + while( ( sk = libconfig->setting_get_elem(skills,c++) ) ) { const char *sk_name = config_setting_name(sk); int skill_id; @@ -9724,23 +9838,23 @@ void pc_read_skill_tree(void) { if( config_setting_is_group(sk) ) { int max = 0, jlevel = 0; - config_setting_lookup_int(sk, "MaxLevel", &max); - config_setting_lookup_int(sk, "MinJobLevel", &jlevel); + libconfig->setting_lookup_int(sk, "MaxLevel", &max); + libconfig->setting_lookup_int(sk, "MinJobLevel", &jlevel); pc->skill_tree[idx][skidx].max = (unsigned char)max; pc->skill_tree[idx][skidx].joblv = (unsigned char)jlevel; - rlen = config_setting_length(sk); + rlen = libconfig->setting_length(sk); offset += jlevel ? 2 : 1; } else { - pc->skill_tree[idx][skidx].max = (unsigned char)config_setting_get_int(sk); + pc->skill_tree[idx][skidx].max = (unsigned char)libconfig->setting_get_int(sk); pc->skill_tree[idx][skidx].joblv = 0; } for( h = offset; h < rlen && h < MAX_PC_SKILL_REQUIRE; h++ ) { - config_setting_t *rsk = config_setting_get_elem(sk,h); + config_setting_t *rsk = libconfig->setting_get_elem(sk,h); if( rsk && ( rskid = skill->name2id(config_setting_name(rsk)) ) ) { pc->skill_tree[idx][skidx].need[h].id = rskid; pc->skill_tree[idx][skidx].need[h].idx = skill->get_index(rskid); - pc->skill_tree[idx][skidx].need[h].lv = (unsigned char)config_setting_get_int(rsk); + pc->skill_tree[idx][skidx].need[h].lv = (unsigned char)libconfig->setting_get_int(rsk); } else if( rsk ) { ShowWarning("pc_read_skill_tree: unknown requirement '%s' for '%s' in '%s'\n",config_setting_name(rsk),sk_name,name); } else { @@ -9756,7 +9870,7 @@ void pc_read_skill_tree(void) { } i = 0; - while( (skt = config_setting_get_elem(skill_tree_conf.root,i++)) ) { + while( (skt = libconfig->setting_get_elem(skill_tree_conf.root,i++)) ) { int k, idx, v = 0; const char *name = config_setting_name(skt); const char *iname; @@ -9770,8 +9884,8 @@ void pc_read_skill_tree(void) { } idx = pc->class2idx(jnames[k].id); - if( ( inherit = config_setting_get_member(skt,"inherit") ) ) { - while( ( iname = config_setting_get_string_elem(inherit, v++) ) ) { + if( ( inherit = libconfig->setting_get_member(skt,"inherit") ) ) { + while( ( iname = libconfig->setting_get_string_elem(inherit, v++) ) ) { int b = 0, a, d, f, fidx; ARR_FIND(0, jnamelen, b, strcmpi(jnames[b].name,iname) == 0 ); @@ -9803,7 +9917,7 @@ void pc_read_skill_tree(void) { } - config_destroy(&skill_tree_conf); + libconfig->destroy(&skill_tree_conf); /* lets update all players skill tree */ iter = mapit_getallusers(); @@ -9995,8 +10109,10 @@ int pc_readdb(void) { while(*p==32 && *p>0) p++; battle->attr_fix_table[lv-1][i][j]=atoi(p); +#ifndef RENEWAL if(battle_config.attr_recover == 0 && battle->attr_fix_table[lv-1][i][j] < 0) battle->attr_fix_table[lv-1][i][j] = 0; +#endif p=strchr(p,','); if(p) *p++=0; } @@ -10022,7 +10138,7 @@ int pc_readdb(void) { int stat; if(line[0]=='/' && line[1]=='/') continue; - if ((stat=strtoul(line,NULL,10))<0) + if ((stat=(int)strtol(line,NULL,10))<0) stat=0; if (i > MAX_LEVEL) break; @@ -10079,25 +10195,357 @@ void pc_itemcd_do(struct map_session_data *sd, bool load) { return; } -/*========================================== - * pc Init/Terminate - *------------------------------------------*/ -void do_final_pc(void) { +void pc_bank_deposit(struct map_session_data *sd, int money) { + unsigned int limit_check = money+sd->status.bank_vault; + + if( money <= 0 || limit_check > MAX_BANK_ZENY ) { + clif->bank_deposit(sd,BDA_OVERFLOW); + return; + } else if ( money > sd->status.zeny ) { + clif->bank_deposit(sd,BDA_NO_MONEY); + return; + } - db_destroy(pc->itemcd_db); + if( pc->payzeny(sd,money, LOG_TYPE_BANK, NULL) ) + clif->bank_deposit(sd,BDA_NO_MONEY); + else { + sd->status.bank_vault += money; + if( map->save_settings&256 ) + chrif->save(sd,0); + clif->bank_deposit(sd,BDA_SUCCESS); + } +} +void pc_bank_withdraw(struct map_session_data *sd, int money) { + unsigned int limit_check = money+sd->status.zeny; + + if( money <= 0 ) { + clif->bank_withdraw(sd,BWA_UNKNOWN_ERROR); + return; + } else if ( money > sd->status.bank_vault ) { + clif->bank_withdraw(sd,BWA_NO_MONEY); + return; + } else if ( limit_check > MAX_ZENY ) { + /* no official response for this scenario exists. */ + clif->colormes(sd->fd,COLOR_RED,msg_txt(1482)); + return; + } + + if( pc->getzeny(sd,money, LOG_TYPE_BANK, NULL) ) + clif->bank_withdraw(sd,BWA_NO_MONEY); + else { + sd->status.bank_vault -= money; + if( map->save_settings&256 ) + chrif->save(sd,0); + clif->bank_withdraw(sd,BWA_SUCCESS); + } +} +/* status change data arrived from char-server */ +void pc_scdata_received(struct map_session_data *sd) { + pc->inventory_rentals(sd); + clif->show_modifiers(sd); + + if (sd->expiration_time != 0) { // don't display if it's unlimited or unknow value + time_t exp_time = sd->expiration_time; + char tmpstr[1024]; + strftime(tmpstr, sizeof(tmpstr) - 1, msg_txt(501), localtime(&exp_time)); // "Your account time limit is: %d-%m-%Y %H:%M:%S." + clif->wis_message(sd->fd, map->wisp_server_name, tmpstr, strlen(tmpstr)+1); + + pc->expire_check(sd); + } + + if( sd->state.standalone ) { + clif->pLoadEndAck(0,sd); + pc->autotrade_populate(sd); + pc->autotrade_start(sd); + } +} +int pc_expiration_timer(int tid, int64 tick, int id, intptr_t data) { + struct map_session_data *sd = map->id2sd(id); + + if( !sd ) return 0; + + sd->expiration_tid = INVALID_TIMER; + + if( sd->fd ) + clif->authfail_fd(sd->fd,10); + + map->quit(sd); + + return 0; +} +/* this timer exists only when a character with a expire timer > 24h is online */ +/* it loops thru online players once an hour to check whether a new < 24h is available */ +int pc_global_expiration_timer(int tid, int64 tick, int id, intptr_t data) { + struct s_mapiterator* iter; + struct map_session_data* sd; - do_final_pc_groups(); + iter = mapit_getallusers(); + + for( sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); sd = (TBL_PC*)mapit->next(iter) ) { + if( sd->expiration_time ) + pc->expire_check(sd); + } + + mapit->free(iter); + + return 0; +} +void pc_expire_check(struct map_session_data *sd) { + /* ongoing timer */ + if( sd->expiration_tid != INVALID_TIMER ) + return; + + /* not within the next 24h, enable the global check */ + if( sd->expiration_time > ( time(NULL) + ( ( 60 * 60 ) * 24 ) ) ) { + + /* global check not running, enable */ + if( pc->expiration_tid == INVALID_TIMER ) { + /* starts in 1h, repeats every hour */ + pc->expiration_tid = timer->add_interval(timer->gettick() + ((1000*60)*60), pc->global_expiration_timer, 0, 0, ((1000*60)*60)); + } + + return; + } + + sd->expiration_tid = timer->add(timer->gettick() + (int64)(sd->expiration_time - time(NULL))*1000, pc->expiration_timer, sd->bl.id, 0); +} +/** + * Loads autotraders + ***/ +void pc_autotrade_load(void) { + struct map_session_data *sd; + char *data; + + if (SQL_ERROR == SQL->Query(map->mysql_handle, "SELECT `account_id`,`char_id`,`sex`,`title` FROM `%s`",map->autotrade_merchants_db)) + Sql_ShowDebug(map->mysql_handle); + + while( SQL_SUCCESS == SQL->NextRow(map->mysql_handle) ) { + int account_id, char_id; + char title[MESSAGE_SIZE]; + unsigned char sex; + + SQL->GetData(map->mysql_handle, 0, &data, NULL); account_id = atoi(data); + SQL->GetData(map->mysql_handle, 1, &data, NULL); char_id = atoi(data); + SQL->GetData(map->mysql_handle, 2, &data, NULL); sex = atoi(data); + SQL->GetData(map->mysql_handle, 3, &data, NULL); safestrncpy(title, data, sizeof(title)); + + CREATE(sd, TBL_PC, 1); + + pc->setnewpc(sd, account_id, char_id, 0, 0, sex, 0); + + safestrncpy(sd->message, title, MESSAGE_SIZE); + + sd->state.standalone = 1; + sd->group = pcg->get_dummy_group(); + + chrif->authreq(sd,true); + } + + SQL->FreeResult(map->mysql_handle); +} +/** + * Loads vending data and sets it up, is triggered when char server data that pc_autotrade_load requested arrives + **/ +void pc_autotrade_start(struct map_session_data *sd) { + unsigned int count = 0; + int i; + char *data; + + if (SQL_ERROR == SQL->Query(map->mysql_handle, "SELECT `itemkey`,`amount`,`price` FROM `%s` WHERE `char_id` = '%d'",map->autotrade_data_db,sd->status.char_id)) + Sql_ShowDebug(map->mysql_handle); + + while( SQL_SUCCESS == SQL->NextRow(map->mysql_handle) ) { + int itemkey, amount, price; + + SQL->GetData(map->mysql_handle, 0, &data, NULL); itemkey = atoi(data); + SQL->GetData(map->mysql_handle, 1, &data, NULL); amount = atoi(data); + SQL->GetData(map->mysql_handle, 2, &data, NULL); price = atoi(data); + + ARR_FIND(0, MAX_CART, i, sd->status.cart[i].id == itemkey); + + if( i != MAX_CART && itemdb_cantrade(&sd->status.cart[i], 0, 0) ) { + if( amount > sd->status.cart[i].amount ) + amount = sd->status.cart[i].amount; + + if( amount ) { + sd->vending[count].index = i; + sd->vending[count].amount = amount; + sd->vending[count].value = cap_value(price, 0, (unsigned int)battle_config.vending_max_value); + + count++; + } + } + } + + if( !count ) { + pc->autotrade_update(sd,PAUC_REMOVE); + map->quit(sd); + } else { + sd->state.autotrade = 1; + sd->vender_id = ++vending->next_id; + sd->vend_num = count; + sd->state.vending = true; + idb_put(vending->db, sd->status.char_id, sd); + if( map->list[sd->bl.m].users ) + clif->showvendingboard(&sd->bl,sd->message,0); + } +} +/** + * Perform a autotrade action + **/ +void pc_autotrade_update(struct map_session_data *sd, enum e_pc_autotrade_update_action action) { + int i; + + /* either way, this goes down */ + if( action != PAUC_START ) { + if (SQL_ERROR == SQL->Query(map->mysql_handle, "DELETE FROM `%s` WHERE `char_id` = '%d'",map->autotrade_data_db,sd->status.char_id)) + Sql_ShowDebug(map->mysql_handle); + } + + switch( action ) { + case PAUC_REMOVE: + if (SQL_ERROR == SQL->Query(map->mysql_handle, "DELETE FROM `%s` WHERE `char_id` = '%d' LIMIT 1",map->autotrade_merchants_db,sd->status.char_id)) + Sql_ShowDebug(map->mysql_handle); + break; + case PAUC_START: { + char title[MESSAGE_SIZE*2+1]; + + SQL->EscapeStringLen(map->mysql_handle, title, sd->message, strnlen(sd->message, MESSAGE_SIZE)); + + if (SQL_ERROR == SQL->Query(map->mysql_handle, "INSERT INTO `%s` (`account_id`,`char_id`,`sex`,`title`) VALUES ('%d','%d','%d','%s')", + map->autotrade_merchants_db, + sd->status.account_id, + sd->status.char_id, + sd->status.sex, + title + )) + Sql_ShowDebug(map->mysql_handle); + } + /* yes we want it to fall */ + case PAUC_REFRESH: + for( i = 0; i < sd->vend_num; i++ ) { + if( sd->vending[i].amount == 0 ) + continue; + + if (SQL_ERROR == SQL->Query(map->mysql_handle, "INSERT INTO `%s` (`char_id`,`itemkey`,`amount`,`price`) VALUES ('%d','%d','%d','%d')", + map->autotrade_data_db, + sd->status.char_id, + sd->status.cart[sd->vending[i].index].id, + sd->vending[i].amount, + sd->vending[i].value + )) + Sql_ShowDebug(map->mysql_handle); + } + break; + } +} +/** + * Handles characters upon @autotrade usage + **/ +void pc_autotrade_prepare(struct map_session_data *sd) { + struct autotrade_vending *data; + int i, cursor = 0; + int account_id, char_id; + char title[MESSAGE_SIZE]; + unsigned char sex; + + CREATE(data, struct autotrade_vending, 1); + + memcpy(data->vending, sd->vending, sizeof(sd->vending)); + + for(i = 0; i < sd->vend_num; i++) { + if( sd->vending[i].amount ) { + memcpy(&data->list[cursor],&sd->status.cart[sd->vending[i].index],sizeof(struct item)); + cursor++; + } + } + + data->vend_num = (unsigned char)cursor; + + idb_put(pc->at_db, sd->status.char_id, data); + + account_id = sd->status.account_id; + char_id = sd->status.char_id; + sex = sd->status.sex; + safestrncpy(title, sd->message, sizeof(title)); + + map->quit(sd); + chrif->auth_delete(account_id, char_id, ST_LOGOUT); + + CREATE(sd, TBL_PC, 1); + + pc->setnewpc(sd, account_id, char_id, 0, 0, sex, 0); + + safestrncpy(sd->message, title, MESSAGE_SIZE); + + sd->state.standalone = 1; + sd->group = pcg->get_dummy_group(); + + chrif->authreq(sd,true); +} +/** + * Prepares autotrade data from pc->at_db from a player that has already returned from char server + **/ +void pc_autotrade_populate(struct map_session_data *sd) { + struct autotrade_vending *data; + int i, j, k, cursor = 0; + + if( !(data = idb_get(pc->at_db,sd->status.char_id)) ) + return; + + for(i = 0; i < data->vend_num; i++) { + if( !data->vending[i].amount ) + continue; + + for(j = 0; j < MAX_CART; j++) { + if( !memcmp((char*)(&data->list[i]) + sizeof(data->list[0].id), (char*)(&sd->status.cart[j]) + sizeof(data->list[0].id), sizeof(struct item) - sizeof(data->list[0].id)) ) { + if( cursor ) { + ARR_FIND(0, cursor, k, sd->vending[k].index == j); + if( k != cursor ) + continue; + } + break; + } + } + + if( j != MAX_CART ) { + sd->vending[cursor].index = j; + sd->vending[cursor].amount = data->vending[i].amount; + sd->vending[cursor].value = data->vending[i].value; + + cursor++; + } + } + + sd->vend_num = cursor; + + pc->autotrade_update(sd,PAUC_START); + + idb_remove(pc->at_db, sd->status.char_id); +} +void do_final_pc(void) { + + db_destroy(pc->itemcd_db); + db_destroy(pc->at_db); + + pcg->final(); ers_destroy(pc->sc_display_ers); + ers_destroy(pc->num_reg_ers); + ers_destroy(pc->str_reg_ers); + return; } -void do_init_pc(void) { - +void do_init_pc(bool minimal) { + if (minimal) + return; + pc->itemcd_db = idb_alloc(DB_OPT_RELEASE_DATA); - + pc->at_db = idb_alloc(DB_OPT_RELEASE_DATA); + pc->readdb(); - + timer->add_func_list(pc->invincible_timer, "pc_invincible_timer"); timer->add_func_list(pc->eventtimer, "pc_eventtimer"); timer->add_func_list(pc->inventory_rental_end, "pc_inventory_rental_end"); @@ -10107,28 +10555,35 @@ void do_init_pc(void) { timer->add_func_list(pc->follow_timer, "pc_follow_timer"); timer->add_func_list(pc->endautobonus, "pc_endautobonus"); timer->add_func_list(pc->charm_timer, "pc_charm_timer"); - + timer->add_func_list(pc->global_expiration_timer,"pc_global_expiration_timer"); + timer->add_func_list(pc->expiration_timer,"pc_expiration_timer"); + timer->add(timer->gettick() + map->autosave_interval, pc->autosave, 0, 0); - + // 0=day, 1=night [Yor] map->night_flag = battle_config.night_at_start ? 1 : 0; - + if (battle_config.day_duration > 0 && battle_config.night_duration > 0) { int day_duration = battle_config.day_duration; int night_duration = battle_config.night_duration; // add night/day timer [Yor] timer->add_func_list(pc->map_day_timer, "pc_map_day_timer"); timer->add_func_list(pc->map_night_timer, "pc_map_night_timer"); - + pc->day_timer_tid = timer->add_interval(timer->gettick() + (map->night_flag ? 0 : day_duration) + night_duration, pc->map_day_timer, 0, 0, day_duration + night_duration); pc->night_timer_tid = timer->add_interval(timer->gettick() + day_duration + (map->night_flag ? night_duration : 0), pc->map_night_timer, 0, 0, day_duration + night_duration); } - - do_init_pc_groups(); - pc->sc_display_ers = ers_new(sizeof(struct sc_display_entry), "pc.c:sc_display_ers", ERS_OPT_NONE); -} + pcg->init(); + + pc->sc_display_ers = ers_new(sizeof(struct sc_display_entry), "pc.c:sc_display_ers", ERS_OPT_FLEX_CHUNK); + pc->num_reg_ers = ers_new(sizeof(struct script_reg_num), "pc.c::num_reg_ers", ERS_OPT_CLEAN|ERS_OPT_FLEX_CHUNK); + pc->str_reg_ers = ers_new(sizeof(struct script_reg_str), "pc.c::str_reg_ers", ERS_OPT_CLEAN|ERS_OPT_FLEX_CHUNK); + ers_chunk_size(pc->sc_display_ers, 150); + ers_chunk_size(pc->num_reg_ers, 300); + ers_chunk_size(pc->str_reg_ers, 50); +} /*===================================== * Default Functions : pc.h * Generated by HerculesInterfaceMaker @@ -10140,12 +10595,12 @@ void pc_defaults(void) { { SG_MOON_ANGER, SG_MOON_BLESS, SG_MOON_COMFORT, "PC_FEEL_MOON", "PC_HATE_MOB_MOON", is_day_of_moon }, { SG_STAR_ANGER, SG_STAR_BLESS, SG_STAR_COMFORT, "PC_FEEL_STAR", "PC_HATE_MOB_STAR", is_day_of_star } }; - unsigned short equip_pos[EQI_MAX]={EQP_ACC_L,EQP_ACC_R,EQP_SHOES,EQP_GARMENT,EQP_HEAD_LOW,EQP_HEAD_MID,EQP_HEAD_TOP,EQP_ARMOR,EQP_HAND_L,EQP_HAND_R,EQP_COSTUME_HEAD_TOP,EQP_COSTUME_HEAD_MID,EQP_COSTUME_HEAD_LOW,EQP_COSTUME_GARMENT,EQP_AMMO}; - + unsigned int equip_pos[EQI_MAX]={EQP_ACC_L,EQP_ACC_R,EQP_SHOES,EQP_GARMENT,EQP_HEAD_LOW,EQP_HEAD_MID,EQP_HEAD_TOP,EQP_ARMOR,EQP_HAND_L,EQP_HAND_R,EQP_COSTUME_HEAD_TOP,EQP_COSTUME_HEAD_MID,EQP_COSTUME_HEAD_LOW,EQP_COSTUME_GARMENT,EQP_AMMO, EQP_SHADOW_ARMOR, EQP_SHADOW_WEAPON, EQP_SHADOW_SHIELD, EQP_SHADOW_SHOES, EQP_SHADOW_ACC_R, EQP_SHADOW_ACC_L }; pc = &pc_s; /* vars */ + pc->at_db = NULL; pc->itemcd_db = NULL; /* */ pc->day_timer_tid = INVALID_TIMER; @@ -10168,17 +10623,21 @@ void pc_defaults(void) { memcpy(pc->sg_info, sg_info, sizeof(pc->sg_info)); /* */ pc->sc_display_ers = NULL; + /* */ + pc->expiration_tid = INVALID_TIMER; + /* */ + pc->num_reg_ers = NULL; + pc->str_reg_ers = NULL; + /* */ + pc->reg_load = false; /* funcs */ pc->init = do_init_pc; pc->final = do_final_pc; pc->get_dummy_sd = pc_get_dummy_sd; pc->class2idx = pc_class2idx; - pc->get_group_level = pc_get_group_level; - pc->can_give_items = pc_can_give_items; pc->can_use_command = pc_can_use_command; - pc->has_permission = pc_has_permission; pc->set_group = pc_set_group; pc->should_log_commands = pc_should_log_commands; @@ -10268,6 +10727,7 @@ void pc_defaults(void) { pc->thisjobexp = pc_thisjobexp; pc->gets_status_point = pc_gets_status_point; pc->need_status_point = pc_need_status_point; + pc->maxparameterincrease = pc_maxparameterincrease; pc->statusup = pc_statusup; pc->statusup2 = pc_statusup2; pc->skillup = pc_skillup; @@ -10402,4 +10862,25 @@ void pc_defaults(void) { pc->checkcombo = pc_checkcombo; pc->calcweapontype = pc_calcweapontype; pc->removecombo = pc_removecombo; + + pc->bank_withdraw = pc_bank_withdraw; + pc->bank_deposit = pc_bank_deposit; + + pc->rental_expire = pc_rental_expire; + pc->scdata_received = pc_scdata_received; + + pc->bound_clear = pc_bound_clear; + + pc->expiration_timer = pc_expiration_timer; + pc->global_expiration_timer = pc_global_expiration_timer; + pc->expire_check = pc_expire_check; + + /** + * Autotrade persistency [Ind/Hercules <3] + **/ + pc->autotrade_load = pc_autotrade_load; + pc->autotrade_update = pc_autotrade_update; + pc->autotrade_start = pc_autotrade_start; + pc->autotrade_prepare = pc_autotrade_prepare; + pc->autotrade_populate = pc_autotrade_populate; } diff --git a/src/map/pc.h b/src/map/pc.h index fadb922b5..47bbe9202 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -1,8 +1,9 @@ // Copyright (c) Hercules Dev Team, licensed under GNU GPL. // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _PC_H_ -#define _PC_H_ + +#ifndef _MAP_PC_H_ +#define _MAP_PC_H_ #include "../common/mmo.h" // JOB_*, MAX_FAME_LIST, struct fame_list, struct mmo_charstatus #include "../common/ers.h" @@ -48,6 +49,12 @@ enum equip_index { EQI_COSTUME_LOW, EQI_COSTUME_GARMENT, EQI_AMMO, + EQI_SHADOW_ARMOR, + EQI_SHADOW_WEAPON, + EQI_SHADOW_SHIELD, + EQI_SHADOW_SHOES, + EQI_SHADOW_ACC_R, + EQI_SHADOW_ACC_L, EQI_MAX }; struct weapon_data { @@ -109,6 +116,12 @@ enum npc_timeout_type { NPCT_MENU = 1, NPCT_WAIT = 2, }; + +struct pc_combos { + struct script_code *bonus;/* the script of the combo */ + unsigned short id;/* this combo id */ +}; + struct map_session_data { struct block_list bl; struct unit_data ud; @@ -133,7 +146,6 @@ struct map_session_data { unsigned int abra_flag : 2; // Abracadabra bugfix by Aru unsigned int autocast : 1; // Autospell flag [Inkfish] unsigned int autotrade : 1; //By Fantik - unsigned int reg_dirty : 4; //By Skotlex (marks whether registry variables have been saved or not yet) unsigned int showdelay :1; unsigned int showexp :1; unsigned int showzeny :1; @@ -160,6 +172,7 @@ struct map_session_data { short pmap; // Previous map on Map Change unsigned short autoloot; unsigned short autolootid[AUTOLOOTITEM_SIZE]; // [Zephyrus] + unsigned short autoloottype; unsigned int autolooting : 1; //performance-saver, autolooting state for @alootid unsigned short autobonus; //flag to indicate if an autobonus is activated. [Inkfish] unsigned int gmaster_flag : 1; @@ -171,6 +184,9 @@ struct map_session_data { unsigned int workinprogress : 3; // 1 = disable skill/item, 2 = disable npc interaction, 3 = disable both unsigned int hold_recalc : 1; unsigned int snovice_call_flag : 3; //Summon Angel (stage 1~3) + unsigned int hpmeter_visible : 1; + unsigned int itemcheck : 1; + unsigned int standalone : 1;/* [Ind/Hercules <3] */ } state; struct { unsigned char no_weapon_damage, no_magic_damage, no_misc_damage; @@ -193,7 +209,6 @@ struct map_session_data { unsigned int extra_temp_permissions; /* permissions from @addperm */ struct mmo_charstatus status; - struct registry save_reg; struct item_data* inventory_data[MAX_INVENTORY]; // direct pointers to itemdb entries (faster than doing item_id lookups) short equip_index[EQI_MAX]; unsigned int weight,max_weight; @@ -210,10 +225,10 @@ struct map_session_data { char npc_str[CHATBOX_SIZE]; // for passing npc input box text to script engine int npc_timer_id; //For player attached npc timers. [Skotlex] unsigned int chatID; - time_t idletime; - struct{ + int64 idletime; + struct { int npc_id; - unsigned int timeout; + int64 timeout; } progressbar; //Progress Bar [Inkfish] struct{ char name[NAME_LENGTH]; @@ -225,21 +240,21 @@ struct map_session_data { uint16 skill_id_old,skill_lv_old; uint16 skill_id_dance,skill_lv_dance; short cook_mastery; // range: [0,1999] [Inkfish] - unsigned char blockskill[MAX_SKILL]; + bool blockskill[MAX_SKILL]; int cloneskill_id, reproduceskill_id; int menuskill_id, menuskill_val, menuskill_val2; int invincible_timer; - unsigned int canlog_tick; - unsigned int canuseitem_tick; // [Skotlex] - unsigned int canusecashfood_tick; - unsigned int canequip_tick; // [Inkfish] - unsigned int cantalk_tick; - unsigned int canskill_tick; // used to prevent abuse from no-delay ACT files - unsigned int cansendmail_tick; // [Mail System Flood Protection] - unsigned int ks_floodprotect_tick; // [Kill Steal Protection] + int64 canlog_tick; + int64 canuseitem_tick; // [Skotlex] + int64 canusecashfood_tick; + int64 canequip_tick; // [Inkfish] + int64 cantalk_tick; + int64 canskill_tick; /// used to prevent abuse from no-delay ACT files + int64 cansendmail_tick; /// Mail System Flood Protection + int64 ks_floodprotect_tick; /// [Kill Steal Protection] struct { short nameid; - unsigned int tick; + int64 tick; } item_delay[MAX_ITEMDELAYS]; // [Paradox924X] short weapontype1,weapontype2; short disguise; // [Valaris] @@ -353,10 +368,6 @@ struct map_session_data { short mission_mobid; //Stores the target mob_id for TK_MISSION int die_counter; //Total number of times you've died int devotion[5]; //Stores the account IDs of chars devoted to. - int reg_num; //Number of registries (type numeric) - int regstr_num; //Number of registries (type string) - struct script_reg *reg; - struct script_regstr *regstr; int trade_partner; struct { struct { @@ -429,12 +440,11 @@ struct map_session_data { bool changed; // if true, should sync with charserver on next mailbox request } mail; - //Quest log system [Kevin] [Inkfish] - int num_quests; - int avail_quests; - int quest_index[MAX_QUEST_DB]; - struct quest quest_log[MAX_QUEST_DB]; - bool save_quest; + // Quest log system + int num_quests; ///< Number of entries in quest_log + int avail_quests; ///< Number of Q_ACTIVE and Q_INACTIVE entries in quest log (index of the first Q_COMPLETE entry) + struct quest *quest_log; ///< Quest log entries (note: Q_COMPLETE quests follow the first <avail_quests>th enties + bool save_quest; ///< Whether the quest_log entries were modified and are waitin to be saved // temporary debug [flaviojs] const char* debug_file; @@ -442,7 +452,6 @@ struct map_session_data { const char* debug_func; unsigned int bg_id; - unsigned short user_font; /** * For the Secure NPC Timeout option (check config/Secure.h) [RR] @@ -460,17 +469,14 @@ struct map_session_data { * @info * - It is updated on every NPC iteration as mentioned above **/ - unsigned int npc_idle_tick; + int64 npc_idle_tick; /* */ enum npc_timeout_type npc_idle_type; #endif - struct { - struct script_code **bonus;/* the script */ - unsigned short *id;/* array of combo ids */ - unsigned char count; - } combos; - + struct pc_combos *combos; + unsigned char combo_count; + /** * Guarantees your friend request is legit (for bugreport:4629) **/ @@ -485,7 +491,7 @@ struct map_session_data { bool stealth; unsigned char fontcolor; unsigned int fontcolor_tid; - unsigned int hchsysch_tick; + int64 hchsysch_tick; /* [Ind/Hercules] */ struct sc_display_entry **sc_display; @@ -511,13 +517,28 @@ struct map_session_data { unsigned char delayed_damage;//ref. counter bugreport:7307 [Ind/Hercules] + /* HPM Custom Struct */ struct HPluginData **hdata; unsigned int hdatac; + /* expiration_time timer id */ + int expiration_tid; + time_t expiration_time; + /* */ struct { unsigned int second,third; } sktree; + + /** + * Account/Char variables & array control of those variables + **/ + DBMap *var_db; + DBMap *array_db; + unsigned char vars_received;/* char loading is only complete when you get it all. */ + bool vars_ok; + bool vars_dirty; + // temporary debugging of bug #3504 const char* delunit_prevfile; int delunit_prevline; @@ -526,21 +547,28 @@ struct map_session_data { //Equip position constants enum equip_pos { - EQP_HEAD_LOW = 0x0001, - EQP_HEAD_MID = 0x0200, //512 - EQP_HEAD_TOP = 0x0100, //256 - EQP_HAND_R = 0x0002, //2 - EQP_HAND_L = 0x0020, //32 - EQP_ARMOR = 0x0010, //16 - EQP_SHOES = 0x0040, //64 - EQP_GARMENT = 0x0004, //4 - EQP_ACC_L = 0x0008, //8 - EQP_ACC_R = 0x0080, //128 - EQP_COSTUME_HEAD_TOP = 0x0400, //1024 - EQP_COSTUME_HEAD_MID = 0x0800, //2048 - EQP_COSTUME_HEAD_LOW = 0x1000, //4096 - EQP_COSTUME_GARMENT = 0x2000, //8192 - EQP_AMMO = 0x8000, //32768 + EQP_HEAD_LOW = 0x000001, + EQP_HEAD_MID = 0x000200, //512 + EQP_HEAD_TOP = 0x000100, //256 + EQP_HAND_R = 0x000002, //2 + EQP_HAND_L = 0x000020, //32 + EQP_ARMOR = 0x000010, //16 + EQP_SHOES = 0x000040, //64 + EQP_GARMENT = 0x000004, //4 + EQP_ACC_L = 0x000008, //8 + EQP_ACC_R = 0x000080, //128 + EQP_COSTUME_HEAD_TOP = 0x000400, //1024 + EQP_COSTUME_HEAD_MID = 0x000800, //2048 + EQP_COSTUME_HEAD_LOW = 0x001000, //4096 + EQP_COSTUME_GARMENT = 0x002000, //8192 + //UNUSED_COSTUME_FLOOR = 0x004000, //16384 + EQP_AMMO = 0x008000, //32768 + EQP_SHADOW_ARMOR = 0x010000, //65536 + EQP_SHADOW_WEAPON = 0x020000, //131072 + EQP_SHADOW_SHIELD = 0x040000, //262144 + EQP_SHADOW_SHOES = 0x080000, //524288 + EQP_SHADOW_ACC_R = 0x100000, //1048576 + EQP_SHADOW_ACC_L = 0x200000, //2097152 }; #define EQP_WEAPON EQP_HAND_R @@ -549,6 +577,8 @@ enum equip_pos { #define EQP_HELM (EQP_HEAD_LOW|EQP_HEAD_MID|EQP_HEAD_TOP) #define EQP_ACC (EQP_ACC_L|EQP_ACC_R) #define EQP_COSTUME (EQP_COSTUME_HEAD_TOP|EQP_COSTUME_HEAD_MID|EQP_COSTUME_HEAD_LOW|EQP_COSTUME_GARMENT) +#define EQP_SHADOW_ACC (EQP_SHADOW_ACC_R|EQP_SHADOW_ACC_L) +#define EQP_SHADOW_ARMS (EQP_SHADOW_WEAPON|EQP_SHADOW_SHIELD) /// Equip positions that use a visible sprite #if PACKETVER < 20110111 @@ -561,7 +591,7 @@ enum equip_pos { #define pc_setsit(sd) ( (sd)->state.dead_sit = (sd)->vd.dead_sit = 2 ) #define pc_isdead(sd) ( (sd)->state.dead_sit == 1 ) #define pc_issit(sd) ( (sd)->vd.dead_sit == 2 ) -#define pc_isidle(sd) ( (sd)->chatID || (sd)->state.vending || (sd)->state.buyingstore || DIFF_TICK(last_tick, (sd)->idletime) >= battle_config.idle_no_share ) +#define pc_isidle(sd) ( (sd)->chatID || (sd)->state.vending || (sd)->state.buyingstore || DIFF_TICK(sockt->last_tick, (sd)->idletime) >= battle_config.idle_no_share ) #define pc_istrading(sd) ( (sd)->npc_id || (sd)->state.vending || (sd)->state.buyingstore || (sd)->state.trading ) #define pc_cant_act(sd) ( (sd)->npc_id || (sd)->state.vending || (sd)->state.buyingstore || (sd)->chatID || ((sd)->sc.opt1 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading || (sd)->state.storage_flag || (sd)->state.prevend ) @@ -596,8 +626,8 @@ enum equip_pos { // Rune Knight Dragon #define pc_isridingdragon(sd) ( (sd)->sc.option&OPTION_DRAGON ) -#define pc_stop_walking(sd, type) unit->stop_walking(&(sd)->bl, type) -#define pc_stop_attack(sd) unit->stop_attack(&(sd)->bl) +#define pc_stop_walking(sd, type) (unit->stop_walking(&(sd)->bl, (type))) +#define pc_stop_attack(sd) (unit->stop_attack(&(sd)->bl)) //Weapon check considering dual wielding. #define pc_check_weapontype(sd, type) ((type)&((sd)->status.weapon < MAX_WEAPON_TYPE? \ @@ -614,7 +644,7 @@ enum equip_pos { || ( (class_) >= JOB_KAGEROU && (class_) <= JOB_OBORO ) \ || ( (class_) >= JOB_REBELLION && (class_) < JOB_MAX ) \ ) -#define pcdb_checkid(class_) pcdb_checkid_sub((unsigned int)class_) +#define pcdb_checkid(class_) pcdb_checkid_sub((unsigned int)(class_)) // clientside display macros (values to the left/right of the "+") #ifdef RENEWAL @@ -652,18 +682,24 @@ enum equip_pos { #define pc_checkoverhp(sd) ((sd)->battle_status.hp == (sd)->battle_status.max_hp) #define pc_checkoversp(sd) ((sd)->battle_status.sp == (sd)->battle_status.max_sp) -#define pc_readglobalreg(sd,reg) pc->readregistry(sd,reg,3) -#define pc_setglobalreg(sd,reg,val) pc->setregistry(sd,reg,val,3) -#define pc_readglobalreg_str(sd,reg) pc->readregistry_str(sd,reg,3) -#define pc_setglobalreg_str(sd,reg,val) pc->setregistry_str(sd,reg,val,3) -#define pc_readaccountreg(sd,reg) pc->readregistry(sd,reg,2) -#define pc_setaccountreg(sd,reg,val) pc->setregistry(sd,reg,val,2) -#define pc_readaccountregstr(sd,reg) pc->readregistry_str(sd,reg,2) -#define pc_setaccountregstr(sd,reg,val) pc->setregistry_str(sd,reg,val,2) -#define pc_readaccountreg2(sd,reg) pc->readregistry(sd,reg,1) -#define pc_setaccountreg2(sd,reg,val) pc->setregistry(sd,reg,val,1) -#define pc_readaccountreg2str(sd,reg) pc->readregistry_str(sd,reg,1) -#define pc_setaccountreg2str(sd,reg,val) pc->setregistry_str(sd,reg,val,1) +#define pc_readglobalreg(sd,reg) (pc->readregistry((sd),(reg))) +#define pc_setglobalreg(sd,reg,val) (pc->setregistry((sd),(reg),(val))) +#define pc_readglobalreg_str(sd,reg) (pc->readregistry_str((sd),(reg))) +#define pc_setglobalreg_str(sd,reg,val) (pc->setregistry_str((sd),(reg),(val))) +#define pc_readaccountreg(sd,reg) (pc->readregistry((sd),(reg))) +#define pc_setaccountreg(sd,reg,val) (pc->setregistry((sd),(reg),(val))) +#define pc_readaccountregstr(sd,reg) (pc->readregistry_str((sd),(reg))) +#define pc_setaccountregstr(sd,reg,val) (pc->setregistry_str((sd),(reg),(val))) +#define pc_readaccountreg2(sd,reg) (pc->readregistry((sd),(reg))) +#define pc_setaccountreg2(sd,reg,val) (pc->setregistry((sd),(reg),(val))) +#define pc_readaccountreg2str(sd,reg) (pc->readregistry_str((sd),(reg))) +#define pc_setaccountreg2str(sd,reg,val) (pc->setregistry_str((sd),(reg),(val))) + +/* pc_groups easy access */ +#define pc_get_group_level(sd) ( (sd)->group->level ) +#define pc_has_permission(sd,permission) ( ((sd)->extra_temp_permissions&(permission)) != 0 || ((sd)->group->e_permissions&(permission)) != 0 ) +#define pc_can_give_items(sd) ( pc_has_permission((sd),PC_PERM_TRADE) ) +#define pc_can_give_bound_items(sd) ( pc_has_permission((sd),PC_PERM_TRADE_BOUND) ) struct skill_tree_entry { short id; @@ -683,7 +719,7 @@ struct sg_data { short comfort_id; char feel_var[NAME_LENGTH]; char hate_var[NAME_LENGTH]; - int (*day_func)(void); + bool (*day_func)(void); }; enum { ADDITEM_EXIST , ADDITEM_NEW , ADDITEM_OVERAMOUNT }; @@ -695,10 +731,25 @@ enum { ADDITEM_EXIST , ADDITEM_NEW , ADDITEM_OVERAMOUNT }; * All cooldowns are reset when server is restarted. **/ struct item_cd { - unsigned int tick[MAX_ITEMDELAYS];//tick + int64 tick[MAX_ITEMDELAYS];//tick short nameid[MAX_ITEMDELAYS];//skill id }; +enum e_pc_autotrade_update_action { + PAUC_START, + PAUC_REFRESH, + PAUC_REMOVE, +}; + +/** + * Used to temporarily remember vending data + **/ +struct autotrade_vending { + struct item list[MAX_VENDING]; + struct s_vending vending[MAX_VENDING]; + unsigned char vend_num; +}; + /*===================================== * Interface : pc.h * Generated by HerculesInterfaceMaker @@ -707,6 +758,8 @@ struct item_cd { struct pc_interface { /* */ + DBMap *at_db;/* char id -> struct autotrade_vending */ + /* */ DBMap* itemcd_db; /* */ int day_timer_tid; @@ -718,7 +771,7 @@ struct pc_interface { #if defined(RENEWAL_DROP) || defined(RENEWAL_EXP) unsigned int level_penalty[3][RC_MAX][MAX_LEVEL*2+1]; #endif - unsigned short equip_pos[EQI_MAX]; + unsigned int equip_pos[EQI_MAX]; /* */ struct skill_tree_entry skill_tree[CLASS_COUNT][MAX_SKILL_TREE]; struct fame_list smith_fame_list[MAX_FAME_LIST]; @@ -727,18 +780,26 @@ struct pc_interface { struct sg_data sg_info[MAX_PC_FEELHATE]; /* */ struct eri *sc_display_ers; + /* global expiration timer id */ + int expiration_tid; + /** + * ERS for the bulk of pc vars + **/ + struct eri *num_reg_ers; + struct eri *str_reg_ers; + /* */ + bool reg_load; /* funcs */ - void (*init) (void); + void (*init) (bool minimal); void (*final) (void); struct map_session_data* (*get_dummy_sd) (void); int (*class2idx) (int class_); - int (*get_group_level) (struct map_session_data *sd); //int (*getrefinebonus) (int lv,int type); FIXME: This function does not exist, nor it is ever called bool (*can_give_items) (struct map_session_data *sd); - + bool (*can_give_bound_items) (struct map_session_data *sd); + bool (*can_use_command) (struct map_session_data *sd, const char *command); - bool (*has_permission) (struct map_session_data *sd, enum e_pc_permission permission); int (*set_group) (struct map_session_data *sd, int group_id); bool (*should_log_commands) (struct map_session_data *sd); @@ -763,8 +824,8 @@ struct pc_interface { int (*calc_skilltree_normalize_job) (struct map_session_data *sd); int (*clean_skilltree) (struct map_session_data *sd); - int (*setpos) (struct map_session_data* sd, unsigned short mapindex, int x, int y, clr_type clrtype); - int (*setsavepoint) (struct map_session_data *sd, short mapindex,int x,int y); + int (*setpos) (struct map_session_data* sd, unsigned short map_index, int x, int y, clr_type clrtype); + int (*setsavepoint) (struct map_session_data *sd, short map_index, int x, int y); int (*randomwarp) (struct map_session_data *sd,clr_type type); int (*memo) (struct map_session_data* sd, int pos); @@ -775,6 +836,7 @@ struct pc_interface { int (*additem) (struct map_session_data *sd,struct item *item_data,int amount,e_log_pick_type log_type); int (*getzeny) (struct map_session_data *sd,int zeny, enum e_log_pick_type type, struct map_session_data *tsd); int (*delitem) (struct map_session_data *sd,int n,int amount,int type, short reason, e_log_pick_type log_type); + // Special Shop System int (*paycash) (struct map_session_data *sd, int price, int points); int (*getcash) (struct map_session_data *sd, int cash, int points); @@ -796,7 +858,7 @@ struct pc_interface { int (*addautobonus) (struct s_autobonus *bonus,char max,const char *bonus_script,short rate,unsigned int dur,short atk_type,const char *o_script,unsigned short pos,bool onskill); int (*exeautobonus) (struct map_session_data* sd,struct s_autobonus *bonus); - int (*endautobonus) (int tid, unsigned int tick, int id, intptr_t data); + int (*endautobonus) (int tid, int64 tick, int id, intptr_t data); int (*delautobonus) (struct map_session_data* sd,struct s_autobonus *bonus,char max,bool restore); int (*bonus) (struct map_session_data *sd,int type,int val); @@ -828,7 +890,8 @@ struct pc_interface { unsigned int (*thisjobexp) (struct map_session_data *sd); int (*gets_status_point) (int level); int (*need_status_point) (struct map_session_data *sd,int type,int val); - int (*statusup) (struct map_session_data *sd,int type); + int (*maxparameterincrease) (struct map_session_data* sd, int type); + bool (*statusup) (struct map_session_data *sd, int type, int increase); int (*statusup2) (struct map_session_data *sd,int type,int val); int (*skillup) (struct map_session_data *sd,uint16 skill_id); int (*allskillup) (struct map_session_data *sd); @@ -863,14 +926,14 @@ struct pc_interface { int (*readparam) (struct map_session_data *sd,int type); int (*setparam) (struct map_session_data *sd,int type,int val); - int (*readreg) (struct map_session_data *sd,int reg); - int (*setreg) (struct map_session_data *sd,int reg,int val); - char * (*readregstr) (struct map_session_data *sd,int reg); - int (*setregstr) (struct map_session_data *sd,int reg,const char *str); - int (*readregistry) (struct map_session_data *sd,const char *reg,int type); - int (*setregistry) (struct map_session_data *sd,const char *reg,int val,int type); - char * (*readregistry_str) (struct map_session_data *sd,const char *reg,int type); - int (*setregistry_str) (struct map_session_data *sd,const char *reg,const char *val,int type); + int (*readreg) (struct map_session_data *sd, int64 reg); + void (*setreg) (struct map_session_data *sd, int64 reg,int val); + char * (*readregstr) (struct map_session_data *sd, int64 reg); + void (*setregstr) (struct map_session_data *sd, int64 reg, const char *str); + int (*readregistry) (struct map_session_data *sd, int64 reg); + int (*setregistry) (struct map_session_data *sd, int64 reg, int val); + char * (*readregistry_str) (struct map_session_data *sd, int64 reg); + int (*setregistry_str) (struct map_session_data *sd, int64 reg, const char *val); int (*addeventtimer) (struct map_session_data *sd,int tick,const char *name); int (*deleventtimer) (struct map_session_data *sd,const char *name); @@ -878,7 +941,7 @@ struct pc_interface { int (*addeventtimercount) (struct map_session_data *sd,const char *name,int tick); int (*calc_pvprank) (struct map_session_data *sd); - int (*calc_pvprank_timer) (int tid, unsigned int tick, int id, intptr_t data); + int (*calc_pvprank_timer) (int tid, int64 tick, int id, intptr_t data); int (*ismarried) (struct map_session_data *sd); int (*marriage) (struct map_session_data *sd,struct map_session_data *dstsd); @@ -909,8 +972,8 @@ struct pc_interface { int (*set_hate_mob) (struct map_session_data *sd, int pos, struct block_list *bl); int (*readdb) (void); - int (*map_day_timer) (int tid, unsigned int tick, int id, intptr_t data); // by [yor] - int (*map_night_timer) (int tid, unsigned int tick, int id, intptr_t data); // by [yor] + int (*map_day_timer) (int tid, int64 tick, int id, intptr_t data); // by [yor] + int (*map_night_timer) (int tid, int64 tick, int id, intptr_t data); // by [yor] // Rental System void (*inventory_rentals) (struct map_session_data *sd); int (*inventory_rental_clear) (struct map_session_data *sd); @@ -934,10 +997,10 @@ struct pc_interface { int (*level_penalty_mod) (int diff, unsigned char race, unsigned short mode, int type); int (*calc_skillpoint) (struct map_session_data* sd); - int (*invincible_timer) (int tid, unsigned int tick, int id, intptr_t data); - int (*spiritball_timer) (int tid, unsigned int tick, int id, intptr_t data); + int (*invincible_timer) (int tid, int64 tick, int id, intptr_t data); + int (*spiritball_timer) (int tid, int64 tick, int id, intptr_t data); int (*check_banding) ( struct block_list *bl, va_list ap ); - int (*inventory_rental_end) (int tid, unsigned int tick, int id, intptr_t data); + int (*inventory_rental_end) (int tid, int64 tick, int id, intptr_t data); void (*check_skilltree) (struct map_session_data *sd, int skill_id); int (*bonus_autospell) (struct s_autospell *spell, int max, short id, short lv, short rate, short flag, short card_id); int (*bonus_autospell_onskill) (struct s_autospell *spell, int max, short src_skill, short id, short lv, short rate, short card_id); @@ -945,26 +1008,47 @@ struct pc_interface { int (*bonus_addeff_onskill) (struct s_addeffectonskill* effect, int max, enum sc_type id, short rate, short skill_id, unsigned char target); int (*bonus_item_drop) (struct s_add_drop *drop, const short max, short id, short group, int race, int rate); void (*calcexp) (struct map_session_data *sd, unsigned int *base_exp, unsigned int *job_exp, struct block_list *src); - int (*respawn_timer) (int tid, unsigned int tick, int id, intptr_t data); + int (*respawn_timer) (int tid, int64 tick, int id, intptr_t data); int (*jobchange_killclone) (struct block_list *bl, va_list ap); int (*getstat) (struct map_session_data* sd, int type); int (*setstat) (struct map_session_data* sd, int type, int val); - int (*eventtimer) (int tid, unsigned int tick, int id, intptr_t data); + int (*eventtimer) (int tid, int64 tick, int id, intptr_t data); int (*daynight_timer_sub) (struct map_session_data *sd,va_list ap); - int (*charm_timer) (int tid, unsigned int tick, int id, intptr_t data); + int (*charm_timer) (int tid, int64 tick, int id, intptr_t data); bool (*readdb_levelpenalty) (char* fields[], int columns, int current); - int (*autosave) (int tid, unsigned int tick, int id, intptr_t data); - int (*follow_timer) (int tid, unsigned int tick, int id, intptr_t data); + int (*autosave) (int tid, int64 tick, int id, intptr_t data); + int (*follow_timer) (int tid, int64 tick, int id, intptr_t data); void (*read_skill_tree) (void); int (*isUseitem) (struct map_session_data *sd,int n); int (*show_steal) (struct block_list *bl,va_list ap); int (*checkcombo) (struct map_session_data *sd, struct item_data *data ); int (*calcweapontype) (struct map_session_data *sd); int (*removecombo) (struct map_session_data *sd, struct item_data *data ); + + void (*bank_deposit) (struct map_session_data *sd, int money); + void (*bank_withdraw) (struct map_session_data *sd, int money); + + void (*rental_expire) (struct map_session_data *sd, int i); + void (*scdata_received) (struct map_session_data *sd); + + void (*bound_clear) (struct map_session_data *sd, enum e_item_bound_type type); + + int (*expiration_timer) (int tid, int64 tick, int id, intptr_t data); + int (*global_expiration_timer) (int tid, int64 tick, int id, intptr_t data); + void (*expire_check) (struct map_session_data *sd); + + /** + * Autotrade persistency [Ind/Hercules <3] + **/ + void (*autotrade_load) (void); + void (*autotrade_update) (struct map_session_data *sd, enum e_pc_autotrade_update_action action); + void (*autotrade_start) (struct map_session_data *sd); + void (*autotrade_prepare) (struct map_session_data *sd); + void (*autotrade_populate) (struct map_session_data *sd); }; struct pc_interface *pc; void pc_defaults(void); -#endif /* _PC_H_ */ +#endif /* _MAP_PC_H_ */ diff --git a/src/map/pc_groups.c b/src/map/pc_groups.c index be02b5f15..906462c7e 100644 --- a/src/map/pc_groups.c +++ b/src/map/pc_groups.c @@ -16,52 +16,10 @@ #include "map.h" // mapiterator #include "pc.h" // pc->set_group() -// Cached config settings for quick lookup -struct GroupSettings { - unsigned int id; // groups.[].id - int level; // groups.[].level - char *name; // copy of groups.[].name - unsigned int e_permissions; // packed groups.[].permissions - bool log_commands; // groups.[].log_commands - int index; // internal index of the group (contiguous range starting at 0) [Ind] - /// Following are used/available only during config reading - config_setting_t *commands; // groups.[].commands - config_setting_t *permissions; // groups.[].permissions - config_setting_t *inherit; // groups.[].inherit - bool inheritance_done; // have all inheritance rules been evaluated? - config_setting_t *root; // groups.[] -}; - -const struct pc_permission_name_table pc_g_permission_name[NUM_PC_PERM] = { - { "can_trade", PC_PERM_TRADE }, - { "can_party", PC_PERM_PARTY }, - { "all_skill", PC_PERM_ALL_SKILL }, - { "all_equipment", PC_PERM_USE_ALL_EQUIPMENT }, - { "skill_unconditional", PC_PERM_SKILL_UNCONDITIONAL }, - { "join_chat", PC_PERM_JOIN_ALL_CHAT }, - { "kick_chat", PC_PERM_NO_CHAT_KICK }, - { "hide_session", PC_PERM_HIDE_SESSION }, - { "who_display_aid", PC_PERM_WHO_DISPLAY_AID }, - { "hack_info", PC_PERM_RECEIVE_HACK_INFO }, - { "any_warp", PC_PERM_WARP_ANYWHERE }, - { "view_hpmeter", PC_PERM_VIEW_HPMETER }, - { "view_equipment", PC_PERM_VIEW_EQUIPMENT }, - { "use_check", PC_PERM_USE_CHECK }, - { "use_changemaptype", PC_PERM_USE_CHANGEMAPTYPE }, - { "all_commands", PC_PERM_USE_ALL_COMMANDS }, - { "receive_requests", PC_PERM_RECEIVE_REQUESTS }, - { "show_bossmobs", PC_PERM_SHOW_BOSS }, - { "disable_pvm", PC_PERM_DISABLE_PVM }, - { "disable_pvp", PC_PERM_DISABLE_PVP }, - { "disable_commands_when_dead", PC_PERM_DISABLE_CMD_DEAD }, - { "hchsys_admin", PC_PERM_HCHSYS_ADMIN }, -}; - -static DBMap* pc_group_db; // id -> GroupSettings -static DBMap* pc_groupname_db; // name -> GroupSettings - static GroupSettings dummy_group; ///< dummy group used in dummy map sessions @see pc_get_dummy_sd() +struct pc_groups_interface pcg_s; + /** * Returns dummy group. * Used in dummy map sessions. @@ -78,7 +36,7 @@ GroupSettings* pc_group_get_dummy_group(void) */ static inline GroupSettings* name2group(const char* group_name) { - return strdb_get(pc_groupname_db, group_name); + return strdb_get(pcg->name_db, group_name); } /** @@ -91,43 +49,43 @@ static void read_config(void) { const char *config_filename = "conf/groups.conf"; // FIXME hardcoded name int group_count = 0; - if (conf_read_file(&pc_group_config, config_filename)) + if (libconfig->read_file(&pc_group_config, config_filename)) return; - groups = config_lookup(&pc_group_config, "groups"); + groups = libconfig->lookup(&pc_group_config, "groups"); if (groups != NULL) { GroupSettings *group_settings = NULL; DBIterator *iter = NULL; int i, loop = 0; - group_count = config_setting_length(groups); + group_count = libconfig->setting_length(groups); for (i = 0; i < group_count; ++i) { int id = 0, level = 0; const char *groupname = NULL; int log_commands = 0; - config_setting_t *group = config_setting_get_elem(groups, i); + config_setting_t *group = libconfig->setting_get_elem(groups, i); - if (!config_setting_lookup_int(group, "id", &id)) { + if (!libconfig->setting_lookup_int(group, "id", &id)) { ShowConfigWarning(group, "pc_groups:read_config: \"groups\" list member #%d has undefined id, removing...", i); - config_setting_remove_elem(groups, i); + libconfig->setting_remove_elem(groups, i); --i; --group_count; continue; } - if (pc_group_exists(id)) { + if (pcg->exists(id)) { ShowConfigWarning(group, "pc_groups:read_config: duplicate group id %d, removing...", i); - config_setting_remove_elem(groups, i); + libconfig->setting_remove_elem(groups, i); --i; --group_count; continue; } - config_setting_lookup_int(group, "level", &level); - config_setting_lookup_bool(group, "log_commands", &log_commands); + libconfig->setting_lookup_int(group, "level", &level); + libconfig->setting_lookup_bool(group, "log_commands", &log_commands); - if (!config_setting_lookup_string(group, "name", &groupname)) { + if (!libconfig->setting_lookup_string(group, "name", &groupname)) { char temp[20]; config_setting_t *name = NULL; snprintf(temp, sizeof(temp), "Group %d", id); @@ -139,12 +97,12 @@ static void read_config(void) { --group_count; continue; } - config_setting_lookup_string(group, "name", &groupname); // Retrieve the pointer + libconfig->setting_lookup_string(group, "name", &groupname); // Retrieve the pointer } if (name2group(groupname) != NULL) { ShowConfigWarning(group, "pc_groups:read_config: duplicate group name %s, removing...", groupname); - config_setting_remove_elem(groups, i); + libconfig->setting_remove_elem(groups, i); --i; --group_count; continue; @@ -155,37 +113,37 @@ static void read_config(void) { group_settings->level = level; group_settings->name = aStrdup(groupname); group_settings->log_commands = (bool)log_commands; - group_settings->inherit = config_setting_get_member(group, "inherit"); - group_settings->commands = config_setting_get_member(group, "commands"); - group_settings->permissions = config_setting_get_member(group, "permissions"); + group_settings->inherit = libconfig->setting_get_member(group, "inherit"); + group_settings->commands = libconfig->setting_get_member(group, "commands"); + group_settings->permissions = libconfig->setting_get_member(group, "permissions"); group_settings->inheritance_done = false; group_settings->root = group; group_settings->index = i; - strdb_put(pc_groupname_db, groupname, group_settings); - idb_put(pc_group_db, id, group_settings); + strdb_put(pcg->name_db, groupname, group_settings); + idb_put(pcg->db, id, group_settings); } - group_count = config_setting_length(groups); // Save number of groups - assert(group_count == db_size(pc_group_db)); + group_count = libconfig->setting_length(groups); // Save number of groups + assert(group_count == db_size(pcg->db)); // Check if all commands and permissions exist - iter = db_iterator(pc_group_db); + iter = db_iterator(pcg->db); for (group_settings = dbi_first(iter); dbi_exists(iter); group_settings = dbi_next(iter)) { config_setting_t *commands = group_settings->commands, *permissions = group_settings->permissions; - int count = 0, i; + int count = 0; // Make sure there is "commands" group if (commands == NULL) - commands = group_settings->commands = config_setting_add(group_settings->root, "commands", CONFIG_TYPE_GROUP); - count = config_setting_length(commands); + commands = group_settings->commands = libconfig->setting_add(group_settings->root, "commands", CONFIG_TYPE_GROUP); + count = libconfig->setting_length(commands); for (i = 0; i < count; ++i) { - config_setting_t *command = config_setting_get_elem(commands, i); + config_setting_t *command = libconfig->setting_get_elem(commands, i); const char *name = config_setting_name(command); if (!atcommand->exists(name)) { ShowConfigWarning(command, "pc_groups:read_config: non-existent command name '%s', removing...", name); - config_setting_remove(commands, name); + libconfig->setting_remove(commands, name); --i; --count; } @@ -193,18 +151,18 @@ static void read_config(void) { // Make sure there is "permissions" group if (permissions == NULL) - permissions = group_settings->permissions = config_setting_add(group_settings->root, "permissions", CONFIG_TYPE_GROUP); - count = config_setting_length(permissions); + permissions = group_settings->permissions = libconfig->setting_add(group_settings->root, "permissions", CONFIG_TYPE_GROUP); + count = libconfig->setting_length(permissions); for(i = 0; i < count; ++i) { - config_setting_t *permission = config_setting_get_elem(permissions, i); + config_setting_t *permission = libconfig->setting_get_elem(permissions, i); const char *name = config_setting_name(permission); int j; - ARR_FIND(0, ARRAYLENGTH(pc_g_permission_name), j, strcmp(pc_g_permission_name[j].name, name) == 0); - if (j == ARRAYLENGTH(pc_g_permission_name)) { + ARR_FIND(0, pcg->permission_count, j, strcmp(pcg->permissions[j].name, name) == 0); + if (j == pcg->permission_count) { ShowConfigWarning(permission, "pc_groups:read_config: non-existent permission name '%s', removing...", name); - config_setting_remove(permissions, name); + libconfig->setting_remove(permissions, name); --i; --count; } @@ -215,7 +173,7 @@ static void read_config(void) { // Apply inheritance i = 0; // counter for processed groups while (i < group_count) { - iter = db_iterator(pc_group_db); + iter = db_iterator(pcg->db); for (group_settings = dbi_first(iter); dbi_exists(iter); group_settings = dbi_next(iter)) { config_setting_t *inherit = NULL, *commands = group_settings->commands, @@ -226,7 +184,7 @@ static void read_config(void) { continue; if ((inherit = group_settings->inherit) == NULL || - (inherit_count = config_setting_length(inherit)) <= 0) { // this group does not inherit from others + (inherit_count = libconfig->setting_length(inherit)) <= 0) { // this group does not inherit from others ++i; group_settings->inheritance_done = true; continue; @@ -234,16 +192,16 @@ static void read_config(void) { for (j = 0; j < inherit_count; ++j) { GroupSettings *inherited_group = NULL; - const char *groupname = config_setting_get_string_elem(inherit, j); + const char *groupname = libconfig->setting_get_string_elem(inherit, j); if (groupname == NULL) { ShowConfigWarning(inherit, "pc_groups:read_config: \"inherit\" array member #%d is not a name, removing...", j); - config_setting_remove_elem(inherit,j); + libconfig->setting_remove_elem(inherit,j); continue; } if ((inherited_group = name2group(groupname)) == NULL) { ShowConfigWarning(inherit, "pc_groups:read_config: non-existent group name \"%s\", removing...", groupname); - config_setting_remove_elem(inherit,j); + libconfig->setting_remove_elem(inherit,j); continue; } if (!inherited_group->inheritance_done) @@ -251,15 +209,15 @@ static void read_config(void) { // Copy settings (commands/permissions) that are not defined yet if (inherited_group->commands != NULL) { - int i = 0, commands_count = config_setting_length(inherited_group->commands); - for (i = 0; i < commands_count; ++i) - config_setting_copy(commands, config_setting_get_elem(inherited_group->commands, i)); + int k = 0, commands_count = libconfig->setting_length(inherited_group->commands); + for (k = 0; k < commands_count; ++k) + libconfig->setting_copy(commands, libconfig->setting_get_elem(inherited_group->commands, k)); } if (inherited_group->permissions != NULL) { - int i = 0, permissions_count = config_setting_length(inherited_group->permissions); - for (i = 0; i < permissions_count; ++i) - config_setting_copy(permissions, config_setting_get_elem(inherited_group->permissions, i)); + int k = 0, permissions_count = libconfig->setting_length(inherited_group->permissions); + for (k = 0; k < permissions_count; ++k) + libconfig->setting_copy(permissions, libconfig->setting_get_elem(inherited_group->permissions, k)); } ++done; // copied commands and permissions from one of inherited groups @@ -280,21 +238,21 @@ static void read_config(void) { } // while(i < group_count) // Pack permissions into GroupSettings.e_permissions for faster checking - iter = db_iterator(pc_group_db); + iter = db_iterator(pcg->db); for (group_settings = dbi_first(iter); dbi_exists(iter); group_settings = dbi_next(iter)) { config_setting_t *permissions = group_settings->permissions; - int i, count = config_setting_length(permissions); + int count = libconfig->setting_length(permissions); for (i = 0; i < count; ++i) { - config_setting_t *perm = config_setting_get_elem(permissions, i); + config_setting_t *perm = libconfig->setting_get_elem(permissions, i); const char *name = config_setting_name(perm); - int val = config_setting_get_bool(perm); + int val = libconfig->setting_get_bool(perm); int j; if (val == 0) // does not have this permission continue; - ARR_FIND(0, ARRAYLENGTH(pc_g_permission_name), j, strcmp(pc_g_permission_name[j].name, name) == 0); - group_settings->e_permissions |= pc_g_permission_name[j].permission; + ARR_FIND(0, pcg->permission_count, j, strcmp(pcg->permissions[j].name, name) == 0); + group_settings->e_permissions |= pcg->permissions[j].permission; } } dbi_destroy(iter); @@ -303,20 +261,20 @@ static void read_config(void) { // Fetch all groups and relevant config setting and send them // to atcommand->load_group() for processing. if (group_count > 0) { - int i = 0; - GroupSettings **groups = NULL; + GroupSettings **pc_groups = NULL; config_setting_t **commands = NULL; - CREATE(groups, GroupSettings*, group_count); + CREATE(pc_groups, GroupSettings*, group_count); CREATE(commands, config_setting_t*, group_count); - iter = db_iterator(pc_group_db); + i = 0; + iter = db_iterator(pcg->db); for (group_settings = dbi_first(iter); dbi_exists(iter); group_settings = dbi_next(iter)) { - groups[i] = group_settings; + pc_groups[i] = group_settings; commands[i] = group_settings->commands; i++; } - atcommand->load_groups(groups, commands, group_count); + atcommand->load_groups(pc_groups, commands, group_count); dbi_destroy(iter); - aFree(groups); + aFree(pc_groups); aFree(commands); } } @@ -324,7 +282,7 @@ static void read_config(void) { ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' groups in '"CL_WHITE"%s"CL_RESET"'.\n", group_count, config_filename); // All data is loaded now, discard config - config_destroy(&pc_group_config); + libconfig->destroy(&pc_group_config); } /** @@ -332,7 +290,7 @@ static void read_config(void) { * @param group group * @param permission permission to check */ -bool pc_group_has_permission(GroupSettings *group, enum e_pc_permission permission) +bool pc_group_has_permission(GroupSettings *group, unsigned int permission) { return ((group->e_permissions&permission) != 0); } @@ -353,7 +311,7 @@ bool pc_group_should_log_commands(GroupSettings *group) */ bool pc_group_exists(int group_id) { - return idb_exists(pc_group_db, group_id); + return idb_exists(pcg->db, group_id); } /** @@ -361,7 +319,7 @@ bool pc_group_exists(int group_id) */ GroupSettings* pc_group_id2group(int group_id) { - return idb_get(pc_group_db, group_id); + return idb_get(pcg->db, group_id); } /** @@ -398,13 +356,87 @@ int pc_group_get_idx(GroupSettings *group) } /** + * Insert a new permission + * @return inserted key or 0 upon failure. + **/ +unsigned int pc_groups_add_permission(const char *name) { + uint64 key = 0x1; + unsigned char i; + + for(i = 0; i < pcg->permission_count; i++) { + if( strcmpi(name,pcg->permissions[i].name) == 0 ) { + ShowError("pc_groups_add_permission(%s): failed! duplicate permission name!\n",name); + return 0; + } + } + + if( i != 0 ) + key = (uint64)pcg->permissions[i - 1].permission << 1; + + if( key >= UINT_MAX ) { + ShowError("pc_groups_add_permission(%s): failed! not enough room, too many permissions!\n",name); + return 0; + } + + i = pcg->permission_count; + RECREATE(pcg->permissions, struct pc_groups_permission_table, ++pcg->permission_count); + + pcg->permissions[i].name = aStrdup(name); + pcg->permissions[i].permission = (unsigned int)key; + + return (unsigned int)key; +} +/** * Initialize PC Groups: allocate DBMaps and read config. * @public */ -void do_init_pc_groups(void) -{ - pc_group_db = idb_alloc(DB_OPT_RELEASE_DATA); - pc_groupname_db = stridb_alloc(DB_OPT_DUP_KEY, 0); +void do_init_pc_groups(void) { + const struct { + const char *name; + unsigned int permission; + } pc_g_defaults[] = { + { "can_trade", PC_PERM_TRADE }, + { "can_party", PC_PERM_PARTY }, + { "all_skill", PC_PERM_ALL_SKILL }, + { "all_equipment", PC_PERM_USE_ALL_EQUIPMENT }, + { "skill_unconditional", PC_PERM_SKILL_UNCONDITIONAL }, + { "join_chat", PC_PERM_JOIN_ALL_CHAT }, + { "kick_chat", PC_PERM_NO_CHAT_KICK }, + { "hide_session", PC_PERM_HIDE_SESSION }, + { "who_display_aid", PC_PERM_WHO_DISPLAY_AID }, + { "hack_info", PC_PERM_RECEIVE_HACK_INFO }, + { "any_warp", PC_PERM_WARP_ANYWHERE }, + { "view_hpmeter", PC_PERM_VIEW_HPMETER }, + { "view_equipment", PC_PERM_VIEW_EQUIPMENT }, + { "use_check", PC_PERM_USE_CHECK }, + { "use_changemaptype", PC_PERM_USE_CHANGEMAPTYPE }, + { "all_commands", PC_PERM_USE_ALL_COMMANDS }, + { "receive_requests", PC_PERM_RECEIVE_REQUESTS }, + { "show_bossmobs", PC_PERM_SHOW_BOSS }, + { "disable_pvm", PC_PERM_DISABLE_PVM }, + { "disable_pvp", PC_PERM_DISABLE_PVP }, + { "disable_commands_when_dead", PC_PERM_DISABLE_CMD_DEAD }, + { "hchsys_admin", PC_PERM_HCHSYS_ADMIN }, + { "can_trade_bound", PC_PERM_TRADE_BOUND }, + }; + unsigned char i, len = ARRAYLENGTH(pc_g_defaults); + + for(i = 0; i < len; i++) { + unsigned int p; + if( ( p = pc_groups_add_permission(pc_g_defaults[i].name) ) != pc_g_defaults[i].permission ) + ShowError("do_init_pc_groups: %s error : %d != %d\n",pc_g_defaults[i].name,p,pc_g_defaults[i].permission); + } + + /** + * Handle plugin-provided permissions + **/ + for(i = 0; i < pcg->HPMpermissions_count; i++) { + *pcg->HPMpermissions[i].mask = pc_groups_add_permission(pcg->HPMpermissions[i].name); + } + + pcg->db = idb_alloc(DB_OPT_RELEASE_DATA); + pcg->name_db = stridb_alloc(DB_OPT_DUP_KEY, 0); + read_config(); } @@ -425,10 +457,19 @@ static int group_db_clear_sub(DBKey key, DBData *data, va_list args) */ void do_final_pc_groups(void) { - if (pc_group_db != NULL) - pc_group_db->destroy(pc_group_db, group_db_clear_sub); - if (pc_groupname_db != NULL) - db_destroy(pc_groupname_db); + if (pcg->db != NULL) + pcg->db->destroy(pcg->db, group_db_clear_sub); + if (pcg->name_db != NULL) + db_destroy(pcg->name_db); + + if(pcg->permissions != NULL) { + unsigned char i; + for(i = 0; i < pcg->permission_count; i++) + aFree(pcg->permissions[i].name); + aFree(pcg->permissions); + pcg->permissions = NULL; + } + pcg->permission_count = 0; } /** @@ -440,8 +481,8 @@ void pc_groups_reload(void) { struct map_session_data *sd = NULL; struct s_mapiterator *iter; - do_final_pc_groups(); - do_init_pc_groups(); + pcg->final(); + pcg->init(); /* refresh online users permissions */ iter = mapit_getallusers(); @@ -454,3 +495,33 @@ void pc_groups_reload(void) { } mapit->free(iter); } + +/** + * Connect Interface + **/ +void pc_groups_defaults(void) { + pcg = &pcg_s; + + /* */ + pcg->db = NULL; + pcg->name_db = NULL; + /* */ + pcg->permissions = NULL; + pcg->permission_count = 0; + /* */ + pcg->HPMpermissions = NULL; + pcg->HPMpermissions_count = 0; + /* */ + pcg->init = do_init_pc_groups; + pcg->final = do_final_pc_groups; + pcg->reload = pc_groups_reload; + /* */ + pcg->get_dummy_group = pc_group_get_dummy_group; + pcg->exists = pc_group_exists; + pcg->id2group = pc_group_id2group; + pcg->has_permission = pc_group_has_permission; + pcg->should_log_commands = pc_group_should_log_commands; + pcg->get_name = pc_group_get_name; + pcg->get_level = pc_group_get_level; + pcg->get_idx = pc_group_get_idx; +} diff --git a/src/map/pc_groups.h b/src/map/pc_groups.h index 8f350c2b6..5c03f999f 100644 --- a/src/map/pc_groups.h +++ b/src/map/pc_groups.h @@ -2,8 +2,8 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _PC_GROUPS_H_ -#define _PC_GROUPS_H_ +#ifndef _MAP_PC_GROUPS_H_ +#define _MAP_PC_GROUPS_H_ /// PC permissions enum e_pc_permission { @@ -30,36 +30,66 @@ enum e_pc_permission { PC_PERM_DISABLE_PVP = 0x080000, // #20 PC_PERM_DISABLE_CMD_DEAD = 0x100000, PC_PERM_HCHSYS_ADMIN = 0x200000, + PC_PERM_TRADE_BOUND = 0x400000, }; -/// Total number of PC permissions (without PC_PERM_NONE). -/// This is manifest constant for the size of pc_g_permission_name array, -/// so it's possible to apply sizeof to it [C-FAQ 1.24] -/// Whenever adding new permission: 1. add enum entry above, 2. add entry into -/// pc_g_permission_name (in pc.c), 3. increase NUM_PC_PERM below by 1. -#define NUM_PC_PERM 22 +// Cached config settings for quick lookup +struct GroupSettings { + unsigned int id; // groups.[].id + int level; // groups.[].level + char *name; // copy of groups.[].name + unsigned int e_permissions; // packed groups.[].permissions + bool log_commands; // groups.[].log_commands + int index; // internal index of the group (contiguous range starting at 0) [Ind] + /// Following are used/available only during config reading + config_setting_t *commands; // groups.[].commands + config_setting_t *permissions; // groups.[].permissions + config_setting_t *inherit; // groups.[].inherit + bool inheritance_done; // have all inheritance rules been evaluated? + config_setting_t *root; // groups.[] +}; + +typedef struct GroupSettings GroupSettings; -struct pc_permission_name_table { - const char *name; - enum e_pc_permission permission; +struct pc_groups_permission_table { + char *name; + unsigned int permission; }; -/// Name <-> enum table for PC permissions -extern const struct pc_permission_name_table pc_g_permission_name[NUM_PC_PERM]; +/* used by plugins to list permissions */ +struct pc_groups_new_permission { + unsigned int pID;/* plugin identity (for the future unload during runtime support) */ + char *name;/* aStrdup' of the permission name */ + unsigned int *mask;/* pointer to the plugin val that will store the value of the mask */ +}; -typedef struct GroupSettings GroupSettings; +struct pc_groups_interface { + /* */ + DBMap* db; // id -> GroupSettings + DBMap* name_db; // name -> GroupSettings + /* */ + struct pc_groups_permission_table *permissions; + unsigned char permission_count; + /* */ + struct pc_groups_new_permission *HPMpermissions; + unsigned char HPMpermissions_count; + /* */ + void (*init) (void); + void (*final) (void); + void (*reload) (void); + /* */ + GroupSettings* (*get_dummy_group) (void); + bool (*exists) (int group_id); + GroupSettings* (*id2group) (int group_id); + bool (*has_permission) (GroupSettings *group, unsigned int permission); + bool (*should_log_commands) (GroupSettings *group); + const char* (*get_name) (GroupSettings *group); + int (*get_level) (GroupSettings *group); + int (*get_idx) (GroupSettings *group); +}; -GroupSettings* pc_group_get_dummy_group(void); -bool pc_group_exists(int group_id); -GroupSettings* pc_group_id2group(int group_id); -bool pc_group_has_permission(GroupSettings *group, enum e_pc_permission permission); -bool pc_group_should_log_commands(GroupSettings *group); -const char* pc_group_get_name(GroupSettings *group); -int pc_group_get_level(GroupSettings *group); -int pc_group_get_idx(GroupSettings *group); +struct pc_groups_interface *pcg; -void do_init_pc_groups(void); -void do_final_pc_groups(void); -void pc_groups_reload(void); +void pc_groups_defaults(void); -#endif // _PC_GROUPS_H_ +#endif /* _MAP_PC_GROUPS_H_ */ diff --git a/src/map/pet.c b/src/map/pet.c index 023059a6b..c04d9267a 100644 --- a/src/map/pet.c +++ b/src/map/pet.c @@ -65,7 +65,7 @@ void pet_set_intimate(struct pet_data *pd, int value) pd->pet.intimate = value; if( (intimate >= battle_config.pet_equip_min_friendly && pd->pet.intimate < battle_config.pet_equip_min_friendly) || (intimate < battle_config.pet_equip_min_friendly && pd->pet.intimate >= battle_config.pet_equip_min_friendly) ) - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_NONE); } int pet_create_egg(struct map_session_data *sd, int item_id) @@ -186,7 +186,7 @@ int pet_sc_check(struct map_session_data *sd, int type) return 0; } -int pet_hungry(int tid, unsigned int tick, int id, intptr_t data) { +int pet_hungry(int tid, int64 tick, int id, intptr_t data) { struct map_session_data *sd; struct pet_data *pd; int interval; @@ -219,7 +219,7 @@ int pet_hungry(int tid, unsigned int tick, int id, intptr_t data) { pd->pet.intimate = 0; pd->status.speed = pd->db->status.speed; } - status_calc_pet(pd, 0); + status_calc_pet(pd, SCO_NONE); clif->send_petdata(sd,pd,1,pd->pet.intimate); } clif->send_petdata(sd,pd,2,pd->pet.hungry); @@ -304,7 +304,7 @@ int pet_return_egg(struct map_session_data *sd, struct pet_data *pd) pd->pet.incuvate = 1; unit->free(&pd->bl,CLR_OUTSIGHT); - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_NONE); sd->status.pet_id = 0; return 1; @@ -360,19 +360,24 @@ int pet_data_init(struct map_session_data *sd, struct s_pet *petinfo) pd->bl.y = pd->ud.to_y; map->addiddb(&pd->bl); - status_calc_pet(pd,1); + status_calc_pet(pd,SCO_FIRST); pd->last_thinktime = timer->gettick(); pd->state.skillbonus = 0; + if( battle_config.pet_status_support ) script->run(pet->db[i].pet_script,0,sd->bl.id,0); - if( pd->petDB && pd->petDB->equip_script ) - status_calc_pc(sd,0); + + if( pd->petDB ) { + if( pd->petDB->equip_script ) + status_calc_pc(sd,SCO_NONE); - if( battle_config.pet_hungry_delay_rate != 100 ) - interval = (pd->petDB->hungry_delay*battle_config.pet_hungry_delay_rate)/100; - else - interval = pd->petDB->hungry_delay; + if( battle_config.pet_hungry_delay_rate != 100 ) + interval = (pd->petDB->hungry_delay*battle_config.pet_hungry_delay_rate)/100; + else + interval = pd->petDB->hungry_delay; + } + if( interval <= 0 ) interval = 1; pd->pet_hungry_timer = timer->add(timer->gettick() + interval, pet->hungry, sd->bl.id, 0); @@ -656,7 +661,7 @@ int pet_equipitem(struct map_session_data *sd,int index) { nameid = sd->status.inventory[index].nameid; if(pd->petDB->AcceID == 0 || nameid != pd->petDB->AcceID || pd->pet.equip != 0) { - clif->equipitemack(sd,0,0,0); + clif->equipitemack(sd,0,0,EIA_FAIL); return 1; } @@ -666,7 +671,7 @@ int pet_equipitem(struct map_session_data *sd,int index) { clif->send_petdata(NULL, sd->pd, 3, sd->pd->vd.head_bottom); if (battle_config.pet_equip_required) { //Skotlex: start support timers if need - unsigned int tick = timer->gettick(); + int64 tick = timer->gettick(); if (pd->s_skill && pd->s_skill->timer == INVALID_TIMER) { if (pd->s_skill->id) pd->s_skill->timer=timer->add(tick+pd->s_skill->delay*1000, pet->skill_support_timer, sd->bl.id, 0); @@ -703,7 +708,7 @@ int pet_unequipitem(struct map_session_data *sd, struct pet_data *pd) { if( pd->state.skillbonus ) { pd->state.skillbonus = 0; - status_calc_pc(sd,0); + status_calc_pc(sd,SCO_NONE); } if( pd->s_skill && pd->s_skill->timer != INVALID_TIMER ) { @@ -759,7 +764,7 @@ int pet_food(struct map_session_data *sd, struct pet_data *pd) } else if( pd->pet.intimate > 1000 ) pd->pet.intimate = 1000; - status_calc_pet(pd, 0); + status_calc_pet(pd, SCO_NONE); pd->pet.hungry += pd->petDB->fullness; if( pd->pet.hungry > 100 ) pd->pet.hungry = 100; @@ -771,8 +776,7 @@ int pet_food(struct map_session_data *sd, struct pet_data *pd) return 0; } -int pet_randomwalk(struct pet_data *pd,unsigned int tick) -{ +int pet_randomwalk(struct pet_data *pd, int64 tick) { nullpo_ret(pd); Assert((pd->msd == 0) || (pd->msd->pd == pd)); @@ -812,8 +816,7 @@ int pet_randomwalk(struct pet_data *pd,unsigned int tick) return 0; } -int pet_ai_sub_hard(struct pet_data *pd, struct map_session_data *sd, unsigned int tick) -{ +int pet_ai_sub_hard(struct pet_data *pd, struct map_session_data *sd, int64 tick) { struct block_list *target = NULL; if(pd->bl.prev == NULL || sd == NULL || sd->bl.prev == NULL) @@ -869,7 +872,7 @@ int pet_ai_sub_hard(struct pet_data *pd, struct map_session_data *sd, unsigned i } } - if(!target && pd->loot && pd->msd && pc->has_permission(pd->msd, PC_PERM_TRADE) && pd->loot->count < pd->loot->max && DIFF_TICK(tick,pd->ud.canact_tick)>0) { + if(!target && pd->loot && pd->msd && pc_has_permission(pd->msd, PC_PERM_TRADE) && pd->loot->count < pd->loot->max && DIFF_TICK(tick,pd->ud.canact_tick)>0) { //Use half the pet's range of sight. map->foreachinrange(pet->ai_sub_hard_lootsearch,&pd->bl, pd->db->range2/2, BL_ITEM,pd,&target); @@ -924,16 +927,15 @@ int pet_ai_sub_hard(struct pet_data *pd, struct map_session_data *sd, unsigned i return 0; } -int pet_ai_sub_foreachclient(struct map_session_data *sd,va_list ap) -{ - unsigned int tick = va_arg(ap,unsigned int); +int pet_ai_sub_foreachclient(struct map_session_data *sd,va_list ap) { + int64 tick = va_arg(ap,int64); if(sd->status.pet_id && sd->pd) pet->ai_sub_hard(sd->pd,sd,tick); return 0; } -int pet_ai_hard(int tid, unsigned int tick, int id, intptr_t data) { +int pet_ai_hard(int tid, int64 tick, int id, intptr_t data) { map->foreachpc(pet->ai_sub_foreachclient,tick); return 0; @@ -966,7 +968,7 @@ int pet_ai_sub_hard_lootsearch(struct block_list *bl,va_list ap) return 0; } -int pet_delay_item_drop(int tid, unsigned int tick, int id, intptr_t data) { +int pet_delay_item_drop(int tid, int64 tick, int id, intptr_t data) { struct item_drop_list *list; struct item_drop *ditem, *ditem_prev; list=(struct item_drop_list *)data; @@ -1034,7 +1036,7 @@ int pet_lootitem_drop(struct pet_data *pd,struct map_session_data *sd) /*========================================== * pet bonus giving skills [Valaris] / Rewritten by [Skotlex] *------------------------------------------*/ -int pet_skill_bonus_timer(int tid, unsigned int tick, int id, intptr_t data) { +int pet_skill_bonus_timer(int tid, int64 tick, int id, intptr_t data) { struct map_session_data *sd=map->id2sd(id); struct pet_data *pd; int bonus; @@ -1065,7 +1067,7 @@ int pet_skill_bonus_timer(int tid, unsigned int tick, int id, intptr_t data) { if (pd->state.skillbonus != bonus) { pd->state.skillbonus = bonus; - status_calc_pc(sd, 0); + status_calc_pc(sd, SCO_NONE); } // wait for the next timer pd->bonus->timer=timer->add(tick+duration,pet->skill_bonus_timer,sd->bl.id,0); @@ -1075,7 +1077,7 @@ int pet_skill_bonus_timer(int tid, unsigned int tick, int id, intptr_t data) { /*========================================== * pet recovery skills [Valaris] / Rewritten by [Skotlex] *------------------------------------------*/ -int pet_recovery_timer(int tid, unsigned int tick, int id, intptr_t data) { +int pet_recovery_timer(int tid, int64 tick, int id, intptr_t data) { struct map_session_data *sd=map->id2sd(id); struct pet_data *pd; @@ -1102,7 +1104,7 @@ int pet_recovery_timer(int tid, unsigned int tick, int id, intptr_t data) { return 0; } -int pet_heal_timer(int tid, unsigned int tick, int id, intptr_t data) { +int pet_heal_timer(int tid, int64 tick, int id, intptr_t data) { struct map_session_data *sd=map->id2sd(id); struct status_data *st; struct pet_data *pd; @@ -1139,7 +1141,7 @@ int pet_heal_timer(int tid, unsigned int tick, int id, intptr_t data) { /*========================================== * pet support skills [Skotlex] *------------------------------------------*/ -int pet_skill_support_timer(int tid, unsigned int tick, int id, intptr_t data) { +int pet_skill_support_timer(int tid, int64 tick, int id, intptr_t data) { struct map_session_data *sd=map->id2sd(id); struct pet_data *pd; struct status_data *st; @@ -1331,8 +1333,10 @@ int read_petdb() /*========================================== * Initialization process relationship skills *------------------------------------------*/ -int do_init_pet(void) -{ +int do_init_pet(bool minimal) { + if (minimal) + return 0; + pet->read_db(); pet->item_drop_ers = ers_new(sizeof(struct item_drop),"pet.c::item_drop_ers",ERS_OPT_NONE); diff --git a/src/map/pet.h b/src/map/pet.h index 2f8e0b7c2..537a50c4b 100644 --- a/src/map/pet.h +++ b/src/map/pet.h @@ -2,8 +2,8 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _PET_H_ -#define _PET_H_ +#ifndef _MAP_PET_H_ +#define _MAP_PET_H_ #define MAX_PET_DB 300 #define MAX_PETLOOT_SIZE 30 @@ -86,7 +86,7 @@ struct pet_data { unsigned skillbonus : 1; } state; int move_fail_count; - unsigned int next_walktime,last_thinktime; + int64 next_walktime, last_thinktime; short rate_fix; //Support rate as modified by intimacy (1000 = 100%) [Skotlex] struct pet_recovery* recovery; @@ -98,15 +98,15 @@ struct pet_data { struct map_session_data *msd; }; -#define pet_stop_walking(pd, type) unit->stop_walking(&(pd)->bl, type) -#define pet_stop_attack(pd) unit->stop_attack(&(pd)->bl) +#define pet_stop_walking(pd, type) (unit->stop_walking(&(pd)->bl, (type))) +#define pet_stop_attack(pd) (unit->stop_attack(&(pd)->bl)) struct pet_interface { struct s_pet_db db[MAX_PET_DB]; struct eri *item_drop_ers; //For loot drops delay structures. struct eri *item_drop_list_ers; /* */ - int (*init) (void); + int (*init) (bool minimal); int (*final) (void); /* */ int (*hungry_val) (struct pet_data *pd); @@ -116,7 +116,7 @@ struct pet_interface { int (*attackskill) (struct pet_data *pd, int target_id); int (*target_check) (struct map_session_data *sd, struct block_list *bl, int type); int (*sc_check) (struct map_session_data *sd, int type); - int (*hungry) (int tid, unsigned int tick, int id, intptr_t data); + int (*hungry) (int tid, int64 tick, int id, intptr_t data); int (*search_petDB_index) (int key, int type); int (*hungry_timer_delete) (struct pet_data *pd); int (*performance) (struct map_session_data *sd, struct pet_data *pd); @@ -135,16 +135,16 @@ struct pet_interface { int (*change_name) (struct map_session_data *sd, char *name); int (*change_name_ack) (struct map_session_data *sd, char *name, int flag); int (*equipitem) (struct map_session_data *sd, int index); - int (*randomwalk) (struct pet_data *pd, unsigned int tick); - int (*ai_sub_hard) (struct pet_data *pd, struct map_session_data *sd, unsigned int tick); + int (*randomwalk) (struct pet_data *pd, int64 tick); + int (*ai_sub_hard) (struct pet_data *pd, struct map_session_data *sd, int64 tick); int (*ai_sub_foreachclient) (struct map_session_data *sd, va_list ap); - int (*ai_hard) (int tid, unsigned int tick, int id, intptr_t data); - int (*delay_item_drop) (int tid, unsigned int tick, int id, intptr_t data); + int (*ai_hard) (int tid, int64 tick, int id, intptr_t data); + int (*delay_item_drop) (int tid, int64 tick, int id, intptr_t data); int (*lootitem_drop) (struct pet_data *pd, struct map_session_data *sd); - int (*skill_bonus_timer) (int tid, unsigned int tick, int id, intptr_t data); - int (*recovery_timer) (int tid, unsigned int tick, int id, intptr_t data); - int (*heal_timer) (int tid, unsigned int tick, int id, intptr_t data); - int (*skill_support_timer) (int tid, unsigned int tick, int id, intptr_t data); + int (*skill_bonus_timer) (int tid, int64 tick, int id, intptr_t data); + int (*recovery_timer) (int tid, int64 tick, int id, intptr_t data); + int (*heal_timer) (int tid, int64 tick, int id, intptr_t data); + int (*skill_support_timer) (int tid, int64 tick, int id, intptr_t data); int (*read_db) (); }; @@ -152,4 +152,4 @@ struct pet_interface *pet; void pet_defaults(void); -#endif /* _PET_H_ */ +#endif /* _MAP_PET_H_ */ diff --git a/src/map/quest.c b/src/map/quest.c index f40b60c3d..bde276f9d 100644 --- a/src/map/quest.c +++ b/src/map/quest.c @@ -35,20 +35,25 @@ struct quest_interface quest_s; -int quest_search_db(int quest_id) -{ - int i; - - ARR_FIND(0, MAX_QUEST_DB,i,quest_id == quest->db[i].id); - if( i == MAX_QUEST_DB ) - return -1; - - return i; +/** + * Searches a quest by ID. + * + * @param quest_id ID to lookup + * @return Quest entry (equals to &quest->dummy if the ID is invalid) + */ +struct quest_db *quest_db(int quest_id) { + if (quest_id < 0 || quest_id > MAX_QUEST_DB || quest->db_data[quest_id] == NULL) + return &quest->dummy; + return quest->db_data[quest_id]; } -//Send quest info on login -int quest_pc_login(TBL_PC * sd) -{ +/** + * Sends quest info to the player on login. + * + * @param sd Player's data + * @return 0 in case of success, nonzero otherwise (i.e. the player has no quests) + */ +int quest_pc_login(TBL_PC *sd) { int i; if(sd->avail_quests == 0) @@ -57,100 +62,109 @@ int quest_pc_login(TBL_PC * sd) clif->quest_send_list(sd); clif->quest_send_mission(sd); for( i = 0; i < sd->avail_quests; i++ ) { - clif->quest_update_objective(sd, &sd->quest_log[i], sd->quest_index[i]); + // TODO[Haru]: is this necessary? Does quest_send_mission not take care of this? + clif->quest_update_objective(sd, &sd->quest_log[i]); } return 0; } -int quest_add(TBL_PC * sd, int quest_id) -{ - - int i, j; - - if( sd->num_quests >= MAX_QUEST_DB ) - { - ShowError("quest_add: Character %d has got all the quests.(max quests: %d)\n", sd->status.char_id, MAX_QUEST_DB); - return 1; +/** + * Adds a quest to the player's list. + * + * New quest will be added as Q_ACTIVE. + * + * @param sd Player's data + * @param quest_id ID of the quest to add. + * @return 0 in case of success, nonzero otherwise + */ +int quest_add(TBL_PC *sd, int quest_id) { + int n; + struct quest_db *qi = quest->db(quest_id); + + if( qi == &quest->dummy ) { + ShowError("quest_add: quest %d not found in DB.\n", quest_id); + return -1; } - if( quest->check(sd, quest_id, HAVEQUEST) >= 0 ) - { + if( quest->check(sd, quest_id, HAVEQUEST) >= 0 ) { ShowError("quest_add: Character %d already has quest %d.\n", sd->status.char_id, quest_id); return -1; } - if( (j = quest->search_db(quest_id)) < 0 ) - { - ShowError("quest_add: quest %d not found in DB.\n", quest_id); - return -1; + n = sd->avail_quests; // Insertion point + + sd->num_quests++; + sd->avail_quests++; + RECREATE(sd->quest_log, struct quest, sd->num_quests); + + if( sd->avail_quests != sd->num_quests ) { + // The character has some completed quests, make room before them so that they will stay at the end of the array + memmove(&sd->quest_log[n+1], &sd->quest_log[n], sizeof(struct quest)*(sd->num_quests-sd->avail_quests)); } - i = sd->avail_quests; - memmove(&sd->quest_log[i+1], &sd->quest_log[i], sizeof(struct quest)*(sd->num_quests-sd->avail_quests)); - memmove(sd->quest_index+i+1, sd->quest_index+i, sizeof(int)*(sd->num_quests-sd->avail_quests)); + memset(&sd->quest_log[n], 0, sizeof(struct quest)); - memset(&sd->quest_log[i], 0, sizeof(struct quest)); - sd->quest_log[i].quest_id = quest->db[j].id; - if( quest->db[j].time ) - sd->quest_log[i].time = (unsigned int)(time(NULL) + quest->db[j].time); - sd->quest_log[i].state = Q_ACTIVE; + sd->quest_log[n].quest_id = qi->id; + if( qi->time ) + sd->quest_log[n].time = (unsigned int)(time(NULL) + qi->time); + sd->quest_log[n].state = Q_ACTIVE; - sd->quest_index[i] = j; - sd->num_quests++; - sd->avail_quests++; sd->save_quest = true; - clif->quest_add(sd, &sd->quest_log[i], sd->quest_index[i]); - clif->quest_update_objective(sd, &sd->quest_log[i], sd->quest_index[i]); + clif->quest_add(sd, &sd->quest_log[n]); + clif->quest_update_objective(sd, &sd->quest_log[n]); + if( map->save_settings&64 ) chrif->save(sd,0); return 0; } -int quest_change(TBL_PC * sd, int qid1, int qid2) -{ - - int i, j; +/** + * Replaces a quest in a player's list with another one. + * + * @param sd Player's data + * @param qid1 Current quest to replace + * @param qid2 New quest to add + * @return 0 in case of success, nonzero otherwise + */ +int quest_change(TBL_PC *sd, int qid1, int qid2) { + int i; + struct quest_db *qi = quest->db(qid2); - if( quest->check(sd, qid2, HAVEQUEST) >= 0 ) - { - ShowError("quest_change: Character %d already has quest %d.\n", sd->status.char_id, qid2); + if( qi == &quest->dummy ) { + ShowError("quest_change: quest %d not found in DB.\n", qid2); return -1; } - if( quest->check(sd, qid1, HAVEQUEST) < 0 ) - { - ShowError("quest_change: Character %d doesn't have quest %d.\n", sd->status.char_id, qid1); + if( quest->check(sd, qid2, HAVEQUEST) >= 0 ) { + ShowError("quest_change: Character %d already has quest %d.\n", sd->status.char_id, qid2); return -1; } - if( (j = quest->search_db(qid2)) < 0 ) - { - ShowError("quest_change: quest %d not found in DB.\n",qid2); + if( quest->check(sd, qid1, HAVEQUEST) < 0 ) { + ShowError("quest_change: Character %d doesn't have quest %d.\n", sd->status.char_id, qid1); return -1; } ARR_FIND(0, sd->avail_quests, i, sd->quest_log[i].quest_id == qid1); - if(i == sd->avail_quests) - { - ShowError("quest_change: Character %d has completed quests %d.\n", sd->status.char_id, qid1); + if( i == sd->avail_quests ) { + ShowError("quest_change: Character %d has completed quest %d.\n", sd->status.char_id, qid1); return -1; } memset(&sd->quest_log[i], 0, sizeof(struct quest)); - sd->quest_log[i].quest_id = quest->db[j].id; - if( quest->db[j].time ) - sd->quest_log[i].time = (unsigned int)(time(NULL) + quest->db[j].time); + sd->quest_log[i].quest_id = qi->id; + if( qi->time ) + sd->quest_log[i].time = (unsigned int)(time(NULL) + qi->time); sd->quest_log[i].state = Q_ACTIVE; - sd->quest_index[i] = j; sd->save_quest = true; clif->quest_delete(sd, qid1); - clif->quest_add(sd, &sd->quest_log[i], sd->quest_index[i]); - clif->quest_update_objective(sd, &sd->quest_log[i], sd->quest_index[i]); + clif->quest_add(sd, &sd->quest_log[i]); + clif->quest_update_objective(sd, &sd->quest_log[i]); if( map->save_settings&64 ) chrif->save(sd,0); @@ -158,27 +172,37 @@ int quest_change(TBL_PC * sd, int qid1, int qid2) return 0; } -int quest_delete(TBL_PC * sd, int quest_id) -{ +/** + * Removes a quest from a player's list + * + * @param sd Player's data + * @param quest_id ID of the quest to remove + * @return 0 in case of success, nonzero otherwise + */ +int quest_delete(TBL_PC *sd, int quest_id) { int i; //Search for quest ARR_FIND(0, sd->num_quests, i, sd->quest_log[i].quest_id == quest_id); - if(i == sd->num_quests) - { + + if(i == sd->num_quests) { ShowError("quest_delete: Character %d doesn't have quest %d.\n", sd->status.char_id, quest_id); return -1; } if( sd->quest_log[i].state != Q_COMPLETE ) sd->avail_quests--; - if( sd->num_quests-- < MAX_QUEST_DB && sd->quest_log[i+1].quest_id ) - { + + if( i < --sd->num_quests ) { + // Compact the array memmove(&sd->quest_log[i], &sd->quest_log[i+1], sizeof(struct quest)*(sd->num_quests-i)); - memmove(sd->quest_index+i, sd->quest_index+i+1, sizeof(int)*(sd->num_quests-i)); } - memset(&sd->quest_log[sd->num_quests], 0, sizeof(struct quest)); - sd->quest_index[sd->num_quests] = 0; + if( sd->num_quests == 0 ) { + aFree(sd->quest_log); + sd->quest_log = NULL; + } else { + RECREATE(sd->quest_log, struct quest, sd->num_quests); + } sd->save_quest = true; clif->quest_delete(sd, quest_id); @@ -189,8 +213,16 @@ int quest_delete(TBL_PC * sd, int quest_id) return 0; } +/** + * Map iterator subroutine to update quest objectives for a party after killing a monster. + * + * @see map_foreachinrange + * @param ap Argument list, expecting: + * int Party ID + * int Mob ID + */ int quest_update_objective_sub(struct block_list *bl, va_list ap) { - struct map_session_data * sd; + struct map_session_data *sd; int mob_id, party_id; nullpo_ret(bl); @@ -210,28 +242,48 @@ int quest_update_objective_sub(struct block_list *bl, va_list ap) { } -void quest_update_objective(TBL_PC * sd, int mob_id) { +/** + * Updates the quest objectives for a character after killing a monster. + * + * @param sd Character's data + * @param mob_id Monster ID + */ +void quest_update_objective(TBL_PC *sd, int mob_id) { int i,j; for( i = 0; i < sd->avail_quests; i++ ) { - if( sd->quest_log[i].state != Q_ACTIVE ) + struct quest_db *qi = NULL; + + if( sd->quest_log[i].state != Q_ACTIVE ) // Skip inactive quests continue; - for( j = 0; j < MAX_QUEST_OBJECTIVES; j++ ) - if( quest->db[sd->quest_index[i]].mob[j] == mob_id && sd->quest_log[i].count[j] < quest->db[sd->quest_index[i]].count[j] ) { + qi = quest->db(sd->quest_log[i].quest_id); + + for( j = 0; j < qi->num_objectives; j++ ) { + if( qi->mob[j] == mob_id && sd->quest_log[i].count[j] < qi->count[j] ) { sd->quest_log[i].count[j]++; sd->save_quest = true; - clif->quest_update_objective(sd,&sd->quest_log[i],sd->quest_index[i]); + clif->quest_update_objective(sd, &sd->quest_log[i]); } + } } } -int quest_update_status(TBL_PC * sd, int quest_id, quest_state qs) { +/** + * Updates a quest's state. + * + * Only status of active and inactive quests can be updated. Completed quests can't (for now). [Inkfish] + * + * @param sd Character's data + * @param quest_id Quest ID to update + * @param qs New quest state + * @return 0 in case of success, nonzero otherwise + */ +int quest_update_status(TBL_PC *sd, int quest_id, enum quest_state qs) { int i; - //Only status of active and inactive quests can be updated. Completed quests can't (for now). [Inkfish] ARR_FIND(0, sd->avail_quests, i, sd->quest_log[i].quest_id == quest_id); - if(i == sd->avail_quests) { + if( i == sd->avail_quests ) { ShowError("quest_update_status: Character %d doesn't have quest %d.\n", sd->status.char_id, quest_id); return -1; } @@ -240,11 +292,13 @@ int quest_update_status(TBL_PC * sd, int quest_id, quest_state qs) { sd->save_quest = true; if( qs < Q_COMPLETE ) { - clif->quest_update_status(sd, quest_id, (bool)qs); + clif->quest_update_status(sd, quest_id, qs == Q_ACTIVE ? true : false); return 0; } - if( i != (--sd->avail_quests) ) { + // The quest is complete, so it needs to be moved to the completed quests block at the end of the array. + + if( i < (--sd->avail_quests) ) { struct quest tmp_quest; memcpy(&tmp_quest, &sd->quest_log[i],sizeof(struct quest)); memcpy(&sd->quest_log[i], &sd->quest_log[sd->avail_quests],sizeof(struct quest)); @@ -259,7 +313,22 @@ int quest_update_status(TBL_PC * sd, int quest_id, quest_state qs) { return 0; } -int quest_check(TBL_PC * sd, int quest_id, quest_check_type type) { +/** + * Queries quest information for a character. + * + * @param sd Character's data + * @param quest_id Quest ID + * @param type Check type + * @return -1 if the quest was not found, otherwise it depends on the type: + * HAVEQUEST: The quest's state + * PLAYTIME: 2 if the quest's timeout has expired + * 1 if the quest was completed + * 0 otherwise + * HUNTING: 2 if the quest has not been marked as completed yet, and its objectives have been fulfilled + * 1 if the quest's timeout has expired + * 0 otherwise + */ +int quest_check(TBL_PC *sd, int quest_id, enum quest_check_type type) { int i; ARR_FIND(0, sd->num_quests, i, sd->quest_log[i].quest_id == quest_id); @@ -271,18 +340,17 @@ int quest_check(TBL_PC * sd, int quest_id, quest_check_type type) { return sd->quest_log[i].state; case PLAYTIME: return (sd->quest_log[i].time < (unsigned int)time(NULL) ? 2 : sd->quest_log[i].state == Q_COMPLETE ? 1 : 0); - case HUNTING: { - if( sd->quest_log[i].state == 0 || sd->quest_log[i].state == 1 ) { - int j; - ARR_FIND(0, MAX_QUEST_OBJECTIVES, j, sd->quest_log[i].count[j] < quest->db[sd->quest_index[i]].count[j]); - if( j == MAX_QUEST_OBJECTIVES ) - return 2; - if( sd->quest_log[i].time < (unsigned int)time(NULL) ) - return 1; - return 0; - } else - return 0; + case HUNTING: + if( sd->quest_log[i].state == Q_INACTIVE || sd->quest_log[i].state == Q_ACTIVE ) { + int j; + struct quest_db *qi = quest->db(sd->quest_log[i].quest_id); + ARR_FIND(0, MAX_QUEST_OBJECTIVES, j, sd->quest_log[i].count[j] < qi->count[j]); + if( j == MAX_QUEST_OBJECTIVES ) + return 2; + if( sd->quest_log[i].time < (unsigned int)time(NULL) ) + return 1; } + return 0; default: ShowError("quest_check_quest: Unknown parameter %d",type); break; @@ -291,84 +359,173 @@ int quest_check(TBL_PC * sd, int quest_id, quest_check_type type) { return -1; } +/** + * Loads quests from the quest db. + * + * @return Number of loaded quests, or -1 if the file couldn't be read. + */ int quest_read_db(void) { + // TODO[Haru] This duplicates some sv_readdb functionalities, and it would be + // nice if it could be replaced by it. The reason why it wasn't is probably + // because we need to accept commas (which is also used as delimiter) in the + // last field (quest name), and sv_readdb isn't capable of doing so. FILE *fp; char line[1024]; - int i,j,k = 0; - char *str[20],*p,*np; + int i, count = 0; + char *str[20], *p, *np; + struct quest_db entry; sprintf(line, "%s/quest_db.txt", map->db_path); - if( (fp=fopen(line,"r"))==NULL ){ + if ((fp=fopen(line,"r"))==NULL) { ShowError("can't read %s\n", line); return -1; } - - while(fgets(line, sizeof(line), fp)) { - if (k == MAX_QUEST_DB) { - ShowError("quest_read_db: Too many entries specified in %s/quest_db.txt!\n", map->db_path); - break; - } - - if(line[0]=='/' && line[1]=='/') + + while (fgets(line, sizeof(line), fp)) { + if (line[0]=='/' && line[1]=='/') continue; memset(str,0,sizeof(str)); - for( j = 0, p = line; j < 8; j++ ) { - if( ( np = strchr(p,',') ) != NULL ) { - str[j] = p; + for (i = 0, p = line; i < 8; i++) { + if (( np = strchr(p,',') ) != NULL) { + str[i] = p; *np = 0; p = np + 1; - } - else if (str[0] == NULL) - continue; - else { + } else if (str[0] == NULL) { + break; + } else { ShowError("quest_read_db: insufficient columns in line %s\n", line); continue; } } - if(str[0]==NULL) + if (str[0] == NULL) + continue; + + memset(&entry, 0, sizeof(entry)); + + entry.id = atoi(str[0]); + + if (entry.id < 0 || entry.id >= MAX_QUEST_DB) { + ShowError("quest_read_db: Invalid quest ID '%d' in line '%s' (min: 0, max: %d.)\n", entry.id, line, MAX_QUEST_DB); continue; + } - memset(&quest->db[k], 0, sizeof(quest->db[0])); + entry.time = atoi(str[1]); - quest->db[k].id = atoi(str[0]); - quest->db[k].time = atoi(str[1]); - - for( i = 0; i < MAX_QUEST_OBJECTIVES; i++ ) { - quest->db[k].mob[i] = atoi(str[2*i+2]); - quest->db[k].count[i] = atoi(str[2*i+3]); + for (i = 0; i < MAX_QUEST_OBJECTIVES; i++) { + entry.mob[i] = atoi(str[2*i+2]); + entry.count[i] = atoi(str[2*i+3]); - if( !quest->db[k].mob[i] || !quest->db[k].count[i] ) + if (!entry.mob[i] || !entry.count[i]) break; } - - quest->db[k].num_objectives = i; - k++; + entry.num_objectives = i; + + if (quest->db_data[entry.id] == NULL) + quest->db_data[entry.id] = aMalloc(sizeof(struct quest_db)); + + memcpy(quest->db_data[entry.id], &entry, sizeof(struct quest_db)); + count++; } fclose(fp); - ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", k, "quest_db.txt"); + ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, "quest_db.txt"); return 0; } -void do_init_quest(void) { +/** + * Map iterator to ensures a player has no invalid quest log entries. + * + * Any entries that are no longer in the db are removed. + * + * @see map->foreachpc + * @param ap Ignored + */ +int quest_reload_check_sub(struct map_session_data *sd, va_list ap) { + int i, j; + + nullpo_ret(sd); + + j = 0; + for (i = 0; i < sd->num_quests; i++) { + struct quest_db *qi = quest->db(sd->quest_log[i].quest_id); + if (qi == &quest->dummy) { // Remove no longer existing entries + if (sd->quest_log[i].state != Q_COMPLETE) // And inform the client if necessary + clif->quest_delete(sd, sd->quest_log[i].quest_id); + continue; + } + if (i != j) { + // Move entries if there's a gap to fill + memcpy(&sd->quest_log[j], &sd->quest_log[i], sizeof(struct quest)); + } + j++; + } + sd->num_quests = j; + ARR_FIND(0, sd->num_quests, i, sd->quest_log[i].state == Q_COMPLETE); + sd->avail_quests = i; + + return 1; +} + +/** + * Clears the quest database for shutdown or reload. + */ +void quest_clear_db(void) { + int i; + + for (i = 0; i < MAX_QUEST_DB; i++) { + if (quest->db_data[i]) { + aFree(quest->db_data[i]); + quest->db_data[i] = NULL; + } + } +} + +/** + * Initializes the quest interface. + * + * @param minimal Run in minimal mode (skips most of the loading) + */ +void do_init_quest(bool minimal) { + if (minimal) + return; + quest->read_db(); } +/** + * Finalizes the quest interface before shutdown. + */ +void do_final_quest(void) { + quest->clear(); +} + +/** + * Reloads the quest database. + */ void do_reload_quest(void) { - memset(&quest->db, 0, sizeof(quest->db)); + quest->clear(); + quest->read_db(); + + // Update quest data for players, to ensure no entries about removed quests are left over. + map->foreachpc(&quest_reload_check_sub); } +/** + * Initializes default values for the quest interface. + */ void quest_defaults(void) { quest = &quest_s; - + memset(&quest->db, 0, sizeof(quest->db)); + memset(&quest->dummy, 0, sizeof(quest->dummy)); /* */ quest->init = do_init_quest; + quest->final = do_final_quest; quest->reload = do_reload_quest; /* */ - quest->search_db = quest_search_db; + quest->db = quest_db; quest->pc_login = quest_pc_login; quest->add = quest_add; quest->change = quest_change; @@ -377,5 +534,6 @@ void quest_defaults(void) { quest->update_objective = quest_update_objective; quest->update_status = quest_update_status; quest->check = quest_check; + quest->clear = quest_clear_db; quest->read_db = quest_read_db; } diff --git a/src/map/quest.h b/src/map/quest.h index 340bc8608..e01e35619 100644 --- a/src/map/quest.h +++ b/src/map/quest.h @@ -2,10 +2,12 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _QUEST_H_ -#define _QUEST_H_ +#ifndef _MAP_QUEST_H_ +#define _MAP_QUEST_H_ -struct s_quest_db { +#define MAX_QUEST_DB (60355+1) // Highest quest ID + 1 + +struct quest_db { int id; unsigned int time; int mob[MAX_QUEST_OBJECTIVES]; @@ -14,23 +16,31 @@ struct s_quest_db { //char name[NAME_LENGTH]; }; -typedef enum quest_check_type { HAVEQUEST, PLAYTIME, HUNTING } quest_check_type; +// Questlog check types +enum quest_check_type { + HAVEQUEST, ///< Query the state of the given quest + PLAYTIME, ///< Check if the given quest has been completed or has yet to expire + HUNTING, ///< Check if the given hunting quest's requirements have been met +}; struct quest_interface { - struct s_quest_db db[MAX_QUEST_DB]; + struct quest_db *db_data[MAX_QUEST_DB]; ///< Quest database + struct quest_db dummy; ///< Dummy entry for invalid quest lookups /* */ - void (*init) (void); + void (*init) (bool minimal); + void (*final) (void); void (*reload) (void); /* */ - int (*search_db) (int quest_id); + struct quest_db *(*db) (int quest_id); int (*pc_login) (TBL_PC *sd); int (*add) (TBL_PC *sd, int quest_id); int (*change) (TBL_PC *sd, int qid1, int qid2); int (*delete) (TBL_PC *sd, int quest_id); int (*update_objective_sub) (struct block_list *bl, va_list ap); void (*update_objective) (TBL_PC *sd, int mob_id); - int (*update_status) (TBL_PC *sd, int quest_id, quest_state qs); - int (*check) (TBL_PC *sd, int quest_id, quest_check_type type); + int (*update_status) (TBL_PC *sd, int quest_id, enum quest_state qs); + int (*check) (TBL_PC *sd, int quest_id, enum quest_check_type type); + void (*clear) (void); int (*read_db) (void); }; @@ -38,4 +48,4 @@ struct quest_interface *quest; void quest_defaults(void); -#endif +#endif /* _MAP_QUEST_H_ */ diff --git a/src/map/script.c b/src/map/script.c index 8460b23b0..0887b7f4e 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -8,7 +8,7 @@ #include "../common/nullpo.h" #include "../common/random.h" #include "../common/showmsg.h" -#include "../common/socket.h" // usage: getcharip +#include "../common/socket.h" // usage: getcharip #include "../common/strlib.h" #include "../common/timer.h" #include "../common/utils.h" @@ -66,11 +66,9 @@ static inline void SETVALUE(unsigned char* buf, int i, int n) { struct script_interface script_s; -const char* script_op2name(int op) -{ +const char* script_op2name(int op) { #define RETURN_OP_NAME(type) case type: return #type - switch( op ) - { + switch( op ) { RETURN_OP_NAME(C_NOP); RETURN_OP_NAME(C_POS); RETURN_OP_NAME(C_INT); @@ -85,6 +83,8 @@ const char* script_op2name(int op) RETURN_OP_NAME(C_USERFUNC); RETURN_OP_NAME(C_USERFUNC_POS); + RETURN_OP_NAME(C_REF); + // operators RETURN_OP_NAME(C_OP3); RETURN_OP_NAME(C_LOR); @@ -108,6 +108,10 @@ const char* script_op2name(int op) RETURN_OP_NAME(C_NOT); RETURN_OP_NAME(C_R_SHIFT); RETURN_OP_NAME(C_L_SHIFT); + RETURN_OP_NAME(C_ADD_POST); + RETURN_OP_NAME(C_SUB_POST); + RETURN_OP_NAME(C_ADD_PRE); + RETURN_OP_NAME(C_SUB_PRE); default: ShowDebug("script_op2name: unexpected op=%d\n", op); @@ -208,10 +212,7 @@ void script_reportdata(struct script_data* data) case C_NAME:// reference if( reference_tovariable(data) ) {// variable const char* name = reference_getname(data); - if( not_array_variable(*name) ) - ShowDebug("Data: variable name='%s'\n", name); - else - ShowDebug("Data: variable name='%s' index=%d\n", name, reference_getindex(data)); + ShowDebug("Data: variable name='%s' index=%d\n", name, reference_getindex(data)); } else if( reference_toconstant(data) ) {// constant ShowDebug("Data: constant name='%s' value=%d\n", reference_getname(data), reference_getconstant(data)); } else if( reference_toparam(data) ) {// param @@ -271,14 +272,14 @@ void script_reportfunc(struct script_state* st) /*========================================== * Output error message *------------------------------------------*/ -void disp_error_message2(const char *mes,const char *pos,int report) -{ +static void disp_error_message2(const char *mes,const char *pos,int report) analyzer_noreturn; +static void disp_error_message2(const char *mes,const char *pos,int report) { script->error_msg = aStrdup(mes); script->error_pos = pos; script->error_report = report; longjmp( script->error_jump, 1 ); } -#define disp_error_message(mes,pos) script->disp_error_message2(mes,pos,1) +#define disp_error_message(mes,pos) (disp_error_message2((mes),(pos),1)) void disp_warning_message(const char *mes, const char *pos) { script->warning(script->parser_current_src,script->parser_current_file,script->parser_current_line,mes,pos); @@ -297,13 +298,47 @@ void check_event(struct script_state *st, const char *evt) /*========================================== * Hashes the input string *------------------------------------------*/ -unsigned int calc_hash(const char* p) -{ +unsigned int calc_hash(const char* p) { unsigned int h; #if defined(SCRIPT_HASH_DJB2) h = 5381; while( *p ) // hash*33 + c + h = ( h << 5 ) + h + ((unsigned char)(*p++)); +#elif defined(SCRIPT_HASH_SDBM) + h = 0; + while( *p ) // hash*65599 + c + h = ( h << 6 ) + ( h << 16 ) - h + ((unsigned char)(*p++)); +#elif defined(SCRIPT_HASH_ELF) // UNIX ELF hash + h = 0; + while( *p ) { + unsigned int g; + h = ( h << 4 ) + ((unsigned char)(*p++)); + g = h & 0xF0000000; + if( g ) { + h ^= g >> 24; + h &= ~g; + } + } +#else // athena hash + h = 0; + while( *p ) + h = ( h << 1 ) + ( h >> 3 ) + ( h >> 5 ) + ( h >> 8 ) + (unsigned char)(*p++); +#endif + + return h % SCRIPT_HASH_SIZE; +} + +/*========================================== + * Hashes the input string in a case insensitive way + *------------------------------------------*/ +unsigned int calc_hash_ci(const char* p) { + unsigned int h = 0; +#ifdef ENABLE_CASE_CHECK + +#if defined(SCRIPT_HASH_DJB2) + h = 5381; + while( *p ) // hash*33 + c h = ( h << 5 ) + h + ((unsigned char)TOLOWER(*p++)); #elif defined(SCRIPT_HASH_SDBM) h = 0; @@ -311,12 +346,11 @@ unsigned int calc_hash(const char* p) h = ( h << 6 ) + ( h << 16 ) - h + ((unsigned char)TOLOWER(*p++)); #elif defined(SCRIPT_HASH_ELF) // UNIX ELF hash h = 0; - while( *p ){ + while( *p ) { unsigned int g; h = ( h << 4 ) + ((unsigned char)TOLOWER(*p++)); g = h & 0xF0000000; - if( g ) - { + if( g ) { h ^= g >> 24; h &= ~g; } @@ -327,6 +361,7 @@ unsigned int calc_hash(const char* p) h = ( h << 1 ) + ( h >> 3 ) + ( h >> 5 ) + ( h >> 8 ) + (unsigned char)TOLOWER(*p++); #endif +#endif // ENABLE_CASE_CHECK return h % SCRIPT_HASH_SIZE; } @@ -347,28 +382,118 @@ int script_search_str(const char* p) { int i; - for( i = script->str_hash[script->calc_hash(p)]; i != 0; i = script->str_data[i].next ) - if( strcasecmp(script->get_str(i),p) == 0 ) + for( i = script->str_hash[script->calc_hash(p)]; i != 0; i = script->str_data[i].next ) { + if( strcmp(script->get_str(i),p) == 0 ) { return i; + } + } return -1; } +void script_casecheck_clear_sub(struct casecheck_data *ccd) { +#ifdef ENABLE_CASE_CHECK + if (ccd->str_data) { + aFree(ccd->str_data); + ccd->str_data = NULL; + } + ccd->str_data_size = 0; + ccd->str_num = 1; + if (ccd->str_buf) { + aFree(ccd->str_buf); + ccd->str_buf = NULL; + } + ccd->str_pos = 0; + ccd->str_size = 0; + memset(ccd->str_hash, 0, sizeof(ccd->str_hash)); +#endif // ENABLE_CASE_CHECK +} + +void script_global_casecheck_clear(void) { + script_casecheck_clear_sub(&script->global_casecheck); +} + +void script_local_casecheck_clear(void) { + script_casecheck_clear_sub(&script->local_casecheck); +} + +const char *script_casecheck_add_str_sub(struct casecheck_data *ccd, const char *p) { +#ifdef ENABLE_CASE_CHECK + int len, i; + int h = script->calc_hash_ci(p); + if( ccd->str_hash[h] == 0 ) { //empty bucket, add new node here + ccd->str_hash[h] = ccd->str_num; + } else { + const char *s = NULL; + for( i = ccd->str_hash[h]; ; i = ccd->str_data[i].next ) { + Assert( i >= 0 && i < ccd->str_size ); + s = ccd->str_buf+ccd->str_data[i].str; + if( strcasecmp(s,p) == 0 ) { + return s; // string already in list + } + if( ccd->str_data[i].next == 0 ) + break; // reached the end + } + + // append node to end of list + ccd->str_data[i].next = ccd->str_num; + } + + // grow list if neccessary + if( ccd->str_num >= ccd->str_data_size ) { + ccd->str_data_size += 1280; + RECREATE(ccd->str_data,struct str_data_struct,ccd->str_data_size); + memset(ccd->str_data + (ccd->str_data_size - 1280), '\0', 1280); + } + + len=(int)strlen(p); + + // grow string buffer if neccessary + while( ccd->str_pos+len+1 >= ccd->str_size ) { + ccd->str_size += 10240; + RECREATE(ccd->str_buf,char,ccd->str_size); + memset(ccd->str_buf + (ccd->str_size - 10240), '\0', 10240); + } + + safestrncpy(ccd->str_buf+ccd->str_pos, p, len+1); + ccd->str_data[ccd->str_num].type = C_NOP; + ccd->str_data[ccd->str_num].str = ccd->str_pos; + ccd->str_data[ccd->str_num].val = 0; + ccd->str_data[ccd->str_num].next = 0; + ccd->str_data[ccd->str_num].func = NULL; + ccd->str_data[ccd->str_num].backpatch = -1; + ccd->str_data[ccd->str_num].label = -1; + ccd->str_pos += len+1; + + ccd->str_num++; +#endif // ENABLE_CASE_CHECK + return NULL; +} + +const char *script_global_casecheck_add_str(const char *p) { + return script_casecheck_add_str_sub(&script->global_casecheck, p); +} + +const char *script_local_casecheck_add_str(const char *p) { + return script_casecheck_add_str_sub(&script->local_casecheck, p); +} + /// Stores a copy of the string and returns its id. /// If an identical string is already present, returns its id instead. int script_add_str(const char* p) { - int i, h; - int len; - - h = script->calc_hash(p); + int i, len, h = script->calc_hash(p); +#ifdef ENABLE_CASE_CHECK + const char *existingentry = NULL; +#endif // ENABLE_CASE_CHECK if( script->str_hash[h] == 0 ) {// empty bucket, add new node here script->str_hash[h] = script->str_num; } else {// scan for end of list, or occurence of identical string for( i = script->str_hash[h]; ; i = script->str_data[i].next ) { - if( strcasecmp(script->get_str(i),p) == 0 ) + if( strcmp(script->get_str(i),p) == 0 ) { return i; // string already in list + } if( script->str_data[i].next == 0 ) break; // reached the end } @@ -377,6 +502,25 @@ int script_add_str(const char* p) script->str_data[i].next = script->str_num; } +#ifdef ENABLE_CASE_CHECK + if( (strncmp(p, ".@", 2) == 0) ) // Local scope vars are checked separately to decrease false positives + existingentry = script->local_casecheck.add_str(p); + else { + existingentry = script->global_casecheck.add_str(p); + if( existingentry ) { + if( strcasecmp(p, "disguise") == 0 || strcasecmp(p, "Poison_Spore") == 0 + || strcasecmp(p, "PecoPeco_Egg") == 0 || strcasecmp(p, "Soccer_Ball") == 0 + || strcasecmp(p, "Horn") == 0 || strcasecmp(p, "Treasure_Box_") == 0 + || strcasecmp(p, "Lord_of_Death") == 0 + ) // Known duplicates, don't bother warning the user + existingentry = NULL; + } + } + if( existingentry ) { + DeprecationWarning2("script_add_str", p, existingentry, script->parser_current_file); // TODO + } +#endif // ENABLE_CASE_CHECK + // grow list if neccessary if( script->str_num >= script->str_data_size ) { script->str_data_size += 1280; @@ -456,7 +600,7 @@ void add_scriptl(int l) { int backpatch = script->str_data[l].backpatch; - switch(script->str_data[l].type){ + switch(script->str_data[l].type) { case C_POS: case C_USERFUNC_POS: script->addc(C_POS); @@ -494,18 +638,18 @@ void set_label(int l,int pos, const char* script_pos) { int i,next; - if(script->str_data[l].type==C_INT || script->str_data[l].type==C_PARAM || script->str_data[l].type==C_FUNC) - { //Prevent overwriting constants values, parameters and built-in functions [Skotlex] + if(script->str_data[l].type==C_INT || script->str_data[l].type==C_PARAM || script->str_data[l].type==C_FUNC) { + //Prevent overwriting constants values, parameters and built-in functions [Skotlex] disp_error_message("set_label: invalid label name",script_pos); return; } - if(script->str_data[l].label!=-1){ + if(script->str_data[l].label!=-1) { disp_error_message("set_label: dup label ",script_pos); return; } script->str_data[l].type=(script->str_data[l].type == C_USERFUNC ? C_USERFUNC_POS : C_POS); script->str_data[l].label=pos; - for(i=script->str_data[l].backpatch;i>=0 && i!=0x00ffffff;){ + for(i=script->str_data[l].backpatch;i>=0 && i!=0x00ffffff;) { next=GETVALUE(script->buf,i); script->buf[i-1]=(script->str_data[l].type == C_USERFUNC ? C_USERFUNC_POS : C_POS); SETVALUE(script->buf,i,pos); @@ -581,7 +725,7 @@ const char* skip_word(const char* p) { /// @see skip_word /// @see script->add_str int add_word(const char* p) { - int len; + size_t len; int i; // Check for a word @@ -592,13 +736,13 @@ int add_word(const char* p) { // Duplicate the word if( len+1 > script->word_size ) RECREATE(script->word_buf, char, (script->word_size = (len+1))); - + memcpy(script->word_buf, p, len); script->word_buf[len] = 0; // add the word i = script->add_str(script->word_buf); - + return i; } @@ -610,17 +754,17 @@ const char* parse_callfunc(const char* p, int require_paren, int is_custom) { const char *p2; char *arg = NULL; + char null_arg = '\0'; int func; func = script->add_word(p); - if( script->str_data[func].type == C_FUNC ){ - char argT = 0; + if( script->str_data[func].type == C_FUNC ) { // buildin function script->addl(func); script->addc(C_ARG); arg = script->buildin[script->str_data[func].val]; - if( !arg ) arg = &argT; - } else if( script->str_data[func].type == C_USERFUNC || script->str_data[func].type == C_USERFUNC_POS ){ + if( !arg ) arg = &null_arg; // Use a dummy, null string + } else if( script->str_data[func].type == C_USERFUNC || script->str_data[func].type == C_USERFUNC_POS ) { // script defined function script->addl(script->buildin_callsub_ref); script->addc(C_ARG); @@ -666,12 +810,12 @@ const char* parse_callfunc(const char* p, int require_paren, int is_custom) script->syntax.curly[script->syntax.curly_count].flag = ARGLIST_NO_PAREN; */ } else {// <func name> <arg list> - if( require_paren ){ + if( require_paren ) { if( *p != '(' ) disp_error_message("need '('",p); ++p; // skip '(' script->syntax.curly[script->syntax.curly_count].flag = ARGLIST_PAREN; - } else if( *p == '(' ){ + } else if( *p == '(' ) { script->syntax.curly[script->syntax.curly_count].flag = ARGLIST_UNDEFINED; } else { script->syntax.curly[script->syntax.curly_count].flag = ARGLIST_NO_PAREN; @@ -695,7 +839,7 @@ const char* parse_callfunc(const char* p, int require_paren, int is_custom) disp_error_message2("parse_callfunc: not enough arguments, expected ','", p, script->config.warn_func_mismatch_paramnum); if( script->syntax.curly[script->syntax.curly_count].type != TYPE_ARGLIST ) disp_error_message("parse_callfunc: DEBUG last curly is not an argument list",p); - if( script->syntax.curly[script->syntax.curly_count].flag == ARGLIST_PAREN ){ + if( script->syntax.curly[script->syntax.curly_count].flag == ARGLIST_PAREN ) { if( *p != ')' ) disp_error_message("parse_callfunc: expected ')' to close argument list",p); ++p; @@ -721,6 +865,38 @@ void parse_nextline(bool first, const char* p) script->str_data[LABEL_NEXTLINE].label = -1; } +/** + * Pushes a variable into stack, processing its array index if needed. + * @see parse_variable + */ +void parse_variable_sub_push(int word, const char *p2) { + const char* p3 = NULL; + + if( p2 ) { + // process the variable index + + // push the getelementofarray method into the stack + script->addl(script->buildin_getelementofarray_ref); + script->addc(C_ARG); + script->addl(word); + + // process the sub-expression for this assignment + p3 = script->parse_subexpr(p2 + 1, 1); + p3 = script->skip_space(p3); + + if( *p3 != ']' ) {// closing parenthesis is required for this script + disp_error_message("Missing closing ']' parenthesis for the variable assignment.", p3); + } + + // push the closing function stack operator onto the stack + script->addc(C_FUNC); + p3++; + } else { + // No array index, simply push the variable or value onto the stack + script->addl(word); + } +} + /// Parse a variable assignment using the direct equals operator /// @param p script position where the function should run from /// @return NULL if not a variable assignment, the new position otherwise @@ -730,21 +906,30 @@ const char* parse_variable(const char* p) { const char *p2 = NULL; const char *var = p; + if( ( p[0] == '+' && p[1] == '+' && (type = C_ADD_PRE) ) // pre ++ + || ( p[0] == '-' && p[1] == '-' && (type = C_SUB_PRE) ) // pre -- + ) { + var = p = script->skip_space(&p[2]); + } + // skip the variable where applicable p = script->skip_word(p); p = script->skip_space(p); - if( p == NULL ) {// end of the line or invalid buffer + if( p == NULL ) { + // end of the line or invalid buffer return NULL; } - if( *p == '[' ) {// array variable so process the array as appropriate + if( *p == '[' ) { + // array variable so process the array as appropriate for( p2 = p, i = 0, j = 1; p; ++ i ) { if( *p ++ == ']' && --(j) == 0 ) break; if( *p == '[' ) ++ j; } - if( !(p = script->skip_space(p)) ) {// end of line or invalid characters remaining + if( !(p = script->skip_space(p)) ) { + // end of line or invalid characters remaining disp_error_message("Missing right expression or closing bracket for variable.", p); } } @@ -759,9 +944,8 @@ const char* parse_variable(const char* p) { || ( p[0] == '*' && p[1] == '=' && (type = C_MUL) ) // *= || ( p[0] == '/' && p[1] == '=' && (type = C_DIV) ) // /= || ( p[0] == '%' && p[1] == '=' && (type = C_MOD) ) // %= - || ( p[0] == '~' && p[1] == '=' && (type = C_NOT) ) // ~= - || ( p[0] == '+' && p[1] == '+' && (type = C_ADD_PP) ) // ++ - || ( p[0] == '-' && p[1] == '-' && (type = C_SUB_PP) ) // -- + || ( p[0] == '+' && p[1] == '+' && (type = C_ADD_POST) ) // post ++ + || ( p[0] == '-' && p[1] == '-' && (type = C_SUB_POST) ) // post -- || ( p[0] == '<' && p[1] == '<' && p[2] == '=' && (type = C_L_SHIFT) ) // <<= || ( p[0] == '>' && p[1] == '>' && p[2] == '=' && (type = C_R_SHIFT) ) // >>= ) ) @@ -770,23 +954,26 @@ const char* parse_variable(const char* p) { } switch( type ) { - case C_EQ: {// incremental modifier + case C_ADD_PRE: // pre ++ + case C_SUB_PRE: // pre -- + // (nothing more to skip) + break; + + case C_EQ: // = p = script->skip_space( &p[1] ); - } - break; + break; - case C_L_SHIFT: - case C_R_SHIFT: {// left or right shift modifier + case C_L_SHIFT: // <<= + case C_R_SHIFT: // >>= p = script->skip_space( &p[3] ); - } - break; + break; - default: {// normal incremental command + default: // everything else p = script->skip_space( &p[2] ); - } } - if( p == NULL ) {// end of line or invalid buffer + if( p == NULL ) { + // end of line or invalid buffer return NULL; } @@ -800,56 +987,45 @@ const char* parse_variable(const char* p) { script->syntax.curly[script->syntax.curly_count].flag = ARGLIST_PAREN; // increment the total curly count for the position in the script - ++ script->syntax.curly_count; + ++script->syntax.curly_count; // parse the variable currently being modified word = script->add_word(var); - if( script->str_data[word].type == C_FUNC || script->str_data[word].type == C_USERFUNC || script->str_data[word].type == C_USERFUNC_POS ) - {// cannot assign a variable which exists as a function or label + if( script->str_data[word].type == C_FUNC + || script->str_data[word].type == C_USERFUNC + || script->str_data[word].type == C_USERFUNC_POS + ) { + // cannot assign a variable which exists as a function or label disp_error_message("Cannot modify a variable which has the same name as a function or label.", p); } - if( p2 ) {// process the variable index - const char* p3 = NULL; - - // push the getelementofarray method into the stack - script->addl(script->buildin_getelementofarray_ref); - script->addc(C_ARG); - script->addl(word); - - // process the sub-expression for this assignment - p3 = script->parse_subexpr(p2 + 1, 1); - p3 = script->skip_space(p3); - - if( *p3 != ']' ) {// closing parenthesis is required for this script - disp_error_message("Missing closing ']' parenthesis for the variable assignment.", p3); - } + parse_variable_sub_push(word, p2); // Push variable onto the stack - // push the closing function stack operator onto the stack - script->addc(C_FUNC); - p3 ++; - } else {// simply push the variable or value onto the stack - script->addl(word); + if( type != C_EQ ) { + parse_variable_sub_push(word, p2); // Push variable onto the stack once again (first argument of setr) } - if( type != C_EQ ) - script->addc(C_REF); + if( type == C_ADD_POST || type == C_SUB_POST ) { // post ++ / -- + script->addi(1); + script->addc(type == C_ADD_POST ? C_ADD : C_SUB); - if( type == C_ADD_PP || type == C_SUB_PP ) {// incremental operator for the method + parse_variable_sub_push(word, p2); // Push variable onto the stack (third argument of setr) + } else if( type == C_ADD_PRE || type == C_SUB_PRE ) { // pre ++ / -- script->addi(1); - script->addc(type == C_ADD_PP ? C_ADD : C_SUB); - } else {// process the value as an expression + script->addc(type == C_ADD_PRE ? C_ADD : C_SUB); + } else { + // process the value as an expression p = script->parse_subexpr(p, -1); - if( type != C_EQ ) - {// push the type of modifier onto the stack + if( type != C_EQ ) { + // push the type of modifier onto the stack script->addc(type); } } // decrement the curly count for the position within the script - -- script->syntax.curly_count; + --script->syntax.curly_count; // close the script by appending the function operator script->addc(C_FUNC); @@ -858,67 +1034,108 @@ const char* parse_variable(const char* p) { return p; } +/* + * Checks whether the gives string is a number literal + * + * Mainly necessary to differentiate between number literals and NPC name + * constants, since several of those start with a digit. + * + * All this does is to check if the string begins with an optional + or - sign, + * followed by a hexadecimal or decimal number literal literal and is NOT + * followed by a underscore or letter. + * + * @param p Pointer to the string to check + * @return Whether the string is a number literal + */ +bool is_number(const char *p) { + const char *np; + if (!p) + return false; + if (*p == '-' || *p == '+') + p++; + np = p; + if (*p == '0' && p[1] == 'x') { + p+=2; + np = p; + // Hexadecimal + while (ISXDIGIT(*np)) + np++; + } else { + // Decimal + while (ISDIGIT(*np)) + np++; + } + if (p != np && *np != '_' && !ISALPHA(*np)) // At least one digit, and next isn't a letter or _ + return true; + return false; +} + /*========================================== * Analysis section *------------------------------------------*/ -const char* parse_simpleexpr(const char *p) -{ - long long i; +const char* parse_simpleexpr(const char *p) { + int i; p=script->skip_space(p); if(*p==';' || *p==',') disp_error_message("parse_simpleexpr: unexpected end of expression",p); - if(*p=='('){ + if(*p=='(') { if( (i=script->syntax.curly_count-1) >= 0 && script->syntax.curly[i].type == TYPE_ARGLIST ) ++script->syntax.curly[i].count; p=script->parse_subexpr(p+1,-1); p=script->skip_space(p); - if( (i=script->syntax.curly_count-1) >= 0 && script->syntax.curly[i].type == TYPE_ARGLIST && - script->syntax.curly[i].flag == ARGLIST_UNDEFINED && --script->syntax.curly[i].count == 0 - ){ - if( *p == ',' ){ + if( (i=script->syntax.curly_count-1) >= 0 && script->syntax.curly[i].type == TYPE_ARGLIST + && script->syntax.curly[i].flag == ARGLIST_UNDEFINED && --script->syntax.curly[i].count == 0 + ) { + if( *p == ',' ) { script->syntax.curly[i].flag = ARGLIST_PAREN; return p; - } else + } else { script->syntax.curly[i].flag = ARGLIST_NO_PAREN; + } } if( *p != ')' ) disp_error_message("parse_simpleexpr: unmatched ')'",p); ++p; - } else if(ISDIGIT(*p) || ((*p=='-' || *p=='+') && ISDIGIT(p[1]))){ + } else if(is_number(p)) { char *np; - while(*p == '0' && ISDIGIT(p[1])) p++; - i=strtoll(p,&np,0); - if( i < INT_MIN ) { - i = INT_MIN; + long long lli; + while(*p == '0' && ISDIGIT(p[1])) p++; // Skip leading zeros, we don't support octal literals + lli=strtoll(p,&np,0); + if( lli < INT_MIN ) { + lli = INT_MIN; script->disp_warning_message("parse_simpleexpr: underflow detected, capping value to INT_MIN",p); - } else if( i > INT_MAX ) { - i = INT_MAX; + } else if( lli > INT_MAX ) { + lli = INT_MAX; script->disp_warning_message("parse_simpleexpr: overflow detected, capping value to INT_MAX",p); } - script->addi((int)i); + script->addi((int)lli); // Cast is safe, as it's already been checked for overflows p=np; - } else if(*p=='"'){ + } else if(*p=='"') { script->addc(C_STR); - p++; - while( *p && *p != '"' ){ - if( (unsigned char)p[-1] <= 0x7e && *p == '\\' ) { - char buf[8]; - size_t len = sv->skip_escaped_c(p) - p; - size_t n = sv->unescape_c(buf, p, len); - if( n != 1 ) - ShowDebug("parse_simpleexpr: unexpected length %d after unescape (\"%.*s\" -> %.*s)\n", (int)n, (int)len, p, (int)n, buf); - p += len; - script->addb(*buf); - continue; - } else if( *p == '\n' ) - disp_error_message("parse_simpleexpr: unexpected newline @ string",p); - script->addb(*p++); - } - if(!*p) - disp_error_message("parse_simpleexpr: unexpected end of file @ string",p); + do { + p++; + while( *p && *p != '"' ) { + if( (unsigned char)p[-1] <= 0x7e && *p == '\\' ) { + char buf[8]; + size_t len = sv->skip_escaped_c(p) - p; + size_t n = sv->unescape_c(buf, p, len); + if( n != 1 ) + ShowDebug("parse_simpleexpr: unexpected length %d after unescape (\"%.*s\" -> %.*s)\n", (int)n, (int)len, p, (int)n, buf); + p += len; + script->addb(*buf); + continue; + } else if( *p == '\n' ) { + disp_error_message("parse_simpleexpr: unexpected newline @ string",p); + } + script->addb(*p++); + } + if(!*p) + disp_error_message("parse_simpleexpr: unexpected end of file @ string",p); + p++; //'"' + p = script->skip_space(p); + } while( *p && *p == '"' ); script->addb(0); - p++; //'"' } else { int l; const char* pv; @@ -928,24 +1145,24 @@ const char* parse_simpleexpr(const char *p) disp_error_message("parse_simpleexpr: unexpected character",p); l=script->add_word(p); - if( script->str_data[l].type == C_FUNC || script->str_data[l].type == C_USERFUNC || script->str_data[l].type == C_USERFUNC_POS) + if( script->str_data[l].type == C_FUNC || script->str_data[l].type == C_USERFUNC || script->str_data[l].type == C_USERFUNC_POS) { return script->parse_callfunc(p,1,0); #ifdef SCRIPT_CALLFUNC_CHECK - else { + } else { const char* name = script->get_str(l); if( strdb_get(script->userfunc_db,name) != NULL ) { return script->parse_callfunc(p,1,1); } - } #endif + } - if( (pv = script->parse_variable(p)) ) - {// successfully processed a variable assignment + if( (pv = script->parse_variable(p)) ) { + // successfully processed a variable assignment return pv; } p=script->skip_word(p); - if( *p == '[' ){ + if( *p == '[' ) { // array(name[i] => getelementofarray(name,i) ) script->addl(script->buildin_getelementofarray_ref); script->addc(C_ARG); @@ -957,8 +1174,9 @@ const char* parse_simpleexpr(const char *p) disp_error_message("parse_simpleexpr: unmatched ']'",p); ++p; script->addc(C_FUNC); - }else + } else { script->addl(l); + } } @@ -968,48 +1186,51 @@ const char* parse_simpleexpr(const char *p) /*========================================== * Analysis of the expression *------------------------------------------*/ -const char* script_parse_subexpr(const char* p,int limit) -{ +const char* script_parse_subexpr(const char* p,int limit) { int op,opl,len; const char* tmpp; p=script->skip_space(p); - if( *p == '-' ){ - tmpp = script->skip_space(p+1); - if( *tmpp == ';' || *tmpp == ',' ){ + if( *p == '-' ) { + tmpp = script->skip_space(p+1); + if( *tmpp == ';' || *tmpp == ',' ) { script->addl(LABEL_NEXTLINE); p++; return p; } } - if((op=C_NEG,*p=='-') || (op=C_LNOT,*p=='!') || (op=C_NOT,*p=='~')){ - p=script->parse_subexpr(p+1,10); + if( (p[0]=='+' && p[1]=='+') /* C_ADD_PRE */ || (p[0]=='-'&&p[1]=='-') /* C_SUB_PRE */ ) { // Pre ++ -- operators + p=script->parse_variable(p); + } else if( (op=C_NEG,*p=='-') || (op=C_LNOT,*p=='!') || (op=C_NOT,*p=='~') ) { // Unary - ! ~ operators + p=script->parse_subexpr(p+1,11); script->addc(op); - } else + } else { p=script->parse_simpleexpr(p); + } p=script->skip_space(p); while(( - (op=C_OP3,opl=0,len=1,*p=='?') || - (op=C_ADD,opl=8,len=1,*p=='+') || - (op=C_SUB,opl=8,len=1,*p=='-') || - (op=C_MUL,opl=9,len=1,*p=='*') || - (op=C_DIV,opl=9,len=1,*p=='/') || - (op=C_MOD,opl=9,len=1,*p=='%') || - (op=C_LAND,opl=2,len=2,*p=='&' && p[1]=='&') || - (op=C_AND,opl=6,len=1,*p=='&') || - (op=C_LOR,opl=1,len=2,*p=='|' && p[1]=='|') || - (op=C_OR,opl=5,len=1,*p=='|') || - (op=C_XOR,opl=4,len=1,*p=='^') || - (op=C_EQ,opl=3,len=2,*p=='=' && p[1]=='=') || - (op=C_NE,opl=3,len=2,*p=='!' && p[1]=='=') || - (op=C_R_SHIFT,opl=7,len=2,*p=='>' && p[1]=='>') || - (op=C_GE,opl=3,len=2,*p=='>' && p[1]=='=') || - (op=C_GT,opl=3,len=1,*p=='>') || - (op=C_L_SHIFT,opl=7,len=2,*p=='<' && p[1]=='<') || - (op=C_LE,opl=3,len=2,*p=='<' && p[1]=='=') || - (op=C_LT,opl=3,len=1,*p=='<')) && opl>limit){ + (op=C_OP3, opl=0, len=1,*p=='?') // ?: + || (op=C_ADD, opl=9, len=1,*p=='+') // + + || (op=C_SUB, opl=9, len=1,*p=='-') // - + || (op=C_MUL, opl=10,len=1,*p=='*') // * + || (op=C_DIV, opl=10,len=1,*p=='/') // / + || (op=C_MOD, opl=10,len=1,*p=='%') // % + || (op=C_LAND, opl=2, len=2,*p=='&' && p[1]=='&') // && + || (op=C_AND, opl=5, len=1,*p=='&') // & + || (op=C_LOR, opl=1, len=2,*p=='|' && p[1]=='|') // || + || (op=C_OR, opl=3, len=1,*p=='|') // | + || (op=C_XOR, opl=4, len=1,*p=='^') // ^ + || (op=C_EQ, opl=6, len=2,*p=='=' && p[1]=='=') // == + || (op=C_NE, opl=6, len=2,*p=='!' && p[1]=='=') // != + || (op=C_R_SHIFT,opl=8, len=2,*p=='>' && p[1]=='>') // >> + || (op=C_GE, opl=7, len=2,*p=='>' && p[1]=='=') // >= + || (op=C_GT, opl=7, len=1,*p=='>') // > + || (op=C_L_SHIFT,opl=8, len=2,*p=='<' && p[1]=='<') // << + || (op=C_LE, opl=7, len=2,*p=='<' && p[1]=='=') // <= + || (op=C_LT, opl=7, len=1,*p=='<') // < + ) && opl>limit) { p+=len; if(op == C_OP3) { p=script->parse_subexpr(p,-1); @@ -1032,7 +1253,7 @@ const char* script_parse_subexpr(const char* p,int limit) *------------------------------------------*/ const char* parse_expr(const char *p) { - switch(*p){ + switch(*p) { case ')': case ';': case ':': case '[': case ']': case '}': disp_error_message("parse_expr: unexpected char",p); @@ -1143,7 +1364,7 @@ const char* parse_curly_close(const char* p) sprintf(label,"__SW%x_FIN",script->syntax.curly[pos].index); l=script->add_str(label); script->set_label(l,script->pos, p); - linkdb_final(&script->syntax.curly[pos].case_label); // free the list of case label + linkdb_final(&script->syntax.curly[pos].case_label); // free the list of case label script->syntax.curly_count--; //Closing decision if, for , while p = script->parse_syntax_close(p + 1); @@ -1164,7 +1385,7 @@ const char* parse_syntax(const char* p) switch(*p) { case 'B': case 'b': - if(p2 - p == 5 && !strncasecmp(p,"break",5)) { + if( p2 - p == 5 && strncmp(p,"break",5) == 0 ) { // break Processing char label[256]; int pos = script->syntax.curly_count - 1; @@ -1197,11 +1418,15 @@ const char* parse_syntax(const char* p) // Closing decision if, for , while p = script->parse_syntax_close(p + 1); return p; +#ifdef ENABLE_CASE_CHECK + } else if( p2 - p == 5 && strncasecmp(p, "break", 5) == 0 ) { + disp_deprecation_message("parse_syntax", "break", p); // TODO +#endif // ENABLE_CASE_CHECK } break; case 'c': case 'C': - if(p2 - p == 4 && !strncasecmp(p,"case",4)) { + if( p2 - p == 4 && strncmp(p, "case", 4) == 0 ) { //Processing case int pos = script->syntax.curly_count-1; if(pos < 0 || script->syntax.curly[pos].type != TYPE_SWITCH) { @@ -1229,21 +1454,23 @@ const char* parse_syntax(const char* p) disp_error_message("parse_syntax: expect space ' '",p); } // check whether case label is integer or not - v = strtol(p,&np,0); - if(np == p) { //Check for constants + if(is_number(p)) { + //Numeric value + v = (int)strtol(p,&np,0); + if((*p == '-' || *p == '+') && ISDIGIT(p[1])) // pre-skip because '-' can not skip_word + p++; + p = script->skip_word(p); + if(np != p) + disp_error_message("parse_syntax: 'case' label is not an integer",np); + } else { + //Check for constants p2 = script->skip_word(p); - v = p2-p; // length of word at p2 + v = (int)(size_t) (p2-p); // length of word at p2 memcpy(label,p,v); label[v]='\0'; if( !script->get_constant(label, &v) ) disp_error_message("parse_syntax: 'case' label is not an integer",p); p = script->skip_word(p); - } else { //Numeric value - if((*p == '-' || *p == '+') && ISDIGIT(p[1])) // pre-skip because '-' can not skip_word - p++; - p = script->skip_word(p); - if(np != p) - disp_error_message("parse_syntax: 'case' label is not an integer",np); } p = script->skip_space(p); if(*p != ':') @@ -1274,7 +1501,7 @@ const char* parse_syntax(const char* p) script->syntax.curly[pos].count++; } return p + 1; - } else if(p2 - p == 8 && !strncasecmp(p,"continue",8)) { + } else if( p2 - p == 8 && strncmp(p, "continue", 8) == 0 ) { // Processing continue char label[256]; int pos = script->syntax.curly_count - 1; @@ -1305,11 +1532,17 @@ const char* parse_syntax(const char* p) //Closing decision if, for , while p = script->parse_syntax_close(p + 1); return p; +#ifdef ENABLE_CASE_CHECK + } else if( p2 - p == 4 && strncasecmp(p, "case", 4) == 0 ) { + disp_deprecation_message("parse_syntax", "case", p); // TODO + } else if( p2 - p == 8 && strncasecmp(p, "continue", 8) == 0 ) { + disp_deprecation_message("parse_syntax", "continue", p); // TODO +#endif // ENABLE_CASE_CHECK } break; case 'd': case 'D': - if(p2 - p == 7 && !strncasecmp(p,"default",7)) { + if( p2 - p == 7 && strncmp(p, "default", 7) == 0 ) { // Switch - default processing int pos = script->syntax.curly_count-1; if(pos < 0 || script->syntax.curly[pos].type != TYPE_SWITCH) { @@ -1343,7 +1576,7 @@ const char* parse_syntax(const char* p) script->syntax.curly[pos].count++; } return p + 1; - } else if(p2 - p == 2 && !strncasecmp(p,"do",2)) { + } else if( p2 - p == 2 && strncmp(p, "do", 2) == 0 ) { int l; char label[256]; p=script->skip_space(p2); @@ -1358,11 +1591,17 @@ const char* parse_syntax(const char* p) script->set_label(l,script->pos,p); script->syntax.curly_count++; return p; +#ifdef ENABLE_CASE_CHECK + } else if( p2 - p == 7 && strncasecmp(p, "default", 7) == 0 ) { + disp_deprecation_message("parse_syntax", "default", p); // TODO + } else if( p2 - p == 2 && strncasecmp(p, "do", 2) == 0 ) { + disp_deprecation_message("parse_syntax", "do", p); // TODO +#endif // ENABLE_CASE_CHECK } break; case 'f': case 'F': - if(p2 - p == 3 && !strncasecmp(p,"for",3)) { + if( p2 - p == 3 && strncmp(p, "for", 3) == 0 ) { int l; char label[256]; int pos = script->syntax.curly_count; @@ -1436,9 +1675,8 @@ const char* parse_syntax(const char* p) l=script->add_str(label); script->set_label(l,script->pos,p); return p; - } - else if( p2 - p == 8 && strncasecmp(p,"function",8) == 0 ) - {// internal script function + } else if( p2 - p == 8 && strncmp(p, "function", 8) == 0 ) { + // internal script function const char *func_name; func_name = script->skip_space(p2); @@ -1498,11 +1736,17 @@ const char* parse_syntax(const char* p) { disp_error_message("expect ';' or '{' at function syntax",p); } +#ifdef ENABLE_CASE_CHECK + } else if( p2 - p == 3 && strncasecmp(p, "for", 3) == 0 ) { + disp_deprecation_message("parse_syntax", "for", p); // TODO + } else if( p2 - p == 8 && strncasecmp(p, "function", 8) == 0 ) { + disp_deprecation_message("parse_syntax", "function", p); // TODO +#endif // ENABLE_CASE_CHECK } break; case 'i': case 'I': - if(p2 - p == 2 && !strncasecmp(p,"if",2)) { + if( p2 - p == 2 && strncmp(p, "if", 2) == 0 ) { // If process char label[256]; p=script->skip_space(p2); @@ -1522,11 +1766,15 @@ const char* parse_syntax(const char* p) script->addl(script->add_str(label)); script->addc(C_FUNC); return p; +#ifdef ENABLE_CASE_CHECK + } else if( p2 - p == 2 && strncasecmp(p, "if", 2) == 0 ) { + disp_deprecation_message("parse_syntax", "if", p); // TODO +#endif // ENABLE_CASE_CHECK } break; case 's': case 'S': - if(p2 - p == 6 && !strncasecmp(p,"switch",6)) { + if( p2 - p == 6 && strncmp(p, "switch", 6) == 0 ) { // Processing of switch () char label[256]; p=script->skip_space(p2); @@ -1549,11 +1797,15 @@ const char* parse_syntax(const char* p) } script->addc(C_FUNC); return p + 1; +#ifdef ENABLE_CASE_CHECK + } else if( p2 - p == 6 && strncasecmp(p, "switch", 6) == 0 ) { + disp_deprecation_message("parse_syntax", "switch", p); // TODO +#endif // ENABLE_CASE_CHECK } break; case 'w': case 'W': - if(p2 - p == 5 && !strncasecmp(p,"while",5)) { + if( p2 - p == 5 && strncmp(p, "while", 5) == 0 ) { int l; char label[256]; p=script->skip_space(p2); @@ -1579,6 +1831,10 @@ const char* parse_syntax(const char* p) script->addl(script->add_str(label)); script->addc(C_FUNC); return p; +#ifdef ENABLE_CASE_CHECK + } else if( p2 - p == 5 && strncasecmp(p, "while", 5) == 0 ) { + disp_deprecation_message("parse_syntax", "while", p); // TODO +#endif // ENABLE_CASE_CHECK } break; } @@ -1596,8 +1852,8 @@ const char* parse_syntax_close(const char *p) { } // Close judgment if, for, while, of do -// flag == 1 : closed -// flag == 0 : not closed +// flag == 1 : closed +// flag == 0 : not closed const char* parse_syntax_close_sub(const char* p,int* flag) { char label[256]; @@ -1629,11 +1885,11 @@ const char* parse_syntax_close_sub(const char* p,int* flag) script->syntax.curly[pos].count++; p = script->skip_space(p); p2 = script->skip_word(p); - if(!script->syntax.curly[pos].flag && p2 - p == 4 && !strncasecmp(p,"else",4)) { + if( !script->syntax.curly[pos].flag && p2 - p == 4 && strncmp(p, "else", 4) == 0 ) { // else or else - if p = script->skip_space(p2); p2 = script->skip_word(p); - if(p2 - p == 2 && !strncasecmp(p,"if",2)) { + if( p2 - p == 2 && strncmp(p, "if", 2) == 0 ) { // else - if p=script->skip_space(p2); if(*p != '(') { @@ -1648,6 +1904,10 @@ const char* parse_syntax_close_sub(const char* p,int* flag) script->addc(C_FUNC); *flag = 0; return p; +#ifdef ENABLE_CASE_CHECK + } else if( p2 - p == 2 && strncasecmp(p, "if", 2) == 0 ) { + disp_deprecation_message("parse_syntax", "if", p); // TODO +#endif // ENABLE_CASE_CHECK } else { // else if(!script->syntax.curly[pos].flag) { @@ -1656,6 +1916,10 @@ const char* parse_syntax_close_sub(const char* p,int* flag) return p; } } +#ifdef ENABLE_CASE_CHECK + } else if( !script->syntax.curly[pos].flag && p2 - p == 4 && strncasecmp(p, "else", 4) == 0 ) { + disp_deprecation_message("parse_syntax", "else", p); // TODO +#endif // ENABLE_CASE_CHECK } // Close if script->syntax.curly_count--; @@ -1669,8 +1933,6 @@ const char* parse_syntax_close_sub(const char* p,int* flag) } return p; } else if(script->syntax.curly[pos].type == TYPE_DO) { - int l; - char label[256]; const char *p2; if(script->syntax.curly[pos].flag) { @@ -1683,8 +1945,12 @@ const char* parse_syntax_close_sub(const char* p,int* flag) // Skip to the end point if the condition is false p = script->skip_space(p); p2 = script->skip_word(p); - if(p2 - p != 5 || strncasecmp(p,"while",5)) + if( p2 - p != 5 || strncmp(p, "while", 5) != 0 ) { +#ifdef ENABLE_CASE_CHECK + if( p2 - p == 5 && strncasecmp(p, "while", 5) == 0 ) disp_deprecation_message("parse_syntax", "while", p); // TODO +#endif // ENABLE_CASE_CHECK disp_error_message("parse_syntax: need 'while'",p); + } p = script->skip_space(p2); if(*p != '(') { @@ -1752,10 +2018,7 @@ const char* parse_syntax_close_sub(const char* p,int* flag) script->set_label(l,script->pos,p); script->syntax.curly_count--; return p; - } else if(script->syntax.curly[script->syntax.curly_count-1].type == TYPE_USERFUNC) { - int pos = script->syntax.curly_count-1; - char label[256]; - int l; + } else if(script->syntax.curly[pos].type == TYPE_USERFUNC) { // Back sprintf(label,"return;"); script->syntax.curly[script->syntax.curly_count++].type = TYPE_NULL; @@ -1805,8 +2068,18 @@ void script_set_constant(const char* name, int value, bool isparameter) { void script_set_constant2(const char *name, int value, bool isparameter) { int n = script->add_str(name); - if( ( script->str_data[n].type == C_NAME || script->str_data[n].type == C_PARAM ) && ( script->str_data[n].val != 0 || script->str_data[n].backpatch != -1 ) ) { // existing parameter or constant - ShowNotice("Conflicting item/script var '%s', prioritising the script var\n",name); + if( script->str_data[n].type == C_PARAM ) { + ShowError("script_set_constant2: Attempted to overwrite existing parameter '%s' with a constant (value=%d).\n", name, value); + return; + } + + if( script->str_data[n].type == C_NAME && script->str_data[n].val ) { + ShowWarning("script_set_constant2: Attempted to overwrite existing variable '%s' with a constant (value=%d).\n", name, value); + return; + } + + if( script->str_data[n].type == C_INT && value && value != script->str_data[n].val ) { // existing constant + ShowWarning("script_set_constant2: Attempted to overwrite existing constant '%s' (old value=%d, new value=%d).\n", name, script->str_data[n].val, value); return; } @@ -1820,21 +2093,6 @@ void script_set_constant2(const char *name, int value, bool isparameter) { script->str_data[n].val = value; } -/* same as constant2 except it will override if necessary, used to clear conflicts during reload */ -void script_set_constant_force(const char *name, int value, bool isparameter) { - int n = script->add_str(name); - - if( script->str_data[n].type == C_PARAM ) - return;/* the one type we don't mess with, reload doesn't affect it. */ - - if( script->str_data[n].type != C_NOP ) { - script->str_data[n].type = C_NOP; - script->str_data[n].val = 0; - script->str_data[n].func = NULL; - script->str_data[n].backpatch = -1; - script->str_data[n].label = -1; - } -} /*========================================== * Reading constant databases * const.txt @@ -1846,7 +2104,7 @@ void read_constdb(void) { sprintf(line, "%s/const.txt", map->db_path); fp=fopen(line, "r"); - if(fp==NULL){ + if(fp==NULL) { ShowError("can't read %s\n", line); return ; } @@ -1856,73 +2114,104 @@ void read_constdb(void) { continue; type=0; if(sscanf(line,"%[A-Za-z0-9_],%[-0-9xXA-Fa-f],%d",name,val,&type)>=2 || - sscanf(line,"%[A-Za-z0-9_] %[-0-9xXA-Fa-f] %d",name,val,&type)>=2){ + sscanf(line,"%[A-Za-z0-9_] %[-0-9xXA-Fa-f] %d",name,val,&type)>=2) { script->set_constant(name, (int)strtol(val, NULL, 0), (bool)type); } } fclose(fp); } +// Standard UNIX tab size is 8 +#define TAB_SIZE 8 +#define update_tabstop(tabstop,chars) \ + do { \ + (tabstop) -= (chars); \ + while ((tabstop) <= 0) (tabstop) += TAB_SIZE; \ + } while (false) + /*========================================== * Display emplacement line of script *------------------------------------------*/ const char* script_print_line(StringBuf* buf, const char* p, const char* mark, int line) { - int i; + int i, mark_pos = 0, tabstop = TAB_SIZE; if( p == NULL || !p[0] ) return NULL; if( line < 0 ) - StrBuf->Printf(buf, "*% 5d : ", -line); + StrBuf->Printf(buf, "*%5d: ", -line); // len = 8 else - StrBuf->Printf(buf, " % 5d : ", line); - for(i=0;p[i] && p[i] != '\n';i++){ - if(p + i != mark) - StrBuf->Printf(buf, "%c", p[i]); + StrBuf->Printf(buf, " %5d: ", line); // len = 8 + update_tabstop(tabstop,8); // len = 8 + for( i=0; p[i] && p[i] != '\n'; i++ ) { + char c = p[i]; + int w = 1; + // Like Clang does, let's print the code with tabs expanded to spaces to ensure that the marker will be under the right character + if( c == '\t' ) { + c = ' '; + w = tabstop; + } + update_tabstop(tabstop, w); + if( p + i < mark) + mark_pos += w; + if( p + i != mark) + StrBuf->Printf(buf, "%*c", w, c); else - StrBuf->Printf(buf, "\'%c\'", p[i]); + StrBuf->Printf(buf, CL_BT_RED"%*c"CL_RESET, w, c); } StrBuf->AppendStr(buf, "\n"); + if( mark ) { + StrBuf->AppendStr(buf, " "CL_BT_CYAN); // len = 8 + for( ; mark_pos > 0; mark_pos-- ) { + StrBuf->AppendStr(buf, "~"); + } + StrBuf->AppendStr(buf, CL_RESET CL_BT_GREEN"^"CL_RESET"\n"); + } return p+i+(p[i] == '\n' ? 1 : 0); } +#undef TAB_SIZE +#undef update_tabstop +#define CONTEXTLINES 3 void script_errorwarning_sub(StringBuf *buf, const char* src, const char* file, int start_line, const char* error_msg, const char* error_pos) { // Find the line where the error occurred int j; int line = start_line; - const char *p; - const char *linestart[5] = { NULL, NULL, NULL, NULL, NULL }; + const char *p, *error_linepos; + const char *linestart[CONTEXTLINES] = { NULL }; - for(p=src;p && *p;line++){ + for(p=src;p && *p;line++) { const char *lineend=strchr(p,'\n'); - if(lineend==NULL || error_pos<lineend){ + if(lineend==NULL || error_pos<lineend) { break; } - for( j = 0; j < 4; j++ ) { + for( j = 0; j < CONTEXTLINES-1; j++ ) { linestart[j] = linestart[j+1]; } - linestart[4] = p; - p=lineend+1; + linestart[CONTEXTLINES-1] = p; + p = lineend+1; } + error_linepos = p; if( line >= 0 ) - StrBuf->Printf(buf, "script error on %s line %d\n", file, line); + StrBuf->Printf(buf, "script error in file '%s' line %d column %d\n", file, line, error_pos-error_linepos+1); else - StrBuf->Printf(buf, "script error on %s item ID %d\n", file, -line); + StrBuf->Printf(buf, "script error in file '%s' item ID %d\n", file, -line); StrBuf->Printf(buf, " %s\n", error_msg); - for(j = 0; j < 5; j++ ) { - script->print_line(buf, linestart[j], NULL, line + j - 5); + for(j = 0; j < CONTEXTLINES; j++ ) { + script->print_line(buf, linestart[j], NULL, line + j - CONTEXTLINES); } p = script->print_line(buf, p, error_pos, -line); - for(j = 0; j < 5; j++) { + for(j = 0; j < CONTEXTLINES; j++) { p = script->print_line(buf, p, NULL, line + j + 1 ); } } +#undef CONTEXTLINES void script_error(const char* src, const char* file, int start_line, const char* error_msg, const char* error_pos) { StringBuf buf; StrBuf->Init(&buf); - StrBuf->AppendStr(&buf, "\a\n"); + StrBuf->AppendStr(&buf, "\a"); script->errorwarning_sub(&buf, src, file, start_line, error_msg, error_pos); @@ -1951,7 +2240,7 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o struct script_code* code = NULL; char end; bool unresolved_names = false; - + script->parser_current_src = src; script->parser_current_file = file; script->parser_current_line = line; @@ -1973,7 +2262,6 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o if( setjmp( script->error_jump ) != 0 ) { //Restore program state when script has problems. [from jA] - int i; const int size = ARRAYLENGTH(script->syntax.curly); if( script->error_report ) script->error(src,file,line,script->error_msg,script->error_pos); @@ -1986,6 +2274,12 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o if(script->str_data[i].type == C_NOP) script->str_data[i].type = C_NAME; for(i=0; i<size; i++) linkdb_final(&script->syntax.curly[i].case_label); +#ifdef ENABLE_CASE_CHECK + script->local_casecheck.clear(); + script->parser_current_src = NULL; + script->parser_current_file = NULL; + script->parser_current_line = 0; +#endif // ENABLE_CASE_CHECK return NULL; } @@ -2000,6 +2294,12 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o script->pos = 0; script->size = 0; script->buf = NULL; +#ifdef ENABLE_CASE_CHECK + script->local_casecheck.clear(); + script->parser_current_src = NULL; + script->parser_current_file = NULL; + script->parser_current_line = 0; +#endif // ENABLE_CASE_CHECK return NULL; } end = '\0'; @@ -2015,17 +2315,23 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o script->pos = 0; script->size = 0; script->buf = NULL; +#ifdef ENABLE_CASE_CHECK + script->local_casecheck.clear(); + script->parser_current_src = NULL; + script->parser_current_file = NULL; + script->parser_current_line = 0; +#endif // ENABLE_CASE_CHECK return NULL; } end = '}'; } // clear references of labels, variables and internal functions - for(i=LABEL_START;i<script->str_num;i++){ + for(i=LABEL_START;i<script->str_num;i++) { if( script->str_data[i].type==C_POS || script->str_data[i].type==C_NAME || script->str_data[i].type==C_USERFUNC || script->str_data[i].type == C_USERFUNC_POS - ){ + ) { script->str_data[i].type=C_NOP; script->str_data[i].backpatch=-1; script->str_data[i].label=-1; @@ -2038,7 +2344,7 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o disp_error_message("unexpected end of script",p); // Special handling only label tmpp=script->skip_space(script->skip_word(p)); - if(*tmpp==':' && !(!strncasecmp(p,"default:",8) && p + 7 == tmpp)){ + if(*tmpp==':' && !(strncmp(p,"default:",8) == 0 && p + 7 == tmpp)) { i=script->add_word(p); script->set_label(i,script->pos,p); if( script->parse_options&SCRIPT_USE_LABEL_DB ) @@ -2062,12 +2368,12 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o RECREATE(script->buf,unsigned char,script->pos); // default unknown references to variables - for(i=LABEL_START;i<script->str_num;i++){ - if(script->str_data[i].type==C_NOP){ + for(i=LABEL_START;i<script->str_num;i++) { + if(script->str_data[i].type==C_NOP) { int j,next; script->str_data[i].type=C_NAME; script->str_data[i].label=i; - for(j=script->str_data[i].backpatch;j>=0 && j!=0x00ffffff;){ + for(j=script->str_data[i].backpatch;j>=0 && j!=0x00ffffff;) { next=GETVALUE(script->buf,j); SETVALUE(script->buf,j,i); j=next; @@ -2086,7 +2392,7 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o } #ifdef SCRIPT_DEBUG_DISP - for(i=0;i<script->pos;i++){ + for(i=0;i<script->pos;i++) { if((i&15)==0) ShowMessage("%04x : ",i); ShowMessage("%02x ",script->buf[i]); if((i&15)==15) ShowMessage("\n"); @@ -2115,7 +2421,7 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o i += 3; break; case C_STR: - j = strlen(script->buf + i); + j = strlen((char*)script->buf + i); ShowMessage(" %s", script->buf + i); i += j+1; break; @@ -2129,6 +2435,12 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o code->script_buf = script->buf; code->script_size = script->size; code->script_vars = NULL; +#ifdef ENABLE_CASE_CHECK + script->local_casecheck.clear(); + script->parser_current_src = NULL; + script->parser_current_file = NULL; + script->parser_current_line = 0; +#endif // ENABLE_CASE_CHECK return code; } @@ -2136,7 +2448,7 @@ struct script_code* parse_script(const char *src,const char *file,int line,int o /// If there is no player attached, the script is terminated. TBL_PC *script_rid2sd(struct script_state *st) { TBL_PC *sd; - if( !( sd = map->id2sd(st->rid) ) ){ + if( !( sd = map->id2sd(st->rid) ) ) { ShowError("script_rid2sd: fatal error ! player not attached!\n"); script->reportfunc(st); script->reportsrc(st); @@ -2145,19 +2457,21 @@ TBL_PC *script_rid2sd(struct script_state *st) { return sd; } -/// Dereferences a variable/constant, replacing it with a copy of the value. -/// -/// @param st Script state -/// @param data Variable/constant -void get_val(struct script_state* st, struct script_data* data) -{ +/** + * Dereferences a variable/constant, replacing it with a copy of the value. + * + * @param st Script state + * @param data Variable/constant + * @return pointer to data, for convenience + */ +struct script_data *get_val(struct script_state* st, struct script_data* data) { const char* name; char prefix; char postfix; TBL_PC* sd = NULL; if( !data_isreference(data) ) - return;// not a variable/constant + return data;// not a variable/constant name = reference_getname(data); prefix = name[0]; @@ -2176,7 +2490,7 @@ void get_val(struct script_state* st, struct script_data* data) data->type = C_INT; data->u.num = 0; } - return; + return data; } } @@ -2191,32 +2505,32 @@ void get_val(struct script_state* st, struct script_data* data) break; case '#': if( name[1] == '#' ) - data->u.str = pc_readaccountreg2str(sd, name);// global + data->u.str = pc_readaccountreg2str(sd, data->u.num);// global else - data->u.str = pc_readaccountregstr(sd, name);// local + data->u.str = pc_readaccountregstr(sd, data->u.num);// local break; case '.': { - struct DBMap* n = - data->ref ? *data->ref: - name[1] == '@' ? st->stack->var_function:// instance/scope variable - st->script->script_vars;// npc variable + struct DBMap* n = data->ref ? + *data->ref : name[1] == '@' ? + st->stack->var_function : // instance/scope variable + st->script->script_vars; // npc variable if( n ) - data->u.str = (char*)idb_get(n,reference_getuid(data)); + data->u.str = (char*)i64db_get(n,reference_getuid(data)); else data->u.str = NULL; } break; case '\'': if ( st->instance_id >= 0 ) { - data->u.str = (char*)idb_get(instance->list[st->instance_id].vars,reference_getuid(data)); + data->u.str = (char*)i64db_get(instance->list[st->instance_id].vars,reference_getuid(data)); } else { ShowWarning("script_get_val: cannot access instance variable '%s', defaulting to \"\"\n", name); data->u.str = NULL; } break; default: - data->u.str = pc_readglobalreg_str(sd, name); + data->u.str = pc_readglobalreg_str(sd, data->u.num); break; } @@ -2246,99 +2560,336 @@ void get_val(struct script_state* st, struct script_data* data) break; case '#': if( name[1] == '#' ) - data->u.num = pc_readaccountreg2(sd, name);// global + data->u.num = pc_readaccountreg2(sd, data->u.num);// global else - data->u.num = pc_readaccountreg(sd, name);// local + data->u.num = pc_readaccountreg(sd, data->u.num);// local break; case '.': { - struct DBMap* n = - data->ref ? *data->ref: - name[1] == '@' ? st->stack->var_function:// instance/scope variable - st->script->script_vars;// npc variable + struct DBMap* n = data->ref ? + *data->ref : name[1] == '@' ? + st->stack->var_function : // instance/scope variable + st->script->script_vars; // npc variable if( n ) - data->u.num = (int)idb_iget(n,reference_getuid(data)); + data->u.num = (int)i64db_iget(n,reference_getuid(data)); else data->u.num = 0; } break; case '\'': if( st->instance_id >= 0 ) - data->u.num = (int)idb_iget(instance->list[st->instance_id].vars,reference_getuid(data)); + data->u.num = (int)i64db_iget(instance->list[st->instance_id].vars,reference_getuid(data)); else { ShowWarning("script_get_val: cannot access instance variable '%s', defaulting to 0\n", name); data->u.num = 0; } break; default: - data->u.num = pc_readglobalreg(sd, name); + data->u.num = pc_readglobalreg(sd, data->u.num); break; } } - return; + return data; } /// Retrieves the value of a reference identified by uid (variable, constant, param) /// The value is left in the top of the stack and needs to be removed manually. -void* get_val2(struct script_state* st, int uid, struct DBMap** ref) { +void* get_val2(struct script_state* st, int64 uid, struct DBMap** ref) { struct script_data* data; script->push_val(st->stack, C_NAME, uid, ref); data = script_getdatatop(st, -1); script->get_val(st, data); - return (data->type == C_INT ? (void*)__64BPTRSIZE(data->u.num) : (void*)__64BPTRSIZE(data->u.str)); + return (data->type == C_INT ? (void*)__64BPTRSIZE((int32)data->u.num) : (void*)__64BPTRSIZE(data->u.str)); // u.num is int32 because it comes from script->get_val } +/** + * Because, currently, array members with key 0 are indifferenciable from normal variables, we should ensure its actually in + * Will be gone as soon as undefined var feature is implemented + **/ +void script_array_ensure_zero(struct script_state *st, struct map_session_data *sd, int64 uid, struct DBMap** ref) { + const char *name = script->get_str(script_getvarid(uid)); + struct DBMap *src = script->array_src(st, sd ? sd : st->rid ? map->id2sd(st->rid) : NULL, name, ref); + struct script_array *sa = NULL; + bool insert = false; + + if( sd && !st ) /* when sd comes, st isn't available */ + insert = true; + else { + if( is_string_variable(name) ) { + char* str = (char*)script->get_val2(st, uid, ref); + if( str && *str ) + insert = true; + script_removetop(st, -1, 0); + } else { + int32 num = (int32)__64BPTRSIZE(script->get_val2(st, uid, ref)); + if( num ) + insert = true; + script_removetop(st, -1, 0); + } + } + if( src ) { + if( (sa = idb_get(src, script_getvarid(uid)) ) ) { + unsigned int i; + + ARR_FIND(0, sa->size, i, sa->members[i] == 0); + if( i != sa->size ) { + if( !insert ) + script->array_remove_member(src,sa,i); + return; + } + + script->array_add_member(sa,0); + } else if( insert ) { + script->array_update(&src,reference_uid(script_getvarid(uid), 0),false); + } + } +} +/** + * Returns array size by ID + **/ +unsigned int script_array_size(struct script_state *st, struct map_session_data *sd, const char *name, struct DBMap **ref) { + struct script_array *sa = NULL; + struct DBMap *src = script->array_src(st, sd, name, ref); + + if( src ) + sa = idb_get(src, script->search_str(name)); + + return sa ? sa->size : 0; +} +/** + * Returns array's highest key (for that awful getarraysize implementation that doesn't really gets the array size) + **/ +unsigned int script_array_highest_key(struct script_state *st, struct map_session_data *sd, const char *name, struct DBMap **ref) { + struct script_array *sa = NULL; + struct DBMap *src = script->array_src(st, sd, name, ref); + + + if( src ) { + int key = script->add_word(name); + + script->array_ensure_zero(st,sd,reference_uid(key, 0),ref); + + if( ( sa = idb_get(src, key) ) ) { + unsigned int i, highest_key = 0; + + for(i = 0; i < sa->size; i++) { + if( sa->members[i] > highest_key ) + highest_key = sa->members[i]; + } + + return sa->size ? highest_key + 1 : 0; + } + } + + return 0; +} +int script_free_array_db(DBKey key, DBData *data, va_list ap) { + struct script_array *sa = DB->data2ptr(data); + aFree(sa->members); + ers_free(script->array_ers, sa); + return 0; +} +/** + * Clears script_array and removes it from script->array_db + **/ +void script_array_delete(struct DBMap *src, struct script_array *sa) { + aFree(sa->members); + idb_remove(src, sa->id); + ers_free(script->array_ers, sa); +} +/** + * Removes a member from a script_array list + * + * @param idx the index of the member in script_array struct list, not of the actual array member + **/ +void script_array_remove_member(struct DBMap *src,struct script_array *sa, unsigned int idx) { + unsigned int i, cursor; + + /* its the only member left, no need to do anything other than delete the array data */ + if( sa->size == 1 ) { + script->array_delete(src,sa); + return; + } + + sa->members[idx] = UINT_MAX; + + for(i = 0, cursor = 0; i < sa->size; i++) { + if( sa->members[i] == UINT_MAX ) + continue; + if( i != cursor ) + sa->members[cursor] = sa->members[i]; + cursor++; + } + + sa->size = cursor; +} +/** + * Appends a new array index to the list in script_array + * + * @param idx the index of the array member being inserted + **/ +void script_array_add_member(struct script_array *sa, unsigned int idx) { + + RECREATE(sa->members, unsigned int, ++sa->size); + + sa->members[sa->size - 1] = idx; + +} +/** + * Obtains the source of the array database for this type and scenario + * Initializes such database when not yet initialised. + **/ +struct DBMap *script_array_src(struct script_state *st, struct map_session_data *sd, const char *name, struct DBMap **ref) { + struct DBMap **src = NULL; + + switch( name[0] ) { + /* from player */ + default: /* char reg */ + case '@':/* temp char reg */ + case '#':/* account reg */ + src = &sd->array_db; + break; + case '$':/* map reg */ + src = &mapreg->array_db; + break; + case '.':/* npc/script */ + if( ref ) + src = (struct DBMap **)((char *)ref + sizeof(struct DBMap *)); + else + src = (name[1] == '@') ? &st->stack->array_function_db : &st->script->script_arrays_db; + break; + case '\'':/* instance */ + if( st->instance_id >= 0 ) { + src = &instance->list[st->instance_id].array_db; + } + break; + } + + if( src ) { + if( !*src ) + *src = idb_alloc(DB_OPT_BASE); + return *src; + } + + return NULL; +} +/** + * Processes a array member modification, and update data accordingly + **/ +void script_array_update(struct DBMap **src, int64 num, bool empty) { + struct script_array *sa = NULL; + int id = script_getvarid(num); + unsigned int index = script_getvaridx(num); + + if( !*src ) { + *src = idb_alloc(DB_OPT_BASE); + } else { + sa = idb_get(*src, id); + } + + if( sa ) { + unsigned int i; + + /* search */ + for(i = 0; i < sa->size; i++) { + if( sa->members[i] == index ) + break; + } + + /* if existent */ + if( i != sa->size ) { + /* if empty, we gotta remove it */ + if( empty ) { + script->array_remove_member(*src,sa,i); + } + } else if( !empty ) { /* new entry */ + script->array_add_member(sa,index); + /* we do nothing if its empty, no point in modifying array data for a new empty member */ + } + } else if ( !empty ) {/* we only move to create if not empty */ + sa = ers_alloc(script->array_ers, struct script_array); + sa->id = id; + sa->members = NULL; + sa->size = 0; + script->array_add_member(sa,index); + idb_put(*src, id, sa); + } +} /*========================================== * Stores the value of a script variable * Return value is 0 on fail, 1 on success. + * TODO: return values are screwed up, have been for some time (reaad: years), e.g. some functions return 1 failure and success. *------------------------------------------*/ -int set_reg(struct script_state* st, TBL_PC* sd, int num, const char* name, const void* value, struct DBMap** ref) -{ +int set_reg(struct script_state* st, TBL_PC* sd, int64 num, const char* name, const void* value, struct DBMap** ref) { char prefix = name[0]; + + if( is_string_variable(name) ) {// string variable + const char *str = (const char*)value; - if( is_string_variable(name) ) - {// string variable - const char* str = (const char*)value; switch (prefix) { - case '@': - return pc->setregstr(sd, num, str); - case '$': - return mapreg->setregstr(num, str); - case '#': - return (name[1] == '#') ? - pc_setaccountreg2str(sd, name, str) : - pc_setaccountregstr(sd, name, str); - case '.': - { - struct DBMap* n; - n = (ref) ? *ref : (name[1] == '@') ? st->stack->var_function : st->script->script_vars; - if( n ) { - idb_remove(n, num); - if (str[0]) idb_put(n, num, aStrdup(str)); + case '@': + pc->setregstr(sd, num, str); + return 1; + case '$': + return mapreg->setregstr(num, str); + case '#': + return (name[1] == '#') ? + pc_setaccountreg2str(sd, num, str) : + pc_setaccountregstr(sd, num, str); + case '.': + { + struct DBMap* n; + n = (ref) ? *ref : (name[1] == '@') ? st->stack->var_function : st->script->script_vars; + if( n ) { + if (str[0]) { + i64db_put(n, num, aStrdup(str)); + if( script_getvaridx(num) ) + script->array_update( + (name[1] == '@') ? + &st->stack->array_function_db : + &st->script->script_arrays_db, + num, + false); + } else { + i64db_remove(n, num); + if( script_getvaridx(num) ) + script->array_update( + (name[1] == '@') ? + &st->stack->array_function_db : + &st->script->script_arrays_db, + num, + true); + } + } } - } - return 1; - case '\'': - if( st->instance_id >= 0 ) { - idb_remove(instance->list[st->instance_id].vars, num); - if( str[0] ) idb_put(instance->list[st->instance_id].vars, num, aStrdup(str)); - } - return 1; - default: - return pc_setglobalreg_str(sd, name, str); + return 1; + case '\'': + if( st->instance_id >= 0 ) { + if( str[0] ) { + i64db_put(instance->list[st->instance_id].vars, num, aStrdup(str)); + if( script_getvaridx(num) ) + script->array_update(&instance->list[st->instance_id].array_db,num,false); + } else { + i64db_remove(instance->list[st->instance_id].vars, num); + if( script_getvaridx(num) ) + script->array_update(&instance->list[st->instance_id].array_db,num,true); + } + } else { + ShowError("script_set_reg: cannot write instance variable '%s', NPC not in a instance!\n", name); + script_reportsrc(st); + } + return 1; + default: + return pc_setglobalreg_str(sd, num, str); } - } - else - {// integer variable + } else {// integer variable int val = (int)__64BPTRSIZE(value); - if(script->str_data[num&0x00ffffff].type == C_PARAM) - { - if( pc->setparam(sd, script->str_data[num&0x00ffffff].val, val) == 0 ) - { - if( st != NULL ) - { + + if(script->str_data[script_getvarid(num)].type == C_PARAM) { + if( pc->setparam(sd, script->str_data[script_getvarid(num)].val, val) == 0 ) { + if( st != NULL ) { ShowError("script:set_reg: failed to set param '%s' to %d.\n", name, val); script->reportsrc(st); st->state = END; @@ -2349,41 +2900,66 @@ int set_reg(struct script_state* st, TBL_PC* sd, int num, const char* name, cons } switch (prefix) { - case '@': - return pc->setreg(sd, num, val); - case '$': - return mapreg->setreg(num, val); - case '#': - return (name[1] == '#') ? - pc_setaccountreg2(sd, name, val) : - pc_setaccountreg(sd, name, val); - case '.': - { - struct DBMap* n; - n = (ref) ? *ref : (name[1] == '@') ? st->stack->var_function : st->script->script_vars; - if( n ) { - idb_remove(n, num); - if( val != 0 ) - idb_iput(n, num, val); + case '@': + pc->setreg(sd, num, val); + return 1; + case '$': + return mapreg->setreg(num, val); + case '#': + return (name[1] == '#') ? + pc_setaccountreg2(sd, num, val) : + pc_setaccountreg(sd, num, val); + case '.': + { + struct DBMap* n; + n = (ref) ? *ref : (name[1] == '@') ? st->stack->var_function : st->script->script_vars; + if( n ) { + if( val != 0 ) { + i64db_iput(n, num, val); + if( script_getvaridx(num) ) + script->array_update( + (name[1] == '@') ? + &st->stack->array_function_db : + &st->script->script_arrays_db, + num, + false); + } else { + i64db_remove(n, num); + if( script_getvaridx(num) ) + script->array_update( + (name[1] == '@') ? + &st->stack->array_function_db : + &st->script->script_arrays_db, + num, + true); + } + } } - } - return 1; - case '\'': - if( st->instance_id >= 0 ) { - idb_remove(instance->list[st->instance_id].vars, num); - if( val != 0 ) - idb_iput(instance->list[st->instance_id].vars, num, val); - } - return 1; - default: - return pc_setglobalreg(sd, name, val); + return 1; + case '\'': + if( st->instance_id >= 0 ) { + if( val != 0 ) { + i64db_iput(instance->list[st->instance_id].vars, num, val); + if( script_getvaridx(num) ) + script->array_update(&instance->list[st->instance_id].array_db,num,false); + } else { + i64db_remove(instance->list[st->instance_id].vars, num); + if( script_getvaridx(num) ) + script->array_update(&instance->list[st->instance_id].array_db,num,true); + } + } else { + ShowError("script_set_reg: cannot write instance variable '%s', NPC not in a instance!\n", name); + script_reportsrc(st); + } + return 1; + default: + return pc_setglobalreg(sd, num, val); } } } -int set_var(TBL_PC* sd, char* name, void* val) -{ - return script->set_reg(NULL, sd, reference_uid(script->add_str(name),0), name, val, NULL); +int set_var(TBL_PC* sd, char* name, void* val) { + return script->set_reg(NULL, sd, reference_uid(script->add_str(name),0), name, val, NULL); } void setd_sub(struct script_state *st, TBL_PC *sd, const char *varname, int elem, void *value, struct DBMap **ref) @@ -2403,7 +2979,7 @@ const char* conv_str(struct script_state* st, struct script_data* data) else if( data_isint(data) ) {// int -> string CREATE(p, char, ITEM_NAME_LENGTH); - snprintf(p, ITEM_NAME_LENGTH, "%d", data->u.num); + snprintf(p, ITEM_NAME_LENGTH, "%"PRId64"", data->u.num); p[ITEM_NAME_LENGTH-1] = '\0'; data->type = C_STR; data->u.str = p; @@ -2477,7 +3053,7 @@ int conv_num(struct script_state* st, struct script_data* data) { data->u.num = 0; } #endif - return data->u.num; + return (int)data->u.num; } // @@ -2494,7 +3070,7 @@ void stack_expand(struct script_stack* stack) { } /// Pushes a value into the stack (with reference) -struct script_data* push_val(struct script_stack* stack, enum c_op type, int val, struct DBMap** ref) { +struct script_data* push_val(struct script_stack* stack, enum c_op type, int64 val, struct DBMap** ref) { if( stack->sp >= stack->sp_max ) script->stack_expand(stack); stack->stack_data[stack->sp].type = type; @@ -2591,12 +3167,18 @@ void pop_stack(struct script_state* st, int start, int end) stack->stack_data[i].type = C_NOP; } // adjust stack pointers - if( st->start > end ) st->start -= end - start; - else if( st->start > start ) st->start = start; - if( st->end > end ) st->end -= end - start; - else if( st->end > start ) st->end = start; - if( stack->defsp > end ) stack->defsp -= end - start; - else if( stack->defsp > start ) stack->defsp = start; + if( st->start > end ) + st->start -= end - start; + else if( st->start > start ) + st->start = start; + if( st->end > end ) + st->end -= end - start; + else if( st->end > start ) + st->end = start; + if( stack->defsp > end ) + stack->defsp -= end - start; + else if( stack->defsp > start ) + stack->defsp = start; stack->sp -= end - start; } @@ -2617,6 +3199,8 @@ void script_free_vars(struct DBMap* var_storage) { void script_free_code(struct script_code* code) { script->free_vars( code->script_vars ); + if( code->script_arrays_db ) + code->script_arrays_db->destroy(code->script_arrays_db,script->array_free_db); aFree( code->script_buf ); aFree( code ); } @@ -2630,14 +3214,15 @@ void script_free_code(struct script_code* code) /// @return Script state struct script_state* script_alloc_state(struct script_code* rootscript, int pos, int rid, int oid) { struct script_state* st; - + st = ers_alloc(script->st_ers, struct script_state); st->stack = ers_alloc(script->stack_ers, struct script_stack); st->stack->sp = 0; st->stack->sp_max = 64; CREATE(st->stack->stack_data, struct script_data, st->stack->sp_max); st->stack->defsp = st->stack->sp; - st->stack->var_function = idb_alloc(DB_OPT_RELEASE_DATA); + st->stack->var_function = i64db_alloc(DB_OPT_RELEASE_DATA); + st->stack->array_function_db = NULL; st->state = RUN; st->script = rootscript; st->pos = pos; @@ -2645,15 +3230,15 @@ struct script_state* script_alloc_state(struct script_code* rootscript, int pos, st->oid = oid; st->sleep.timer = INVALID_TIMER; st->npc_item_flag = battle_config.item_enabled_npc; - + if( !st->script->script_vars ) - st->script->script_vars = idb_alloc(DB_OPT_RELEASE_DATA); - + st->script->script_vars = i64db_alloc(DB_OPT_RELEASE_DATA); + st->id = script->next_id++; script->active_scripts++; idb_put(script->st_db, st->id, st); - + return st; } @@ -2670,14 +3255,22 @@ void script_free_state(struct script_state* st) { timer->delete(st->sleep.timer, script->run_timer); if( st->stack ) { script->free_vars(st->stack->var_function); + if( st->stack->array_function_db ) + st->stack->array_function_db->destroy(st->stack->array_function_db,script->array_free_db); script->pop_stack(st, 0, st->stack->sp); aFree(st->stack->stack_data); ers_free(script->stack_ers, st->stack); st->stack = NULL; } - if( st->script && st->script->script_vars && !db_size(st->script->script_vars) ) { - script->free_vars(st->script->script_vars); - st->script->script_vars = NULL; + if( st->script ) { + if( st->script->script_vars && !db_size(st->script->script_vars) ) { + script->free_vars(st->script->script_vars); + st->script->script_vars = NULL; + } + if( st->script->script_arrays_db && !db_size(st->script->script_arrays_db) ) { + script->free_vars(st->script->script_arrays_db); + st->script->script_arrays_db = NULL; + } } st->pos = -1; idb_remove(script->st_db, st->id); @@ -2698,10 +3291,10 @@ c_op get_com(unsigned char *scriptbuf,int *pos) { int i = 0, j = 0; - if(scriptbuf[*pos]>=0x80){ + if(scriptbuf[*pos]>=0x80) { return C_INT; } - while(scriptbuf[*pos]>=0x40){ + while(scriptbuf[*pos]>=0x40) { i=scriptbuf[(*pos)++]<<j; j+=6; } @@ -2715,27 +3308,13 @@ int get_num(unsigned char *scriptbuf,int *pos) { int i,j; i=0; j=0; - while(scriptbuf[*pos]>=0xc0){ + while(scriptbuf[*pos]>=0xc0) { i+=(scriptbuf[(*pos)++]&0x7f)<<j; j+=6; } return i+((scriptbuf[(*pos)++]&0x7f)<<j); } -/*========================================== - * Remove the value from the stack - *------------------------------------------*/ -int pop_val(struct script_state* st) -{ - if(st->stack->sp<=0) - return 0; - st->stack->sp--; - script->get_val(st,&(st->stack->stack_data[st->stack->sp])); - if(st->stack->stack_data[st->stack->sp].type==C_INT) - return st->stack->stack_data[st->stack->sp].u.num; - return 0; -} - /// Ternary operators /// test ? if_true : if_false void op_3(struct script_state* st, int op) @@ -2749,7 +3328,7 @@ void op_3(struct script_state* st, int op) if( data_isstring(data) ) flag = data->u.str[0];// "" -> false else if( data_isint(data) ) - flag = data->u.num;// 0 -> false + flag = data->u.num == 0 ? 0 : 1;// 0 -> false else { ShowError("script:op_3: invalid data for the ternary operator test\n"); @@ -2778,7 +3357,7 @@ void op_2str(struct script_state* st, int op, const char* s1, const char* s2) { int a = 0; - switch(op){ + switch(op) { case C_EQ: a = (strcmp(s1,s2) == 0); break; case C_NE: a = (strcmp(s1,s2) != 0); break; case C_GT: a = (strcmp(s1,s2) > 0); break; @@ -2811,21 +3390,20 @@ void op_2num(struct script_state* st, int op, int i1, int i2) int ret; double ret_double; - switch( op ) - { - case C_AND: ret = i1 & i2; break; - case C_OR: ret = i1 | i2; break; - case C_XOR: ret = i1 ^ i2; break; - case C_LAND: ret = (i1 && i2); break; - case C_LOR: ret = (i1 || i2); break; - case C_EQ: ret = (i1 == i2); break; - case C_NE: ret = (i1 != i2); break; - case C_GT: ret = (i1 > i2); break; - case C_GE: ret = (i1 >= i2); break; - case C_LT: ret = (i1 < i2); break; - case C_LE: ret = (i1 <= i2); break; - case C_R_SHIFT: ret = i1>>i2; break; - case C_L_SHIFT: ret = i1<<i2; break; + switch( op ) { + case C_AND: ret = i1 & i2; break; + case C_OR: ret = i1 | i2; break; + case C_XOR: ret = i1 ^ i2; break; + case C_LAND: ret = (i1 && i2); break; + case C_LOR: ret = (i1 || i2); break; + case C_EQ: ret = (i1 == i2); break; + case C_NE: ret = (i1 != i2); break; + case C_GT: ret = (i1 > i2); break; + case C_GE: ret = (i1 >= i2); break; + case C_LT: ret = (i1 < i2); break; + case C_LE: ret = (i1 <= i2); break; + case C_R_SHIFT: ret = i1>>i2; break; + case C_L_SHIFT: ret = i1<<i2; break; case C_DIV: case C_MOD: if( i2 == 0 ) @@ -2920,8 +3498,8 @@ void op_2(struct script_state *st, int op) } else if( data_isint(left) && data_isint(right) ) {// ii => op_2num - int i1 = left->u.num; - int i2 = right->u.num; + int i1 = (int)left->u.num; + int i2 = (int)right->u.num; script_removetop(st, leftref.type == C_NOP ? -2 : -1, 0); script->op_2num(st, op, i1, i2); @@ -2963,19 +3541,18 @@ void op_1(struct script_state* st, int op) return; } - i1 = data->u.num; + i1 = (int)data->u.num; script_removetop(st, -1, 0); - switch( op ) - { - case C_NEG: i1 = -i1; break; - case C_NOT: i1 = ~i1; break; - case C_LNOT: i1 = !i1; break; - default: - ShowError("script:op_1: unexpected operator %s i1=%d\n", script->op2name(op), i1); - script->reportsrc(st); - script_pushnil(st); - st->state = END; - return; + switch( op ) { + case C_NEG: i1 = -i1; break; + case C_NOT: i1 = ~i1; break; + case C_LNOT: i1 = !i1; break; + default: + ShowError("script:op_1: unexpected operator %s i1=%d\n", script->op2name(op), i1); + script->reportsrc(st); + script_pushnil(st); + st->state = END; + return; } script_pushint(st, i1); } @@ -2995,7 +3572,7 @@ void script_check_buildin_argtype(struct script_state* st, int func) struct script_data* data = script_getdata(st, idx); type = sf[idx-2]; - + if( type == '?' || type == '*' ) {// optional argument or unknown number of optional parameters ( no types are after this ) break; } else if( type == 0 ) {// more arguments than necessary ( should not happen, as it is checked before ) @@ -3036,7 +3613,7 @@ void script_check_buildin_argtype(struct script_state* st, int func) } break; case 'r': - if( !data_isreference(data) ) + if( !data_isreference(data) || reference_toconstant(data) ) {// variables ShowWarning("Unexpected type for argument %d. Expected variable, got %s.\n", idx-1,script->op2name(data->type)); script->reportdata(data); @@ -3086,7 +3663,7 @@ int run_func(struct script_state *st) data = &st->stack->stack_data[st->start]; if( data->type == C_NAME && script->str_data[data->u.num].type == C_FUNC ) - func = data->u.num; + func = (int)data->u.num; else { ShowError("script:run_func: not a buildin command.\n"); @@ -3100,11 +3677,11 @@ int run_func(struct script_state *st) script->check_buildin_argtype(st, func); } - if(script->str_data[func].func){ + if(script->str_data[func].func) { if (!(script->str_data[func].func(st))) //Report error script->reportsrc(st); } else { - ShowError("script:run_func: '%s' (id=%d type=%s) has no C function. please report this!!!\n", script->get_str(func), func, script->op2name(script->str_data[func].type)); + ShowError("script:run_func: '%s' (id=%"PRId64" type=%s) has no C function. please report this!!!\n", script->get_str(func), func, script->op2name(script->str_data[func].type)); script->reportsrc(st); st->state = END; } @@ -3154,37 +3731,37 @@ void run_script(struct script_code *rootscript,int pos,int rid,int oid) { if( rootscript == NULL || pos < 0 ) return; - + // TODO In jAthena, this function can take over the pending script in the player. [FlavioJS] // It is unclear how that can be triggered, so it needs the be traced/checked in more detail. // NOTE At the time of this change, this function wasn't capable of taking over the script state because st->scriptroot was never set. st = script->alloc_state(rootscript, pos, rid, oid); - + script->run_main(st); } void script_stop_instances(struct script_code *code) { DBIterator *iter; struct script_state* st; - + if( !script->active_scripts ) return;//dont even bother. - + iter = db_iterator(script->st_db); - + for( st = dbi_first(iter); dbi_exists(iter); st = dbi_next(iter) ) { if( st->script == code ) { script->free_state(st); } } - + dbi_destroy(iter); } /*========================================== * Timer function for sleep *------------------------------------------*/ -int run_script_timer(int tid, unsigned int tick, int id, intptr_t data) { +int run_script_timer(int tid, int64 tick, int id, intptr_t data) { struct script_state *st = idb_get(script->st_db,(int)data); if( st ) { TBL_PC *sd = map->id2sd(st->rid); @@ -3217,13 +3794,9 @@ void script_detach_state(struct script_state* st, bool dequeue_event) { st->bk_st = NULL; st->bk_npcid = 0; } else if(dequeue_event) { - /** - * For the Secure NPC Timeout option (check config/Secure.h) [RR] - **/ + // For the Secure NPC Timeout option (check config/Secure.h) [RR] #ifdef SECURE_NPCTIMEOUT - /** - * We're done with this NPC session, so we cancel the timer (if existent) and move on - **/ + // We're done with this NPC session, so we cancel the timer (if existent) and move on if( sd->npc_idle_timer != INVALID_TIMER ) { timer->delete(sd->npc_idle_timer,npc->secure_timeout_timer); sd->npc_idle_timer = INVALID_TIMER; @@ -3296,9 +3869,9 @@ void run_script_main(struct script_state *st) { } else if(st->state != END) st->state = RUN; - while( st->state == RUN ){ + while( st->state == RUN ) { enum c_op c = script->get_com(st->script->script_buf,&st->pos); - switch(c){ + switch(c) { case C_EOL: if( stack->defsp > stack->sp ) ShowError("script:run_script_main: unexpected stack position (defsp=%d sp=%d). please report this!!!\n", stack->defsp, stack->sp); @@ -3322,9 +3895,9 @@ void run_script_main(struct script_state *st) { break; case C_FUNC: script->run_func(st); - if(st->state==GOTO){ + if(st->state==GOTO) { st->state = RUN; - if( !st->freeloop && gotocount>0 && (--gotocount)<=0 ){ + if( !st->freeloop && gotocount>0 && (--gotocount)<=0 ) { ShowError("run_script: infinity loop !\n"); script->reportsrc(st); st->state=END; @@ -3376,8 +3949,8 @@ void run_script_main(struct script_state *st) { st->state=END; break; } - if( !st->freeloop && cmdcount>0 && (--cmdcount)<=0 ){ - ShowError("run_script: infinity loop !\n"); + if( !st->freeloop && cmdcount>0 && (--cmdcount)<=0 ) { + ShowError("run_script: too many opeartions being processed non-stop !\n"); script->reportsrc(st); st->state=END; } @@ -3391,7 +3964,7 @@ void run_script_main(struct script_state *st) { st->sleep.charid = sd?sd->status.char_id:0; st->sleep.timer = timer->add(timer->gettick()+st->sleep.tick, script->run_timer, st->sleep.charid, (intptr_t)st->id); - } else if(st->state != END && st->rid){ + } else if(st->state != END && st->rid) { //Resume later (st is already attached to player). if(st->bk_st) { ShowWarning("Unable to restore stack! Double continuation!\n"); @@ -3407,16 +3980,14 @@ void run_script_main(struct script_state *st) { } else { //Dispose of script. if ((sd = map->id2sd(st->rid))!=NULL) { //Restore previous stack and save char. - if(sd->state.using_fake_npc){ + if(sd->state.using_fake_npc) { clif->clearunit_single(sd->npc_id, CLR_OUTSIGHT, sd->fd); sd->state.using_fake_npc = 0; } //Restore previous script if any. script->detach_state(st, true); - if (sd->state.reg_dirty&2) - intif->saveregistry(sd,2); - if (sd->state.reg_dirty&1) - intif->saveregistry(sd,1); + if (sd->vars_dirty) + intif->saveregistry(sd); } script->free_state(st); st = NULL; @@ -3429,7 +4000,7 @@ int script_config_read(char *cfgName) { FILE *fp; - if( !( fp = fopen(cfgName,"r") ) ){ + if( !( fp = fopen(cfgName,"r") ) ) { ShowError("File not found: %s\n", cfgName); return 1; } @@ -3458,7 +4029,7 @@ int script_config_read(char *cfgName) { else if(strcmpi(w1,"warn_func_mismatch_argtypes")==0) { script->config.warn_func_mismatch_argtypes = config_switch(w2); } - else if(strcmpi(w1,"import")==0){ + else if(strcmpi(w1,"import")==0) { script->config_read(w2); } else { @@ -3503,70 +4074,102 @@ void script_add_autobonus(const char *autobonus) /// resets a temporary character array variable to given value -void script_cleararray_pc(struct map_session_data* sd, const char* varname, void* value) -{ +void script_cleararray_pc(struct map_session_data* sd, const char* varname, void* value) { + struct script_array *sa = NULL; + struct DBMap *src = NULL; + unsigned int i, *list = NULL, size = 0; int key; - uint8 idx; - - if( not_array_variable(varname[0]) || !not_server_variable(varname[0]) ) - { - ShowError("script_cleararray_pc: Variable '%s' has invalid scope (char_id=%d).\n", varname, sd->status.char_id); - return; - } key = script->add_str(varname); - - if( is_string_variable(varname) ) - { - for( idx = 0; idx < SCRIPT_MAX_ARRAYSIZE; idx++ ) - { - pc->setregstr(sd, reference_uid(key, idx), (const char*)value); - } - } - else - { - for( idx = 0; idx < SCRIPT_MAX_ARRAYSIZE; idx++ ) - { - pc->setreg(sd, reference_uid(key, idx), (int)__64BPTRSIZE(value)); - } + + if( !(src = script->array_src(NULL,sd,varname,NULL) ) ) + return; + + if( value ) + script->array_ensure_zero(NULL,sd,reference_uid(key,0),NULL); + + if( !(sa = idb_get(src, key)) ) /* non-existent array, nothing to empty */ + return; + + size = sa->size; + list = script->array_cpy_list(sa); + + for(i = 0; i < size; i++) { + script->set_reg(NULL,sd,reference_uid(key, list[i]),varname,value,NULL); } } /// sets a temporary character array variable element idx to given value /// @param refcache Pointer to an int variable, which keeps a copy of the reference to varname and must be initialized to 0. Can be NULL if only one element is set. -void script_setarray_pc(struct map_session_data* sd, const char* varname, uint8 idx, void* value, int* refcache) -{ +void script_setarray_pc(struct map_session_data* sd, const char* varname, uint32 idx, void* value, int* refcache) { int key; - - if( not_array_variable(varname[0]) || !not_server_variable(varname[0]) ) - { - ShowError("script_setarray_pc: Variable '%s' has invalid scope (char_id=%d).\n", varname, sd->status.char_id); - return; - } - - if( idx >= SCRIPT_MAX_ARRAYSIZE ) - { - ShowError("script_setarray_pc: Variable '%s' has invalid index '%d' (char_id=%d).\n", varname, (int)idx, sd->status.char_id); + + if( idx >= SCRIPT_MAX_ARRAYSIZE ) { + ShowError("script_setarray_pc: Variable '%s' has invalid index '%u' (char_id=%d).\n", varname, idx, sd->status.char_id); return; } key = ( refcache && refcache[0] ) ? refcache[0] : script->add_str(varname); - - if( is_string_variable(varname) ) - { - pc->setregstr(sd, reference_uid(key, idx), (const char*)value); - } - else - { - pc->setreg(sd, reference_uid(key, idx), (int)__64BPTRSIZE(value)); - } - + + script->set_reg(NULL,sd,reference_uid(key, idx),varname,value,NULL); + if( refcache ) {// save to avoid repeated script->add_str calls refcache[0] = key; } } +/** + * Clears persistent variables from memory + **/ +int script_reg_destroy(DBKey key, DBData *data, va_list ap) { + struct script_reg_state *src; + + if( data->type != DB_DATA_PTR )/* got no need for those! */ + return 0; + + src = DB->data2ptr(data); + + if( src->type ) { + struct script_reg_str *p = (struct script_reg_str *)src; + + if( p->value ) + aFree(p->value); + + ers_free(pc->str_reg_ers,p); + } else { + ers_free(pc->num_reg_ers,(struct script_reg_num*)src); + } + + return 0; +} +/** + * Clears a single persistent variable + **/ +void script_reg_destroy_single(struct map_session_data *sd, int64 reg, struct script_reg_state *data) { + i64db_remove(sd->var_db, reg); + + if( data->type ) { + struct script_reg_str *p = (struct script_reg_str*)data; + + if( p->value ) + aFree(p->value); + + ers_free(pc->str_reg_ers,p); + } else { + ers_free(pc->num_reg_ers,(struct script_reg_num*)data); + } +} +unsigned int *script_array_cpy_list(struct script_array *sa) { + if( sa->size > script->generic_ui_array_size ) + script->generic_ui_array_expand(sa->size); + memcpy(script->generic_ui_array, sa->members, sizeof(unsigned int)*sa->size); + return script->generic_ui_array; +} +void script_generic_ui_array_expand (unsigned int plus) { + script->generic_ui_array_size += plus + 100; + RECREATE(script->generic_ui_array, unsigned int, script->generic_ui_array_size); +} /*========================================== * Destructor *------------------------------------------*/ @@ -3574,7 +4177,7 @@ void do_final_script(void) { int i; DBIterator *iter; struct script_state *st; - + #ifdef SCRIPT_DEBUG_HASH if (battle_config.etc_log) { @@ -3601,19 +4204,19 @@ void do_final_script(void) { for(i=0; i<SCRIPT_HASH_SIZE; i++) { fprintf(fp," hash %3d = %d\n",i,count[i]); if(min > count[i]) - min = count[i]; // minimun count of collision + min = count[i]; // minimun count of collision if(max < count[i]) - max = count[i]; // maximun count of collision + max = count[i]; // maximun count of collision if(count[i] == 0) zero++; ++count2[count[i]]; } fprintf(fp,"\n--------------------\n items : buckets\n--------------------\n"); - for( i=min; i <= max; ++i ){ + for( i=min; i <= max; ++i ) { fprintf(fp," %5d : %7d\n",i,count2[i]); mean += 1.0f*i*count2[i]/SCRIPT_HASH_SIZE; // Note: this will always result in <nr labels>/<nr buckets> } - for( i=min; i <= max; ++i ){ + for( i=min; i <= max; ++i ) { n += count2[i]; if( n*2 >= SCRIPT_HASH_SIZE ) { @@ -3631,18 +4234,18 @@ void do_final_script(void) { #endif iter = db_iterator(script->st_db); - + for( st = dbi_first(iter); dbi_exists(iter); st = dbi_next(iter) ) { script->free_state(st); } - + dbi_destroy(iter); - + mapreg->final(); script->userfunc_db->destroy(script->userfunc_db, script->db_free_code_sub); script->autobonus_db->destroy(script->autobonus_db, script->db_free_code_sub); - + if (script->str_data) aFree(script->str_data); if (script->str_buf) @@ -3654,7 +4257,7 @@ void do_final_script(void) { if( atcommand->binding_count != 0 ) aFree(atcommand->binding); - + for( i = 0; i < script->buildin_count; i++) { if( script->buildin[i] ) { aFree(script->buildin[i]); @@ -3663,7 +4266,7 @@ void do_final_script(void) { } aFree(script->buildin); - + if( script->hqs ) { for( i = 0; i < script->hqs; i++ ) { if( script->hq[i].item != NULL ) @@ -3682,31 +4285,46 @@ void do_final_script(void) { aFree(script->hqi); if( script->word_buf != NULL ) aFree(script->word_buf); - + +#ifdef ENABLE_CASE_CHECK + script->global_casecheck.clear(); + script->local_casecheck.clear(); +#endif // ENABLE_CASE_CHECK + ers_destroy(script->st_ers); ers_destroy(script->stack_ers); - + db_destroy(script->st_db); - + if( script->labels != NULL ) aFree(script->labels); + + ers_destroy(script->array_ers); + + if( script->generic_ui_array ) + aFree(script->generic_ui_array); } /*========================================== * Initialization *------------------------------------------*/ -void do_init_script(void) { +void do_init_script(bool minimal) { script->st_db = idb_alloc(DB_OPT_BASE); script->userfunc_db = strdb_alloc(DB_OPT_DUP_KEY,0); script->autobonus_db = strdb_alloc(DB_OPT_DUP_KEY,0); - script->st_ers = ers_new(sizeof(struct script_state), "script.c::st_ers", ERS_OPT_NONE); - script->stack_ers = ers_new(sizeof(struct script_stack), "script.c::script_stack", ERS_OPT_NONE); + script->st_ers = ers_new(sizeof(struct script_state), "script.c::st_ers", ERS_OPT_CLEAN|ERS_OPT_FLEX_CHUNK); + script->stack_ers = ers_new(sizeof(struct script_stack), "script.c::script_stack", ERS_OPT_NONE|ERS_OPT_FLEX_CHUNK); + script->array_ers = ers_new(sizeof(struct script_array), "script.c::array_ers", ERS_OPT_CLEAN|ERS_OPT_CLEAR); ers_chunk_size(script->st_ers, 10); ers_chunk_size(script->stack_ers, 10); - + script->parse_builtin(); script->read_constdb(); + + if (minimal) + return; + mapreg->init(); } @@ -3715,14 +4333,18 @@ int script_reload(void) { DBIterator *iter; struct script_state *st; +#ifdef ENABLE_CASE_CHECK + script->global_casecheck.clear(); +#endif // ENABLE_CASE_CHECK + iter = db_iterator(script->st_db); - + for( st = dbi_first(iter); dbi_exists(iter); st = dbi_next(iter) ) { script->free_state(st); } - + dbi_destroy(iter); - + script->userfunc_db->clear(script->userfunc_db, script->db_free_code_sub); script->label_count = 0; @@ -3734,23 +4356,31 @@ int script_reload(void) { aFree(atcommand->binding); atcommand->binding_count = 0; - + db_clear(script->st_db); - + mapreg->reload(); - - itemdb->force_name_constants(); - + + itemdb->name_constants(); + return 0; } +/* returns name of current function being run, from within the stack [Ind/Hercules] */ +const char *script_getfuncname(struct script_state *st) { + struct script_data *data; + + data = &st->stack->stack_data[st->start]; + + if( data->type == C_NAME && script->str_data[data->u.num].type == C_FUNC ) + return script->get_str(script_getvarid(data->u.num)); + + return NULL; +} //----------------------------------------------------------------------------- // buildin functions // -#define BUILDIN_DEF(x,args) { buildin_ ## x , #x , args } -#define BUILDIN_DEF2(x,x2,args) { buildin_ ## x , x2 , args } - ///////////////////////////////////////////////////////////////////// // NPC interaction // @@ -3763,18 +4393,18 @@ BUILDIN(mes) { TBL_PC* sd = script->rid2sd(st); if( sd == NULL ) return true; - + if( !script_hasdata(st, 3) ) {// only a single line detected in the script clif->scriptmes(sd, st->oid, script_getstr(st, 2)); } else {// parse multiple lines as they exist int i; - + for( i = 2; script_hasdata(st, i); i++ ) { // send the message to the client clif->scriptmes(sd, st->oid, script_getstr(st, i)); } } - + return true; } @@ -3785,7 +4415,7 @@ BUILDIN(mes) { BUILDIN(next) { TBL_PC* sd; - + sd = script->rid2sd(st); if( sd == NULL ) return true; @@ -3803,11 +4433,11 @@ BUILDIN(next) /// close; BUILDIN(close) { TBL_PC* sd; - + sd = script->rid2sd(st); if( sd == NULL ) return true; - + st->state = sd->state.dialog == 1 ? CLOSE : END; clif->scriptclose(sd, st->oid); return true; @@ -3819,11 +4449,11 @@ BUILDIN(close) { /// close2; BUILDIN(close2) { TBL_PC* sd; - + sd = script->rid2sd(st); if( sd == NULL ) return true; - + if( sd->state.dialog == 1 ) st->state = STOP; else { @@ -3842,11 +4472,11 @@ int menu_countoptions(const char* str, int max_count, int* total) { int count = 0; int bogus_total; - + if( total == NULL ) total = &bogus_total; ++(*total); - + // initial empty options while( *str == ':' ) { @@ -3892,35 +4522,35 @@ BUILDIN(menu) int i; const char* text; TBL_PC* sd; - + sd = script->rid2sd(st); if( sd == NULL ) return true; - + #ifdef SECURE_NPCTIMEOUT sd->npc_idle_type = NPCT_MENU; #endif - + // TODO detect multiple scripts waiting for input at the same time, and what to do when that happens if( sd->state.menu_or_input == 0 ) { struct StringBuf buf; struct script_data* data; - + if( script_lastdata(st) % 2 == 0 ) {// argument count is not even (1st argument is at index 2) ShowError("script:menu: illegal number of arguments (%d).\n", (script_lastdata(st) - 1)); st->state = END; return false; } - + StrBuf->Init(&buf); sd->npc_menu = 0; for( i = 2; i < script_lastdata(st); i += 2 ) { // menu options text = script_getstr(st, i); - + // target label data = script_getdata(st, i+1); if( !data_islabel(data) ) @@ -3931,7 +4561,7 @@ BUILDIN(menu) st->state = END; return false; } - + // append option(s) if( text[0] == '\0' ) continue;// empty string, ignore @@ -3942,10 +4572,8 @@ BUILDIN(menu) } st->state = RERUNLINE; sd->state.menu_or_input = 1; - - /** - * menus beyond this length crash the client (see bugreport:6402) - **/ + + /* menus beyond this length crash the client (see bugreport:6402) */ if( StrBuf->Length(&buf) >= 2047 ) { struct npc_data * nd = map->id2nd(st->oid); char* menu; @@ -3956,9 +4584,9 @@ BUILDIN(menu) aFree(menu); } else clif->scriptmenu(sd, st->oid, StrBuf->Value(&buf)); - + StrBuf->Destroy(&buf); - + if( sd->npc_menu >= 0xff ) {// client supports only up to 254 entries; 0 is not used and 255 is reserved for cancel; excess entries are displayed but cause 'uint8' overflow ShowWarning("buildin_menu: Too many options specified (current=%d, max=254).\n", sd->npc_menu); @@ -3973,7 +4601,7 @@ BUILDIN(menu) else {// goto target label int menu = 0; - + sd->state.menu_or_input = 0; if( sd->npc_menu <= 0 ) { @@ -3981,7 +4609,7 @@ BUILDIN(menu) st->state = END; return false; } - + // get target label for( i = 2; i < script_lastdata(st); i += 2 ) { @@ -4021,36 +4649,34 @@ BUILDIN(select) int i; const char* text; TBL_PC* sd; - + sd = script->rid2sd(st); if( sd == NULL ) return true; - + #ifdef SECURE_NPCTIMEOUT sd->npc_idle_type = NPCT_MENU; #endif - + if( sd->state.menu_or_input == 0 ) { struct StringBuf buf; - + StrBuf->Init(&buf); sd->npc_menu = 0; for( i = 2; i <= script_lastdata(st); ++i ) { text = script_getstr(st, i); - + if( sd->npc_menu > 0 ) StrBuf->AppendStr(&buf, ":"); - + StrBuf->AppendStr(&buf, text); sd->npc_menu += script->menu_countoptions(text, 0, NULL); } - + st->state = RERUNLINE; sd->state.menu_or_input = 1; - - /** - * menus beyond this length crash the client (see bugreport:6402) - **/ + + /* menus beyond this length crash the client (see bugreport:6402) */ if( StrBuf->Length(&buf) >= 2047 ) { struct npc_data * nd = map->id2nd(st->oid); char* menu; @@ -4062,7 +4688,7 @@ BUILDIN(select) } else clif->scriptmenu(sd, st->oid, StrBuf->Value(&buf)); StrBuf->Destroy(&buf); - + if( sd->npc_menu >= 0xff ) { ShowWarning("buildin_select: Too many options specified (current=%d, max=254).\n", sd->npc_menu); script->reportsrc(st); @@ -4072,7 +4698,7 @@ BUILDIN(select) st->state = END; } else {// return selected option int menu = 0; - + sd->state.menu_or_input = 0; for( i = 2; i <= script_lastdata(st); ++i ) { text = script_getstr(st, i); @@ -4100,19 +4726,19 @@ BUILDIN(prompt) int i; const char *text; TBL_PC* sd; - + sd = script->rid2sd(st); if( sd == NULL ) return true; - + #ifdef SECURE_NPCTIMEOUT sd->npc_idle_type = NPCT_MENU; #endif - + if( sd->state.menu_or_input == 0 ) { struct StringBuf buf; - + StrBuf->Init(&buf); sd->npc_menu = 0; for( i = 2; i <= script_lastdata(st); ++i ) @@ -4123,13 +4749,11 @@ BUILDIN(prompt) StrBuf->AppendStr(&buf, text); sd->npc_menu += script->menu_countoptions(text, 0, NULL); } - + st->state = RERUNLINE; sd->state.menu_or_input = 1; - - /** - * menus beyond this length crash the client (see bugreport:6402) - **/ + + /* menus beyond this length crash the client (see bugreport:6402) */ if( StrBuf->Length(&buf) >= 2047 ) { struct npc_data * nd = map->id2nd(st->oid); char* menu; @@ -4141,7 +4765,7 @@ BUILDIN(prompt) } else clif->scriptmenu(sd, st->oid, StrBuf->Value(&buf)); StrBuf->Destroy(&buf); - + if( sd->npc_menu >= 0xff ) { ShowWarning("buildin_prompt: Too many options specified (current=%d, max=254).\n", sd->npc_menu); @@ -4158,7 +4782,7 @@ BUILDIN(prompt) else {// return selected option int menu = 0; - + sd->state.menu_or_input = 0; for( i = 2; i <= script_lastdata(st); ++i ) { @@ -4190,7 +4814,7 @@ BUILDIN(goto) st->state = END; return false; } - + st->pos = script_getnum(st,2); st->state = GOTO; return true; @@ -4206,7 +4830,7 @@ BUILDIN(callfunc) struct script_code* scr; const char* str = script_getstr(st,2); DBMap **ref = NULL; - + scr = (struct script_code*)strdb_get(script->userfunc_db, str); if( !scr ) { @@ -4214,7 +4838,7 @@ BUILDIN(callfunc) st->state = END; return false; } - + for( i = st->start+3, j = 0; i < st->end; i++, j++ ) { struct script_data* data = script->push_copy(st->stack,i); @@ -4223,14 +4847,23 @@ BUILDIN(callfunc) const char* name = reference_getname(data); if( name[0] == '.' ) { if( !ref ) { - ref = (struct DBMap**)aCalloc(sizeof(struct DBMap*), 1); + ref = (struct DBMap**)aCalloc(sizeof(struct DBMap*), 2); ref[0] = (name[1] == '@' ? st->stack->var_function : st->script->script_vars); + if( name[1] == '@' ) { + if( !st->stack->array_function_db ) + st->stack->array_function_db = idb_alloc(DB_OPT_BASE); + ref[1] = st->stack->array_function_db; + } else { + if( !st->script->script_arrays_db ) + st->script->script_arrays_db = idb_alloc(DB_OPT_BASE); + ref[1] = st->script->script_arrays_db; + } } data->ref = ref; } } } - + CREATE(ri, struct script_retinfo, 1); ri->script = st->script;// script code ri->var_function = st->stack->var_function;// scope variables @@ -4238,13 +4871,13 @@ BUILDIN(callfunc) ri->nargs = j;// argument count ri->defsp = st->stack->defsp;// default stack pointer script->push_retinfo(st->stack, ri, ref); - + st->pos = 0; st->script = scr; st->stack->defsp = st->stack->sp; st->state = GOTO; - st->stack->var_function = idb_alloc(DB_OPT_RELEASE_DATA); - + st->stack->var_function = i64db_alloc(DB_OPT_RELEASE_DATA); + return true; } /*========================================== @@ -4256,7 +4889,7 @@ BUILDIN(callsub) struct script_retinfo* ri; int pos = script_getnum(st,2); DBMap **ref = NULL; - + if( !data_islabel(script_getdata(st,2)) && !data_isfunclabel(script_getdata(st,2)) ) { ShowError("script:callsub: argument is not a label\n"); @@ -4264,7 +4897,7 @@ BUILDIN(callsub) st->state = END; return false; } - + for( i = st->start+3, j = 0; i < st->end; i++, j++ ) { struct script_data* data = script->push_copy(st->stack,i); @@ -4273,14 +4906,17 @@ BUILDIN(callsub) const char* name = reference_getname(data); if( name[0] == '.' && name[1] == '@' ) { if ( !ref ) { - ref = (struct DBMap**)aCalloc(sizeof(struct DBMap*), 1); + ref = (struct DBMap**)aCalloc(sizeof(struct DBMap*), 2); ref[0] = st->stack->var_function; + if( !st->stack->array_function_db ) + st->stack->array_function_db = idb_alloc(DB_OPT_BASE); + ref[1] = st->stack->array_function_db; } data->ref = ref; } } } - + CREATE(ri, struct script_retinfo, 1); ri->script = st->script;// script code ri->var_function = st->stack->var_function;// scope variables @@ -4288,12 +4924,12 @@ BUILDIN(callsub) ri->nargs = j;// argument count ri->defsp = st->stack->defsp;// default stack pointer script->push_retinfo(st->stack, ri, ref); - + st->pos = pos; st->stack->defsp = st->stack->sp; st->state = GOTO; - st->stack->var_function = idb_alloc(DB_OPT_RELEASE_DATA); - + st->stack->var_function = i64db_alloc(DB_OPT_RELEASE_DATA); + return true; } @@ -4305,7 +4941,7 @@ BUILDIN(getarg) { struct script_retinfo* ri; int idx; - + if( st->stack->defsp < 1 || st->stack->stack_data[st->stack->defsp - 1].type != C_RETINFO ) { ShowError("script:getarg: no callfunc or callsub!\n"); @@ -4313,9 +4949,9 @@ BUILDIN(getarg) return false; } ri = st->stack->stack_data[st->stack->defsp - 1].u.ri; - + idx = script_getnum(st,2); - + if( idx >= 0 && idx < ri->nargs ) script->push_copy(st->stack, st->stack->defsp - 1 - ri->nargs + idx); else if( script_hasdata(st,3) ) @@ -4326,7 +4962,7 @@ BUILDIN(getarg) st->state = END; return false; } - + return true; } @@ -4347,12 +4983,16 @@ BUILDIN(return) const char* name = reference_getname(data); if( name[0] == '.' && name[1] == '@' ) {// scope variable - if( !data->ref || data->ref == (DBMap**)&st->stack->var_function ) + if( !data->ref || data->ref[0] == st->stack->var_function ) script->get_val(st, data);// current scope, convert to value } else if( name[0] == '.' && !data->ref ) {// script variable, link to current script - data->ref = &st->script->script_vars; + data->ref = (struct DBMap**)aCalloc(sizeof(struct DBMap*), 2); + data->ref[0] = st->script->script_vars; + if( !st->script->script_arrays_db ) + st->script->script_arrays_db = idb_alloc(DB_OPT_BASE); + data->ref[1] = st->script->script_arrays_db; } } } @@ -4374,7 +5014,7 @@ BUILDIN(rand) int range; int min; int max; - + if( script_hasdata(st,3) ) {// min,max min = script_getnum(st,2); @@ -4392,7 +5032,7 @@ BUILDIN(rand) script_pushint(st, min); else script_pushint(st, rnd()%range + min); - + return true; } @@ -4405,27 +5045,27 @@ BUILDIN(warp) int x,y; const char* str; TBL_PC* sd; - + sd = script->rid2sd(st); if( sd == NULL ) return true; - + str = script_getstr(st,2); x = script_getnum(st,3); y = script_getnum(st,4); - + if(strcmp(str,"Random")==0) ret = pc->randomwarp(sd,CLR_TELEPORT); else if(strcmp(str,"SavePoint")==0 || strcmp(str,"Save")==0) ret = pc->setpos(sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT); else - ret = pc->setpos(sd,mapindex_name2id(str),x,y,CLR_OUTSIGHT); - + ret = pc->setpos(sd,mapindex->name2id(str),x,y,CLR_OUTSIGHT); + if( ret ) { ShowError("buildin_warp: moving player '%s' to \"%s\",%d,%d failed.\n", sd->status.name, str, x, y); script->reportsrc(st); } - + return true; } /*========================================== @@ -4435,29 +5075,29 @@ int buildin_areawarp_sub(struct block_list *bl,va_list ap) { int x2,y2,x3,y3; unsigned int index; - + index = va_arg(ap,unsigned int); x2 = va_arg(ap,int); y2 = va_arg(ap,int); x3 = va_arg(ap,int); y3 = va_arg(ap,int); - + if(index == 0) pc->randomwarp((TBL_PC *)bl,CLR_TELEPORT); else if(x3 && y3) { int max, tx, ty, j = 0; - + // choose a suitable max number of attempts if( (max = (y3-y2+1)*(x3-x2+1)*3) > 1000 ) max = 1000; - + // find a suitable map cell do { tx = rnd()%(x3-x2+1)+x2; ty = rnd()%(y3-y2+1)+y2; j++; } while( map->getcell(index,tx,ty,CELL_CHKNOPASS) && j < max ); - + pc->setpos((TBL_PC *)bl,index,tx,ty,CLR_OUTSIGHT); } else @@ -4470,7 +5110,7 @@ BUILDIN(areawarp) unsigned int index; const char *str; const char *mapname; - + mapname = script_getstr(st,2); x0 = script_getnum(st,3); y0 = script_getnum(st,4); @@ -4479,9 +5119,9 @@ BUILDIN(areawarp) str = script_getstr(st,7); x2 = script_getnum(st,8); y2 = script_getnum(st,9); - + if( script_hasdata(st,10) && script_hasdata(st,11) ) { // Warp area to area - if( (x3 = script_getnum(st,10)) < 0 || (y3 = script_getnum(st,11)) < 0 ){ + if( (x3 = script_getnum(st,10)) < 0 || (y3 = script_getnum(st,11)) < 0 ) { x3 = 0; y3 = 0; } else if( x3 && y3 ) { @@ -4490,15 +5130,15 @@ BUILDIN(areawarp) if( y3 < y2 ) swap(y3,y2); } } - + if( (m = map->mapname2mapid(mapname)) < 0 ) return true; - + if( strcmp(str,"Random") == 0 ) index = 0; - else if( !(index=mapindex_name2id(str)) ) + else if( !(index=mapindex->name2id(str)) ) return true; - + map->foreachinarea(script->buildin_areawarp_sub, m,x0,y0,x1,y1, BL_PC, index,x2,y2,x3,y3); return true; } @@ -4518,7 +5158,7 @@ BUILDIN(areapercentheal) { int hp,sp,m; const char *mapname; int x0,y0,x1,y1; - + mapname=script_getstr(st,2); x0=script_getnum(st,3); y0=script_getnum(st,4); @@ -4526,10 +5166,10 @@ BUILDIN(areapercentheal) { y1=script_getnum(st,6); hp=script_getnum(st,7); sp=script_getnum(st,8); - + if( (m=map->mapname2mapid(mapname))< 0) return true; - + map->foreachinarea(script->buildin_areapercentheal_sub,m,x0,y0,x1,y1,BL_PC,hp,sp); return true; } @@ -4544,24 +5184,24 @@ BUILDIN(warpchar) { int x,y,a; const char *str; TBL_PC *sd; - + str=script_getstr(st,2); x=script_getnum(st,3); y=script_getnum(st,4); a=script_getnum(st,5); - + sd = map->charid2sd(a); if( sd == NULL ) return true; - + if(strcmp(str, "Random") == 0) pc->randomwarp(sd, CLR_TELEPORT); else if(strcmp(str, "SavePoint") == 0) pc->setpos(sd, sd->status.save_point.map,sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT); else - pc->setpos(sd, mapindex_name2id(str), x, y, CLR_TELEPORT); - + pc->setpos(sd, mapindex->name2id(str), x, y, CLR_TELEPORT); + return true; } /*========================================== @@ -4575,9 +5215,9 @@ BUILDIN(warpparty) TBL_PC *pl_sd; struct party_data* p; int type; - int mapindex; + int map_index; int i; - + const char* str = script_getstr(st,2); int x = script_getnum(st,3); int y = script_getnum(st,4); @@ -4585,17 +5225,17 @@ BUILDIN(warpparty) const char* str2 = NULL; if ( script_hasdata(st,6) ) str2 = script_getstr(st,6); - + p = party->search(p_id); if(!p) return true; - + type = ( strcmp(str,"Random")==0 ) ? 0 : ( strcmp(str,"SavePointAll")==0 ) ? 1 : ( strcmp(str,"SavePoint")==0 ) ? 2 : ( strcmp(str,"Leader")==0 ) ? 3 : 4; - + switch (type) { case 3: @@ -4603,32 +5243,32 @@ BUILDIN(warpparty) if (i == MAX_PARTY || !p->data[i].sd) //Leader not found / not online return true; pl_sd = p->data[i].sd; - mapindex = pl_sd->mapindex; + map_index = pl_sd->mapindex; x = pl_sd->bl.x; y = pl_sd->bl.y; break; case 4: - mapindex = mapindex_name2id(str); + map_index = mapindex->name2id(str); break; case 2: //"SavePoint" uses save point of the currently attached player if (( sd = script->rid2sd(st) ) == NULL ) return true; default: - mapindex = 0; + map_index = 0; break; } - + for (i = 0; i < MAX_PARTY; i++) { if( !(pl_sd = p->data[i].sd) || pl_sd->status.party_id != p_id ) continue; - + if( str2 && strcmp(str2, map->list[pl_sd->bl.m].name) != 0 ) continue; - + if( pc_isdead(pl_sd) ) continue; - + switch( type ) { case 0: // Random @@ -4646,11 +5286,11 @@ BUILDIN(warpparty) case 3: // Leader case 4: // m,x,y if(!map->list[pl_sd->bl.m].flag.noreturn && !map->list[pl_sd->bl.m].flag.nowarp) - pc->setpos(pl_sd,mapindex,x,y,CLR_TELEPORT); + pc->setpos(pl_sd,map_index,x,y,CLR_TELEPORT); break; } } - + return true; } /*========================================== @@ -4664,32 +5304,32 @@ BUILDIN(warpguild) struct guild* g; struct s_mapiterator* iter; int type; - + const char* str = script_getstr(st,2); int x = script_getnum(st,3); int y = script_getnum(st,4); int gid = script_getnum(st,5); - + g = guild->search(gid); if( g == NULL ) return true; - + type = ( strcmp(str,"Random")==0 ) ? 0 : ( strcmp(str,"SavePointAll")==0 ) ? 1 : ( strcmp(str,"SavePoint")==0 ) ? 2 : 3; - + if( type == 2 && ( sd = script->rid2sd(st) ) == NULL ) {// "SavePoint" uses save point of the currently attached player return true; } - + iter = mapit_getallusers(); for( pl_sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); pl_sd = (TBL_PC*)mapit->next(iter) ) { if( pl_sd->status.guild_id != gid ) continue; - + switch( type ) { case 0: // Random @@ -4706,12 +5346,12 @@ BUILDIN(warpguild) break; case 3: // m,x,y if(!map->list[pl_sd->bl.m].flag.noreturn && !map->list[pl_sd->bl.m].flag.nowarp) - pc->setpos(pl_sd,mapindex_name2id(str),x,y,CLR_TELEPORT); + pc->setpos(pl_sd,mapindex->name2id(str),x,y,CLR_TELEPORT); break; } } mapit->free(iter); - + return true; } /*========================================== @@ -4720,10 +5360,10 @@ BUILDIN(warpguild) BUILDIN(heal) { TBL_PC *sd; int hp,sp; - + sd = script->rid2sd(st); if (!sd) return true; - + hp=script_getnum(st,2); sp=script_getnum(st,3); status->heal(&sd->bl, hp, sp, 1); @@ -4736,16 +5376,16 @@ BUILDIN(itemheal) { TBL_PC *sd; int hp,sp; - + hp=script_getnum(st,2); sp=script_getnum(st,3); - + if(script->potion_flag==1) { script->potion_hp = hp; script->potion_sp = sp; return true; } - + sd = script->rid2sd(st); if (!sd) return true; pc->itemheal(sd,sd->itemid,hp,sp); @@ -4758,16 +5398,16 @@ BUILDIN(percentheal) { int hp,sp; TBL_PC* sd; - + hp=script_getnum(st,2); sp=script_getnum(st,3); - + if(script->potion_flag==1) { script->potion_per_hp = hp; script->potion_per_sp = sp; return true; } - + sd = script->rid2sd(st); if( sd == NULL ) return true; @@ -4785,22 +5425,22 @@ BUILDIN(percentheal) BUILDIN(jobchange) { int job, upper=-1; - + job=script_getnum(st,2); if( script_hasdata(st,3) ) upper=script_getnum(st,3); - + if (pcdb_checkid(job)) { TBL_PC* sd; - + sd = script->rid2sd(st); if( sd == NULL ) return true; - + pc->jobchange(sd, job, upper); } - + return true; } @@ -4825,17 +5465,17 @@ BUILDIN(input) { TBL_PC* sd; struct script_data* data; - int uid; + int64 uid; const char* name; int min; int max; - + sd = script->rid2sd(st); if( sd == NULL ) return true; - + data = script_getdata(st,2); - if( !data_isreference(data) ){ + if( !data_isreference(data) ) { ShowError("script:input: not a variable\n"); script->reportdata(data); st->state = END; @@ -4845,22 +5485,21 @@ BUILDIN(input) name = reference_getname(data); min = (script_hasdata(st,3) ? script_getnum(st,3) : script->config.input_min_value); max = (script_hasdata(st,4) ? script_getnum(st,4) : script->config.input_max_value); - + #ifdef SECURE_NPCTIMEOUT sd->npc_idle_type = NPCT_WAIT; #endif - - if( !sd->state.menu_or_input ) - { // first invocation, display npc input box + + if( !sd->state.menu_or_input ) { + // first invocation, display npc input box sd->state.menu_or_input = 1; st->state = RERUNLINE; if( is_string_variable(name) ) clif->scriptinputstr(sd,st->oid); else clif->scriptinput(sd,st->oid); - } - else - { // take received text/value and store it in the designated variable + } else { + // take received text/value and store it in the designated variable sd->state.menu_or_input = 0; if( is_string_variable(name) ) { @@ -4886,75 +5525,81 @@ BUILDIN(copyarray); /// The value is converted to the type of the variable. /// /// set(<variable>,<value>) -> <variable> -BUILDIN(set) -{ +BUILDIN(setr) { TBL_PC* sd = NULL; struct script_data* data; //struct script_data* datavalue; - int num; + int64 num; const char* name; char prefix; - + data = script_getdata(st,2); //datavalue = script_getdata(st,3); - if( !data_isreference(data) ) - { + if( !data_isreference(data) || reference_toconstant(data) ) { ShowError("script:set: not a variable\n"); script->reportdata(script_getdata(st,2)); st->state = END; return false; } - + num = reference_getuid(data); name = reference_getname(data); prefix = *name; - - if( not_server_variable(prefix) ) - { + + if( not_server_variable(prefix) ) { sd = script->rid2sd(st); - if( sd == NULL ) - { + if( sd == NULL ) { ShowError("script:set: no player attached for player variable '%s'\n", name); return true; } } - + #if 0 - if( data_isreference(datavalue) ) - {// the value being referenced is a variable + // TODO: see de43fa0f73be01080bd11c08adbfb7c158324c81 + if( data_isreference(datavalue) ) { + // the value being referenced is a variable const char* namevalue = reference_getname(datavalue); - - if( !not_array_variable(*namevalue) ) - {// array variable being copied into another array variable - if( sd == NULL && not_server_variable(*namevalue) && !(sd = script->rid2sd(st)) ) - {// player must be attached in order to copy a player variable + + if( !not_array_variable(*namevalue) ) { + // array variable being copied into another array variable + if( sd == NULL && not_server_variable(*namevalue) && !(sd = script->rid2sd(st)) ) { + // player must be attached in order to copy a player variable ShowError("script:set: no player attached for player variable '%s'\n", namevalue); return true; } - - if( is_string_variable(namevalue) != is_string_variable(name) ) - {// non-matching array value types + + if( is_string_variable(namevalue) != is_string_variable(name) ) { + // non-matching array value types ShowWarning("script:set: two array variables do not match in type.\n"); return true; } - + // push the maximum number of array values to the stack script->push_val(st->stack, C_INT, SCRIPT_MAX_ARRAYSIZE,NULL); - + // call the copy array method directly return buildin_copyarray(st); } } #endif - + + if( script_hasdata(st, 4) ) { + // Optional argument used by post-increment/post-decrement constructs to return the previous value + if( is_string_variable(name) ) { + script_pushstrcopy(st, script_getstr(st, 4)); + } else { + script_pushint(st, script_getnum(st, 4)); + } + } else { + // return a copy of the variable reference + script_pushcopy(st,2); + } + if( is_string_variable(name) ) script->set_reg(st,sd,num,name,(void*)script_getstr(st,3),script_getref(st,2)); else script->set_reg(st,sd,num,name,(void*)__64BPTRSIZE(script_getnum(st,3)),script_getref(st,2)); - - // return a copy of the variable reference - script_pushcopy(st,2); - + return true; } @@ -4962,34 +5607,6 @@ BUILDIN(set) /// Array variables /// -/// Returns the size of the specified array -int32 getarraysize(struct script_state* st, int32 id, int32 idx, int isstring, struct DBMap** ref) -{ - int32 ret = idx; - - if( isstring ) - { - for( ; idx < SCRIPT_MAX_ARRAYSIZE; ++idx ) - { - char* str = (char*)script->get_val2(st, reference_uid(id, idx), ref); - if( str && *str ) - ret = idx + 1; - script_removetop(st, -1, 0); - } - } - else - { - for( ; idx < SCRIPT_MAX_ARRAYSIZE; ++idx ) - { - int32 num = (int32)__64BPTRSIZE(script->get_val2(st, reference_uid(id, idx), ref)); - if( num ) - ret = idx + 1; - script_removetop(st, -1, 0); - } - } - return ret; -} - /// Sets values of an array, from the starting index. /// ex: setarray arr[1],1,2,3; /// @@ -4998,43 +5615,36 @@ BUILDIN(setarray) { struct script_data* data; const char* name; - int32 start; - int32 end; + uint32 start; + uint32 end; int32 id; int32 i; TBL_PC* sd = NULL; - + data = script_getdata(st, 2); - if( !data_isreference(data) ) + if( !data_isreference(data) || reference_toconstant(data) ) { ShowError("script:setarray: not a variable\n"); script->reportdata(data); st->state = END; return false;// not a variable } - + id = reference_getid(data); start = reference_getindex(data); name = reference_getname(data); - if( not_array_variable(*name) ) - { - ShowError("script:setarray: illegal scope\n"); - script->reportdata(data); - st->state = END; - return false;// not supported - } - + if( not_server_variable(*name) ) { sd = script->rid2sd(st); if( sd == NULL ) return true;// no player attached } - + end = start + script_lastdata(st) - 2; if( end > SCRIPT_MAX_ARRAYSIZE ) end = SCRIPT_MAX_ARRAYSIZE; - + if( is_string_variable(name) ) {// string array for( i = 3; start < end; ++start, ++i ) @@ -5056,12 +5666,12 @@ BUILDIN(cleararray) { struct script_data* data; const char* name; - int32 start; - int32 end; + uint32 start; + uint32 end; int32 id; void* v; TBL_PC* sd = NULL; - + data = script_getdata(st, 2); if( !data_isreference(data) ) { @@ -5070,34 +5680,27 @@ BUILDIN(cleararray) st->state = END; return false;// not a variable } - + id = reference_getid(data); start = reference_getindex(data); name = reference_getname(data); - if( not_array_variable(*name) ) - { - ShowError("script:cleararray: illegal scope\n"); - script->reportdata(data); - st->state = END; - return false;// not supported - } - + if( not_server_variable(*name) ) { sd = script->rid2sd(st); if( sd == NULL ) return true;// no player attached } - + if( is_string_variable(name) ) v = (void*)script_getstr(st, 3); else v = (void*)__64BPTRSIZE(script_getnum(st, 3)); - + end = start + script_getnum(st, 4); if( end > SCRIPT_MAX_ARRAYSIZE ) end = SCRIPT_MAX_ARRAYSIZE; - + for( ; start < end; ++start ) script->set_reg(st, sd, reference_uid(id, start), name, v, script_getref(st,2)); return true; @@ -5119,9 +5722,9 @@ BUILDIN(copyarray) int32 id2; void* v; int32 i; - int32 count; + uint32 count; TBL_PC* sd = NULL; - + data1 = script_getdata(st, 2); data2 = script_getdata(st, 3); if( !data_isreference(data1) || !data_isreference(data2) ) @@ -5132,22 +5735,14 @@ BUILDIN(copyarray) st->state = END; return false;// not a variable } - + id1 = reference_getid(data1); id2 = reference_getid(data2); idx1 = reference_getindex(data1); idx2 = reference_getindex(data2); name1 = reference_getname(data1); name2 = reference_getname(data2); - if( not_array_variable(*name1) || not_array_variable(*name2) ) - { - ShowError("script:copyarray: illegal scope\n"); - script->reportdata(data1); - script->reportdata(data2); - st->state = END; - return false;// not supported - } - + if( is_string_variable(name1) != is_string_variable(name2) ) { ShowError("script:copyarray: type mismatch\n"); @@ -5156,20 +5751,20 @@ BUILDIN(copyarray) st->state = END; return false;// data type mismatch } - + if( not_server_variable(*name1) || not_server_variable(*name2) ) { sd = script->rid2sd(st); if( sd == NULL ) return true;// no player attached } - + count = script_getnum(st, 4); if( count > SCRIPT_MAX_ARRAYSIZE - idx1 ) count = SCRIPT_MAX_ARRAYSIZE - idx1; if( count <= 0 || (id1 == id2 && idx1 == idx2) ) return true;// nothing to copy - + if( id1 == id2 && idx1 > idx2 ) {// destination might be overlapping the source - copy in reverse order for( i = count - 1; i >= 0; --i ) @@ -5204,8 +5799,7 @@ BUILDIN(copyarray) BUILDIN(getarraysize) { struct script_data* data; - const char* name; - + data = script_getdata(st, 2); if( !data_isreference(data) ) { @@ -5215,20 +5809,13 @@ BUILDIN(getarraysize) st->state = END; return false;// not a variable } - - name = reference_getname(data); - if( not_array_variable(*name) ) - { - ShowError("script:getarraysize: illegal scope\n"); - script->reportdata(data); - script_pushnil(st); - st->state = END; - return false;// not supported - } - - script_pushint(st, script->getarraysize(st, reference_getid(data), reference_getindex(data), is_string_variable(name), reference_getref(data))); + + script_pushint(st, script->array_highest_key(st,st->rid ? script->rid2sd(st) : NULL,reference_getname(data),reference_getref(data))); return true; } +int script_array_index_cmp(const void *a, const void *b) { + return ( *(unsigned int*)a - *(unsigned int*)b ); +} /// Deletes count or all the elements in an array, from the starting index. /// ex: deletearray arr[4],2; @@ -5239,11 +5826,13 @@ BUILDIN(deletearray) { struct script_data* data; const char* name; - int start; - int end; + unsigned int start, end, i; int id; TBL_PC *sd = NULL; - + struct script_array *sa = NULL; + struct DBMap *src = NULL; + void *value; + data = script_getdata(st, 2); if( !data_isreference(data) ) { @@ -5252,58 +5841,94 @@ BUILDIN(deletearray) st->state = END; return false;// not a variable } - + id = reference_getid(data); start = reference_getindex(data); name = reference_getname(data); - if( not_array_variable(*name) ) - { - ShowError("script:deletearray: illegal scope\n"); - script->reportdata(data); - st->state = END; - return false;// not supported - } - + if( not_server_variable(*name) ) { sd = script->rid2sd(st); if( sd == NULL ) return true;// no player attached } + + if( !(src = script->array_src(st,sd,name, reference_getref(data)) ) ) { + ShowError("script:deletearray: not a array\n"); + script->reportdata(data); + st->state = END; + return false;// not a variable + } + + script->array_ensure_zero(st,NULL,data->u.num,reference_getref(data)); - end = SCRIPT_MAX_ARRAYSIZE; + if ( !(sa = idb_get(src, id)) ) { /* non-existent array, nothing to empty */ + return true;// not a variable + } + + end = script->array_highest_key(st,sd,name,reference_getref(data)); if( start >= end ) return true;// nothing to free + + if( is_string_variable(name) ) + value = (void *)""; + else + value = (void *)0; - if( script_hasdata(st,3) ) - { - int count = script_getnum(st, 3); + if( script_hasdata(st,3) ) { + unsigned int count = script_getnum(st, 3); if( count > end - start ) count = end - start; if( count <= 0 ) return true;// nothing to free + + if( end - start < sa->size ) { + // Better to iterate directly on the array, no speed-up from using sa + for( ; start + count < end; ++start ) { + // Compact and overwrite + void* v = script->get_val2(st, reference_uid(id, start + count), reference_getref(data)); + script->set_reg(st, sd, reference_uid(id, start), name, v, reference_getref(data)); + script_removetop(st, -1, 0); + } + for( ; start < end; start++ ) { + // Clean up any leftovers that weren't overwritten + script->set_reg(st, sd, reference_uid(id, start), name, value, reference_getref(data)); + } + } else { + // using sa to speed up + unsigned int *list = NULL, size = 0; + list = script->array_cpy_list(sa); + size = sa->size; + qsort(list, size, sizeof(unsigned int), script_array_index_cmp); + + ARR_FIND(0, size, i, list[i] >= start); + + for( ; i < size && list[i] < start + count; i++ ) { + // Clear any entries between start and start+count, if they exist + script->set_reg(st, sd, reference_uid(id, list[i]), name, value, reference_getref(data)); + } + + for( ; i < size && list[i] < end; i++ ) { + // Move back count positions any entries between start+count to fill the gaps + void* v = script->get_val2(st, reference_uid(id, list[i]), reference_getref(data)); + script->set_reg(st, sd, reference_uid(id, list[i]-count), name, v, reference_getref(data)); + script_removetop(st, -1, 0); + // Clear their originals + script->set_reg(st, sd, reference_uid(id, list[i]), name, value, reference_getref(data)); + } + } + } else { + unsigned int *list = NULL, size = 0; + list = script->array_cpy_list(sa); + size = sa->size; - // move rest of the elements backward - for( ; start + count < end; ++start ) - { - void* v = script->get_val2(st, reference_uid(id, start + count), reference_getref(data)); - script->set_reg(st, sd, reference_uid(id, start), name, v, reference_getref(data)); - script_removetop(st, -1, 0); + for(i = 0; i < size; i++) { + if( list[i] >= start ) // Less expensive than sorting it, most likely + script->set_reg(st, sd, reference_uid(id, list[i]), name, value, reference_getref(data)); } } - - // clear the rest of the array - if( is_string_variable(name) ) - { - for( ; start < end; ++start ) - script->set_reg(st, sd, reference_uid(id, start), name, (void *)"", reference_getref(data)); - } - else - { - for( ; start < end; ++start ) - script->set_reg(st, sd, reference_uid(id, start), name, (void*)0, reference_getref(data)); - } + return true; } @@ -5314,10 +5939,9 @@ BUILDIN(deletearray) BUILDIN(getelementofarray) { struct script_data* data; - const char* name; int32 id; - int i; - + int64 i; + data = script_getdata(st, 2); if( !data_isreference(data) ) { @@ -5327,29 +5951,20 @@ BUILDIN(getelementofarray) st->state = END; return false;// not a variable } - + id = reference_getid(data); - name = reference_getname(data); - if( not_array_variable(*name) ) - { - ShowError("script:getelementofarray: illegal scope\n"); - script->reportdata(data); - script_pushnil(st); - st->state = END; - return false;// not supported - } - + i = script_getnum(st, 3); if( i < 0 || i >= SCRIPT_MAX_ARRAYSIZE ) { - ShowWarning("script:getelementofarray: index out of range (%d)\n", i); + ShowWarning("script:getelementofarray: index out of range (%lld)\n", i); script->reportdata(data); script_pushnil(st); st->state = END; return false;// out of range } - - script->push_val(st->stack, C_NAME, reference_uid(id, i), reference_getref(data)); + + script->push_val(st->stack, C_NAME, reference_uid(id, (unsigned int)i), reference_getref(data)); return true; } @@ -5364,16 +5979,16 @@ BUILDIN(setlook) { int type,val; TBL_PC* sd; - + type=script_getnum(st,2); val=script_getnum(st,3); - + sd = script->rid2sd(st); if( sd == NULL ) return true; - + pc->changelook(sd,type,val); - + return true; } @@ -5381,16 +5996,16 @@ BUILDIN(changelook) { // As setlook but only client side int type,val; TBL_PC* sd; - + type=script_getnum(st,2); val=script_getnum(st,3); - + sd = script->rid2sd(st); if( sd == NULL ) return true; - + clif->changelook(&sd->bl,type,val); - + return true; } @@ -5400,11 +6015,11 @@ BUILDIN(changelook) BUILDIN(cutin) { TBL_PC* sd; - + sd = script->rid2sd(st); if( sd == NULL ) return true; - + clif->cutin(sd,script_getstr(st,2),script_getnum(st,3)); return true; } @@ -5416,104 +6031,90 @@ BUILDIN(viewpoint) { int type,x,y,id,color; TBL_PC* sd; - + type=script_getnum(st,2); x=script_getnum(st,3); y=script_getnum(st,4); id=script_getnum(st,5); color=script_getnum(st,6); - + sd = script->rid2sd(st); if( sd == NULL ) return true; - + clif->viewpoint(sd,st->oid,type,x,y,id,color); - + return true; } /*========================================== * *------------------------------------------*/ -BUILDIN(countitem) -{ +BUILDIN(countitem) { int nameid, i; int count = 0; struct item_data* id = NULL; - struct script_data* data; - + TBL_PC* sd = script->rid2sd(st); if (!sd) { script_pushint(st,0); return true; } - - data = script_getdata(st,2); - script->get_val(st, data); // convert into value in case of a variable - - if( data_isstring(data) ) - {// item name - id = itemdb->search_name(script->conv_str(st, data)); - } - else - {// item id - id = itemdb->exists(script->conv_num(st, data)); + + if( script_isstringtype(st, 2) ) { + // item name + id = itemdb->search_name(script_getstr(st, 2)); + } else { + // item id + id = itemdb->exists(script_getnum(st, 2)); } - - if( id == NULL ) - { + + if( id == NULL ) { ShowError("buildin_countitem: Invalid item '%s'.\n", script_getstr(st,2)); // returns string, regardless of what it was script_pushint(st,0); return false; } - + nameid = id->nameid; - + for(i = 0; i < MAX_INVENTORY; i++) if(sd->status.inventory[i].nameid == nameid) count += sd->status.inventory[i].amount; - + script_pushint(st,count); return true; } /*========================================== - * countitem2(nameID,Identified,Refine,Attribute,Card0,Card1,Card2,Card3) [Lupus] - * returns number of items that meet the conditions + * countitem2(nameID,Identified,Refine,Attribute,Card0,Card1,Card2,Card3) [Lupus] + * returns number of items that meet the conditions *------------------------------------------*/ -BUILDIN(countitem2) -{ +BUILDIN(countitem2) { int nameid, iden, ref, attr, c1, c2, c3, c4; int count = 0; int i; struct item_data* id = NULL; - struct script_data* data; - + TBL_PC* sd = script->rid2sd(st); if (!sd) { script_pushint(st,0); return true; } - - data = script_getdata(st,2); - script->get_val(st, data); // convert into value in case of a variable - - if( data_isstring(data) ) - {// item name - id = itemdb->search_name(script->conv_str(st, data)); - } - else - {// item id - id = itemdb->exists(script->conv_num(st, data)); + + if( script_isstringtype(st, 2) ) { + // item name + id = itemdb->search_name(script_getstr(st, 2)); + } else { + // item id + id = itemdb->exists(script_getnum(st, 2)); } - - if( id == NULL ) - { + + if( id == NULL ) { ShowError("buildin_countitem2: Invalid item '%s'.\n", script_getstr(st,2)); // returns string, regardless of what it was script_pushint(st,0); return false; } - + nameid = id->nameid; iden = script_getnum(st,3); ref = script_getnum(st,4); @@ -5522,7 +6123,7 @@ BUILDIN(countitem2) c2 = (short)script_getnum(st,7); c3 = (short)script_getnum(st,8); c4 = (short)script_getnum(st,9); - + for(i = 0; i < MAX_INVENTORY; i++) if (sd->status.inventory[i].nameid > 0 && sd->inventory_data[i] != NULL && sd->status.inventory[i].amount > 0 && sd->status.inventory[i].nameid == nameid && @@ -5532,7 +6133,7 @@ BUILDIN(countitem2) sd->status.inventory[i].card[3] == c4 ) count += sd->status.inventory[i].amount; - + script_pushint(st,count); return true; } @@ -5541,8 +6142,8 @@ BUILDIN(countitem2) * Check if item with this amount can fit in inventory * Checking : weight, stack amount >32k, slots amount >(MAX_INVENTORY) * Return - * 0 : fail - * 1 : success (npc side only) + * 0 : fail + * 1 : success (npc side only) *------------------------------------------*/ BUILDIN(checkweight) { @@ -5550,73 +6151,76 @@ BUILDIN(checkweight) unsigned int weight=0, i, nbargs; struct item_data* id = NULL; struct map_session_data* sd; - struct script_data* data; - - if( ( sd = script->rid2sd(st) ) == NULL ){ + + if( ( sd = script->rid2sd(st) ) == NULL ) { return true; } nbargs = script_lastdata(st)+1; - if(nbargs%2){ - ShowError("buildin_checkweight: Invalid nb of args should be a multiple of 2.\n"); - script_pushint(st,0); - return false; + if(nbargs%2) { + ShowError("buildin_checkweight: Invalid nb of args should be a multiple of 2.\n"); + script_pushint(st,0); + return false; } slots = pc->inventoryblank(sd); //nb of empty slot - - for(i=2; i<nbargs; i=i+2){ - data = script_getdata(st,i); - script->get_val(st, data); // convert into value in case of a variable - if( data_isstring(data) ){// item name - id = itemdb->search_name(script->conv_str(st, data)); - } else {// item id - id = itemdb->exists(script->conv_num(st, data)); - } - if( id == NULL ) { - ShowError("buildin_checkweight: Invalid item '%s'.\n", script_getstr(st,i)); // returns string, regardless of what it was - script_pushint(st,0); - return false; - } - nameid = id->nameid; - - amount = script_getnum(st,i+1); - if( amount < 1 ) { - ShowError("buildin_checkweight: Invalid amount '%d'.\n", amount); - script_pushint(st,0); - return false; - } - - weight += itemdb_weight(nameid)*amount; //total weight for all chk - if( weight + sd->weight > sd->max_weight ) - {// too heavy - script_pushint(st,0); - return true; - } - - switch( pc->checkadditem(sd, nameid, amount) ) - { - case ADDITEM_EXIST: - // item is already in inventory, but there is still space for the requested amount - break; - case ADDITEM_NEW: - if( itemdb->isstackable(nameid) ) {// stackable - amount2++; - if( slots < amount2 ) { - script_pushint(st,0); - return true; - } - } - else {// non-stackable - amount2 += amount; - if( slots < amount2){ - script_pushint(st,0); - return true; - } - } - break; - case ADDITEM_OVERAMOUNT: - script_pushint(st,0); - return true; - } + + for( i = 2; i < nbargs; i += 2 ) { + if( script_isstringtype(st, i) ) { + // item name + id = itemdb->search_name(script_getstr(st, i)); + } else if ( script_isinttype(st, i) ) { + // item id + id = itemdb->exists(script_getnum(st, i)); + } else { + ShowError("buildin_checkweight: invalid type for argument '%d'.\n", i); + script_pushint(st,0); + return false; + } + if( id == NULL ) { + ShowError("buildin_checkweight: Invalid item '%s'.\n", script_getstr(st,i)); // returns string, regardless of what it was + script_pushint(st,0); + return false; + } + nameid = id->nameid; + + amount = script_getnum(st,i+1); + if( amount < 1 ) { + ShowError("buildin_checkweight: Invalid amount '%d'.\n", amount); + script_pushint(st,0); + return false; + } + + weight += itemdb_weight(nameid)*amount; //total weight for all chk + if( weight + sd->weight > sd->max_weight ) + {// too heavy + script_pushint(st,0); + return true; + } + + switch( pc->checkadditem(sd, nameid, amount) ) { + case ADDITEM_EXIST: + // item is already in inventory, but there is still space for the requested amount + break; + case ADDITEM_NEW: + if( itemdb->isstackable(nameid) ) { + // stackable + amount2++; + if( slots < amount2 ) { + script_pushint(st,0); + return true; + } + } else { + // non-stackable + amount2 += amount; + if( slots < amount2) { + script_pushint(st,0); + return true; + } + } + break; + case ADDITEM_OVERAMOUNT: + script_pushint(st,0); + return true; + } } script_pushint(st,1); return true; @@ -5628,7 +6232,7 @@ BUILDIN(checkweight2) int32 nameid=-1, amount=-1; int i=0, amount2=0, slots=0, weight=0; short fail=0; - + //variable for array parsing struct script_data* data_it; struct script_data* data_nb; @@ -5637,13 +6241,13 @@ BUILDIN(checkweight2) int32 id_it, id_nb; int32 idx_it, idx_nb; int nb_it, nb_nb; //array size - + TBL_PC *sd = script->rid2sd(st); - nullpo_retr(1,sd); - + nullpo_retr(false,sd); + data_it = script_getdata(st, 2); data_nb = script_getdata(st, 3); - + if( !data_isreference(data_it) || !data_isreference(data_nb)) { ShowError("script:checkweight2: parameter not a variable\n"); @@ -5656,70 +6260,64 @@ BUILDIN(checkweight2) idx_nb = reference_getindex(data_nb); name_it = reference_getname(data_it); name_nb = reference_getname(data_nb); - - if( not_array_variable(*name_it) || not_array_variable(*name_nb)) - { - ShowError("script:checkweight2: illegal scope\n"); - script_pushint(st,0); - return false;// not supported - } - if(is_string_variable(name_it) || is_string_variable(name_nb)){ + + if(is_string_variable(name_it) || is_string_variable(name_nb)) { ShowError("script:checkweight2: illegal type, need int\n"); script_pushint(st,0); return false;// not supported } - nb_it = script->getarraysize(st, id_it, idx_it, 0, reference_getref(data_it)); - nb_nb = script->getarraysize(st, id_nb, idx_nb, 0, reference_getref(data_nb)); - if(nb_it != nb_nb){ + nb_it = script->array_highest_key(st,sd,reference_getname(data_it),reference_getref(data_it)); + nb_nb = script->array_highest_key(st,sd,reference_getname(data_nb),reference_getref(data_nb)); + if(nb_it != nb_nb) { ShowError("Size mistmatch: nb_it=%d, nb_nb=%d\n",nb_it,nb_nb); fail = 1; } - + slots = pc->inventoryblank(sd); - for(i=0; i<nb_it; i++){ + for(i=0; i<nb_it; i++) { nameid = (int32)__64BPTRSIZE(script->get_val2(st,reference_uid(id_it,idx_it+i),reference_getref(data_it))); - script_removetop(st, -1, 0); - amount = (int32)__64BPTRSIZE(script->get_val2(st,reference_uid(id_nb,idx_nb+i),reference_getref(data_nb))); - script_removetop(st, -1, 0); - if(fail) continue; //cpntonie to depop rest - - if(itemdb->exists(nameid) == NULL ){ + script_removetop(st, -1, 0); + amount = (int32)__64BPTRSIZE(script->get_val2(st,reference_uid(id_nb,idx_nb+i),reference_getref(data_nb))); + script_removetop(st, -1, 0); + if(fail) continue; //cpntonie to depop rest + + if(itemdb->exists(nameid) == NULL ) { ShowError("buildin_checkweight2: Invalid item '%d'.\n", nameid); fail=1; continue; } - if(amount < 0 ){ + if(amount < 0 ) { ShowError("buildin_checkweight2: Invalid amount '%d'.\n", amount); fail = 1; continue; } - weight += itemdb_weight(nameid)*amount; - if( weight + sd->weight > sd->max_weight ){ + weight += itemdb_weight(nameid)*amount; + if( weight + sd->weight > sd->max_weight ) { fail = 1; continue; - } - switch( pc->checkadditem(sd, nameid, amount) ) { - case ADDITEM_EXIST: + } + switch( pc->checkadditem(sd, nameid, amount) ) { + case ADDITEM_EXIST: // item is already in inventory, but there is still space for the requested amount - break; - case ADDITEM_NEW: - if( itemdb->isstackable(nameid) ){// stackable - amount2++; - if( slots < amount2 ) - fail = 1; - } - else {// non-stackable - amount2 += amount; - if( slots < amount2 ){ - fail = 1; - } - } - break; - case ADDITEM_OVERAMOUNT: - fail = 1; - } //end switch + break; + case ADDITEM_NEW: + if( itemdb->isstackable(nameid) ) {// stackable + amount2++; + if( slots < amount2 ) + fail = 1; + } + else {// non-stackable + amount2 += amount; + if( slots < amount2 ) { + fail = 1; + } + } + break; + case ADDITEM_OVERAMOUNT: + fail = 1; + } //end switch } //end loop DO NOT break it prematurly we need to depop all stack - + fail?script_pushint(st,0):script_pushint(st,1); return true; } @@ -5727,66 +6325,78 @@ BUILDIN(checkweight2) /*========================================== * getitem <item id>,<amount>{,<account ID>}; * getitem "<item name>",<amount>{,<account ID>}; + * + * getitembound <item id>,<amount>,<type>{,<account ID>}; + * getitembound "<item id>",<amount>,<type>{,<account ID>}; *------------------------------------------*/ -BUILDIN(getitem) -{ - int nameid,amount,get_count,i,flag = 0; +BUILDIN(getitem) { + int nameid,amount,get_count,i,flag = 0, offset = 0; struct item it; TBL_PC *sd; - struct script_data *data; struct item_data *item_data; - - data=script_getdata(st,2); - script->get_val(st,data); - if( data_isstring(data) ) - {// "<item name>" - const char *name=script->conv_str(st,data); - if( (item_data = itemdb->search_name(name)) == NULL ){ - ShowError("buildin_getitem: Nonexistant item %s requested.\n", name); + + if( script_isstringtype(st, 2) ) { + // "<item name>" + const char *name = script_getstr(st, 2); + if( (item_data = itemdb->search_name(name)) == NULL ) { + ShowError("buildin_%s: Nonexistant item %s requested.\n", script->getfuncname(st), name); return false; //No item created. } nameid=item_data->nameid; - } else if( data_isint(data) ) {// <item id> - nameid=script->conv_num(st,data); + } else { + // <item id> + nameid = script_getnum(st, 2); //Violet Box, Blue Box, etc - random item pick if( nameid < 0 ) { nameid = -nameid; flag = 1; } - if( nameid <= 0 || !(item_data = itemdb->exists(nameid)) ){ - ShowError("buildin_getitem: Nonexistant item %d requested.\n", nameid); + if( nameid <= 0 || !(item_data = itemdb->exists(nameid)) ) { + ShowError("buildin_%s: Nonexistant item %d requested.\n", script->getfuncname(st), nameid); return false; //No item created. } - } else { - ShowError("buildin_getitem: invalid data type for argument #1 (%d).", data->type); - return false; } - + // <amount> if( (amount=script_getnum(st,3)) <= 0) return true; //return if amount <=0, skip the useles iteration - + memset(&it,0,sizeof(it)); it.nameid=nameid; + if(!flag) it.identify=1; else it.identify=itemdb->isidentified2(item_data); - - if( script_hasdata(st,4) ) - sd=map->id2sd(script_getnum(st,4)); // <Account ID> + + if( !strcmp(script->getfuncname(st),"getitembound") ) { + int bound = script_getnum(st,4); + if( bound < IBT_MIN || bound > IBT_MAX ) { //Not a correct bound type + ShowError("script_getitembound: Not a correct bound type! Type=%d\n",bound); + return false; + } + if( item_data->type == IT_PETEGG || item_data->type == IT_PETARMOR ) { + ShowError("script_getitembound: can't bind a pet egg/armor!\n",bound); + return false; + } + it.bound = (unsigned char)bound; + offset += 1; + } + + if( script_hasdata(st,4+offset) ) + sd=map->id2sd(script_getnum(st,4+offset)); // <Account ID> else sd=script->rid2sd(st); // Attached player - + if( sd == NULL ) // no target return true; - + //Check if it's stackable. if (!itemdb->isstackable(nameid)) get_count = 1; else get_count = amount; - + for (i = 0; i < amount; i += get_count) { // if not pet egg if (!pet->create_egg(sd, nameid)) { @@ -5797,42 +6407,46 @@ BUILDIN(getitem) } } } - + return true; } /*========================================== * *------------------------------------------*/ -BUILDIN(getitem2) -{ - int nameid,amount,get_count,i,flag = 0; - int iden,ref,attr,c1,c2,c3,c4; - struct item_data *item_data; - struct item item_tmp; +BUILDIN(getitem2) { + int nameid,amount,i,flag = 0, offset = 0; + int iden,ref,attr,c1,c2,c3,c4, bound = 0; TBL_PC *sd; - struct script_data *data; - - if( script_hasdata(st,11) ) - sd=map->id2sd(script_getnum(st,11)); // <Account ID> + + if( !strcmp(script->getfuncname(st),"getitembound2") ) { + bound = script_getnum(st,11); + if( bound < IBT_MIN || bound > IBT_MAX ) { //Not a correct bound type + ShowError("script_getitembound2: Not a correct bound type! Type=%d\n",bound); + return false; + } + offset += 1; + } + + if( script_hasdata(st,11+offset) ) + sd=map->id2sd(script_getnum(st,11+offset)); // <Account ID> else sd=script->rid2sd(st); // Attached player - + if( sd == NULL ) // no target return true; - - data=script_getdata(st,2); - script->get_val(st,data); - if( data_isstring(data) ){ - const char *name=script->conv_str(st,data); + + if( script_isstringtype(st, 2) ) { + const char *name = script_getstr(st, 2); struct item_data *item_data = itemdb->search_name(name); if( item_data ) nameid=item_data->nameid; else nameid=UNKNOWN_ITEM_ID; - }else - nameid=script->conv_num(st,data); - + } else { + nameid = script_getnum(st, 2); + } + amount=script_getnum(st,3); iden=script_getnum(st,4); ref=script_getnum(st,5); @@ -5841,18 +6455,25 @@ BUILDIN(getitem2) c2=(short)script_getnum(st,8); c3=(short)script_getnum(st,9); c4=(short)script_getnum(st,10); - + + if( bound && (itemdb_type(nameid) == IT_PETEGG || itemdb_type(nameid) == IT_PETARMOR) ) { + ShowError("script_getitembound2: can't bind a pet egg/armor!\n",bound); + return false; + } + if(nameid<0) { // Invalide nameid nameid = -nameid; flag = 1; } - + if(nameid > 0) { + struct item item_tmp; + struct item_data *item_data = itemdb->exists(nameid); + int get_count; memset(&item_tmp,0,sizeof(item_tmp)); - item_data=itemdb->exists(nameid); if (item_data == NULL) return -1; - if(item_data->type==IT_WEAPON || item_data->type==IT_ARMOR){ + if(item_data->type==IT_WEAPON || item_data->type==IT_ARMOR) { if(ref > MAX_REFINE) ref = MAX_REFINE; } else if(item_data->type==IT_PETEGG) { @@ -5863,7 +6484,7 @@ BUILDIN(getitem2) iden = 1; ref = attr = 0; } - + item_tmp.nameid=nameid; if(!flag) item_tmp.identify=iden; @@ -5871,17 +6492,18 @@ BUILDIN(getitem2) item_tmp.identify=0; item_tmp.refine=ref; item_tmp.attribute=attr; + item_tmp.bound=(unsigned char)bound; item_tmp.card[0]=(short)c1; item_tmp.card[1]=(short)c2; item_tmp.card[2]=(short)c3; item_tmp.card[3]=(short)c4; - + //Check if it's stackable. if (!itemdb->isstackable(nameid)) get_count = 1; else get_count = amount; - + for (i = 0; i < amount; i += get_count) { // if not pet egg if (!pet->create_egg(sd, nameid)) { @@ -5893,7 +6515,7 @@ BUILDIN(getitem2) } } } - + return true; } @@ -5901,23 +6523,17 @@ BUILDIN(getitem2) * rentitem <item id>,<seconds> * rentitem "<item name>",<seconds> *------------------------------------------*/ -BUILDIN(rentitem) -{ +BUILDIN(rentitem) { struct map_session_data *sd; - struct script_data *data; struct item it; int seconds; int nameid = 0, flag; - - data = script_getdata(st,2); - script->get_val(st,data); - + if( (sd = script->rid2sd(st)) == NULL ) return true; - - if( data_isstring(data) ) - { - const char *name = script->conv_str(st,data); + + if( script_isstringtype(st, 2) ) { + const char *name = script_getstr(st, 2); struct item_data *itd = itemdb->search_name(name); if( itd == NULL ) { @@ -5925,34 +6541,27 @@ BUILDIN(rentitem) return false; } nameid = itd->nameid; - } - else if( data_isint(data) ) - { - nameid = script->conv_num(st,data); - if( nameid <= 0 || !itemdb->exists(nameid) ) - { + } else { + nameid = script_getnum(st, 2); + if( nameid <= 0 || !itemdb->exists(nameid) ) { ShowError("buildin_rentitem: Nonexistant item %d requested.\n", nameid); return false; } } - else - { - ShowError("buildin_rentitem: invalid data type for argument #1 (%d).\n", data->type); - return false; - } - + seconds = script_getnum(st,3); memset(&it, 0, sizeof(it)); it.nameid = nameid; it.identify = 1; it.expire_time = (unsigned int)(time(NULL) + seconds); - + it.bound = 0; + if( (flag = pc->additem(sd, &it, 1, LOG_TYPE_SCRIPT)) ) { clif->additem(sd, 0, 0, flag); return false; } - + return true; } @@ -5962,53 +6571,48 @@ BUILDIN(rentitem) * Returned Qty is always 1, only works on equip-able * equipment *------------------------------------------*/ -BUILDIN(getnameditem) -{ +BUILDIN(getnameditem) { int nameid; struct item item_tmp; TBL_PC *sd, *tsd; - struct script_data *data; - + sd = script->rid2sd(st); - if (sd == NULL) - { //Player not attached! + if (sd == NULL) { + //Player not attached! script_pushint(st,0); return true; } - - data=script_getdata(st,2); - script->get_val(st,data); - if( data_isstring(data) ){ - const char *name=script->conv_str(st,data); + + if( script_isstringtype(st, 2) ) { + const char *name = script_getstr(st, 2); struct item_data *item_data = itemdb->search_name(name); - if( item_data == NULL) - { //Failed + if( item_data == NULL) { + //Failed script_pushint(st,0); return true; } nameid = item_data->nameid; - }else - nameid = script->conv_num(st,data); - - if(!itemdb->exists(nameid)/* || itemdb->isstackable(nameid)*/) - { //Even though named stackable items "could" be risky, they are required for certain quests. + } else { + nameid = script_getnum(st, 2); + } + + if(!itemdb->exists(nameid)/* || itemdb->isstackable(nameid)*/) { + //Even though named stackable items "could" be risky, they are required for certain quests. script_pushint(st,0); return true; } - - data=script_getdata(st,3); - script->get_val(st,data); - if( data_isstring(data) ) //Char Name - tsd=map->nick2sd(script->conv_str(st,data)); + + if( script_isstringtype(st, 3) ) //Char Name + tsd=map->nick2sd(script_getstr(st, 3)); else //Char Id was given - tsd=map->charid2sd(script->conv_num(st,data)); - - if( tsd == NULL ) - { //Failed + tsd=map->charid2sd(script_getnum(st, 3)); + + if( tsd == NULL ) { + //Failed script_pushint(st,0); return true; } - + memset(&item_tmp,0,sizeof(item_tmp)); item_tmp.nameid=nameid; item_tmp.amount=1; @@ -6018,9 +6622,9 @@ BUILDIN(getnameditem) item_tmp.card[3]=tsd->status.char_id >> 16; if(pc->additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT)) { script_pushint(st,0); - return true; //Failed to add item, we will not drop if they don't fit + return true; //Failed to add item, we will not drop if they don't fit } - + script_pushint(st,1); return true; } @@ -6032,7 +6636,7 @@ BUILDIN(getnameditem) BUILDIN(grouprandomitem) { struct item_data *data; int nameid; - + if( script_hasdata(st, 2) ) nameid = script_getnum(st, 2); else if ( script->current_item_id ) @@ -6042,7 +6646,7 @@ BUILDIN(grouprandomitem) { script_pushint(st, 0); return true; } - + if( !(data = itemdb->exists(nameid)) ) { ShowWarning("buildin_grouprandomitem: unknown item id %d\n",nameid); script_pushint(st, 0); @@ -6052,7 +6656,7 @@ BUILDIN(grouprandomitem) { } else { script_pushint(st, itemdb->group_item(data->group)); } - + return true; } @@ -6065,29 +6669,26 @@ BUILDIN(makeitem) int x,y,m; const char *mapname; struct item item_tmp; - struct script_data *data; struct item_data *item_data; - data=script_getdata(st,2); - script->get_val(st,data); - if( data_isstring(data) ){ - const char *name=script->conv_str(st,data); + if( script_isstringtype(st, 2) ) { + const char *name = script_getstr(st, 2); if( (item_data = itemdb->search_name(name)) ) nameid=item_data->nameid; else nameid=UNKNOWN_ITEM_ID; } else { - nameid=script->conv_num(st,data); - if( nameid <= 0 || !(item_data = itemdb->exists(nameid)) ){ + nameid = script_getnum(st, 2); + if( nameid <= 0 || !(item_data = itemdb->exists(nameid)) ) { ShowError("makeitem: Nonexistant item %d requested.\n", nameid); return false; //No item created. } } - amount=script_getnum(st,3); - mapname =script_getstr(st,4); - x =script_getnum(st,5); - y =script_getnum(st,6); - + amount = script_getnum(st,3); + mapname = script_getstr(st,4); + x = script_getnum(st,5); + y = script_getnum(st,6); + if(strcmp(mapname,"this")==0) { TBL_PC *sd; sd = script->rid2sd(st); @@ -6095,22 +6696,22 @@ BUILDIN(makeitem) m=sd->bl.m; } else m=map->mapname2mapid(mapname); - + if( m == -1 ) { ShowError("makeitem: creating map on unexistent map '%s'!\n", mapname); return false; } - - + + memset(&item_tmp,0,sizeof(item_tmp)); item_tmp.nameid=nameid; if(!flag) item_tmp.identify=1; else item_tmp.identify=itemdb->isidentified2(item_data); - + map->addflooritem(&item_tmp,amount,m,x,y,0,0,0,0); - + return true; } @@ -6122,9 +6723,9 @@ void buildin_delitem_delete(struct map_session_data* sd, int idx, int* amount, b { int delamount; struct item* inv = &sd->status.inventory[idx]; - + delamount = ( amount[0] < inv->amount ) ? amount[0] : inv->amount; - + if( delete_items ) { if( sd->inventory_data[idx]->type == IT_PETEGG && inv->card[0] == CARD0_PET ) @@ -6133,7 +6734,7 @@ void buildin_delitem_delete(struct map_session_data* sd, int idx, int* amount, b } pc->delitem(sd, idx, delamount, 0, 0, LOG_TYPE_SCRIPT); } - + amount[0]-= delamount; } @@ -6148,10 +6749,10 @@ bool buildin_delitem_search(struct map_session_data* sd, struct item* it, bool e bool delete_items = false; int i, amount, important; struct item* inv; - + // prefer always non-equipped items it->equip = 0; - + // when searching for nameid only, prefer additionally if( !exact_match ) { @@ -6160,28 +6761,28 @@ bool buildin_delitem_search(struct map_session_data* sd, struct item* it, bool e // card-less items memset(it->card, 0, sizeof(it->card)); } - + for(;;) { amount = it->amount; important = 0; - + // 1st pass -- less important items / exact match for( i = 0; amount && i < ARRAYLENGTH(sd->status.inventory); i++ ) { inv = &sd->status.inventory[i]; - + if( !inv->nameid || !sd->inventory_data[i] || inv->nameid != it->nameid ) {// wrong/invalid item continue; } - + if( inv->equip != it->equip || inv->refine != it->refine ) {// not matching attributes important++; continue; } - + if( exact_match ) { if( inv->identify != it->identify || inv->attribute != it->attribute || memcmp(inv->card, it->card, sizeof(inv->card)) ) @@ -6204,11 +6805,11 @@ bool buildin_delitem_search(struct map_session_data* sd, struct item* it, bool e continue; } } - + // count / delete item script->buildin_delitem_delete(sd, i, &amount, delete_items); } - + // 2nd pass -- any matching item if( amount == 0 || important == 0 ) {// either everything was already consumed or no items were skipped @@ -6217,17 +6818,17 @@ bool buildin_delitem_search(struct map_session_data* sd, struct item* it, bool e else for( i = 0; amount && i < ARRAYLENGTH(sd->status.inventory); i++ ) { inv = &sd->status.inventory[i]; - + if( !inv->nameid || !sd->inventory_data[i] || inv->nameid != it->nameid ) {// wrong/invalid item continue; } - + if( sd->inventory_data[i]->type == IT_PETEGG && inv->card[0] == CARD0_PET && intif->CheckForCharServer() ) {// pet which cannot be deleted continue; } - + if( exact_match ) { if( inv->refine != it->refine || inv->identify != it->identify || inv->attribute != it->attribute || memcmp(inv->card, it->card, sizeof(inv->card)) ) @@ -6235,11 +6836,11 @@ bool buildin_delitem_search(struct map_session_data* sd, struct item* it, bool e continue; } } - + // count / delete item script->buildin_delitem_delete(sd, i, &amount, delete_items); } - + if( amount ) {// not enough items return false; @@ -6261,12 +6862,10 @@ bool buildin_delitem_search(struct map_session_data* sd, struct item* it, bool e /// /// delitem <item id>,<amount>{,<account id>} /// delitem "<item name>",<amount>{,<account id>} -BUILDIN(delitem) -{ +BUILDIN(delitem) { TBL_PC *sd; struct item it; - struct script_data *data; - + if( script_hasdata(st,4) ) { int account_id = script_getnum(st,4); @@ -6284,24 +6883,18 @@ BUILDIN(delitem) if( sd == NULL ) return true; } - - data = script_getdata(st,2); - script->get_val(st,data); - if( data_isstring(data) ) - { - const char* item_name = script->conv_str(st,data); + + if( script_isstringtype(st, 2) ) { + const char* item_name = script_getstr(st, 2); struct item_data* id = itemdb->search_name(item_name); - if( id == NULL ) - { + if( id == NULL ) { ShowError("script:delitem: unknown item \"%s\".\n", item_name); st->state = END; return false; } it.nameid = id->nameid;// "<item name>" - } - else - { - it.nameid = script->conv_num(st,data);// <item id> + } else { + it.nameid = script_getnum(st, 2);// <item id> if( !itemdb->exists( it.nameid ) ) { ShowError("script:delitem: unknown item \"%d\".\n", it.nameid); @@ -6309,17 +6902,17 @@ BUILDIN(delitem) return false; } } - + it.amount=script_getnum(st,3); - + if( it.amount <= 0 ) return true;// nothing to do - + if( script->buildin_delitem_search(sd, &it, false) ) {// success return true; } - + ShowError("script:delitem: failed to delete %d items (AID=%d item_id=%d).\n", it.amount, sd->status.account_id, it.nameid); st->state = END; clif->scriptclose(sd, st->oid); @@ -6333,8 +6926,7 @@ BUILDIN(delitem) BUILDIN(delitem2) { TBL_PC *sd; struct item it; - struct script_data *data; - + if( script_hasdata(st,11) ) { int account_id = script_getnum(st,11); sd = map->id2sd(account_id); // <account id> @@ -6350,32 +6942,25 @@ BUILDIN(delitem2) { if( sd == NULL ) return true; } - - data = script_getdata(st,2); - script->get_val(st,data); - if( data_isstring(data) ) - { - const char* item_name = script->conv_str(st,data); + + if( script_isstringtype(st, 2) ) { + const char* item_name = script_getstr(st, 2); struct item_data* id = itemdb->search_name(item_name); - if( id == NULL ) - { + if( id == NULL ) { ShowError("script:delitem2: unknown item \"%s\".\n", item_name); st->state = END; return false; } it.nameid = id->nameid;// "<item name>" - } - else - { - it.nameid = script->conv_num(st,data);// <item id> - if( !itemdb->exists( it.nameid ) ) - { + } else { + it.nameid = script_getnum(st, 2);// <item id> + if( !itemdb->exists( it.nameid ) ) { ShowError("script:delitem: unknown item \"%d\".\n", it.nameid); st->state = END; return false; } } - + it.amount=script_getnum(st,3); it.identify=script_getnum(st,4); it.refine=script_getnum(st,5); @@ -6384,15 +6969,15 @@ BUILDIN(delitem2) { it.card[1]=(short)script_getnum(st,8); it.card[2]=(short)script_getnum(st,9); it.card[3]=(short)script_getnum(st,10); - + if( it.amount <= 0 ) return true;// nothing to do - + if( script->buildin_delitem_search(sd, &it, true) ) {// success return true; } - + ShowError("script:delitem2: failed to delete %d items (AID=%d item_id=%d).\n", it.amount, sd->status.account_id, it.nameid); st->state = END; clif->scriptclose(sd, st->oid); @@ -6427,47 +7012,47 @@ BUILDIN(disableitemuse) BUILDIN(readparam) { int type; TBL_PC *sd; - + type=script_getnum(st,2); if( script_hasdata(st,3) ) sd=map->nick2sd(script_getstr(st,3)); else sd=script->rid2sd(st); - - if(sd==NULL){ + + if(sd==NULL) { script_pushint(st,-1); return true; } - + script_pushint(st,pc->readparam(sd,type)); - + return true; } /*========================================== * Return charid identification * return by @num : - * 0 : char_id - * 1 : party_id - * 2 : guild_id - * 3 : account_id - * 4 : bg_id + * 0 : char_id + * 1 : party_id + * 2 : guild_id + * 3 : account_id + * 4 : bg_id *------------------------------------------*/ BUILDIN(getcharid) { int num; TBL_PC *sd; - + num = script_getnum(st,2); if( script_hasdata(st,3) ) sd=map->nick2sd(script_getstr(st,3)); else sd=script->rid2sd(st); - - if(sd==NULL){ - script_pushint(st,0); //return 0, according docs + + if(sd==NULL) { + script_pushint(st,0); //return 0, according docs return true; } - + switch( num ) { case 0: script_pushint(st,sd->status.char_id); break; case 1: script_pushint(st,sd->status.party_id); break; @@ -6479,7 +7064,7 @@ BUILDIN(getcharid) { script_pushint(st,0); break; } - + return true; } /*========================================== @@ -6489,7 +7074,7 @@ BUILDIN(getnpcid) { int num = script_getnum(st,2); struct npc_data* nd = NULL; - + if( script_hasdata(st,3) ) {// unique npc name if( ( nd = npc->name2id(script_getstr(st,3)) ) == NULL ) @@ -6499,7 +7084,7 @@ BUILDIN(getnpcid) return false; } } - + switch (num) { case 0: script_pushint(st,nd ? nd->bl.id : st->oid); @@ -6509,7 +7094,7 @@ BUILDIN(getnpcid) script_pushint(st,0); return false; } - + return true; } @@ -6521,9 +7106,9 @@ BUILDIN(getpartyname) { int party_id; struct party_data* p; - + party_id = script_getnum(st,2); - + if( ( p = party->search(party_id) ) != NULL ) { script_pushstrcopy(st,p->party.name); @@ -6539,23 +7124,23 @@ BUILDIN(getpartyname) * Get the information of the members of a party by type * @party_id, @type * return by @type : - * - : nom des membres - * 1 : char_id des membres - * 2 : account_id des membres + * - : nom des membres + * 1 : char_id des membres + * 2 : account_id des membres *------------------------------------------*/ BUILDIN(getpartymember) { struct party_data *p; int i,j=0,type=0; - + p=party->search(script_getnum(st,2)); - + if( script_hasdata(st,3) ) - type=script_getnum(st,3); - - if(p!=NULL){ - for(i=0;i<MAX_PARTY;i++){ - if(p->party.member[i].account_id){ + type=script_getnum(st,3); + + if(p!=NULL) { + for(i=0;i<MAX_PARTY;i++) { + if(p->party.member[i].account_id) { switch (type) { case 2: mapreg->setreg(reference_uid(script->add_str("$@partymemberaid"), j),p->party.member[i].account_id); @@ -6571,7 +7156,7 @@ BUILDIN(getpartymember) } } mapreg->setreg(script->add_str("$@partymembercount"),j); - + return true; } @@ -6583,16 +7168,16 @@ BUILDIN(getpartyleader) { int party_id, type = 0, i=0; struct party_data *p; - + party_id=script_getnum(st,2); if( script_hasdata(st,3) ) - type=script_getnum(st,3); - + type=script_getnum(st,3); + p=party->search(party_id); - + if (p) //Search leader for(i = 0; i < MAX_PARTY && !p->party.member[i].leader; i++); - + if (!p || i == MAX_PARTY) { //leader not found if (type) script_pushint(st,-1); @@ -6600,7 +7185,7 @@ BUILDIN(getpartyleader) script_pushconststr(st,"null"); return true; } - + switch (type) { case 1: script_pushint(st,p->party.member[i].account_id); break; case 2: script_pushint(st,p->party.member[i].char_id); break; @@ -6620,9 +7205,9 @@ BUILDIN(getguildname) { int guild_id; struct guild* g; - + guild_id = script_getnum(st,2); - + if( ( g = guild->search(guild_id) ) != NULL ) { script_pushstrcopy(st,g->name); @@ -6642,9 +7227,9 @@ BUILDIN(getguildmaster) { int guild_id; struct guild* g; - + guild_id = script_getnum(st,2); - + if( ( g = guild->search(guild_id) ) != NULL ) { script_pushstrcopy(st,g->member[0].name); @@ -6660,9 +7245,9 @@ BUILDIN(getguildmasterid) { int guild_id; struct guild* g; - + guild_id = script_getnum(st,2); - + if( ( g = guild->search(guild_id) ) != NULL ) { script_pushint(st,g->member[0].char_id); @@ -6677,11 +7262,11 @@ BUILDIN(getguildmasterid) /*========================================== * Get char string information by type : * Return by @type : - * 0 : char_name - * 1 : party_name or "" - * 2 : guild_name or "" - * 3 : map_name - * - : "" + * 0 : char_name + * 1 : party_name or "" + * 2 : guild_name or "" + * 3 : map_name + * - : "" *------------------------------------------*/ BUILDIN(strcharinfo) { @@ -6689,14 +7274,14 @@ BUILDIN(strcharinfo) int num; struct guild* g; struct party_data* p; - + sd=script->rid2sd(st); if (!sd) { //Avoid crashing.... script_pushconststr(st,""); return true; } num=script_getnum(st,2); - switch(num){ + switch(num) { case 0: script_pushstrcopy(st,sd->status.name); break; @@ -6722,32 +7307,32 @@ BUILDIN(strcharinfo) script_pushconststr(st,""); break; } - + return true; } /*========================================== * Get npc string information by type * return by @type: - * 0 : name - * 1 : str# - * 2 : #str - * 3 : ::str - * 4 : map name + * 0 : name + * 1 : str# + * 2 : #str + * 3 : ::str + * 4 : map name *------------------------------------------*/ BUILDIN(strnpcinfo) { TBL_NPC* nd; int num; char *buf,*name=NULL; - + nd = map->id2nd(st->oid); if (!nd) { script_pushconststr(st, ""); return true; } - + num = script_getnum(st,2); - switch(num){ + switch(num) { case 0: // display name name = aStrdup(nd->name); break; @@ -6767,38 +7352,39 @@ BUILDIN(strnpcinfo) { name = aStrdup(nd->exname); break; case 4: // map name - name = aStrdup(map->list[nd->bl.m].name); + if( nd->bl.m >= 0 ) // Only valid map indexes allowed (issue:8034) + name = aStrdup(map->list[nd->bl.m].name); break; } - + if(name) script_pushstr(st, name); else script_pushconststr(st, ""); - + return true; } /*========================================== - * GetEquipID(Pos); Pos: 1-10 + * GetEquipID(Pos); Pos: 1-SCRIPT_EQUIP_TABLE_SIZE *------------------------------------------*/ BUILDIN(getequipid) { int i, num; TBL_PC* sd; struct item_data* item; - + sd = script->rid2sd(st); if( sd == NULL ) return true; - + num = script_getnum(st,2) - 1; if( num < 0 || num >= ARRAYLENGTH(script->equip) ) { script_pushint(st,-1); return true; } - + // get inventory position of item i = pc->checkequip(sd,script->equip[num]); if( i < 0 ) @@ -6806,13 +7392,13 @@ BUILDIN(getequipid) script_pushint(st,-1); return true; } - + item = sd->inventory_data[i]; if( item != 0 ) script_pushint(st,item->nameid); else script_pushint(st,0); - + return true; } @@ -6825,18 +7411,18 @@ BUILDIN(getequipname) int i, num; TBL_PC* sd; struct item_data* item; - + sd = script->rid2sd(st); if( sd == NULL ) return true; - + num = script_getnum(st,2) - 1; if( num < 0 || num >= ARRAYLENGTH(script->equip) ) { script_pushconststr(st,""); return true; } - + // get inventory position of item i = pc->checkequip(sd,script->equip[num]); if( i < 0 ) @@ -6844,13 +7430,13 @@ BUILDIN(getequipname) script_pushconststr(st,""); return true; } - + item = sd->inventory_data[i]; if( item != 0 ) script_pushstrcopy(st,item->jname); else script_pushconststr(st,""); - + return true; } @@ -6861,24 +7447,24 @@ BUILDIN(getbrokenid) { int i,num,id=0,brokencounter=0; TBL_PC *sd; - + sd = script->rid2sd(st); if( sd == NULL ) return true; - + num=script_getnum(st,2); for(i=0; i<MAX_INVENTORY; i++) { - if(sd->status.inventory[i].attribute){ + if(sd->status.inventory[i].attribute) { brokencounter++; - if(num==brokencounter){ + if(num==brokencounter) { id=sd->status.inventory[i].nameid; break; } } } - + script_pushint(st,id); - + return true; } @@ -6890,16 +7476,16 @@ BUILDIN(repair) int i,num; int repaircounter=0; TBL_PC *sd; - + sd = script->rid2sd(st); if( sd == NULL ) return true; - + num=script_getnum(st,2); for(i=0; i<MAX_INVENTORY; i++) { - if(sd->status.inventory[i].attribute){ + if(sd->status.inventory[i].attribute) { repaircounter++; - if(num==repaircounter){ + if(num==repaircounter) { sd->status.inventory[i].attribute=0; clif->equiplist(sd); clif->produce_effect(sd, 0, sd->status.inventory[i].nameid); @@ -6908,7 +7494,7 @@ BUILDIN(repair) } } } - + return true; } @@ -6919,11 +7505,11 @@ BUILDIN(repairall) { int i, repaircounter = 0; TBL_PC *sd; - + sd = script->rid2sd(st); if(sd == NULL) return true; - + for(i = 0; i < MAX_INVENTORY; i++) { if(sd->status.inventory[i].nameid && sd->status.inventory[i].attribute) @@ -6933,13 +7519,13 @@ BUILDIN(repairall) repaircounter++; } } - + if(repaircounter) { clif->misceffect(&sd->bl, 3); clif->equiplist(sd); } - + return true; } @@ -6950,15 +7536,15 @@ BUILDIN(getequipisequiped) { int i = -1,num; TBL_PC *sd; - + num = script_getnum(st,2); sd = script->rid2sd(st); if( sd == NULL ) return true; - + if (num > 0 && num <= ARRAYLENGTH(script->equip)) i=pc->checkequip(sd,script->equip[num-1]); - + if(i >= 0) script_pushint(st,1); else @@ -6970,78 +7556,78 @@ BUILDIN(getequipisequiped) * Chk if the player have something equiped at pos * if so chk if this item ain't marked not refinable or rental * return (npc) - * 1 : true - * 0 : false + * 1 : true + * 0 : false *------------------------------------------*/ BUILDIN(getequipisenableref) { int i = -1,num; TBL_PC *sd; - + num = script_getnum(st,2); sd = script->rid2sd(st); if( sd == NULL ) return true; - + if( num > 0 && num <= ARRAYLENGTH(script->equip) ) i = pc->checkequip(sd,script->equip[num-1]); if( i >= 0 && sd->inventory_data[i] && !sd->inventory_data[i]->flag.no_refine && !sd->status.inventory[i].expire_time ) script_pushint(st,1); else script_pushint(st,0); - + return true; } /*========================================== * Chk if the item equiped at pos is identify (huh ?) * return (npc) - * 1 : true - * 0 : false + * 1 : true + * 0 : false *------------------------------------------*/ BUILDIN(getequipisidentify) { int i = -1,num; TBL_PC *sd; - + num = script_getnum(st,2); sd = script->rid2sd(st); if( sd == NULL ) return true; - + if (num > 0 && num <= ARRAYLENGTH(script->equip)) i=pc->checkequip(sd,script->equip[num-1]); if(i >= 0) script_pushint(st,sd->status.inventory[i].identify); else script_pushint(st,0); - + return true; } /*========================================== * Get the item refined value at pos * return (npc) - * x : refine amount - * 0 : false (not refined) + * x : refine amount + * 0 : false (not refined) *------------------------------------------*/ BUILDIN(getequiprefinerycnt) { int i = -1,num; TBL_PC *sd; - + num = script_getnum(st,2); sd = script->rid2sd(st); if( sd == NULL ) return true; - + if (num > 0 && num <= ARRAYLENGTH(script->equip)) i=pc->checkequip(sd,script->equip[num-1]); if(i >= 0) script_pushint(st,sd->status.inventory[i].refine); else script_pushint(st,0); - + return true; } @@ -7049,95 +7635,98 @@ BUILDIN(getequiprefinerycnt) * Get the weapon level value at pos * (pos should normally only be EQI_HAND_L or EQI_HAND_R) * return (npc) - * x : weapon level - * 0 : false + * x : weapon level + * 0 : false *------------------------------------------*/ BUILDIN(getequipweaponlv) { int i = -1,num; TBL_PC *sd; - + num = script_getnum(st,2); sd = script->rid2sd(st); if( sd == NULL ) return true; - + if (num > 0 && num <= ARRAYLENGTH(script->equip)) i=pc->checkequip(sd,script->equip[num-1]); if(i >= 0 && sd->inventory_data[i]) script_pushint(st,sd->inventory_data[i]->wlv); else script_pushint(st,0); - + return true; } /*========================================== * Get the item refine chance (from refine.txt) for item at pos * return (npc) - * x : refine chance - * 0 : false (max refine level or unequip..) + * x : refine chance + * 0 : false (max refine level or unequip..) *------------------------------------------*/ BUILDIN(getequippercentrefinery) { int i = -1,num; TBL_PC *sd; - + num = script_getnum(st,2); sd = script->rid2sd(st); if( sd == NULL ) return true; - + if (num > 0 && num <= ARRAYLENGTH(script->equip)) i=pc->checkequip(sd,script->equip[num-1]); if(i >= 0 && sd->status.inventory[i].nameid && sd->status.inventory[i].refine < MAX_REFINE) script_pushint(st,status->get_refine_chance(itemdb_wlv(sd->status.inventory[i].nameid), (int)sd->status.inventory[i].refine)); else script_pushint(st,0); - + return true; } /*========================================== * Refine +1 item at pos and log and display refine *------------------------------------------*/ -BUILDIN(successrefitem) -{ - int i=-1,num,ep; +BUILDIN(successrefitem) { + int i = -1 , num, ep, up = 1; TBL_PC *sd; - + num = script_getnum(st,2); sd = script->rid2sd(st); if( sd == NULL ) return true; + + if( script_hasdata(st, 3) ) + up = script_getnum(st, 3); if (num > 0 && num <= ARRAYLENGTH(script->equip)) i=pc->checkequip(sd,script->equip[num-1]); if(i >= 0) { ep=sd->status.inventory[i].equip; - + //Logs items, got from (N)PC scripts [Lupus] logs->pick_pc(sd, LOG_TYPE_SCRIPT, -1, &sd->status.inventory[i],sd->inventory_data[i]); - + if (sd->status.inventory[i].refine >= MAX_REFINE) return true; - - sd->status.inventory[i].refine++; + + sd->status.inventory[i].refine += up; + sd->status.inventory[i].refine = cap_value( sd->status.inventory[i].refine, 0, MAX_REFINE); pc->unequipitem(sd,i,2); // status calc will happen in pc->equipitem() below - + clif->refine(sd->fd,0,i,sd->status.inventory[i].refine); clif->delitem(sd,i,1,3); - + //Logs items, got from (N)PC scripts [Lupus] logs->pick_pc(sd, LOG_TYPE_SCRIPT, 1, &sd->status.inventory[i],sd->inventory_data[i]); - + clif->additem(sd,i,1,0); pc->equipitem(sd,i,ep); clif->misceffect(&sd->bl,3); if(sd->status.inventory[i].refine == 10 && sd->status.inventory[i].card[0] == CARD0_FORGE && sd->status.char_id == (int)MakeDWord(sd->status.inventory[i].card[2],sd->status.inventory[i].card[3]) - ){ // Fame point system [DracoRPG] - switch (sd->inventory_data[i]->wlv){ + ) { // Fame point system [DracoRPG] + switch (sd->inventory_data[i]->wlv) { case 1: pc->addfame(sd,1); // Success to refine to +10 a lv1 weapon you forged = +1 fame point break; @@ -7150,7 +7739,7 @@ BUILDIN(successrefitem) } } } - + return true; } @@ -7161,24 +7750,24 @@ BUILDIN(failedrefitem) { int i=-1,num; TBL_PC *sd; - + num = script_getnum(st,2); sd = script->rid2sd(st); if( sd == NULL ) return true; - + if (num > 0 && num <= ARRAYLENGTH(script->equip)) i=pc->checkequip(sd,script->equip[num-1]); if(i >= 0) { sd->status.inventory[i].refine = 0; pc->unequipitem(sd,i,3); //recalculate bonus clif->refine(sd->fd,1,i,sd->status.inventory[i].refine); //notify client of failure - + pc->delitem(sd,i,1,0,2,LOG_TYPE_SCRIPT); - - clif->misceffect(&sd->bl,2); // display failure effect + + clif->misceffect(&sd->bl,2); // display failure effect } - + return true; } @@ -7189,37 +7778,37 @@ BUILDIN(downrefitem) { int i = -1,num,ep, down = 1; TBL_PC *sd; - + sd = script->rid2sd(st); if( sd == NULL ) return true; num = script_getnum(st,2); if( script_hasdata(st, 3) ) down = script_getnum(st, 3); - + if (num > 0 && num <= ARRAYLENGTH(script->equip)) i = pc->checkequip(sd,script->equip[num-1]); if(i >= 0) { ep = sd->status.inventory[i].equip; - + //Logs items, got from (N)PC scripts [Lupus] logs->pick_pc(sd, LOG_TYPE_SCRIPT, -1, &sd->status.inventory[i],sd->inventory_data[i]); - + pc->unequipitem(sd,i,2); // status calc will happen in pc->equipitem() below sd->status.inventory[i].refine -= down; sd->status.inventory[i].refine = cap_value( sd->status.inventory[i].refine, 0, MAX_REFINE); clif->refine(sd->fd,2,i,sd->status.inventory[i].refine); clif->delitem(sd,i,1,3); - + //Logs items, got from (N)PC scripts [Lupus] logs->pick_pc(sd, LOG_TYPE_SCRIPT, 1, &sd->status.inventory[i],sd->inventory_data[i]); - + clif->additem(sd,i,1,0); pc->equipitem(sd,i,ep); clif->misceffect(&sd->bl,2); } - + return true; } @@ -7230,37 +7819,36 @@ BUILDIN(delequip) { int i=-1,num; TBL_PC *sd; - + num = script_getnum(st,2); sd = script->rid2sd(st); if( sd == NULL ) return true; - + if (num > 0 && num <= ARRAYLENGTH(script->equip)) i=pc->checkequip(sd,script->equip[num-1]); if(i >= 0) { pc->unequipitem(sd,i,3); //recalculate bonus pc->delitem(sd,i,1,0,2,LOG_TYPE_SCRIPT); } - + return true; } /*========================================== * *------------------------------------------*/ -BUILDIN(statusup) -{ +BUILDIN(statusup) { int type; TBL_PC *sd; - + type=script_getnum(st,2); sd = script->rid2sd(st); if( sd == NULL ) return true; - - pc->statusup(sd,type); - + + pc->statusup(sd, type, 1); + return true; } /*========================================== @@ -7270,15 +7858,15 @@ BUILDIN(statusup2) { int type,val; TBL_PC *sd; - + type=script_getnum(st,2); val=script_getnum(st,3); sd = script->rid2sd(st); if( sd == NULL ) return true; - + pc->statusup2(sd,type,val); - + return true; } @@ -7289,8 +7877,7 @@ BUILDIN(statusup2) /// bonus3 <bonus type>,<val1>,<val2>,<val3>; /// bonus4 <bonus type>,<val1>,<val2>,<val3>,<val4>; /// bonus5 <bonus type>,<val1>,<val2>,<val3>,<val4>,<val5>; -BUILDIN(bonus) -{ +BUILDIN(bonus) { int type; int val1; int val2 = 0; @@ -7298,11 +7885,11 @@ BUILDIN(bonus) int val4 = 0; int val5 = 0; TBL_PC* sd; - + sd = script->rid2sd(st); if( sd == NULL ) return true; // no player attached - + type = script_getnum(st,2); switch( type ) { case SP_AUTOSPELL: @@ -7322,13 +7909,16 @@ BUILDIN(bonus) case SP_FIXCASTRATE: case SP_SKILL_USE_SP: // these bonuses support skill names - val1 = ( script_isstring(st,3) ? skill->name2id(script_getstr(st,3)) : script_getnum(st,3) ); - break; + if (script_isstringtype(st, 3)) { + val1 = skill->name2id(script_getstr(st, 3)); + break; + } + // else fall through default: val1 = script_getnum(st,3); break; } - + switch( script_lastdata(st)-2 ) { case 1: pc->bonus(sd, type, val1); @@ -7343,21 +7933,21 @@ BUILDIN(bonus) pc->bonus3(sd, type, val1, val2, val3); break; case 4: - if( type == SP_AUTOSPELL_ONSKILL && script_isstring(st,4) ) + if( type == SP_AUTOSPELL_ONSKILL && script_isstringtype(st,4) ) val2 = skill->name2id(script_getstr(st,4)); // 2nd value can be skill name else val2 = script_getnum(st,4); - + val3 = script_getnum(st,5); val4 = script_getnum(st,6); pc->bonus4(sd, type, val1, val2, val3, val4); break; case 5: - if( type == SP_AUTOSPELL_ONSKILL && script_isstring(st,4) ) + if( type == SP_AUTOSPELL_ONSKILL && script_isstringtype(st,4) ) val2 = skill->name2id(script_getstr(st,4)); // 2nd value can be skill name else val2 = script_getnum(st,4); - + val3 = script_getnum(st,5); val4 = script_getnum(st,6); val5 = script_getnum(st,7); @@ -7367,7 +7957,7 @@ BUILDIN(bonus) ShowDebug("buildin_bonus: unexpected number of arguments (%d)\n", (script_lastdata(st) - 1)); break; } - + return true; } @@ -7377,25 +7967,25 @@ BUILDIN(autobonus) { short atk_type = 0; TBL_PC* sd; const char *bonus_script, *other_script = NULL; - + sd = script->rid2sd(st); if( sd == NULL ) return true; // no player attached - + if( sd->state.autobonus&sd->status.inventory[status->current_equip_item_index].equip ) return true; - + rate = script_getnum(st,3); dur = script_getnum(st,4); bonus_script = script_getstr(st,2); if( !rate || !dur || !bonus_script ) return true; - + if( script_hasdata(st,5) ) atk_type = script_getnum(st,5); if( script_hasdata(st,6) ) other_script = script_getstr(st,6); - + if( pc->addautobonus(sd->autobonus,ARRAYLENGTH(sd->autobonus),bonus_script,rate,dur,atk_type,other_script, sd->status.inventory[status->current_equip_item_index].equip,false) ) { @@ -7403,7 +7993,7 @@ BUILDIN(autobonus) { if( other_script ) script->add_autobonus(other_script); } - + return true; } @@ -7413,25 +8003,25 @@ BUILDIN(autobonus2) { short atk_type = 0; TBL_PC* sd; const char *bonus_script, *other_script = NULL; - + sd = script->rid2sd(st); if( sd == NULL ) return true; // no player attached - + if( sd->state.autobonus&sd->status.inventory[status->current_equip_item_index].equip ) return true; - + rate = script_getnum(st,3); dur = script_getnum(st,4); bonus_script = script_getstr(st,2); if( !rate || !dur || !bonus_script ) return true; - + if( script_hasdata(st,5) ) atk_type = script_getnum(st,5); if( script_hasdata(st,6) ) other_script = script_getstr(st,6); - + if( pc->addautobonus(sd->autobonus2,ARRAYLENGTH(sd->autobonus2),bonus_script,rate,dur,atk_type,other_script, sd->status.inventory[status->current_equip_item_index].equip,false) ) { @@ -7439,7 +8029,7 @@ BUILDIN(autobonus2) { if( other_script ) script->add_autobonus(other_script); } - + return true; } @@ -7448,24 +8038,24 @@ BUILDIN(autobonus3) { short rate,atk_type; TBL_PC* sd; const char *bonus_script, *other_script = NULL; - + sd = script->rid2sd(st); if( sd == NULL ) return true; // no player attached - + if( sd->state.autobonus&sd->status.inventory[status->current_equip_item_index].equip ) return true; - + rate = script_getnum(st,3); dur = script_getnum(st,4); - atk_type = ( script_isstring(st,5) ? skill->name2id(script_getstr(st,5)) : script_getnum(st,5) ); + atk_type = ( script_isstringtype(st,5) ? skill->name2id(script_getstr(st,5)) : script_getnum(st,5) ); bonus_script = script_getstr(st,2); if( !rate || !dur || !atk_type || !bonus_script ) return true; - + if( script_hasdata(st,6) ) other_script = script_getstr(st,6); - + if( pc->addautobonus(sd->autobonus3,ARRAYLENGTH(sd->autobonus3),bonus_script,rate,dur,atk_type,other_script, sd->status.inventory[status->current_equip_item_index].equip,true) ) { @@ -7473,7 +8063,7 @@ BUILDIN(autobonus3) { if( other_script ) script->add_autobonus(other_script); } - + return true; } @@ -7487,23 +8077,22 @@ BUILDIN(autobonus3) { /// skill <skill id>,<level> /// skill "<skill name>",<level>,<flag> /// skill "<skill name>",<level> -BUILDIN(skill) -{ +BUILDIN(skill) { int id; int level; int flag = 1; TBL_PC* sd; - + sd = script->rid2sd(st); if( sd == NULL ) return true;// no player attached, report source - - id = ( script_isstring(st,2) ? skill->name2id(script_getstr(st,2)) : script_getnum(st,2) ); + + id = ( script_isstringtype(st,2) ? skill->name2id(script_getstr(st,2)) : script_getnum(st,2) ); level = script_getnum(st,3); if( script_hasdata(st,4) ) flag = script_getnum(st,4); pc->skill(sd, id, level, flag); - + return true; } @@ -7516,23 +8105,22 @@ BUILDIN(skill) /// addtoskill "<skill name>",<amount> /// /// @see skill -BUILDIN(addtoskill) -{ +BUILDIN(addtoskill) { int id; int level; int flag = 2; TBL_PC* sd; - + sd = script->rid2sd(st); if( sd == NULL ) return true;// no player attached, report source - - id = ( script_isstring(st,2) ? skill->name2id(script_getstr(st,2)) : script_getnum(st,2) ); + + id = ( script_isstringtype(st,2) ? skill->name2id(script_getstr(st,2)) : script_getnum(st,2) ); level = script_getnum(st,3); if( script_hasdata(st,4) ) flag = script_getnum(st,4); pc->skill(sd, id, level, flag); - + return true; } @@ -7540,22 +8128,21 @@ BUILDIN(addtoskill) /// /// guildskill <skill id>,<amount>; /// guildskill "<skill name>",<amount>; -BUILDIN(guildskill) -{ +BUILDIN(guildskill) { int id; int level; TBL_PC* sd; int i; - + sd = script->rid2sd(st); if( sd == NULL ) return true;// no player attached, report source - - id = ( script_isstring(st,2) ? skill->name2id(script_getstr(st,2)) : script_getnum(st,2) ); + + id = ( script_isstringtype(st,2) ? skill->name2id(script_getstr(st,2)) : script_getnum(st,2) ); level = script_getnum(st,3); for( i=0; i < level; i++ ) guild->skillup(sd, id); - + return true; } @@ -7563,18 +8150,17 @@ BUILDIN(guildskill) /// /// getskilllv(<skill id>) -> <level> /// getskilllv("<skill name>") -> <level> -BUILDIN(getskilllv) -{ +BUILDIN(getskilllv) { int id; TBL_PC* sd; - + sd = script->rid2sd(st); if( sd == NULL ) return true;// no player attached, report source - - id = ( script_isstring(st,2) ? skill->name2id(script_getstr(st,2)) : script_getnum(st,2) ); + + id = ( script_isstringtype(st,2) ? skill->name2id(script_getstr(st,2)) : script_getnum(st,2) ); script_pushint(st, pc->checkskill(sd,id)); - + return true; } @@ -7582,20 +8168,19 @@ BUILDIN(getskilllv) /// /// getgdskilllv(<guild id>,<skill id>) -> <level> /// getgdskilllv(<guild id>,"<skill name>") -> <level> -BUILDIN(getgdskilllv) -{ +BUILDIN(getgdskilllv) { int guild_id; uint16 skill_id; struct guild* g; - + guild_id = script_getnum(st,2); - skill_id = ( script_isstring(st,3) ? skill->name2id(script_getstr(st,3)) : script_getnum(st,3) ); + skill_id = ( script_isstringtype(st,3) ? skill->name2id(script_getstr(st,3)) : script_getnum(st,3) ); g = guild->search(guild_id); if( g == NULL ) script_pushint(st, -1); else script_pushint(st, guild->checkskill(g,skill_id)); - + return true; } @@ -7616,13 +8201,13 @@ BUILDIN(basicskillcheck) BUILDIN(getgmlevel) { TBL_PC* sd; - + sd = script->rid2sd(st); if( sd == NULL ) return true;// no player attached, report source - - script_pushint(st, pc->get_group_level(sd)); - + + script_pushint(st, pc_get_group_level(sd)); + return true; } @@ -7632,12 +8217,12 @@ BUILDIN(getgmlevel) BUILDIN(getgroupid) { TBL_PC* sd; - + sd = script->rid2sd(st); if (sd == NULL) return false; // no player attached, report source script_pushint(st, pc_get_group_id(sd)); - + return true; } @@ -7656,17 +8241,17 @@ BUILDIN(checkoption) { int option; TBL_PC* sd; - + sd = script->rid2sd(st); if( sd == NULL ) return true;// no player attached, report source - + option = script_getnum(st,2); if( sd->sc.option&option ) script_pushint(st, 1); else script_pushint(st, 0); - + return true; } @@ -7677,17 +8262,17 @@ BUILDIN(checkoption1) { int opt1; TBL_PC* sd; - + sd = script->rid2sd(st); if( sd == NULL ) return true;// no player attached, report source - + opt1 = script_getnum(st,2); if( sd->sc.opt1 == opt1 ) script_pushint(st, 1); else script_pushint(st, 0); - + return true; } @@ -7698,17 +8283,17 @@ BUILDIN(checkoption2) { int opt2; TBL_PC* sd; - + sd = script->rid2sd(st); if( sd == NULL ) return true;// no player attached, report source - + opt2 = script_getnum(st,2); if( sd->sc.opt2&opt2 ) script_pushint(st, 1); else script_pushint(st, 0); - + return true; } @@ -7724,28 +8309,28 @@ BUILDIN(setoption) int option; int flag = 1; TBL_PC* sd; - + sd = script->rid2sd(st); if( sd == NULL ) return true;// no player attached, report source - + option = script_getnum(st,2); if( script_hasdata(st,3) ) flag = script_getnum(st,3); - else if( !option ){// Request to remove everything. + else if( !option ) {// Request to remove everything. flag = 0; option = OPTION_FALCON|OPTION_RIDING; #ifndef NEW_CARTS option |= OPTION_CART; #endif } - if( flag ){// Add option + if( flag ) {// Add option if( option&OPTION_WEDDING && !battle_config.wedding_modifydisplay ) option &= ~OPTION_WEDDING;// Do not show the wedding sprites pc->setoption(sd, sd->sc.option|option); } else// Remove option pc->setoption(sd, sd->sc.option&~option); - + return true; } @@ -7757,16 +8342,16 @@ BUILDIN(setoption) BUILDIN(checkcart) { TBL_PC* sd; - + sd = script->rid2sd(st); if( sd == NULL ) return true;// no player attached, report source - + if( pc_iscarton(sd) ) script_pushint(st, 1); else script_pushint(st, 0); - + return true; } @@ -7785,15 +8370,15 @@ BUILDIN(setcart) { int type = 1; TBL_PC* sd; - + sd = script->rid2sd(st); if( sd == NULL ) return true;// no player attached, report source - + if( script_hasdata(st,2) ) type = script_getnum(st,2); pc->setcart(sd, type); - + return true; } @@ -7805,16 +8390,16 @@ BUILDIN(setcart) BUILDIN(checkfalcon) { TBL_PC* sd; - + sd = script->rid2sd(st); if( sd == NULL ) return true;// no player attached, report source - + if( pc_isfalcon(sd) ) script_pushint(st, 1); else script_pushint(st, 0); - + return true; } @@ -7827,16 +8412,16 @@ BUILDIN(setfalcon) { int flag = 1; TBL_PC* sd; - + sd = script->rid2sd(st); if( sd == NULL ) return true;// no player attached, report source - + if( script_hasdata(st,2) ) flag = script_getnum(st,2); - + pc->setfalcon(sd, flag); - + return true; } @@ -7848,16 +8433,16 @@ BUILDIN(setfalcon) BUILDIN(checkriding) { TBL_PC* sd; - + sd = script->rid2sd(st); if( sd == NULL ) return true;// no player attached, report source - + if( pc_isriding(sd) || pc_isridingwug(sd) || pc_isridingdragon(sd) ) script_pushint(st, 1); else script_pushint(st, 0); - + return true; } @@ -7870,15 +8455,15 @@ BUILDIN(setriding) { int flag = 1; TBL_PC* sd; - + sd = script->rid2sd(st); if( sd == NULL ) return true;// no player attached, report source - + if( script_hasdata(st,2) ) flag = script_getnum(st,2); pc->setriding(sd, flag); - + return true; } @@ -7889,16 +8474,16 @@ BUILDIN(setriding) BUILDIN(checkwug) { TBL_PC* sd; - + sd = script->rid2sd(st); if( sd == NULL ) return true;// no player attached, report source - + if( pc_iswug(sd) || pc_isridingwug(sd) ) script_pushint(st, 1); else script_pushint(st, 0); - + return true; } @@ -7909,16 +8494,16 @@ BUILDIN(checkwug) BUILDIN(checkmadogear) { TBL_PC* sd; - + sd = script->rid2sd(st); if( sd == NULL ) return true;// no player attached, report source - + if( pc_ismadogear(sd) ) script_pushint(st, 1); else script_pushint(st, 0); - + return true; } @@ -7931,15 +8516,15 @@ BUILDIN(setmadogear) { int flag = 1; TBL_PC* sd; - + sd = script->rid2sd(st); if( sd == NULL ) return true;// no player attached, report source - + if( script_hasdata(st,2) ) flag = script_getnum(st,2); pc->setmadogear(sd, flag); - + return true; } @@ -7953,18 +8538,18 @@ BUILDIN(savepoint) { short mapid; const char* str; TBL_PC* sd; - + sd = script->rid2sd(st); if( sd == NULL ) return true;// no player attached, report source - + str = script_getstr(st,2); x = script_getnum(st,3); y = script_getnum(st,4); - mapid = mapindex_name2id(str); + mapid = mapindex->name2id(str); if( mapid ) pc->setsavepoint(sd, mapid, x, y); - + return true; } @@ -7975,10 +8560,10 @@ BUILDIN(gettimetick) { /* Asgard Version */ int type; time_t clock; struct tm *t; - + type=script_getnum(st,2); - - switch(type){ + + switch(type) { case 2: //type 2:(Get the number of seconds elapsed since 00:00 hours, Jan 1, 1970 UTC // from the system clock.) @@ -7993,7 +8578,7 @@ BUILDIN(gettimetick) { /* Asgard Version */ case 0: default: //type 0:(System Ticks) - script_pushint(st,timer->gettick()); + script_pushint(st,(int)timer->gettick()); // TODO: change this to int64 when we'll support 64 bit script values break; } return true; @@ -8008,13 +8593,13 @@ BUILDIN(gettime) { /* Asgard Version */ int type; time_t clock; struct tm *t; - + type=script_getnum(st,2); - + time(&clock); t=localtime(&clock); - - switch(type){ + + switch(type) { case 1://Sec(0~59) script_pushint(st,t->tm_sec); break; @@ -8055,14 +8640,14 @@ BUILDIN(gettimestr) const char *fmtstr; int maxlen; time_t now = time(NULL); - + fmtstr=script_getstr(st,2); maxlen=script_getnum(st,3); - + tmpstr=(char *)aMalloc((maxlen+1)*sizeof(char)); strftime(tmpstr,maxlen,fmtstr,localtime(&now)); tmpstr[maxlen]='\0'; - + script_pushstr(st,tmpstr); return true; } @@ -8072,11 +8657,11 @@ BUILDIN(gettimestr) *------------------------------------------*/ BUILDIN(openstorage) { TBL_PC* sd; - + sd = script->rid2sd(st); if( sd == NULL ) return true; - + storage->open(sd); return true; } @@ -8084,11 +8669,11 @@ BUILDIN(openstorage) { BUILDIN(guildopenstorage) { TBL_PC* sd; int ret; - + sd = script->rid2sd(st); if( sd == NULL ) return true; - + ret = gstorage->open(sd); script_pushint(st,ret); return true; @@ -8103,12 +8688,12 @@ BUILDIN(itemskill) { int id; int lv; TBL_PC* sd; - + sd = script->rid2sd(st); if( sd == NULL || sd->ud.skilltimer != INVALID_TIMER ) return true; - - id = ( script_isstring(st,2) ? skill->name2id(script_getstr(st,2)) : script_getnum(st,2) ); + + id = ( script_isstringtype(st,2) ? skill->name2id(script_getstr(st,2)) : script_getnum(st,2) ); lv = script_getnum(st,3); /* temporarily disabled, awaiting for kenpachi to detail this so we can make it work properly */ #if 0 @@ -8129,11 +8714,11 @@ BUILDIN(produce) { int trigger; TBL_PC* sd; - + sd = script->rid2sd(st); if( sd == NULL ) return true; - + trigger=script_getnum(st,2); clif->skill_produce_mix_list(sd, -1, trigger); return true; @@ -8145,11 +8730,11 @@ BUILDIN(cooking) { int trigger; TBL_PC* sd; - + sd = script->rid2sd(st); if( sd == NULL ) return true; - + trigger=script_getnum(st,2); clif->cooking_list(sd, trigger, AM_PHARMACY, 1, 1); return true; @@ -8161,25 +8746,24 @@ BUILDIN(makepet) { TBL_PC* sd; int id,pet_id; - + id=script_getnum(st,2); sd = script->rid2sd(st); if( sd == NULL ) return true; - + pet_id = pet->search_petDB_index(id, PET_CLASS); - + if (pet_id < 0) pet_id = pet->search_petDB_index(id, PET_EGG); if (pet_id >= 0 && sd) { sd->catch_target_class = pet->db[pet_id].class_; - intif->create_pet( - sd->status.account_id, sd->status.char_id, - (short)pet->db[pet_id].class_, (short)mob->db(pet->db[pet_id].class_)->lv, - (short)pet->db[pet_id].EggID, 0, (short)pet->db[pet_id].intimate, - 100, 0, 1, pet->db[pet_id].jname); + intif->create_pet(sd->status.account_id, sd->status.char_id, + (short)pet->db[pet_id].class_, (short)mob->db(pet->db[pet_id].class_)->lv, + (short)pet->db[pet_id].EggID, 0, (short)pet->db[pet_id].intimate, + 100, 0, 1, pet->db[pet_id].jname); } - + return true; } /*========================================== @@ -8190,23 +8774,23 @@ BUILDIN(getexp) TBL_PC* sd; int base=0,job=0; double bonus; - + sd = script->rid2sd(st); if( sd == NULL ) return true; - + base=script_getnum(st,2); job =script_getnum(st,3); if(base<0 || job<0) return true; - + // bonus for npc-given exp bonus = battle_config.quest_exp_rate / 100.; base = (int) cap_value(base * bonus, 0, INT_MAX); job = (int) cap_value(job * bonus, 0, INT_MAX); - + pc->gainexp(sd, NULL, base, job, true); - + return true; } @@ -8217,17 +8801,17 @@ BUILDIN(guildgetexp) { TBL_PC* sd; int exp; - + sd = script->rid2sd(st); if( sd == NULL ) return true; - + exp = script_getnum(st,2); if(exp < 0) return true; if(sd && sd->status.guild_id > 0) guild->getexp (sd, exp); - + return true; } @@ -8238,49 +8822,49 @@ BUILDIN(guildchangegm) { TBL_PC *sd; int guild_id; const char *name; - + guild_id = script_getnum(st,2); name = script_getstr(st,3); sd=map->nick2sd(name); - + if (!sd) script_pushint(st,0); else script_pushint(st,guild->gm_change(guild_id, sd)); - + return true; } /*========================================== * Spawn a monster : - @mapn,x,y : location - @str : monster name - @class_ : mob_id - @amount : nb to spawn - @event : event to attach to mob + * @mapn,x,y : location + * @str : monster name + * @class_ : mob_id + * @amount : nb to spawn + * @event : event to attach to mob *------------------------------------------*/ BUILDIN(monster) { - const char* mapn = script_getstr(st,2); - int x = script_getnum(st,3); - int y = script_getnum(st,4); - const char* str = script_getstr(st,5); - int class_ = script_getnum(st,6); - int amount = script_getnum(st,7); - const char* event = ""; - unsigned int size = SZ_SMALL; - unsigned int ai = AI_NONE; + const char *mapn = script_getstr(st,2); + int x = script_getnum(st,3); + int y = script_getnum(st,4); + const char *str = script_getstr(st,5); + int class_ = script_getnum(st,6); + int amount = script_getnum(st,7); + const char *event = ""; + unsigned int size = SZ_MEDIUM; + unsigned int ai = AI_NONE; int mob_id; - + struct map_session_data* sd; int16 m; - + if (script_hasdata(st, 8)) { event = script_getstr(st, 8); script->check_event(st, event); } - + if (script_hasdata(st, 9)) { size = script_getnum(st, 9); @@ -8290,7 +8874,7 @@ BUILDIN(monster) return false; } } - + if (script_hasdata(st, 10)) { ai = script_getnum(st, 10); @@ -8300,15 +8884,15 @@ BUILDIN(monster) return false; } } - + if (class_ >= 0 && !mob->db_checkid(class_)) { ShowWarning("buildin_monster: Attempted to spawn non-existing monster class %d\n", class_); return false; } - + sd = map->id2sd(st->rid); - + if (sd && strcmp(mapn, "this") == 0) m = sd->bl.m; else { @@ -8316,7 +8900,7 @@ BUILDIN(monster) ShowWarning("buildin_monster: Attempted to spawn monster class %d on non-existing map '%s'\n",class_, mapn); return false; } - + if (map->list[m].flag.src4instance && st->instance_id >= 0) { // Try to redirect to the instance map, not the src map if ((m = instance->mapid2imapid(m, st->instance_id)) < 0) { ShowError("buildin_monster: Trying to spawn monster (%d) on instance map (%s) without instance attached.\n", class_, mapn); @@ -8324,7 +8908,7 @@ BUILDIN(monster) } } } - + mob_id = mob->once_spawn(sd, m, x, y, str, class_, amount, event, size, ai); script_pushint(st, mob_id); return true; @@ -8337,59 +8921,58 @@ BUILDIN(getmobdrops) int class_ = script_getnum(st,2); int i, j = 0; struct mob_db *monster; - + if( !mob->db_checkid(class_) ) { script_pushint(st, 0); return true; } - + monster = mob->db(class_); - + for( i = 0; i < MAX_MOB_DROP; i++ ) { if( monster->dropitem[i].nameid < 1 ) continue; if( itemdb->exists(monster->dropitem[i].nameid) == NULL ) continue; - + mapreg->setreg(reference_uid(script->add_str("$@MobDrop_item"), j), monster->dropitem[i].nameid); mapreg->setreg(reference_uid(script->add_str("$@MobDrop_rate"), j), monster->dropitem[i].p); - + j++; } - + mapreg->setreg(script->add_str("$@MobDrop_count"), j); script_pushint(st, 1); - + return true; } /*========================================== * Same as monster but randomize location in x0,x1,y0,y1 area *------------------------------------------*/ -BUILDIN(areamonster) -{ - const char* mapn = script_getstr(st,2); - int x0 = script_getnum(st,3); - int y0 = script_getnum(st,4); - int x1 = script_getnum(st,5); - int y1 = script_getnum(st,6); - const char* str = script_getstr(st,7); - int class_ = script_getnum(st,8); - int amount = script_getnum(st,9); - const char* event = ""; - unsigned int size = SZ_SMALL; - unsigned int ai = AI_NONE; +BUILDIN(areamonster) { + const char *mapn = script_getstr(st,2); + int x0 = script_getnum(st,3); + int y0 = script_getnum(st,4); + int x1 = script_getnum(st,5); + int y1 = script_getnum(st,6); + const char *str = script_getstr(st,7); + int class_ = script_getnum(st,8); + int amount = script_getnum(st,9); + const char *event = ""; + unsigned int size = SZ_MEDIUM; + unsigned int ai = AI_NONE; int mob_id; - + struct map_session_data* sd; int16 m; - + if (script_hasdata(st,10)) { event = script_getstr(st, 10); script->check_event(st, event); } - + if (script_hasdata(st, 11)) { size = script_getnum(st, 11); if (size > 3) { @@ -8397,7 +8980,7 @@ BUILDIN(areamonster) return false; } } - + if (script_hasdata(st, 12)) { ai = script_getnum(st, 12); if (ai > 4) { @@ -8405,9 +8988,9 @@ BUILDIN(areamonster) return false; } } - + sd = map->id2sd(st->rid); - + if (sd && strcmp(mapn, "this") == 0) m = sd->bl.m; else { @@ -8422,10 +9005,10 @@ BUILDIN(areamonster) } } } - + mob_id = mob->once_spawn_area(sd, m, x0, y0, x1, y1, str, class_, amount, event, size, ai); script_pushint(st, mob_id); - + return true; } /*========================================== @@ -8436,13 +9019,13 @@ int buildin_killmonster_sub_strip(struct block_list *bl,va_list ap) TBL_MOB* md = (TBL_MOB*)bl; char *event=va_arg(ap,char *); int allflag=va_arg(ap,int); - + md->state.npc_killmonster = 1; - - if(!allflag){ + + if(!allflag) { if(strcmp(event,md->npc_event)==0) status_kill(bl); - }else{ + } else { if(!md->spawn) status_kill(bl); } @@ -8454,11 +9037,11 @@ int buildin_killmonster_sub(struct block_list *bl,va_list ap) TBL_MOB* md = (TBL_MOB*)bl; char *event=va_arg(ap,char *); int allflag=va_arg(ap,int); - - if(!allflag){ + + if(!allflag) { if(strcmp(event,md->npc_event)==0) status_kill(bl); - }else{ + } else { if(!md->spawn) status_kill(bl); } @@ -8473,20 +9056,20 @@ BUILDIN(killmonster) { allflag = 1; else script->check_event(st, event); - + if( (m=map->mapname2mapid(mapname))<0 ) return true; - + if( map->list[m].flag.src4instance && st->instance_id >= 0 && (m = instance->mapid2imapid(m, st->instance_id)) < 0 ) return true; - + if( script_hasdata(st,4) ) { if ( script_getnum(st,4) == 1 ) { map->foreachinmap(script->buildin_killmonster_sub, m, BL_MOB, event ,allflag); return true; } } - + map->freeblock_lock(); map->foreachinmap(script->buildin_killmonster_sub_strip, m, BL_MOB, event ,allflag); map->freeblock_unlock(); @@ -8496,11 +9079,11 @@ BUILDIN(killmonster) { int buildin_killmonsterall_sub_strip(struct block_list *bl,va_list ap) { //Strips the event from the mob if it's killed the old method. struct mob_data *md; - + md = BL_CAST(BL_MOB, bl); if (md->npc_event[0]) md->npc_event[0] = 0; - + status_kill(bl); return 0; } @@ -8513,20 +9096,20 @@ BUILDIN(killmonsterall) { const char *mapname; int16 m; mapname=script_getstr(st,2); - + if( (m = map->mapname2mapid(mapname))<0 ) return true; - + if( map->list[m].flag.src4instance && st->instance_id >= 0 && (m = instance->mapid2imapid(m, st->instance_id)) < 0 ) return true; - + if( script_hasdata(st,3) ) { if ( script_getnum(st,3) == 1 ) { map->foreachinmap(script->buildin_killmonsterall_sub,m,BL_MOB); return true; } } - + map->foreachinmap(script->buildin_killmonsterall_sub_strip,m,BL_MOB); return true; } @@ -8540,32 +9123,32 @@ BUILDIN(clone) { int char_id,master_id=0,x,y, mode = 0, flag = 0, m; unsigned int duration = 0; const char *mapname, *event=""; - + mapname=script_getstr(st,2); x=script_getnum(st,3); y=script_getnum(st,4); event=script_getstr(st,5); char_id=script_getnum(st,6); - + if( script_hasdata(st,7) ) master_id=script_getnum(st,7); - + if( script_hasdata(st,8) ) mode=script_getnum(st,8); - + if( script_hasdata(st,9) ) flag=script_getnum(st,9); - + if( script_hasdata(st,10) ) duration=script_getnum(st,10); - + script->check_event(st, event); - + m = map->mapname2mapid(mapname); if (m < 0) return true; - + sd = map->charid2sd(char_id); - + if (master_id) { msd = map->charid2sd(master_id); if (msd) @@ -8577,7 +9160,7 @@ BUILDIN(clone) { script_pushint(st,mob->clone_spawn(sd, m, x, y, event, master_id, mode, flag, 1000*duration)); else //Failed to create clone. script_pushint(st,0); - + return true; } /*========================================== @@ -8586,12 +9169,12 @@ BUILDIN(doevent) { const char* event = script_getstr(st,2); struct map_session_data* sd; - + if( ( sd = script->rid2sd(st) ) == NULL ) { return true; } - + script->check_event(st, event); npc->event(sd, event, 0); return true; @@ -8612,9 +9195,8 @@ BUILDIN(donpcevent) } /// for Aegis compatibility -/// basically a specialized 'donpcevent', with the event specified as two arguments instead of one -BUILDIN(cmdothernpc) // Added by RoVeRT -{ +/// basically a specialized 'donpcevent', with the event specified as two arguments instead of one [RoVeRT] +BUILDIN(cmdothernpc) { const char* npc_name = script_getstr(st,2); const char* command = script_getstr(st,3); char event[EVENT_NAME_LENGTH]; @@ -8631,12 +9213,12 @@ BUILDIN(addtimer) int tick = script_getnum(st,2); const char* event = script_getstr(st, 3); TBL_PC* sd; - + script->check_event(st, event); sd = script->rid2sd(st); if( sd == NULL ) return true; - + pc->addeventtimer(sd,tick,event); return true; } @@ -8646,12 +9228,12 @@ BUILDIN(deltimer) { const char *event; TBL_PC* sd; - + event=script_getstr(st, 2); sd = script->rid2sd(st); if( sd == NULL ) return true; - + script->check_event(st, event); pc->deleventtimer(sd,event); return true; @@ -8663,13 +9245,13 @@ BUILDIN(addtimercount) const char *event; int tick; TBL_PC* sd; - + event=script_getstr(st, 2); tick=script_getnum(st,3); sd = script->rid2sd(st); if( sd == NULL ) return true; - + script->check_event(st, event); pc->addeventtimercount(sd,event,tick); return true; @@ -8681,17 +9263,16 @@ BUILDIN(initnpctimer) { struct npc_data *nd; int flag = 0; - - if( script_hasdata(st,3) ) - { //Two arguments: NPC name and attach flag. + + if( script_hasdata(st,3) ) { + //Two arguments: NPC name and attach flag. nd = npc->name2id(script_getstr(st, 2)); flag = script_getnum(st,3); - } - else if( script_hasdata(st,2) ) - { //Check if argument is numeric (flag) or string (npc name) + } else if( script_hasdata(st,2) ) { + //Check if argument is numeric (flag) or string (npc name) struct script_data *data; data = script_getdata(st,2); - script->get_val(st,data); + script->get_val(st,data); // dereference if it's a variable if( data_isstring(data) ) //NPC name nd = npc->name2id(script->conv_str(st, data)); else if( data_isint(data) ) { @@ -8704,7 +9285,7 @@ BUILDIN(initnpctimer) } } else nd = (struct npc_data *)map->id2bl(st->oid); - + if( !nd ) return true; if( flag ) //Attach @@ -8714,7 +9295,7 @@ BUILDIN(initnpctimer) return true; nd->u.scr.rid = sd->bl.id; } - + nd->u.scr.timertick = 0; npc->settimerevent_tick(nd,0); npc->timerevent_start(nd, st->rid); @@ -8726,17 +9307,16 @@ BUILDIN(startnpctimer) { struct npc_data *nd; int flag = 0; - - if( script_hasdata(st,3) ) - { //Two arguments: NPC name and attach flag. + + if( script_hasdata(st,3) ) { + //Two arguments: NPC name and attach flag. nd = npc->name2id(script_getstr(st, 2)); flag = script_getnum(st,3); - } - else if( script_hasdata(st,2) ) - { //Check if argument is numeric (flag) or string (npc name) + } else if( script_hasdata(st,2) ) { + //Check if argument is numeric (flag) or string (npc name) struct script_data *data; data = script_getdata(st,2); - script->get_val(st,data); + script->get_val(st,data); // dereference if it's a variable if( data_isstring(data) ) //NPC name nd = npc->name2id(script->conv_str(st, data)); else if( data_isint(data) ) { @@ -8749,7 +9329,7 @@ BUILDIN(startnpctimer) } } else nd=(struct npc_data *)map->id2bl(st->oid); - + if( !nd ) return true; if( flag ) //Attach @@ -8759,7 +9339,7 @@ BUILDIN(startnpctimer) return true; nd->u.scr.rid = sd->bl.id; } - + npc->timerevent_start(nd, st->rid); return true; } @@ -8768,17 +9348,16 @@ BUILDIN(startnpctimer) BUILDIN(stopnpctimer) { struct npc_data *nd; int flag = 0; - - if( script_hasdata(st,3) ) - { //Two arguments: NPC name and attach flag. + + if( script_hasdata(st,3) ) { + //Two arguments: NPC name and attach flag. nd = npc->name2id(script_getstr(st, 2)); flag = script_getnum(st,3); - } - else if( script_hasdata(st,2) ) - { //Check if argument is numeric (flag) or string (npc name) + } else if( script_hasdata(st,2) ) { + //Check if argument is numeric (flag) or string (npc name) struct script_data *data; data = script_getdata(st,2); - script->get_val(st,data); + script->get_val(st,data); // Dereference if it's a variable if( data_isstring(data) ) //NPC name nd = npc->name2id(script->conv_str(st, data)); else if( data_isint(data) ) { @@ -8791,12 +9370,12 @@ BUILDIN(stopnpctimer) { } } else nd=(struct npc_data *)map->id2bl(st->oid); - + if( !nd ) return true; if( flag ) //Detach nd->u.scr.rid = 0; - + npc->timerevent_stop(nd); return true; } @@ -8807,21 +9386,21 @@ BUILDIN(getnpctimer) { TBL_PC *sd; int type = script_getnum(st,2); int val = 0; - + if( script_hasdata(st,3) ) nd = npc->name2id(script_getstr(st,3)); else nd = (struct npc_data *)map->id2bl(st->oid); - + if( !nd || nd->bl.type != BL_NPC ) { script_pushint(st,0); ShowError("getnpctimer: Invalid NPC.\n"); return false; } - + switch( type ) { - case 0: val = npc->gettimerevent_tick(nd); break; + case 0: val = (int)npc->gettimerevent_tick(nd); break; // FIXME: change this to int64 when we'll support 64 bit script values case 1: if( nd->u.scr.rid ) { sd = map->id2sd(nd->u.scr.rid); @@ -8836,7 +9415,7 @@ BUILDIN(getnpctimer) { break; case 2: val = nd->u.scr.timeramount; break; } - + script_pushint(st,val); return true; } @@ -8846,19 +9425,19 @@ BUILDIN(setnpctimer) { int tick; struct npc_data *nd; - + tick = script_getnum(st,2); if( script_hasdata(st,3) ) nd = npc->name2id(script_getstr(st,3)); else nd = (struct npc_data *)map->id2bl(st->oid); - + if( !nd || nd->bl.type != BL_NPC ) { script_pushint(st,1); ShowError("setnpctimer: Invalid NPC.\n"); return false; } - + npc->settimerevent_tick(nd,tick); script_pushint(st,0); return true; @@ -8870,26 +9449,26 @@ BUILDIN(setnpctimer) BUILDIN(attachnpctimer) { TBL_PC *sd; struct npc_data *nd = (struct npc_data *)map->id2bl(st->oid); - + if( !nd || nd->bl.type != BL_NPC ) { script_pushint(st,1); ShowError("setnpctimer: Invalid NPC.\n"); return false; } - + if( script_hasdata(st,2) ) sd = map->nick2sd(script_getstr(st,2)); else sd = script->rid2sd(st); - + if( !sd ) { script_pushint(st,1); ShowWarning("attachnpctimer: Invalid player.\n"); return false; } - + nd->u.scr.rid = sd->bl.id; script_pushint(st,0); return true; @@ -8900,19 +9479,19 @@ BUILDIN(attachnpctimer) { *------------------------------------------*/ BUILDIN(detachnpctimer) { struct npc_data *nd; - + if( script_hasdata(st,2) ) nd = npc->name2id(script_getstr(st,2)); else nd = (struct npc_data *)map->id2bl(st->oid); - + if( !nd || nd->bl.type != BL_NPC ) { script_pushint(st,1); ShowError("detachnpctimer: Invalid NPC.\n"); return false; } - + nd->u.scr.rid = 0; script_pushint(st,0); return true; @@ -8941,14 +9520,14 @@ BUILDIN(announce) { int fontSize = script_hasdata(st,6) ? script_getnum(st,6) : 12; // default fontSize int fontAlign = script_hasdata(st,7) ? script_getnum(st,7) : 0; // default fontAlign int fontY = script_hasdata(st,8) ? script_getnum(st,8) : 0; // default fontY - + if( flag&(BC_TARGET_MASK|BC_SOURCE_MASK) ) { // Broadcast source or broadcast region defined send_target target; struct block_list *bl = (flag&BC_NPC) ? map->id2bl(st->oid) : (struct block_list *)script->rid2sd(st); // If bc_npc flag is set, use NPC as broadcast source if (bl == NULL) return true; - + switch( flag&BC_TARGET_MASK ) { case BC_MAP: target = ALL_SAMEMAP; break; case BC_AREA: target = AREA; break; @@ -8957,12 +9536,12 @@ BUILDIN(announce) { } if (fontColor) - clif->broadcast2(bl, mes, (int)strlen(mes)+1, strtol(fontColor, (char **)NULL, 0), fontType, fontSize, fontAlign, fontY, target); + clif->broadcast2(bl, mes, (int)strlen(mes)+1, (unsigned int)strtoul(fontColor, (char **)NULL, 0), fontType, fontSize, fontAlign, fontY, target); else clif->broadcast(bl, mes, (int)strlen(mes)+1, flag&BC_COLOR_MASK, target); } else { if (fontColor) - intif->broadcast2(mes, (int)strlen(mes)+1, strtol(fontColor, (char **)NULL, 0), fontType, fontSize, fontAlign, fontY); + intif->broadcast2(mes, (int)strlen(mes)+1, (unsigned int)strtoul(fontColor, (char **)NULL, 0), fontType, fontSize, fontAlign, fontY); else intif->broadcast(mes, (int)strlen(mes)+1, flag&BC_COLOR_MASK); } @@ -8981,7 +9560,7 @@ int buildin_announce_sub(struct block_list *bl, va_list ap) short fontAlign = (short)va_arg(ap, int); short fontY = (short)va_arg(ap, int); if (fontColor) - clif->broadcast2(bl, mes, len, strtol(fontColor, (char **)NULL, 0), fontType, fontSize, fontAlign, fontY, SELF); + clif->broadcast2(bl, mes, len, (unsigned int)strtoul(fontColor, (char **)NULL, 0), fontType, fontSize, fontAlign, fontY, SELF); else clif->broadcast(bl, mes, len, type, SELF); return 0; @@ -8992,36 +9571,29 @@ int buildin_announce_sub(struct block_list *bl, va_list ap) BUILDIN(itemeffect) { TBL_NPC *nd; TBL_PC *sd; - struct script_data *data; struct item_data *item_data; - - nullpo_retr( 1, ( sd = script->rid2sd( st ) ) ); - nullpo_retr( 1, ( nd = (TBL_NPC *)map->id2bl( sd->npc_id ) ) ); - - data = script_getdata( st, 2 ); - script->get_val( st, data ); - - if( data_isstring( data ) ){ - const char *name = script->conv_str( st, data ); - - if( ( item_data = itemdb->search_name( name ) ) == NULL ){ + + nullpo_retr( false, ( sd = script->rid2sd( st ) ) ); + nullpo_retr( false, ( nd = (TBL_NPC *)map->id2bl( sd->npc_id ) ) ); + + if( script_isstringtype(st, 2) ) { + const char *name = script_getstr(st, 2); + + if( ( item_data = itemdb->search_name( name ) ) == NULL ) { ShowError( "buildin_itemeffect: Nonexistant item %s requested.\n", name ); return false; } - } else if( data_isint( data ) ){ - int nameid = script->conv_num( st, data ); - - if( ( item_data = itemdb->exists( nameid ) ) == NULL ){ + } else { + int nameid = script_getnum(st, 2); + + if( ( item_data = itemdb->exists( nameid ) ) == NULL ) { ShowError("buildin_itemeffect: Nonexistant item %d requested.\n", nameid ); return false; } - } else { - ShowError("buildin_itemeffect: invalid data type for argument #1 (%d).", data->type ); - return false; } - + script->run( item_data->script, 0, sd->bl.id, nd->bl.id ); - + return true; } @@ -9035,10 +9607,10 @@ BUILDIN(mapannounce) { int fontAlign = script_hasdata(st,8) ? script_getnum(st,8) : 0; // default fontAlign int fontY = script_hasdata(st,9) ? script_getnum(st,9) : 0; // default fontY int16 m; - + if ((m = map->mapname2mapid(mapname)) < 0) return true; - + map->foreachinmap(script->buildin_announce_sub, m, BL_PC, mes, strlen(mes)+1, flag&BC_COLOR_MASK, fontColor, fontType, fontSize, fontAlign, fontY); return true; @@ -9059,10 +9631,10 @@ BUILDIN(areaannounce) { int fontAlign = script_hasdata(st,12) ? script_getnum(st,12) : 0; // default fontAlign int fontY = script_hasdata(st,13) ? script_getnum(st,13) : 0; // default fontY int16 m; - + if ((m = map->mapname2mapid(mapname)) < 0) return true; - + map->foreachinarea(script->buildin_announce_sub, m, x0, y0, x1, y1, BL_PC, mes, strlen(mes)+1, flag&BC_COLOR_MASK, fontColor, fontType, fontSize, fontAlign, fontY); return true; @@ -9074,9 +9646,9 @@ BUILDIN(getusers) { int flag, val = 0; struct map_session_data* sd; struct block_list* bl = NULL; - + flag = script_getnum(st,2); - + switch(flag&0x07) { case 0: if(flag&0x8) { @@ -9086,7 +9658,7 @@ BUILDIN(getusers) { // pc bl = &sd->bl; } - + if(bl) { val = map->list[bl->m].users; } @@ -9099,7 +9671,7 @@ BUILDIN(getusers) { script_pushint(st,0); return false; } - + script_pushint(st,val); return true; } @@ -9111,17 +9683,17 @@ BUILDIN(getusersname) TBL_PC *sd, *pl_sd; int /*disp_num=1,*/ group_level = 0; struct s_mapiterator* iter; - + sd = script->rid2sd(st); if (!sd) return true; - - group_level = pc->get_group_level(sd); + + group_level = pc_get_group_level(sd); iter = mapit_getallusers(); for( pl_sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); pl_sd = (TBL_PC*)mapit->next(iter) ) { - if (pc->has_permission(pl_sd, PC_PERM_HIDE_SESSION) && pc->get_group_level(pl_sd) > group_level) + if (pc_has_permission(pl_sd, PC_PERM_HIDE_SESSION) && pc_get_group_level(pl_sd) > group_level) continue; // skip hidden sessions - + /* Temporary fix for bugreport:1023. * Do not uncomment unless you want thousands of 'next' buttons. if((disp_num++)%10==0) @@ -9129,7 +9701,7 @@ BUILDIN(getusersname) clif->scriptmes(sd,st->oid,pl_sd->status.name); } mapit->free(iter); - + return true; } /*========================================== @@ -9149,15 +9721,15 @@ BUILDIN(getmapguildusers) return true; } g = guild->search(gid); - - if (g){ + + if (g) { for(i = 0; i < g->max_member; i++) { if (g->member[i].sd && g->member[i].sd->bl.m == m) c++; } } - + script_pushint(st,c); return true; } @@ -9167,7 +9739,7 @@ BUILDIN(getmapusers) { const char *str; int16 m; str=script_getstr(st,2); - if( (m=map->mapname2mapid(str))< 0){ + if( (m=map->mapname2mapid(str))< 0) { script_pushint(st,-1); return true; } @@ -9191,7 +9763,7 @@ BUILDIN(getareausers) y0=script_getnum(st,4); x1=script_getnum(st,5); y1=script_getnum(st,6); - if( (m=map->mapname2mapid(str))< 0){ + if( (m=map->mapname2mapid(str))< 0) { script_pushint(st,-1); return true; } @@ -9208,37 +9780,34 @@ int buildin_getareadropitem_sub(struct block_list *bl,va_list ap) int item=va_arg(ap,int); int *amount=va_arg(ap,int *); struct flooritem_data *drop=(struct flooritem_data *)bl; - + if(drop->item_data.nameid==item) (*amount)+=drop->item_data.amount; - + return 0; } -BUILDIN(getareadropitem) -{ +BUILDIN(getareadropitem) { const char *str; int16 m,x0,y0,x1,y1; int item,amount=0; - struct script_data *data; - + str=script_getstr(st,2); x0=script_getnum(st,3); y0=script_getnum(st,4); x1=script_getnum(st,5); y1=script_getnum(st,6); - - data=script_getdata(st,7); - script->get_val(st,data); - if( data_isstring(data) ){ - const char *name=script->conv_str(st,data); + + if( script_isstringtype(st, 7) ) { + const char *name = script_getstr(st, 7); struct item_data *item_data = itemdb->search_name(name); item=UNKNOWN_ITEM_ID; if( item_data ) item=item_data->nameid; - }else - item=script->conv_num(st,data); - - if( (m=map->mapname2mapid(str))< 0){ + } else { + item=script_getnum(st, 7); + } + + if( (m=map->mapname2mapid(str))< 0) { script_pushint(st,-1); return true; } @@ -9294,7 +9863,7 @@ BUILDIN(sc_start) { int tick; int val1; int val4 = 0; - + type = (sc_type)script_getnum(st,2); tick = script_getnum(st,3); val1 = script_getnum(st,4); @@ -9302,22 +9871,22 @@ BUILDIN(sc_start) { bl = map->id2bl(script_getnum(st,5)); else bl = map->id2bl(st->rid); - + if( tick == 0 && val1 > 0 && type > SC_NONE && type < SC_MAX && status->sc2skill(type) != 0 ) { // When there isn't a duration specified, try to get it from the skill_db tick = skill->get_time(status->sc2skill(type), val1); } - + if( script->potion_flag == 1 && script->potion_target ) { //skill.c set the flags before running the script, this must be a potion-pitched effect. bl = map->id2bl(script->potion_target); tick /= 2;// Thrown potions only last half. val4 = 1;// Mark that this was a thrown sc_effect } - + if( bl ) - status->change_start(bl, type, 10000, val1, 0, 0, val4, tick, 2); - + status->change_start(NULL, bl, type, 10000, val1, 0, 0, val4, tick, 2); + return true; } @@ -9331,7 +9900,7 @@ BUILDIN(sc_start2) { int val1; int val4 = 0; int rate; - + type = (sc_type)script_getnum(st,2); tick = script_getnum(st,3); val1 = script_getnum(st,4); @@ -9340,22 +9909,22 @@ BUILDIN(sc_start2) { bl = map->id2bl(script_getnum(st,6)); else bl = map->id2bl(st->rid); - + if( tick == 0 && val1 > 0 && type > SC_NONE && type < SC_MAX && status->sc2skill(type) != 0 ) { // When there isn't a duration specified, try to get it from the skill_db tick = skill->get_time(status->sc2skill(type), val1); } - + if( script->potion_flag == 1 && script->potion_target ) { //skill.c set the flags before running the script, this must be a potion-pitched effect. bl = map->id2bl(script->potion_target); tick /= 2;// Thrown potions only last half. val4 = 1;// Mark that this was a thrown sc_effect } - + if( bl ) - status->change_start(bl, type, rate, val1, 0, 0, val4, tick, 2); - + status->change_start(NULL, bl, type, rate, val1, 0, 0, val4, tick, 2); + return true; } @@ -9370,7 +9939,7 @@ BUILDIN(sc_start4) { int val2; int val3; int val4; - + type = (sc_type)script_getnum(st,2); tick = script_getnum(st,3); val1 = script_getnum(st,4); @@ -9381,21 +9950,21 @@ BUILDIN(sc_start4) { bl = map->id2bl(script_getnum(st,8)); else bl = map->id2bl(st->rid); - + if( tick == 0 && val1 > 0 && type > SC_NONE && type < SC_MAX && status->sc2skill(type) != 0 ) { // When there isn't a duration specified, try to get it from the skill_db tick = skill->get_time(status->sc2skill(type), val1); } - + if( script->potion_flag == 1 && script->potion_target ) { //skill.c set the flags before running the script, this must be a potion-pitched effect. bl = map->id2bl(script->potion_target); tick /= 2;// Thrown potions only last half. } - + if( bl ) - status->change_start(bl, type, 10000, val1, val2, val3, val4, tick, 2); - + status->change_start(NULL, bl, type, 10000, val1, val2, val3, val4, tick, 2); + return true; } @@ -9405,26 +9974,27 @@ BUILDIN(sc_start4) { BUILDIN(sc_end) { struct block_list* bl; int type; - + type = script_getnum(st, 2); if (script_hasdata(st, 3)) bl = map->id2bl(script_getnum(st, 3)); else bl = map->id2bl(st->rid); - + if (script->potion_flag == 1 && script->potion_target) //##TODO how does this work [FlavioJS] bl = map->id2bl(script->potion_target); - + if (!bl) return true; - + if (type >= 0 && type < SC_MAX) { struct status_change *sc = status->get_sc(bl); struct status_change_entry *sce = sc ? sc->data[type] : NULL; - + if (!sce) return true; - + + /* status that can't be individually removed (TODO sc_config option?) */ switch (type) { case SC_WEIGHTOVER50: case SC_WEIGHTOVER90: @@ -9434,14 +10004,14 @@ BUILDIN(sc_end) { default: break; } - + //This should help status_change_end force disabling the SC in case it has no limit. sce->val1 = sce->val2 = sce->val3 = sce->val4 = 0; status_change_end(bl, (sc_type)type, INVALID_TIMER); } else status->change_clear(bl, 3); // remove all effects - + return true; } @@ -9451,17 +10021,17 @@ BUILDIN(sc_end) { BUILDIN(getscrate) { struct block_list *bl; int type,rate; - + type=script_getnum(st,2); rate=script_getnum(st,3); if( script_hasdata(st,4) ) //get for the bl assigned bl = map->id2bl(script_getnum(st,4)); else bl = map->id2bl(st->rid); - + if (bl) - rate = status->get_sc_def(bl, (sc_type)type, 10000, 10000, 0); - + rate = status->get_sc_def(bl, bl, (sc_type)type, 10000, 10000, 0); + script_pushint(st,rate); return true; } @@ -9473,45 +10043,45 @@ BUILDIN(getstatus) { int id, type; struct map_session_data* sd = script->rid2sd(st); - + if( sd == NULL ) {// no player attached return true; } - + id = script_getnum(st, 2); type = script_hasdata(st, 3) ? script_getnum(st, 3) : 0; - + if( id <= SC_NONE || id >= SC_MAX ) {// invalid status type given ShowWarning("script.c:getstatus: Invalid status type given (%d).\n", id); return true; } - + if( sd->sc.count == 0 || !sd->sc.data[id] ) {// no status is active script_pushint(st, 0); return true; } - + switch( type ) { - case 1: script_pushint(st, sd->sc.data[id]->val1); break; - case 2: script_pushint(st, sd->sc.data[id]->val2); break; - case 3: script_pushint(st, sd->sc.data[id]->val3); break; - case 4: script_pushint(st, sd->sc.data[id]->val4); break; + case 1: script_pushint(st, sd->sc.data[id]->val1); break; + case 2: script_pushint(st, sd->sc.data[id]->val2); break; + case 3: script_pushint(st, sd->sc.data[id]->val3); break; + case 4: script_pushint(st, sd->sc.data[id]->val4); break; case 5: { struct TimerData* td = (struct TimerData*)timer->get(sd->sc.data[id]->timer); - + if( td ) { // return the amount of time remaining - script_pushint(st, td->tick - timer->gettick()); + script_pushint(st, (int)(td->tick - timer->gettick())); // TODO: change this to int64 when we'll support 64 bit script values } } break; default: script_pushint(st, 1); break; } - + return true; } @@ -9532,12 +10102,12 @@ BUILDIN(catchpet) { int pet_id; TBL_PC *sd; - + pet_id= script_getnum(st,2); sd=script->rid2sd(st); if( sd == NULL ) return true; - + pet->catch_process1(sd,pet_id); return true; } @@ -9548,11 +10118,11 @@ BUILDIN(catchpet) BUILDIN(homunculus_evolution) { TBL_PC *sd; - + sd=script->rid2sd(st); if( sd == NULL ) return true; - + if(homun_alive(sd->hd)) { if (sd->hd->homunculus.intimacy > 91000) homun->evolve(sd->hd); @@ -9564,44 +10134,82 @@ BUILDIN(homunculus_evolution) /*========================================== * [Xantara] + * Checks for vaporized morph state + * and deletes ITEMID_STRANGE_EMBRYO. *------------------------------------------*/ BUILDIN(homunculus_mutate) { int homun_id; enum homun_type m_class, m_id; TBL_PC *sd; - + bool success = false; + sd = script->rid2sd(st); if( sd == NULL || sd->hd == NULL ) return true; - - if( script_hasdata(st,2) ) - homun_id = script_getnum(st,2); - else - homun_id = 6048 + (rnd() % 4); - - if( homun_alive(sd->hd) ) { + + if( sd->hd->homunculus.vaporize == HOM_ST_MORPH ) { + int i = pc->search_inventory(sd, ITEMID_STRANGE_EMBRYO); + if( script_hasdata(st,2) ) + homun_id = script_getnum(st,2); + else + homun_id = 6048 + (rnd() % 4); + m_class = homun->class2type(sd->hd->homunculus.class_); m_id = homun->class2type(homun_id); - - if( m_class != HT_INVALID && m_id != HT_INVALID && m_class == HT_EVO && m_id == HT_S && sd->hd->homunculus.level >= 99 ) + + if( m_class == HT_EVO && m_id == HT_S && + sd->hd->homunculus.level >= 99 && i >= 0 && + !pc->delitem(sd, i, 1, 0, 0, LOG_TYPE_SCRIPT) ) { + sd->hd->homunculus.vaporize = HOM_ST_REST; // Remove morph state. + homun->call(sd); // Respawn homunculus. homun->mutate(sd->hd, homun_id); - else + success = true; + } else clif->emotion(&sd->hd->bl, E_SWT); - } + } else + clif->emotion(&sd->hd->bl, E_SWT); + + script_pushint(st,success?1:0); return true; } -// [Zephyrus] -BUILDIN(homunculus_shuffle) { +/*========================================== + * Puts homunculus into morph state + * and gives ITEMID_STRANGE_EMBRYO. + *------------------------------------------*/ +BUILDIN(homunculus_morphembryo) { + enum homun_type m_class; + int i = 0; TBL_PC *sd; - - sd=script->rid2sd(st); - if( sd == NULL ) + bool success = false; + + sd = script->rid2sd(st); + if( sd == NULL || sd->hd == NULL ) return true; - - if(homun_alive(sd->hd)) - homun->shuffle(sd->hd); - + + if( homun_alive(sd->hd) ) { + m_class = homun->class2type(sd->hd->homunculus.class_); + + if ( m_class == HT_EVO && sd->hd->homunculus.level >= 99 ) { + struct item item_tmp; + + memset(&item_tmp, 0, sizeof(item_tmp)); + item_tmp.nameid = ITEMID_STRANGE_EMBRYO; + item_tmp.identify = 1; + + if( (i = pc->additem(sd, &item_tmp, 1, LOG_TYPE_SCRIPT)) ) { + clif->additem(sd, 0, 0, i); + clif->emotion(&sd->hd->bl, E_SWT); + } else { + homun->vaporize(sd, HOM_ST_MORPH); + success = true; + } + } else + clif->emotion(&sd->hd->bl, E_SWT); + } else + clif->emotion(&sd->hd->bl, E_SWT); + + script_pushint(st, success?1:0); return true; } @@ -9612,20 +10220,28 @@ BUILDIN(homunculus_shuffle) { * 1 = Homunculus is vaporized (rest) * 2 = Homunculus is in morph state *------------------------------------------*/ -BUILDIN(checkhomcall) -{ +BUILDIN(homunculus_checkcall) { TBL_PC *sd = script->rid2sd(st); - TBL_HOM *hd; - if( sd == NULL ) - return false; - - hd = sd->hd; - - if( !hd ) + if( sd == NULL || !sd->hd ) script_pushint(st, -1); else - script_pushint(st, hd->homunculus.vaporize); + script_pushint(st, sd->hd->homunculus.vaporize); + + return true; +} + + +// [Zephyrus] +BUILDIN(homunculus_shuffle) { + TBL_PC *sd; + + sd=script->rid2sd(st); + if( sd == NULL ) + return true; + + if(homun_alive(sd->hd)) + homun->shuffle(sd->hd); return true; } @@ -9675,12 +10291,12 @@ BUILDIN(birthpet) sd=script->rid2sd(st); if( sd == NULL ) return true; - + if( sd->status.pet_id ) {// do not send egg list, when you already have a pet return true; } - + clif->sendegg(sd); return true; } @@ -9688,21 +10304,21 @@ BUILDIN(birthpet) /*========================================== * Added - AppleGirl For Advanced Classes, (Updated for Cleaner Script Purposes) * @type - * 1 : make like after rebirth - * 2 : blvl,jlvl=1, skillpoint=0 - * 3 : don't reset skill, blvl=1 - * 4 : jlvl=0 + * 1 : make like after rebirth + * 2 : blvl,jlvl=1, skillpoint=0 + * 3 : don't reset skill, blvl=1 + * 4 : jlvl=0 *------------------------------------------*/ BUILDIN(resetlvl) { TBL_PC *sd; - + int type=script_getnum(st,2); - + sd=script->rid2sd(st); if( sd == NULL ) return true; - + pc->resetlvl(sd,type); return true; } @@ -9745,15 +10361,15 @@ BUILDIN(skillpointcount) BUILDIN(changebase) { TBL_PC *sd=NULL; int vclass; - + if( script_hasdata(st,3) ) sd=map->id2sd(script_getnum(st,3)); else sd=script->rid2sd(st); - + if(sd == NULL) return true; - + vclass = script_getnum(st,2); if(vclass == JOB_WEDDING) { @@ -9762,7 +10378,7 @@ BUILDIN(changebase) { ) return true; } - + if(sd->disguise == -1 && vclass != sd->vd.class_) { status->set_viewdata(&sd->bl, vclass); //Updated client view. Base, Weapon and Cloth Colors. @@ -9772,7 +10388,7 @@ BUILDIN(changebase) { clif->changelook(&sd->bl,LOOK_CLOTHES_COLOR,sd->vd.cloth_color); clif->skillinfoblock(sd); } - + return true; } @@ -9784,7 +10400,7 @@ BUILDIN(changesex) int i; TBL_PC *sd = NULL; sd = script->rid2sd(st); - + pc->resetskill(sd,4); // to avoid any problem with equipment and invalid sex, equipment is unequiped. for( i=0; i<EQI_MAX; i++ ) @@ -9800,18 +10416,19 @@ BUILDIN(globalmes) { struct block_list *bl = map->id2bl(st->oid); struct npc_data *nd = (struct npc_data *)bl; const char *name=NULL,*mes; - + mes=script_getstr(st,2); if(mes==NULL) return true; - - if(script_hasdata(st,3)){ // npc name to display + + if(script_hasdata(st,3)) { + // npc name to display name=script_getstr(st,3); } else { name=nd->name; //use current npc name } - - npc->globalmessage(name,mes); // broadcast to all players connected - + + npc->globalmessage(name,mes); // broadcast to all players connected + return true; } @@ -9832,11 +10449,11 @@ BUILDIN(waitingroom) { int zeny = script_hasdata(st,6) ? script_getnum(st,6) : 0; int minLvl = script_hasdata(st,7) ? script_getnum(st,7) : 1; int maxLvl = script_hasdata(st,8) ? script_getnum(st,8) : MAX_LEVEL; - + nd = (struct npc_data *)map->id2bl(st->oid); if( nd != NULL ) chat->create_npc_chat(nd, title, limit, pub, trigger, ev, zeny, minLvl, maxLvl); - + return true; } @@ -9862,12 +10479,12 @@ BUILDIN(delwaitingroom) { BUILDIN(waitingroomkickall) { struct npc_data* nd; struct chat_data* cd; - + if( script_hasdata(st,2) ) nd = npc->name2id(script_getstr(st,2)); else nd = (struct npc_data *)map->id2bl(st->oid); - + if( nd != NULL && (cd=(struct chat_data *)map->id2bl(nd->chat_id)) != NULL ) chat->npc_kick_all(cd); return true; @@ -9880,12 +10497,12 @@ BUILDIN(waitingroomkickall) { BUILDIN(enablewaitingroomevent) { struct npc_data* nd; struct chat_data* cd; - + if( script_hasdata(st,2) ) nd = npc->name2id(script_getstr(st, 2)); else nd = (struct npc_data *)map->id2bl(st->oid); - + if( nd != NULL && (cd=(struct chat_data *)map->id2bl(nd->chat_id)) != NULL ) chat->enable_event(cd); return true; @@ -9898,12 +10515,12 @@ BUILDIN(enablewaitingroomevent) { BUILDIN(disablewaitingroomevent) { struct npc_data *nd; struct chat_data *cd; - + if( script_hasdata(st,2) ) nd = npc->name2id(script_getstr(st, 2)); else nd = (struct npc_data *)map->id2bl(st->oid); - + if( nd != NULL && (cd=(struct chat_data *)map->id2bl(nd->chat_id)) != NULL ) chat->disable_event(cd); return true; @@ -9927,18 +10544,18 @@ BUILDIN(getwaitingroomstate) { struct npc_data *nd; struct chat_data *cd; int type; - + type = script_getnum(st,2); if( script_hasdata(st,3) ) nd = npc->name2id(script_getstr(st, 3)); else nd = (struct npc_data *)map->id2bl(st->oid); - + if( nd == NULL || (cd=(struct chat_data *)map->id2bl(nd->chat_id)) == NULL ) { script_pushint(st, -1); return true; } - + switch(type) { case 0: script_pushint(st, cd->users); break; case 1: script_pushint(st, cd->limit); break; @@ -9975,27 +10592,27 @@ BUILDIN(warpwaitingpc) { struct npc_data* nd; struct chat_data* cd; TBL_PC* sd; - + nd = (struct npc_data *)map->id2bl(st->oid); if( nd == NULL || (cd=(struct chat_data *)map->id2bl(nd->chat_id)) == NULL ) return true; - + map_name = script_getstr(st,2); x = script_getnum(st,3); y = script_getnum(st,4); n = cd->trigger&0x7f; - + if( script_hasdata(st,5) ) n = script_getnum(st,5); - + for( i = 0; i < n && cd->users > 0; i++ ) { sd = cd->usersd[0]; - + if( strcmp(map_name,"SavePoint") == 0 && map->list[sd->bl.m].flag.noteleport ) { // can't teleport on this map break; } - + if( cd->zeny ) { // fee set if( (uint32)sd->status.zeny < cd->zeny ) { @@ -10004,15 +10621,15 @@ BUILDIN(warpwaitingpc) { } pc->payzeny(sd, cd->zeny, LOG_TYPE_NPC, NULL); } - + mapreg->setreg(reference_uid(script->add_str("$@warpwaitingpc"), i), sd->bl.id); - + if( strcmp(map_name,"Random") == 0 ) pc->randomwarp(sd,CLR_TELEPORT); else if( strcmp(map_name,"SavePoint") == 0 ) pc->setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT); else - pc->setpos(sd, mapindex_name2id(map_name), x, y, CLR_OUTSIGHT); + pc->setpos(sd, mapindex->name2id(map_name), x, y, CLR_OUTSIGHT); } mapreg->setreg(script->add_str("$@warpwaitingpcnum"), i); return true; @@ -10037,10 +10654,10 @@ void script_detach_rid(struct script_state* st) { *------------------------------------------*/ BUILDIN(attachrid) { int rid = script_getnum(st,2); - + if (map->id2sd(rid) != NULL) { script->detach_rid(st); - + st->rid = rid; script->attach_state(st); script_pushint(st,1); @@ -10074,23 +10691,23 @@ BUILDIN(isloggedin) { *------------------------------------------*/ BUILDIN(setmapflagnosave) { int16 m,x,y; - unsigned short mapindex; + unsigned short map_index; const char *str,*str2; - + str=script_getstr(st,2); str2=script_getstr(st,3); x=script_getnum(st,4); y=script_getnum(st,5); m = map->mapname2mapid(str); - mapindex = mapindex_name2id(str2); - - if(m >= 0 && mapindex) { + map_index = mapindex->name2id(str2); + + if(m >= 0 && map_index) { map->list[m].flag.nosave=1; - map->list[m].save.map=mapindex; + map->list[m].save.map=map_index; map->list[m].save.x=x; map->list[m].save.y=y; } - + return true; } @@ -10098,10 +10715,10 @@ BUILDIN(getmapflag) { int16 m,i; const char *str; - + str=script_getstr(st,2); i=script_getnum(st,3); - + m = map->mapname2mapid(str); if(m >= 0) { switch(i) { @@ -10155,9 +10772,10 @@ BUILDIN(getmapflag) case MF_BATTLEGROUND: script_pushint(st,map->list[m].flag.battleground); break; case MF_RESET: script_pushint(st,map->list[m].flag.reset); break; case MF_NOTOMB: script_pushint(st,map->list[m].flag.notomb); break; + case MF_NOCASHSHOP: script_pushint(st,map->list[m].flag.nocashshop); break; } } - + return true; } /* pvp timer handling */ @@ -10178,26 +10796,24 @@ int script_mapflag_pvp_sub(struct block_list *bl,va_list ap) { BUILDIN(setmapflag) { int16 m,i; const char *str, *val2 = NULL; - struct script_data* data; int val=0; - + str=script_getstr(st,2); - + i = script_getnum(st, 3); - - if(script_hasdata(st,4)) { - data = script_getdata(st,4); - script->get_val(st, data); - - - if( data_isstring(data) ) + + if (script_hasdata(st,4)) { + if (script_isstringtype(st, 4)) { val2 = script_getstr(st, 4); - else + } else if (script_isinttype(st, 4)) { val = script_getnum(st, 4); - + } else { + ShowError("buildin_setmapflag: invalid data type for argument 3.\n"); + return false; + } } m = map->mapname2mapid(str); - + if(m >= 0) { switch(i) { case MF_NOMEMO: map->list[m].flag.nomemo = 1; break; @@ -10246,13 +10862,14 @@ BUILDIN(setmapflag) { case MF_NORETURN: map->list[m].flag.noreturn = 1; break; case MF_NOWARPTO: map->list[m].flag.nowarpto = 1; break; case MF_NIGHTMAREDROP: map->list[m].flag.pvp_nightmaredrop = 1; break; - case MF_ZONE: { - char zone[6] = "zone\0"; - char empty[1] = "\0"; - char params[MAP_ZONE_MAPFLAG_LENGTH]; - memcpy(params, val2, MAP_ZONE_MAPFLAG_LENGTH); - npc->parse_mapflag(map->list[m].name, empty, zone, params, empty, empty, empty); - } + case MF_ZONE: + if( val2 ) { + char zone[6] = "zone\0"; + char empty[1] = "\0"; + char params[MAP_ZONE_MAPFLAG_LENGTH]; + memcpy(params, val2, MAP_ZONE_MAPFLAG_LENGTH); + npc->parse_mapflag(map->list[m].name, empty, zone, params, empty, empty, empty); + } break; case MF_NOCOMMAND: map->list[m].nocommand = (val <= 0) ? 100 : val; break; case MF_NODROP: map->list[m].flag.nodrop = 1; break; @@ -10271,16 +10888,17 @@ BUILDIN(setmapflag) { case MF_BATTLEGROUND: map->list[m].flag.battleground = (val <= 0 || val > 2) ? 1 : val; break; case MF_RESET: map->list[m].flag.reset = 1; break; case MF_NOTOMB: map->list[m].flag.notomb = 1; break; + case MF_NOCASHSHOP: map->list[m].flag.nocashshop = 1; break; } } - + return true; } BUILDIN(removemapflag) { int16 m,i; const char *str; - + str=script_getstr(st,2); i=script_getnum(st,3); @@ -10356,9 +10974,10 @@ BUILDIN(removemapflag) { case MF_BATTLEGROUND: map->list[m].flag.battleground = 0; break; case MF_RESET: map->list[m].flag.reset = 0; break; case MF_NOTOMB: map->list[m].flag.notomb = 0; break; + case MF_NOCASHSHOP: map->list[m].flag.nocashshop = 0; break; } } - + return true; } @@ -10368,34 +10987,34 @@ BUILDIN(pvpon) { TBL_PC* sd = NULL; struct s_mapiterator* iter; struct block_list bl; - + str = script_getstr(st,2); m = map->mapname2mapid(str); if( m < 0 || map->list[m].flag.pvp ) return true; // nothing to do - + if( !strdb_exists(map->zone_db,MAP_ZONE_PVP_NAME) ) { ShowError("buildin_pvpon: zone_db missing '%s'\n",MAP_ZONE_PVP_NAME); return true; } - + map->zone_change2(m, strdb_get(map->zone_db, MAP_ZONE_PVP_NAME)); map->list[m].flag.pvp = 1; clif->map_property_mapall(m, MAPPROPERTY_FREEPVPZONE); bl.type = BL_NUL; bl.m = m; clif->maptypeproperty2(&bl,ALL_SAMEMAP); - - + + if(battle_config.pk_mode) // disable ranking functions if pk_mode is on [Valaris] return true; - + iter = mapit_getallusers(); for( sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); sd = (TBL_PC*)mapit->next(iter) ) { if( sd->bl.m != m || sd->pvp_timer != INVALID_TIMER ) continue; // not applicable - + sd->pvp_timer = timer->add(timer->gettick()+200,pc->calc_pvprank_timer,sd->bl.id,0); sd->pvp_rank = 0; sd->pvp_lastusers = 0; @@ -10404,7 +11023,7 @@ BUILDIN(pvpon) { sd->pvp_lost = 0; } mapit->free(iter); - + return true; } @@ -10423,22 +11042,22 @@ BUILDIN(pvpoff) { int16 m; const char *str; struct block_list bl; - + str=script_getstr(st,2); m = map->mapname2mapid(str); if(m < 0 || !map->list[m].flag.pvp) return true; //fixed Lupus - + map->zone_change2(m, map->list[m].prev_zone); map->list[m].flag.pvp = 0; clif->map_property_mapall(m, MAPPROPERTY_NOTHING); bl.type = BL_NUL; bl.m = m; clif->maptypeproperty2(&bl,ALL_SAMEMAP); - + if(battle_config.pk_mode) // disable ranking options if pk_mode is on [Valaris] return true; - + map->foreachinmap(script->buildin_pvpoff_sub, m, BL_PC); return true; } @@ -10446,17 +11065,17 @@ BUILDIN(pvpoff) { BUILDIN(gvgon) { int16 m; const char *str; - + str=script_getstr(st,2); m = map->mapname2mapid(str); if(m >= 0 && !map->list[m].flag.gvg) { struct block_list bl; - + if( !strdb_exists(map->zone_db,MAP_ZONE_GVG_NAME) ) { ShowError("buildin_gvgon: zone_db missing '%s'\n",MAP_ZONE_GVG_NAME); return true; } - + map->zone_change2(m, strdb_get(map->zone_db, MAP_ZONE_GVG_NAME)); map->list[m].flag.gvg = 1; clif->map_property_mapall(m, MAPPROPERTY_AGITZONE); @@ -10464,13 +11083,13 @@ BUILDIN(gvgon) { bl.m = m; clif->maptypeproperty2(&bl,ALL_SAMEMAP); } - + return true; } BUILDIN(gvgoff) { int16 m; const char *str; - + str=script_getstr(st,2); m = map->mapname2mapid(str); if(m >= 0 && map->list[m].flag.gvg) { @@ -10482,25 +11101,25 @@ BUILDIN(gvgoff) { bl.m = m; clif->maptypeproperty2(&bl,ALL_SAMEMAP); } - + return true; } /*========================================== - * Shows an emoticon on top of the player/npc - * emotion emotion#, <target: 0 - NPC, 1 - PC>, <NPC/PC name> + * Shows an emoticon on top of the player/npc + * emotion emotion#, <target: 0 - NPC, 1 - PC>, <NPC/PC name> *------------------------------------------*/ //Optional second parameter added by [Skotlex] BUILDIN(emotion) { int type; int player=0; - + type=script_getnum(st,2); if(type < 0 || type > 100) return true; - + if( script_hasdata(st,3) ) player=script_getnum(st,3); - + if (player) { TBL_PC *sd = NULL; if( script_hasdata(st,4) ) @@ -10523,14 +11142,14 @@ int buildin_maprespawnguildid_sub_pc(struct map_session_data* sd, va_list ap) int16 m=va_arg(ap,int); int g_id=va_arg(ap,int); int flag=va_arg(ap,int); - + if(!sd || sd->bl.m != m) return 0; if( - (sd->status.guild_id == g_id && flag&1) || //Warp out owners - (sd->status.guild_id != g_id && flag&2) || //Warp out outsiders - (sd->status.guild_id == 0) // Warp out players not in guild [Valaris] - ) + (sd->status.guild_id == g_id && flag&1) //Warp out owners + || (sd->status.guild_id != g_id && flag&2) //Warp out outsiders + || (sd->status.guild_id == 0) // Warp out players not in guild [Valaris] + ) pc->setpos(sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT); return 1; } @@ -10538,10 +11157,10 @@ int buildin_maprespawnguildid_sub_pc(struct map_session_data* sd, va_list ap) int buildin_maprespawnguildid_sub_mob(struct block_list *bl,va_list ap) { struct mob_data *md=(struct mob_data *)bl; - + if(!md->guardian_data && md->class_ != MOBID_EMPERIUM) status_kill(bl); - + return 0; } @@ -10549,12 +11168,12 @@ BUILDIN(maprespawnguildid) { const char *mapname=script_getstr(st,2); int g_id=script_getnum(st,3); int flag=script_getnum(st,4); - + int16 m=map->mapname2mapid(mapname); - + if(m == -1) return true; - + //Catch ALL players (in case some are 'between maps' on execution time) map->foreachpc(script->buildin_maprespawnguildid_sub_pc,m,g_id,flag); if (flag&4) //Remove script mobs. @@ -10591,7 +11210,7 @@ BUILDIN(agitend2) { } /*========================================== - * Returns whether woe is on or off. // choice script + * Returns whether woe is on or off. *------------------------------------------*/ BUILDIN(agitcheck) { script_pushint(st,map->agit_flag); @@ -10599,7 +11218,7 @@ BUILDIN(agitcheck) { } /*========================================== - * Returns whether woese is on or off. // choice script + * Returns whether woese is on or off. *------------------------------------------*/ BUILDIN(agitcheck2) { script_pushint(st,map->agit2_flag); @@ -10612,9 +11231,9 @@ BUILDIN(agitcheck2) { BUILDIN(flagemblem) { TBL_NPC* nd; int g_id = script_getnum(st,2); - + if(g_id < 0) return true; - + nd = (TBL_NPC*)map->id2nd(st->oid); if( nd == NULL ) { ShowError("script:flagemblem: npc %d not found\n", st->oid); @@ -10635,7 +11254,7 @@ BUILDIN(flagemblem) { BUILDIN(getcastlename) { - const char* mapname = mapindex_getmapname(script_getstr(st,2),NULL); + const char* mapname = mapindex->getmapname(script_getstr(st,2),NULL); struct guild_castle* gc = guild->mapname2gc(mapname); const char* name = (gc) ? gc->castle_name : ""; script_pushstrcopy(st,name); @@ -10644,16 +11263,16 @@ BUILDIN(getcastlename) BUILDIN(getcastledata) { - const char *mapname = mapindex_getmapname(script_getstr(st,2),NULL); + const char *mapname = mapindex->getmapname(script_getstr(st,2),NULL); int index = script_getnum(st,3); struct guild_castle *gc = guild->mapname2gc(mapname); - + if (gc == NULL) { script_pushint(st,0); ShowWarning("buildin_setcastledata: guild castle for map '%s' not found\n", mapname); return false; } - + switch (index) { case 1: script_pushint(st,gc->guild_id); break; @@ -10687,21 +11306,21 @@ BUILDIN(getcastledata) BUILDIN(setcastledata) { - const char *mapname = mapindex_getmapname(script_getstr(st,2),NULL); + const char *mapname = mapindex->getmapname(script_getstr(st,2),NULL); int index = script_getnum(st,3); int value = script_getnum(st,4); struct guild_castle *gc = guild->mapname2gc(mapname); - + if (gc == NULL) { ShowWarning("buildin_setcastledata: guild castle for map '%s' not found\n", mapname); return false; } - + if (index <= 0 || index > 9+MAX_GUARDIANS) { ShowWarning("buildin_setcastledata: index = '%d' is out of allowed range\n", index); return false; } - + guild->castledatasave(gc->castle_id, index, value); return true; } @@ -10712,12 +11331,12 @@ BUILDIN(requestguildinfo) { int guild_id=script_getnum(st,2); const char *event=NULL; - - if( script_hasdata(st,3) ){ + + if( script_hasdata(st,3) ) { event=script_getstr(st,3); script->check_event(st, event); } - + if(guild_id>0) guild->npc_request_info(guild_id,event); return true; @@ -10730,28 +11349,28 @@ BUILDIN(getequipcardcnt) int i=-1,j,num; TBL_PC *sd; int count; - + num=script_getnum(st,2); sd=script->rid2sd(st); if (num > 0 && num <= ARRAYLENGTH(script->equip)) i=pc->checkequip(sd,script->equip[num-1]); - + if (i < 0 || !sd->inventory_data[i]) { script_pushint(st,0); return true; } - + if(itemdb_isspecial(sd->status.inventory[i].card[0])) { script_pushint(st,0); return true; } - + count = 0; for( j = 0; j < sd->inventory_data[i]->slot; j++ ) if( sd->status.inventory[i].card[j] && itemdb_type(sd->status.inventory[i].card[j]) == IT_CARD ) count++; - + script_pushint(st,count); return true; } @@ -10761,20 +11380,20 @@ BUILDIN(getequipcardcnt) /// successremovecards <slot>; BUILDIN(successremovecards) { int i=-1,j,c,cardflag=0; - + TBL_PC* sd = script->rid2sd(st); int num = script_getnum(st,2); - + if (num > 0 && num <= ARRAYLENGTH(script->equip)) i=pc->checkequip(sd,script->equip[num-1]); - + if (i < 0 || !sd->inventory_data[i]) { return true; } - + if(itemdb_isspecial(sd->status.inventory[i].card[0])) return true; - + for( c = sd->inventory_data[i]->slot - 1; c >= 0; --c ) { if( sd->status.inventory[i].card[c] && itemdb_type(sd->status.inventory[i].card[c]) == IT_CARD ) {// extract this card from the item int flag; @@ -10783,34 +11402,37 @@ BUILDIN(successremovecards) { cardflag = 1; item_tmp.nameid = sd->status.inventory[i].card[c]; item_tmp.identify = 1; - - if((flag=pc->additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT))){ // get back the cart in inventory + + if((flag=pc->additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT))) { + // get back the cart in inventory clif->additem(sd,0,0,flag); map->addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0); } } } - + if(cardflag == 1) {//if card was remove remplace item with no card int flag; struct item item_tmp; memset(&item_tmp,0,sizeof(item_tmp)); - + item_tmp.nameid = sd->status.inventory[i].nameid; item_tmp.identify = 1; item_tmp.refine = sd->status.inventory[i].refine; item_tmp.attribute = sd->status.inventory[i].attribute; item_tmp.expire_time = sd->status.inventory[i].expire_time; - + item_tmp.bound = sd->status.inventory[i].bound; + for (j = sd->inventory_data[i]->slot; j < MAX_SLOTS; j++) item_tmp.card[j]=sd->status.inventory[i].card[j]; - + pc->delitem(sd,i,1,0,3,LOG_TYPE_SCRIPT); - if((flag=pc->additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT))){ //chk if can be spawn in inventory otherwise put on floor + if((flag=pc->additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT))) { + //chk if can be spawn in inventory otherwise put on floor clif->additem(sd,0,0,flag); map->addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0); } - + clif->misceffect(&sd->bl,3); } return true; @@ -10824,76 +11446,79 @@ BUILDIN(successremovecards) { /// <type>=? : will just display the failure effect. BUILDIN(failedremovecards) { int i=-1,j,c,cardflag=0; - + TBL_PC* sd = script->rid2sd(st); int num = script_getnum(st,2); int typefail = script_getnum(st,3); - + if (num > 0 && num <= ARRAYLENGTH(script->equip)) i=pc->checkequip(sd,script->equip[num-1]); - + if (i < 0 || !sd->inventory_data[i]) return true; - + if(itemdb_isspecial(sd->status.inventory[i].card[0])) return true; - + for( c = sd->inventory_data[i]->slot - 1; c >= 0; --c ) { if( sd->status.inventory[i].card[c] && itemdb_type(sd->status.inventory[i].card[c]) == IT_CARD ) { cardflag = 1; - + if(typefail == 2) {// add cards to inventory, clear int flag; struct item item_tmp; - + memset(&item_tmp,0,sizeof(item_tmp)); - + item_tmp.nameid = sd->status.inventory[i].card[c]; item_tmp.identify = 1; - - if((flag=pc->additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT))){ + + if((flag=pc->additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT))) { clif->additem(sd,0,0,flag); map->addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0); } } } } - + if(cardflag == 1) { - if(typefail == 0 || typefail == 2){ // destroy the item + if(typefail == 0 || typefail == 2) { + // destroy the item pc->delitem(sd,i,1,0,2,LOG_TYPE_SCRIPT); } - if(typefail == 1){ // destroy the card + if(typefail == 1) { + // destroy the card int flag; struct item item_tmp; - + memset(&item_tmp,0,sizeof(item_tmp)); - + item_tmp.nameid = sd->status.inventory[i].nameid; item_tmp.identify = 1; item_tmp.refine = sd->status.inventory[i].refine; item_tmp.attribute = sd->status.inventory[i].attribute; item_tmp.expire_time = sd->status.inventory[i].expire_time; - + item_tmp.bound = sd->status.inventory[i].bound; + for (j = sd->inventory_data[i]->slot; j < MAX_SLOTS; j++) item_tmp.card[j]=sd->status.inventory[i].card[j]; - + pc->delitem(sd,i,1,0,2,LOG_TYPE_SCRIPT); - - if((flag=pc->additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT))){ + + if((flag=pc->additem(sd,&item_tmp,1,LOG_TYPE_SCRIPT))) { clif->additem(sd,0,0,flag); map->addflooritem(&item_tmp,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0); } } clif->misceffect(&sd->bl,2); } - + return true; } /* ================================================================ * mapwarp "<from map>","<to map>",<x>,<y>,<type>,<ID for Type>; - * type: 0=everyone, 1=guild, 2=party; [Reddozen] + * type: 0=everyone, 1=guild, 2=party; [Reddozen] * improved by [Lance] * ================================================================*/ // Added by RoVeRT @@ -10908,24 +11533,24 @@ BUILDIN(mapwarp) { str=script_getstr(st,3); x=script_getnum(st,4); y=script_getnum(st,5); - if(script_hasdata(st,7)){ + if(script_hasdata(st,7)) { check_val=script_getnum(st,6); check_ID=script_getnum(st,7); } - + if((m=map->mapname2mapid(mapname))< 0) return true; - - if(!(index=mapindex_name2id(str))) + + if(!(index=mapindex->name2id(str))) return true; - - switch(check_val){ + + switch(check_val) { case 1: g = guild->search(check_ID); - if (g){ + if (g) { for( i=0; i < g->max_member; i++) { - if(g->member[i].sd && g->member[i].sd->bl.m==m){ + if(g->member[i].sd && g->member[i].sd->bl.m==m) { pc->setpos(g->member[i].sd,index,x,y,CLR_TELEPORT); } } @@ -10933,9 +11558,9 @@ BUILDIN(mapwarp) { break; case 2: p = party->search(check_ID); - if(p){ - for(i=0;i<MAX_PARTY; i++){ - if(p->data[i].sd && p->data[i].sd->bl.m == m){ + if(p) { + for(i=0;i<MAX_PARTY; i++) { + if(p->data[i].sd && p->data[i].sd->bl.m == m) { pc->setpos(p->data[i].sd,index,x,y,CLR_TELEPORT); } } @@ -10945,12 +11570,12 @@ BUILDIN(mapwarp) { map->foreachinmap(script->buildin_areawarp_sub,m,BL_PC,index,x,y,0,0); break; } - + return true; } -int buildin_mobcount_sub(struct block_list *bl,va_list ap) // Added by RoVeRT -{ +// Added by RoVeRT +int buildin_mobcount_sub(struct block_list *bl,va_list ap) { char *event=va_arg(ap,char *); struct mob_data *md = ((struct mob_data *)bl); if( md->status.hp > 0 && (!event || strcmp(event,md->npc_event) == 0) ) @@ -10964,7 +11589,7 @@ BUILDIN(mobcount) { int16 m; mapname=script_getstr(st,2); event=script_getstr(st,3); - + if( strcmp(event, "all") == 0 ) event = NULL; else @@ -10989,7 +11614,7 @@ BUILDIN(mobcount) { } script_pushint(st,map->foreachinmap(script->buildin_mobcount_sub, m, BL_MOB, event)); - + return true; } @@ -10997,8 +11622,8 @@ BUILDIN(marriage) { const char *partner=script_getstr(st,2); TBL_PC *sd=script->rid2sd(st); TBL_PC *p_sd=map->nick2sd(partner); - - if(sd==NULL || p_sd==NULL || pc->marriage(sd,p_sd) < 0){ + + if(sd==NULL || p_sd==NULL || pc->marriage(sd,p_sd) < 0) { script_pushint(st,0); return true; } @@ -11008,7 +11633,7 @@ BUILDIN(marriage) { BUILDIN(wedding_effect) { TBL_PC *sd=script->rid2sd(st); struct block_list *bl; - + if(sd==NULL) { bl=map->id2bl(st->oid); } else @@ -11019,7 +11644,7 @@ BUILDIN(wedding_effect) { BUILDIN(divorce) { TBL_PC *sd=script->rid2sd(st); - if(sd==NULL || pc->divorce(sd) < 0){ + if(sd==NULL || pc->divorce(sd) < 0) { script_pushint(st,0); return true; } @@ -11029,86 +11654,82 @@ BUILDIN(divorce) BUILDIN(ispartneron) { TBL_PC *sd=script->rid2sd(st); - - if(sd==NULL || !pc->ismarried(sd) || - map->charid2sd(sd->status.partner_id) == NULL) { + + if (sd==NULL || !pc->ismarried(sd) + || map->charid2sd(sd->status.partner_id) == NULL) { script_pushint(st,0); return true; } - + script_pushint(st,1); return true; } -BUILDIN(getpartnerid) -{ - TBL_PC *sd=script->rid2sd(st); - if (sd == NULL) { - script_pushint(st,0); - return true; - } - - script_pushint(st,sd->status.partner_id); - return true; +BUILDIN(getpartnerid) { + TBL_PC *sd=script->rid2sd(st); + if (sd == NULL) { + script_pushint(st,0); + return true; + } + + script_pushint(st,sd->status.partner_id); + return true; } -BUILDIN(getchildid) -{ - TBL_PC *sd=script->rid2sd(st); - if (sd == NULL) { - script_pushint(st,0); - return true; - } - - script_pushint(st,sd->status.child); - return true; +BUILDIN(getchildid) { + TBL_PC *sd=script->rid2sd(st); + if (sd == NULL) { + script_pushint(st,0); + return true; + } + + script_pushint(st,sd->status.child); + return true; } -BUILDIN(getmotherid) -{ - TBL_PC *sd=script->rid2sd(st); - if (sd == NULL) { - script_pushint(st,0); - return true; - } - - script_pushint(st,sd->status.mother); - return true; +BUILDIN(getmotherid) { + TBL_PC *sd=script->rid2sd(st); + if (sd == NULL) { + script_pushint(st,0); + return true; + } + + script_pushint(st,sd->status.mother); + return true; } -BUILDIN(getfatherid) -{ - TBL_PC *sd=script->rid2sd(st); - if (sd == NULL) { - script_pushint(st,0); - return true; - } - - script_pushint(st,sd->status.father); - return true; +BUILDIN(getfatherid) { + TBL_PC *sd=script->rid2sd(st); + if (sd == NULL) { + script_pushint(st,0); + return true; + } + + script_pushint(st,sd->status.father); + return true; } BUILDIN(warppartner) { int x,y; - unsigned short mapindex; + unsigned short map_index; const char *str; TBL_PC *sd=script->rid2sd(st); TBL_PC *p_sd=NULL; - - if(sd==NULL || !pc->ismarried(sd) || - (p_sd=map->charid2sd(sd->status.partner_id)) == NULL) { + + if ( sd==NULL || !pc->ismarried(sd) + || (p_sd=map->charid2sd(sd->status.partner_id)) == NULL) { script_pushint(st,0); return true; } - + str=script_getstr(st,2); x=script_getnum(st,3); y=script_getnum(st,4); - - mapindex = mapindex_name2id(str); - if (mapindex) { - pc->setpos(p_sd,mapindex,x,y,CLR_OUTSIGHT); + + map_index = mapindex->name2id(str); + if (map_index) { + pc->setpos(p_sd,map_index,x,y,CLR_OUTSIGHT); script_pushint(st,1); } else script_pushint(st,0); @@ -11120,10 +11741,10 @@ BUILDIN(warppartner) *------------------------------------------------*/ BUILDIN(strmobinfo) { - + int num=script_getnum(st,2); int class_=script_getnum(st,3); - + if(!mob->db_checkid(class_)) { if (num < 3) //requested a string @@ -11132,7 +11753,7 @@ BUILDIN(strmobinfo) script_pushint(st,0); return true; } - + switch (num) { case 1: script_pushstrcopy(st,mob->db(class_)->name); break; case 2: script_pushstrcopy(st,mob->db(class_)->jname); break; @@ -11155,28 +11776,27 @@ BUILDIN(strmobinfo) BUILDIN(guardian) { int class_ = 0, x = 0, y = 0, guardian = 0; const char *str, *mapname, *evt=""; - struct script_data *data; bool has_index = false; - + mapname = script_getstr(st,2); x = script_getnum(st,3); y = script_getnum(st,4); str = script_getstr(st,5); class_ = script_getnum(st,6); - + if( script_hasdata(st,8) ) {// "<event label>",<guardian index> evt=script_getstr(st,7); guardian=script_getnum(st,8); has_index = true; - } else if( script_hasdata(st,7) ){ - data=script_getdata(st,7); - script->get_val(st,data); - if( data_isstring(data) ) - {// "<event label>" + } else if( script_hasdata(st,7) ) { + struct script_data *data = script_getdata(st,7); + script->get_val(st,data); // Dereference if it's a variable + if( data_isstring(data) ) { + // "<event label>" evt=script_getstr(st,7); - } else if( data_isint(data) ) - {// <guardian index> + } else if( data_isint(data) ) { + // <guardian index> guardian=script_getnum(st,7); has_index = true; } else { @@ -11185,10 +11805,10 @@ BUILDIN(guardian) { return false; } } - + script->check_event(st, evt); script_pushint(st, mob->spawn_guardian(mapname,x,y,str,class_,evt,guardian,has_index)); - + return true; } /*========================================== @@ -11198,7 +11818,7 @@ BUILDIN(setwall) { const char *mapname, *name; int x, y, m, size, dir; bool shootable; - + mapname = script_getstr(st,2); x = script_getnum(st,3); y = script_getnum(st,4); @@ -11206,17 +11826,17 @@ BUILDIN(setwall) { dir = script_getnum(st,6); shootable = script_getnum(st,7); name = script_getstr(st,8); - + if( (m = map->mapname2mapid(mapname)) < 0 ) return true; // Invalid Map - + map->iwall_set(m, x, y, size, dir, shootable, name); return true; } BUILDIN(delwall) { const char *name = script_getstr(st,2); map->iwall_remove(name); - + return true; } @@ -11228,18 +11848,18 @@ BUILDIN(delwall) { /// 2 - current hp /// BUILDIN(guardianinfo) { - const char* mapname = mapindex_getmapname(script_getstr(st,2),NULL); + const char* mapname = mapindex->getmapname(script_getstr(st,2),NULL); int id = script_getnum(st,3); int type = script_getnum(st,4); - + struct guild_castle* gc = guild->mapname2gc(mapname); struct mob_data* gd; - + if( gc == NULL || id < 0 || id >= MAX_GUARDIANS ) { script_pushint(st,-1); return true; } - + if( type == 0 ) script_pushint(st, gc->guardian[id].visible); else if( !gc->guardian[id].visible ) @@ -11252,39 +11872,34 @@ BUILDIN(guardianinfo) { script_pushint(st,gd->status.hp); else script_pushint(st,-1); - + return true; } /*========================================== * Get the item name by item_id or null *------------------------------------------*/ -BUILDIN(getitemname) -{ +BUILDIN(getitemname) { int item_id=0; struct item_data *i_data; char *item_name; - struct script_data *data; - - data=script_getdata(st,2); - script->get_val(st,data); - - if( data_isstring(data) ){ - const char *name=script->conv_str(st,data); + + if( script_isstringtype(st, 2) ) { + const char *name = script_getstr(st, 2); struct item_data *item_data = itemdb->search_name(name); if( item_data ) item_id=item_data->nameid; - }else - item_id=script->conv_num(st,data); - + } else { + item_id = script_getnum(st, 2); + } + i_data = itemdb->exists(item_id); - if (i_data == NULL) - { + if (i_data == NULL) { script_pushconststr(st,"null"); return true; } item_name=(char *)aMalloc(ITEM_NAME_LENGTH*sizeof(char)); - + memcpy(item_name, i_data->jname, ITEM_NAME_LENGTH); script_pushstr(st,item_name); return true; @@ -11296,11 +11911,11 @@ BUILDIN(getitemslots) { int item_id; struct item_data *i_data; - + item_id=script_getnum(st,2); - + i_data = itemdb->exists(item_id); - + if (i_data) script_pushint(st,i_data->slot); else @@ -11313,35 +11928,35 @@ BUILDIN(getitemslots) /*========================================== * Returns some values of an item [Lupus] * Price, Weight, etc... - getiteminfo(itemID,n), where n - 0 value_buy; - 1 value_sell; - 2 type; - 3 maxchance = Max drop chance of this item e.g. 1 = 0.01% , etc.. - if = 0, then monsters don't drop it at all (rare or a quest item) - if = -1, then this item is sold in NPC shops only - 4 sex; - 5 equip; - 6 weight; - 7 atk; - 8 def; - 9 range; - 10 slot; - 11 look; - 12 elv; - 13 wlv; - 14 view id + * getiteminfo(itemID,n), where n + * 0 value_buy; + * 1 value_sell; + * 2 type; + * 3 maxchance = Max drop chance of this item e.g. 1 = 0.01% , etc.. + * if = 0, then monsters don't drop it at all (rare or a quest item) + * if = -1, then this item is sold in NPC shops only + * 4 sex; + * 5 equip; + * 6 weight; + * 7 atk; + * 8 def; + * 9 range; + * 10 slot; + * 11 look; + * 12 elv; + * 13 wlv; + * 14 view id *------------------------------------------*/ BUILDIN(getiteminfo) { int item_id,n; int *item_arr; struct item_data *i_data; - - item_id = script_getnum(st,2); - n = script_getnum(st,3); - i_data = itemdb->exists(item_id); - + + item_id = script_getnum(st,2); + n = script_getnum(st,3); + i_data = itemdb->exists(item_id); + if (i_data && n>=0 && n<=14) { item_arr = (int*)&i_data->value_buy; script_pushint(st,item_arr[n]); @@ -11353,24 +11968,24 @@ BUILDIN(getiteminfo) /*========================================== * Set some values of an item [Lupus] * Price, Weight, etc... - setiteminfo(itemID,n,Value), where n - 0 value_buy; - 1 value_sell; - 2 type; - 3 maxchance = Max drop chance of this item e.g. 1 = 0.01% , etc.. - if = 0, then monsters don't drop it at all (rare or a quest item) - if = -1, then this item is sold in NPC shops only - 4 sex; - 5 equip; - 6 weight; - 7 atk; - 8 def; - 9 range; - 10 slot; - 11 look; - 12 elv; - 13 wlv; - 14 view id + * setiteminfo(itemID,n,Value), where n + * 0 value_buy; + * 1 value_sell; + * 2 type; + * 3 maxchance = Max drop chance of this item e.g. 1 = 0.01% , etc.. + * if = 0, then monsters don't drop it at all (rare or a quest item) + * if = -1, then this item is sold in NPC shops only + * 4 sex; + * 5 equip; + * 6 weight; + * 7 atk; + * 8 def; + * 9 range; + * 10 slot; + * 11 look; + * 12 elv; + * 13 wlv; + * 14 view id * Returns Value or -1 if the wrong field's been set *------------------------------------------*/ BUILDIN(setiteminfo) @@ -11378,12 +11993,12 @@ BUILDIN(setiteminfo) int item_id,n,value; int *item_arr; struct item_data *i_data; - - item_id = script_getnum(st,2); - n = script_getnum(st,3); - value = script_getnum(st,4); - i_data = itemdb->exists(item_id); - + + item_id = script_getnum(st,2); + n = script_getnum(st,3); + value = script_getnum(st,4); + i_data = itemdb->exists(item_id); + if (i_data && n>=0 && n<=14) { item_arr = (int*)&i_data->value_buy; item_arr[n] = value; @@ -11395,21 +12010,21 @@ BUILDIN(setiteminfo) /*========================================== * Returns value from equipped item slot n [Lupus] - getequpcardid(num,slot) - where - num = eqip position slot - slot = 0,1,2,3 (Card Slot N) - - This func returns CARD ID, 255,254,-255 (for card 0, if the item is produced) - it's useful when you want to check item cards or if it's signed - Useful for such quests as "Sign this refined item with players name" etc - Hat[0] +4 -> Player's Hat[0] +4 + * getequpcardid(num,slot) + * where + * num = eqip position slot + * slot = 0,1,2,3 (Card Slot N) + * + * This func returns CARD ID, 255,254,-255 (for card 0, if the item is produced) + * it's useful when you want to check item cards or if it's signed + * Useful for such quests as "Sign this refined item with players name" etc + * Hat[0] +4 -> Player's Hat[0] +4 *------------------------------------------*/ BUILDIN(getequipcardid) { int i=-1,num,slot; TBL_PC *sd; - + num=script_getnum(st,2); slot=script_getnum(st,3); sd=script->rid2sd(st); @@ -11419,7 +12034,7 @@ BUILDIN(getequipcardid) script_pushint(st,sd->status.inventory[i].card[slot]); else script_pushint(st,0); - + return true; } @@ -11429,12 +12044,12 @@ BUILDIN(getequipcardid) BUILDIN(petskillbonus) { struct pet_data *pd; - + TBL_PC *sd=script->rid2sd(st); - + if(sd==NULL || sd->pd==NULL) return true; - + pd=sd->pd; if (pd->bonus) { //Clear previous bonus @@ -11442,21 +12057,21 @@ BUILDIN(petskillbonus) timer->delete(pd->bonus->timer, pet->skill_bonus_timer); } else //init pd->bonus = (struct pet_bonus *) aMalloc(sizeof(struct pet_bonus)); - + pd->bonus->type=script_getnum(st,2); pd->bonus->val=script_getnum(st,3); pd->bonus->duration=script_getnum(st,4); pd->bonus->delay=script_getnum(st,5); - + if (pd->state.skillbonus == 1) - pd->state.skillbonus=0; // waiting state - + pd->state.skillbonus=0; // waiting state + // wait for timer to start if (battle_config.pet_equip_required && pd->pet.equip == 0) pd->bonus->timer = INVALID_TIMER; else pd->bonus->timer = timer->add(timer->gettick()+pd->bonus->delay*1000, pet->skill_bonus_timer, sd->bl.id, 0); - + return true; } @@ -11468,32 +12083,32 @@ BUILDIN(petloot) int max; struct pet_data *pd; TBL_PC *sd=script->rid2sd(st); - + if(sd==NULL || sd->pd==NULL) return true; - + max=script_getnum(st,2); - + if(max < 1) - max = 1; //Let'em loot at least 1 item. + max = 1; //Let'em loot at least 1 item. else if (max > MAX_PETLOOT_SIZE) max = MAX_PETLOOT_SIZE; - + pd = sd->pd; - if (pd->loot != NULL) - { //Release whatever was there already and reallocate memory + if (pd->loot != NULL) { + //Release whatever was there already and reallocate memory pet->lootitem_drop(pd, pd->msd); aFree(pd->loot->item); } else pd->loot = (struct pet_loot *)aMalloc(sizeof(struct pet_loot)); - + pd->loot->item = (struct item *)aCalloc(max,sizeof(struct item)); - + pd->loot->max=max; pd->loot->count = 0; pd->loot->weight = 0; - + return true; } /*========================================== @@ -11507,11 +12122,11 @@ BUILDIN(getinventorylist) { TBL_PC *sd=script->rid2sd(st); char card_var[NAME_LENGTH]; - + int i,j=0,k; if(!sd) return true; - for(i=0;i<MAX_INVENTORY;i++){ - if(sd->status.inventory[i].nameid > 0 && sd->status.inventory[i].amount > 0){ + for(i=0;i<MAX_INVENTORY;i++) { + if(sd->status.inventory[i].nameid > 0 && sd->status.inventory[i].amount > 0) { pc->setreg(sd,reference_uid(script->add_str("@inventorylist_id"), j),sd->status.inventory[i].nameid); pc->setreg(sd,reference_uid(script->add_str("@inventorylist_amount"), j),sd->status.inventory[i].amount); pc->setreg(sd,reference_uid(script->add_str("@inventorylist_equip"), j),sd->status.inventory[i].equip); @@ -11524,6 +12139,7 @@ BUILDIN(getinventorylist) pc->setreg(sd,reference_uid(script->add_str(card_var), j),sd->status.inventory[i].card[k]); } pc->setreg(sd,reference_uid(script->add_str("@inventorylist_expire"), j),sd->status.inventory[i].expire_time); + pc->setreg(sd,reference_uid(script->add_str("@inventorylist_bound"), j),sd->status.inventory[i].bound); j++; } } @@ -11536,8 +12152,8 @@ BUILDIN(getskilllist) TBL_PC *sd=script->rid2sd(st); int i,j=0; if(!sd) return true; - for(i=0;i<MAX_SKILL;i++){ - if(sd->status.skill[i].id > 0 && sd->status.skill[i].lv > 0){ + for(i=0;i<MAX_SKILL;i++) { + if(sd->status.skill[i].id > 0 && sd->status.skill[i].lv > 0) { pc->setreg(sd,reference_uid(script->add_str("@skilllist_id"), j),sd->status.skill[i].id); pc->setreg(sd,reference_uid(script->add_str("@skilllist_lv"), j),sd->status.skill[i].lv); pc->setreg(sd,reference_uid(script->add_str("@skilllist_flag"), j),sd->status.skill[i].flag); @@ -11569,15 +12185,15 @@ BUILDIN(disguise) int id; TBL_PC* sd = script->rid2sd(st); if (sd == NULL) return true; - + id = script_getnum(st,2); - + if (mob->db_checkid(id) || npcdb_checkid(id)) { pc->disguise(sd, id); script_pushint(st,id); } else script_pushint(st,0); - + return true; } @@ -11588,7 +12204,7 @@ BUILDIN(undisguise) { TBL_PC* sd = script->rid2sd(st); if (sd == NULL) return true; - + if (sd->disguise != -1) { pc->disguise(sd, -1); script_pushint(st,0); @@ -11605,9 +12221,9 @@ BUILDIN(undisguise) BUILDIN(classchange) { int _class,type; struct block_list *bl=map->id2bl(st->oid); - + if(bl==NULL) return true; - + _class=script_getnum(st,2); type=script_getnum(st,3); clif->class_change(bl,_class,type); @@ -11620,13 +12236,13 @@ BUILDIN(classchange) { BUILDIN(misceffect) { int type; - + type=script_getnum(st,2); if(st->oid && st->oid != npc->fake_nd->bl.id) { struct block_list *bl = map->id2bl(st->oid); if (bl) clif->specialeffect(bl,type,AREA); - } else{ + } else { TBL_PC *sd=script->rid2sd(st); if(sd) clif->specialeffect(&sd->bl,type,AREA); @@ -11636,34 +12252,34 @@ BUILDIN(misceffect) /*========================================== * Play a BGM on a single client [Rikter/Yommy] *------------------------------------------*/ -BUILDIN(playBGM) +BUILDIN(playbgm) { const char* name; struct map_session_data* sd; - + if( ( sd = script->rid2sd(st) ) != NULL ) { name = script_getstr(st,2); - + clif->playBGM(sd, name); } - + return true; } -int playBGM_sub(struct block_list* bl,va_list ap) +int playbgm_sub(struct block_list* bl,va_list ap) { const char* name = va_arg(ap,const char*); - + clif->playBGM(BL_CAST(BL_PC, bl), name); - + return 0; } -int playBGM_foreachpc_sub(struct map_session_data* sd, va_list args) +int playbgm_foreachpc_sub(struct map_session_data* sd, va_list args) { const char* name = va_arg(args, const char*); - + clif->playBGM(sd, name); return 0; } @@ -11671,11 +12287,11 @@ int playBGM_foreachpc_sub(struct map_session_data* sd, va_list args) /*========================================== * Play a BGM on multiple client [Rikter/Yommy] *------------------------------------------*/ -BUILDIN(playBGMall) { +BUILDIN(playbgmall) { const char* name; - + name = script_getstr(st,2); - + if( script_hasdata(st,7) ) { // specified part of map const char *mapname = script_getstr(st,3); @@ -11684,29 +12300,29 @@ BUILDIN(playBGMall) { int x1 = script_getnum(st,6); int y1 = script_getnum(st,7); int m; - + if ( ( m = map->mapname2mapid(mapname) ) == -1 ) { - ShowWarning("playBGMall: Attempted to play song '%s' on non-existent map '%s'\n",name, mapname); + ShowWarning("playbgmall: Attempted to play song '%s' on non-existent map '%s'\n",name, mapname); return true; } - - map->foreachinarea(script->playBGM_sub, m, x0, y0, x1, y1, BL_PC, name); + + map->foreachinarea(script->playbgm_sub, m, x0, y0, x1, y1, BL_PC, name); } else if( script_hasdata(st,3) ) { // entire map const char* mapname = script_getstr(st,3); int m; - + if ( ( m = map->mapname2mapid(mapname) ) == -1 ) { - ShowWarning("playBGMall: Attempted to play song '%s' on non-existent map '%s'\n",name, mapname); + ShowWarning("playbgmall: Attempted to play song '%s' on non-existent map '%s'\n",name, mapname); return true; } - - map->foreachinmap(script->playBGM_sub, m, BL_PC, name); + + map->foreachinmap(script->playbgm_sub, m, BL_PC, name); } else { // entire server - map->foreachpc(script->playBGM_foreachpc_sub, name); + map->foreachpc(script->playbgm_foreachpc_sub, name); } - + return true; } @@ -11718,7 +12334,7 @@ BUILDIN(soundeffect) TBL_PC* sd = script->rid2sd(st); const char* name = script_getstr(st,2); int type = script_getnum(st,3); - + if(sd) { clif->soundeffect(sd,&sd->bl,name,type); @@ -11730,9 +12346,9 @@ int soundeffect_sub(struct block_list* bl,va_list ap) { char* name = va_arg(ap,char*); int type = va_arg(ap,int); - + clif->soundeffect((TBL_PC *)bl, bl, name, type); - + return true; } @@ -11744,28 +12360,28 @@ BUILDIN(soundeffectall) { struct block_list* bl; const char* name; int type; - + bl = (st->rid) ? &(script->rid2sd(st)->bl) : map->id2bl(st->oid); if (!bl) return true; - + name = script_getstr(st,2); type = script_getnum(st,3); - + //FIXME: enumerating map squares (map->foreach) is slower than enumerating the list of online players (map->foreachpc?) [ultramage] - + if(!script_hasdata(st,4)) { // area around clif->soundeffectall(bl, name, type, AREA); } else { if(!script_hasdata(st,5)) { // entire map const char *mapname = script_getstr(st,4); int m; - + if ( ( m = map->mapname2mapid(mapname) ) == -1 ) { ShowWarning("soundeffectall: Attempted to play song '%s' (type %d) on non-existent map '%s'\n",name,type, mapname); return true; } - + map->foreachinmap(script->soundeffect_sub, m, BL_PC, name, type); } else if(script_hasdata(st,8)) { // specified part of map const char *mapname = script_getstr(st,4); @@ -11774,18 +12390,18 @@ BUILDIN(soundeffectall) { int x1 = script_getnum(st,7); int y1 = script_getnum(st,8); int m; - + if ( ( m = map->mapname2mapid(mapname) ) == -1 ) { ShowWarning("soundeffectall: Attempted to play song '%s' (type %d) on non-existent map '%s'\n",name,type, mapname); return true; } - + map->foreachinarea(script->soundeffect_sub, m, x0, y0, x1, y1, BL_PC, name, type); } else { ShowError("buildin_soundeffectall: insufficient arguments for specific area broadcast.\n"); } } - + return true; } /*========================================== @@ -11795,23 +12411,23 @@ BUILDIN(petrecovery) { struct pet_data *pd; TBL_PC *sd=script->rid2sd(st); - + if(sd==NULL || sd->pd==NULL) return true; - + pd=sd->pd; - + if (pd->recovery) { //Halt previous bonus if (pd->recovery->timer != INVALID_TIMER) timer->delete(pd->recovery->timer, pet->recovery_timer); } else //Init pd->recovery = (struct pet_recovery *)aMalloc(sizeof(struct pet_recovery)); - + pd->recovery->type = (sc_type)script_getnum(st,2); pd->recovery->delay = script_getnum(st,3); pd->recovery->timer = INVALID_TIMER; - + return true; } @@ -11822,10 +12438,10 @@ BUILDIN(petheal) { struct pet_data *pd; TBL_PC *sd=script->rid2sd(st); - + if(sd==NULL || sd->pd==NULL) return true; - + pd=sd->pd; if (pd->s_skill) { //Clear previous skill @@ -11838,20 +12454,20 @@ BUILDIN(petheal) } } else //init memory pd->s_skill = (struct pet_skill_support *) aMalloc(sizeof(struct pet_skill_support)); - + pd->s_skill->id=0; //This id identifies that it IS petheal rather than pet_skillsupport //Use the lv as the amount to heal pd->s_skill->lv=script_getnum(st,2); pd->s_skill->delay=script_getnum(st,3); pd->s_skill->hp=script_getnum(st,4); pd->s_skill->sp=script_getnum(st,5); - + //Use delay as initial offset to avoid skill/heal exploits if (battle_config.pet_equip_required && pd->pet.equip == 0) pd->s_skill->timer = INVALID_TIMER; else pd->s_skill->timer = timer->add(timer->gettick()+pd->s_skill->delay*1000,pet->heal_timer,sd->bl.id,0); - + return true; } @@ -11860,24 +12476,23 @@ BUILDIN(petheal) *------------------------------------------*/ /// petskillattack <skill id>,<level>,<rate>,<bonusrate> /// petskillattack "<skill name>",<level>,<rate>,<bonusrate> -BUILDIN(petskillattack) -{ +BUILDIN(petskillattack) { struct pet_data *pd; TBL_PC *sd=script->rid2sd(st); - + if(sd==NULL || sd->pd==NULL) return true; - + pd=sd->pd; if (pd->a_skill == NULL) pd->a_skill = (struct pet_skill_attack *)aMalloc(sizeof(struct pet_skill_attack)); - - pd->a_skill->id=( script_isstring(st,2) ? skill->name2id(script_getstr(st,2)) : script_getnum(st,2) ); + + pd->a_skill->id=( script_isstringtype(st,2) ? skill->name2id(script_getstr(st,2)) : script_getnum(st,2) ); pd->a_skill->lv=script_getnum(st,3); pd->a_skill->div_ = 0; pd->a_skill->rate=script_getnum(st,4); pd->a_skill->bonusrate=script_getnum(st,5); - + return true; } @@ -11886,24 +12501,23 @@ BUILDIN(petskillattack) *------------------------------------------*/ /// petskillattack2 <skill id>,<level>,<div>,<rate>,<bonusrate> /// petskillattack2 "<skill name>",<level>,<div>,<rate>,<bonusrate> -BUILDIN(petskillattack2) -{ +BUILDIN(petskillattack2) { struct pet_data *pd; TBL_PC *sd=script->rid2sd(st); - + if(sd==NULL || sd->pd==NULL) return true; - + pd=sd->pd; if (pd->a_skill == NULL) pd->a_skill = (struct pet_skill_attack *)aMalloc(sizeof(struct pet_skill_attack)); - - pd->a_skill->id=( script_isstring(st,2) ? skill->name2id(script_getstr(st,2)) : script_getnum(st,2) ); + + pd->a_skill->id=( script_isstringtype(st,2) ? skill->name2id(script_getstr(st,2)) : script_getnum(st,2) ); pd->a_skill->lv=script_getnum(st,3); pd->a_skill->div_ = script_getnum(st,4); pd->a_skill->rate=script_getnum(st,5); pd->a_skill->bonusrate=script_getnum(st,6); - + return true; } @@ -11912,14 +12526,13 @@ BUILDIN(petskillattack2) *------------------------------------------*/ /// petskillsupport <skill id>,<level>,<delay>,<hp>,<sp> /// petskillsupport "<skill name>",<level>,<delay>,<hp>,<sp> -BUILDIN(petskillsupport) -{ +BUILDIN(petskillsupport) { struct pet_data *pd; TBL_PC *sd=script->rid2sd(st); - + if(sd==NULL || sd->pd==NULL) return true; - + pd=sd->pd; if (pd->s_skill) { //Clear previous skill @@ -11932,19 +12545,19 @@ BUILDIN(petskillsupport) } } else //init memory pd->s_skill = (struct pet_skill_support *) aMalloc(sizeof(struct pet_skill_support)); - - pd->s_skill->id=( script_isstring(st,2) ? skill->name2id(script_getstr(st,2)) : script_getnum(st,2) ); + + pd->s_skill->id=( script_isstringtype(st,2) ? skill->name2id(script_getstr(st,2)) : script_getnum(st,2) ); pd->s_skill->lv=script_getnum(st,3); pd->s_skill->delay=script_getnum(st,4); pd->s_skill->hp=script_getnum(st,5); pd->s_skill->sp=script_getnum(st,6); - + //Use delay as initial offset to avoid skill/heal exploits if (battle_config.pet_equip_required && pd->pet.equip == 0) pd->s_skill->timer = INVALID_TIMER; else pd->s_skill->timer = timer->add(timer->gettick()+pd->s_skill->delay*1000,pet->skill_support_timer,sd->bl.id,0); - + return true; } @@ -11953,16 +12566,15 @@ BUILDIN(petskillsupport) *------------------------------------------*/ /// skilleffect <skill id>,<level> /// skilleffect "<skill name>",<level> -BUILDIN(skilleffect) -{ +BUILDIN(skilleffect) { TBL_PC *sd; - - uint16 skill_id=( script_isstring(st,2) ? skill->name2id(script_getstr(st,2)) : script_getnum(st,2) ); + + uint16 skill_id=( script_isstringtype(st,2) ? skill->name2id(script_getstr(st,2)) : script_getnum(st,2) ); uint16 skill_lv=script_getnum(st,3); sd=script->rid2sd(st); - + clif->skill_nodamage(&sd->bl,&sd->bl,skill_id,skill_lv,1); - + return true; } @@ -11973,15 +12585,15 @@ BUILDIN(skilleffect) /// npcskilleffect "<skill name>",<level>,<x>,<y> BUILDIN(npcskilleffect) { struct block_list *bl= map->id2bl(st->oid); - - uint16 skill_id=( script_isstring(st,2) ? skill->name2id(script_getstr(st,2)) : script_getnum(st,2) ); + + uint16 skill_id=( script_isstringtype(st,2) ? skill->name2id(script_getstr(st,2)) : script_getnum(st,2) ); uint16 skill_lv=script_getnum(st,3); int x=script_getnum(st,4); int y=script_getnum(st,5); - + if (bl) clif->skill_poseffect(bl,skill_id,skill_lv,x,y,timer->gettick()); - + return true; } @@ -11992,10 +12604,10 @@ BUILDIN(specialeffect) { struct block_list *bl=map->id2bl(st->oid); int type = script_getnum(st,2); enum send_target target = script_hasdata(st,3) ? (send_target)script_getnum(st,3) : AREA; - + if(bl==NULL) return true; - + if( script_hasdata(st,4) ) { TBL_NPC *nd = npc->name2id(script_getstr(st,4)); @@ -12012,7 +12624,7 @@ BUILDIN(specialeffect) { clif->specialeffect(bl, type, target); } } - + return true; } @@ -12020,13 +12632,13 @@ BUILDIN(specialeffect2) { TBL_PC *sd=script->rid2sd(st); int type = script_getnum(st,2); enum send_target target = script_hasdata(st,3) ? (send_target)script_getnum(st,3) : AREA; - + if( script_hasdata(st,4) ) sd = map->nick2sd(script_getstr(st,4)); - + if (sd) clif->specialeffect(&sd->bl, type, target); - + return true; } @@ -12037,10 +12649,10 @@ BUILDIN(nude) { TBL_PC *sd = script->rid2sd(st); int i, calcflag = 0; - + if( sd == NULL ) return true; - + for( i = 0 ; i < EQI_MAX; i++ ) { if( sd->equip_index[ i ] >= 0 ) { if( !calcflag ) @@ -12048,10 +12660,10 @@ BUILDIN(nude) pc->unequipitem( sd , sd->equip_index[ i ] , 2); } } - + if( calcflag ) - status_calc_pc(sd,0); - + status_calc_pc(sd,SCO_NONE); + return true; } @@ -12063,16 +12675,16 @@ BUILDIN(atcommand) { int fd; const char* cmd; bool ret = true; - + cmd = script_getstr(st,2); - + if (st->rid) { sd = script->rid2sd(st); fd = sd->fd; } else { //Use a dummy character. sd = dummy_sd = pc->get_dummy_sd(); fd = 0; - + if (st->oid) { struct block_list* bl = map->id2bl(st->oid); memcpy(&sd->bl, bl, sizeof(struct block_list)); @@ -12080,8 +12692,8 @@ BUILDIN(atcommand) { safestrncpy(sd->status.name, ((TBL_NPC*)bl)->name, NAME_LENGTH); } } - - if (!atcommand->parse(fd, sd, cmd, 0)) { + + if (!atcommand->exec(fd, sd, cmd, false)) { ShowWarning("script: buildin_atcommand: failed to execute command '%s'\n", cmd); script->reportsrc(st); ret = false; @@ -12099,7 +12711,7 @@ BUILDIN(dispbottom) const char *message; message=script_getstr(st,2); if(sd) - clif->disp_onlyself(sd,message,(int)strlen(message)); + clif_disp_onlyself(sd,message,(int)strlen(message)); return true; } @@ -12111,7 +12723,7 @@ BUILDIN(recovery) { TBL_PC* sd; struct s_mapiterator* iter; - + iter = mapit_getallusers(); for( sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); sd = (TBL_PC*)mapit->next(iter) ) { @@ -12134,7 +12746,7 @@ BUILDIN(getpetinfo) TBL_PC *sd=script->rid2sd(st); TBL_PET *pd; int type=script_getnum(st,2); - + if(!sd || !sd->pd) { if (type == 2) script_pushconststr(st,"null"); @@ -12143,7 +12755,7 @@ BUILDIN(getpetinfo) return true; } pd = sd->pd; - switch(type){ + switch(type) { case 0: script_pushint(st,pd->pet.pet_id); break; case 1: script_pushint(st,pd->pet.class_); break; case 2: script_pushstrcopy(st,pd->pet.name); break; @@ -12166,27 +12778,24 @@ BUILDIN(getpetinfo) BUILDIN(gethominfo) { TBL_PC *sd=script->rid2sd(st); - TBL_HOM *hd; - int type=script_getnum(st,2); - - hd = sd?sd->hd:NULL; - if(!homun_alive(hd)) - { + int type = script_getnum(st,2); + + if(!sd || !sd->hd) { if (type == 2) script_pushconststr(st,"null"); else script_pushint(st,0); return true; } - - switch(type){ - case 0: script_pushint(st,hd->homunculus.hom_id); break; - case 1: script_pushint(st,hd->homunculus.class_); break; - case 2: script_pushstrcopy(st,hd->homunculus.name); break; - case 3: script_pushint(st,hd->homunculus.intimacy); break; - case 4: script_pushint(st,hd->homunculus.hunger); break; - case 5: script_pushint(st,hd->homunculus.rename_flag); break; - case 6: script_pushint(st,hd->homunculus.level); break; + + switch(type) { + case 0: script_pushint(st,sd->hd->homunculus.hom_id); break; + case 1: script_pushint(st,sd->hd->homunculus.class_); break; + case 2: script_pushstrcopy(st,sd->hd->homunculus.name); break; + case 3: script_pushint(st,sd->hd->homunculus.intimacy); break; + case 4: script_pushint(st,sd->hd->homunculus.hunger); break; + case 5: script_pushint(st,sd->hd->homunculus.rename_flag); break; + case 6: script_pushint(st,sd->hd->homunculus.level); break; default: script_pushint(st,0); break; @@ -12200,12 +12809,12 @@ BUILDIN(getmercinfo) { int type, char_id; struct map_session_data* sd; struct mercenary_data* md; - + type = script_getnum(st,2); - + if( script_hasdata(st,3) ) { char_id = script_getnum(st,3); - + if( ( sd = map->charid2sd(char_id) ) == NULL ) { ShowError("buildin_getmercinfo: No such character (char_id=%d).\n", char_id); script_pushnil(st); @@ -12217,9 +12826,9 @@ BUILDIN(getmercinfo) { return true; } } - + md = ( sd->status.mer_id && sd->md ) ? sd->md : NULL; - + switch( type ) { case 0: script_pushint(st,md ? md->mercenary.mercenary_id : 0); break; @@ -12240,29 +12849,29 @@ BUILDIN(getmercinfo) { script_pushnil(st); return false; } - + return true; } /*========================================== * Shows wether your inventory(and equips) contain - selected card or not. - checkequipedcard(4001); + * selected card or not. + * checkequipedcard(4001); *------------------------------------------*/ BUILDIN(checkequipedcard) { TBL_PC *sd=script->rid2sd(st); - - if(sd){ + + if(sd) { int n,i,c=0; c=script_getnum(st,2); - - for(i=0;i<MAX_INVENTORY;i++){ - if(sd->status.inventory[i].nameid > 0 && sd->status.inventory[i].amount && sd->inventory_data[i]){ + + for(i=0;i<MAX_INVENTORY;i++) { + if(sd->status.inventory[i].nameid > 0 && sd->status.inventory[i].amount && sd->inventory_data[i]) { if (itemdb_isspecial(sd->status.inventory[i].card[0])) continue; - for(n=0;n<sd->inventory_data[i]->slot;n++){ - if(sd->status.inventory[i].card[n]==c){ + for(n=0;n<sd->inventory_data[i]->slot;n++) { + if(sd->status.inventory[i].card[n]==c) { script_pushint(st,1); return true; } @@ -12280,12 +12889,12 @@ BUILDIN(jump_zero) sel=script_getnum(st,2); if(!sel) { int pos; - if( !data_islabel(script_getdata(st,3)) ){ + if( !data_islabel(script_getdata(st,3)) ) { ShowError("script: jump_zero: not label !\n"); st->state=END; return false; } - + pos=script_getnum(st,3); st->pos=pos; st->state=GOTO; @@ -12300,14 +12909,14 @@ BUILDIN(movenpc) { TBL_NPC *nd = NULL; const char *npc_name; int x,y; - + npc_name = script_getstr(st,2); x = script_getnum(st,3); y = script_getnum(st,4); - + if ((nd = npc->name2id(npc_name)) == NULL) return -1; - + if (script_hasdata(st,5)) nd->dir = script_getnum(st,5) % 8; npc->movenpc(nd, x, y); @@ -12320,14 +12929,14 @@ BUILDIN(movenpc) { BUILDIN(message) { const char *msg,*player; TBL_PC *pl_sd = NULL; - + player = script_getstr(st,2); msg = script_getstr(st,3); - + if((pl_sd=map->nick2sd((char *) player)) == NULL) return true; clif->message(pl_sd->fd, msg); - + return true; } @@ -12337,10 +12946,10 @@ BUILDIN(message) { BUILDIN(npctalk) { const char* str; char name[NAME_LENGTH], message[256]; - + struct npc_data* nd = (struct npc_data *)map->id2bl(st->oid); str = script_getstr(st,2); - + if(nd) { safestrncpy(name, nd->name, sizeof(name)); @@ -12348,7 +12957,7 @@ BUILDIN(npctalk) { safesnprintf(message, sizeof(message), "%s : %s", name, str); clif->disp_overhead(&nd->bl, message); } - + return true; } @@ -12356,47 +12965,47 @@ BUILDIN(npctalk) { BUILDIN(npcspeed) { struct npc_data* nd; int speed; - + speed = script_getnum(st,2); nd = (struct npc_data *)map->id2bl(st->oid); - + if( nd ) { unit->bl2ud2(&nd->bl); // ensure nd->ud is safe to edit nd->speed = speed; nd->ud->state.speed_changed = 1; } - + return true; } // make an npc walk to a position [Valaris] BUILDIN(npcwalkto) { struct npc_data *nd=(struct npc_data *)map->id2bl(st->oid); int x=0,y=0; - + x=script_getnum(st,2); y=script_getnum(st,3); - + if( nd ) { unit->bl2ud2(&nd->bl); // ensure nd->ud is safe to edit if (!nd->status.hp) { - status_calc_npc(nd, true); + status_calc_npc(nd, SCO_FIRST); } else { - status_calc_npc(nd, false); + status_calc_npc(nd, SCO_NONE); } unit->walktoxy(&nd->bl,x,y,0); } - + return true; } // stop an npc's movement [Valaris] BUILDIN(npcstop) { struct npc_data *nd = (struct npc_data *)map->id2bl(st->oid); - + if( nd ) { unit->bl2ud2(&nd->bl); // ensure nd->ud is safe to edit unit->stop_walking(&nd->bl,1|4); } - + return true; } @@ -12409,22 +13018,22 @@ BUILDIN(getlook) int type,val; TBL_PC *sd; sd=script->rid2sd(st); - + type=script_getnum(st,2); - val=-1; + val = -1; switch(type) { - case LOOK_HAIR: val=sd->status.hair; break; //1 - case LOOK_WEAPON: val=sd->status.weapon; break; //2 - case LOOK_HEAD_BOTTOM: val=sd->status.head_bottom; break; //3 - case LOOK_HEAD_TOP: val=sd->status.head_top; break; //4 - case LOOK_HEAD_MID: val=sd->status.head_mid; break; //5 - case LOOK_HAIR_COLOR: val=sd->status.hair_color; break; //6 - case LOOK_CLOTHES_COLOR:val=sd->status.clothes_color; break; //7 - case LOOK_SHIELD: val=sd->status.shield; break; //8 - case LOOK_SHOES: break; //9 - case LOOK_ROBE: val=sd->status.robe; break; //12 + case LOOK_HAIR: val = sd->status.hair; break; //1 + case LOOK_WEAPON: val = sd->status.weapon; break; //2 + case LOOK_HEAD_BOTTOM: val = sd->status.head_bottom; break; //3 + case LOOK_HEAD_TOP: val = sd->status.head_top; break; //4 + case LOOK_HEAD_MID: val = sd->status.head_mid; break; //5 + case LOOK_HAIR_COLOR: val = sd->status.hair_color; break; //6 + case LOOK_CLOTHES_COLOR: val = sd->status.clothes_color; break; //7 + case LOOK_SHIELD: val = sd->status.shield; break; //8 + case LOOK_SHOES: break; //9 + case LOOK_ROBE: val = sd->status.robe; break; //12 } - + script_pushint(st,val); return true; } @@ -12436,15 +13045,15 @@ BUILDIN(getsavepoint) { TBL_PC* sd; int type; - + sd = script->rid2sd(st); if (sd == NULL) { script_pushint(st,0); return true; } - + type = script_getnum(st,2); - + switch(type) { case 0: script_pushstrcopy(st,mapindex_id2name(sd->status.save_point.map)); break; case 1: script_pushint(st,sd->status.save_point.x); break; @@ -12482,44 +13091,44 @@ BUILDIN(getmapxy) { struct block_list *bl = NULL; TBL_PC *sd=NULL; - - int num; + + int64 num; const char *name; char prefix; - + int x,y,type; char mapname[MAP_NAME_LENGTH]; - - if( !data_isreference(script_getdata(st,2)) ){ + + if( !data_isreference(script_getdata(st,2)) ) { ShowWarning("script: buildin_getmapxy: not mapname variable\n"); script_pushint(st,-1); return false; } - if( !data_isreference(script_getdata(st,3)) ){ + if( !data_isreference(script_getdata(st,3)) ) { ShowWarning("script: buildin_getmapxy: not mapx variable\n"); script_pushint(st,-1); return false; } - if( !data_isreference(script_getdata(st,4)) ){ + if( !data_isreference(script_getdata(st,4)) ) { ShowWarning("script: buildin_getmapxy: not mapy variable\n"); script_pushint(st,-1); return false; } - + // Possible needly check function parameters on C_STR,C_INT,C_INT type=script_getnum(st,5); - - switch (type){ - case 0: //Get Character Position + + switch (type) { + case 0: //Get Character Position if( script_hasdata(st,6) ) sd=map->nick2sd(script_getstr(st,6)); else sd=script->rid2sd(st); - + if (sd) bl = &sd->bl; break; - case 1: //Get NPC Position + case 1: //Get NPC Position if( script_hasdata(st,6) ) { struct npc_data *nd; @@ -12529,23 +13138,23 @@ BUILDIN(getmapxy) } else //In case the origin is not an npc? bl=map->id2bl(st->oid); break; - case 2: //Get Pet Position + case 2: //Get Pet Position if(script_hasdata(st,6)) sd=map->nick2sd(script_getstr(st,6)); else sd=script->rid2sd(st); - + if (sd && sd->pd) bl = &sd->pd->bl; break; - case 3: //Get Mob Position + case 3: //Get Mob Position break; //Not supported? - case 4: //Get Homun Position + case 4: //Get Homun Position if(script_hasdata(st,6)) sd=map->nick2sd(script_getstr(st,6)); else sd=script->rid2sd(st); - + if (sd && sd->hd) bl = &sd->hd->bl; break; @@ -12554,7 +13163,7 @@ BUILDIN(getmapxy) sd=map->nick2sd(script_getstr(st,6)); else sd=script->rid2sd(st); - + if (sd && sd->md) bl = &sd->md->bl; break; @@ -12563,7 +13172,7 @@ BUILDIN(getmapxy) sd=map->nick2sd(script_getstr(st,6)); else sd=script->rid2sd(st); - + if (sd && sd->ed) bl = &sd->ed->bl; break; @@ -12576,44 +13185,44 @@ BUILDIN(getmapxy) script_pushint(st,-1); return true; } - + x= bl->x; y= bl->y; safestrncpy(mapname, map->list[bl->m].name, MAP_NAME_LENGTH); - + //Set MapName$ num=st->stack->stack_data[st->start+2].u.num; - name=script->get_str(num&0x00ffffff); + name=script->get_str(script_getvarid(num)); prefix=*name; - + if(not_server_variable(prefix)) sd=script->rid2sd(st); else sd=NULL; script->set_reg(st,sd,num,name,(void*)mapname,script_getref(st,2)); - + //Set MapX num=st->stack->stack_data[st->start+3].u.num; - name=script->get_str(num&0x00ffffff); + name=script->get_str(script_getvarid(num)); prefix=*name; - + if(not_server_variable(prefix)) sd=script->rid2sd(st); else sd=NULL; script->set_reg(st,sd,num,name,(void*)__64BPTRSIZE(x),script_getref(st,3)); - + //Set MapY num=st->stack->stack_data[st->start+4].u.num; - name=script->get_str(num&0x00ffffff); + name=script->get_str(script_getvarid(num)); prefix=*name; - + if(not_server_variable(prefix)) sd=script->rid2sd(st); else sd=NULL; script->set_reg(st,sd,num,name,(void*)__64BPTRSIZE(y),script_getref(st,4)); - + //Return Success value script_pushint(st,0); return true; @@ -12626,11 +13235,11 @@ BUILDIN(logmes) { const char *str; TBL_PC* sd; - + sd = script->rid2sd(st); if( sd == NULL ) return false; - + str = script_getstr(st,2); logs->npc(sd,str); return true; @@ -12642,23 +13251,23 @@ BUILDIN(summon) const char *str,*event=""; TBL_PC *sd; struct mob_data *md; - int tick = timer->gettick(); - + int64 tick = timer->gettick(); + sd=script->rid2sd(st); if (!sd) return true; - - str =script_getstr(st,2); - _class=script_getnum(st,3); + + str = script_getstr(st,2); + _class = script_getnum(st,3); if( script_hasdata(st,4) ) timeout=script_getnum(st,4); - if( script_hasdata(st,5) ){ + if( script_hasdata(st,5) ) { event=script_getstr(st,5); script->check_event(st, event); } - + clif->skill_poseffect(&sd->bl,AM_CALLHOMUN,1,sd->bl.x,sd->bl.y,tick); - - md = mob->once_spawn_sub(&sd->bl, sd->bl.m, sd->bl.x, sd->bl.y, str, _class, event, SZ_SMALL, AI_NONE); + + md = mob->once_spawn_sub(&sd->bl, sd->bl.m, sd->bl.x, sd->bl.y, str, _class, event, SZ_MEDIUM, AI_NONE); if (md) { md->master_id=sd->bl.id; md->special_state.ai = AI_ATTACK; @@ -12667,7 +13276,7 @@ BUILDIN(summon) md->deletetimer = timer->add(tick+(timeout>0?timeout*1000:60000),mob->timer_delete,md->bl.id,0); mob->spawn (md); //Now it is ready for spawning. clif->specialeffect(&md->bl,344,AREA); - sc_start4(&md->bl, SC_MODECHANGE, 100, 1, 0, MD_AGGRESSIVE, 0, 60000); + sc_start4(NULL, &md->bl, SC_MODECHANGE, 100, 1, 0, MD_AGGRESSIVE, 0, 60000); } return true; } @@ -12694,18 +13303,18 @@ BUILDIN(isequippedcnt) TBL_PC *sd; int i, j, k, id = 1; int ret = 0; - + sd = script->rid2sd(st); if (!sd) { //If the player is not attached it is a script error anyway... but better prevent the map server from crashing... script_pushint(st,0); return true; } - + for (i=0; id!=0; i++) { - script_fetch(st,i+2, id) else id = 0; + script_fetch(st,i+2, id); if (id <= 0) continue; - + for (j=0; j<EQI_MAX; j++) { int index; index = sd->equip_index[j]; @@ -12713,10 +13322,10 @@ BUILDIN(isequippedcnt) if(j == EQI_HAND_R && sd->equip_index[EQI_HAND_L] == index) continue; if(j == EQI_HEAD_MID && sd->equip_index[EQI_HEAD_LOW] == index) continue; if(j == EQI_HEAD_TOP && (sd->equip_index[EQI_HEAD_MID] == index || sd->equip_index[EQI_HEAD_LOW] == index)) continue; - + if(!sd->inventory_data[index]) continue; - + if (itemdb_type(id) != IT_CARD) { //No card. Count amount in inventory. if (sd->inventory_data[index]->nameid == id) ret+= sd->status.inventory[index].amount; @@ -12730,7 +13339,7 @@ BUILDIN(isequippedcnt) } } } - + script_pushint(st,ret); return true; } @@ -12749,18 +13358,18 @@ BUILDIN(isequipped) int ret = -1; //Original hash to reverse it when full check fails. unsigned int setitem_hash = 0, setitem_hash2 = 0; - + sd = script->rid2sd(st); - + if (!sd) { //If the player is not attached it is a script error anyway... but better prevent the map server from crashing... script_pushint(st,0); return true; } - + setitem_hash = sd->bonus.setitem_hash; setitem_hash2 = sd->bonus.setitem_hash2; for (i=0; id!=0; i++) { - script_fetch(st,i+2, id) else id = 0; + script_fetch(st,i+2, id); if (id <= 0) continue; flag = 0; @@ -12770,10 +13379,10 @@ BUILDIN(isequipped) if(j == EQI_HAND_R && sd->equip_index[EQI_HAND_L] == index) continue; if(j == EQI_HEAD_MID && sd->equip_index[EQI_HEAD_LOW] == index) continue; if(j == EQI_HEAD_TOP && (sd->equip_index[EQI_HEAD_MID] == index || sd->equip_index[EQI_HEAD_LOW] == index)) continue; - + if(!sd->inventory_data[index]) continue; - + if (itemdb_type(id) != IT_CARD) { if (sd->inventory_data[index]->nameid != id) continue; @@ -12783,18 +13392,18 @@ BUILDIN(isequipped) if (sd->inventory_data[index]->slot == 0 || itemdb_isspecial(sd->status.inventory[index].card[0])) continue; - - for (k = 0; k < sd->inventory_data[index]->slot; k++) - { //New hash system which should support up to 4 slots on any equipment. [Skotlex] + + for (k = 0; k < sd->inventory_data[index]->slot; k++) { + //New hash system which should support up to 4 slots on any equipment. [Skotlex] unsigned int hash = 0; if (sd->status.inventory[index].card[k] != id) continue; - + hash = 1<<((j<5?j:j-5)*4 + k); // check if card is already used by another set if ( ( j < 5 ? sd->bonus.setitem_hash : sd->bonus.setitem_hash2 ) & hash) continue; - + // We have found a match flag = 1; // Set hash so this card cannot be used by another @@ -12830,20 +13439,20 @@ BUILDIN(cardscnt) { int i, k, id = 1; int ret = 0; int index; - + sd = script->rid2sd(st); - + for (i=0; id!=0; i++) { - script_fetch(st,i+2, id) else id = 0; + script_fetch(st,i+2, id); if (id <= 0) continue; - + index = status->current_equip_item_index; //we get CURRENT WEAPON inventory index from status.c [Lupus] if(index < 0) continue; - + if(!sd->inventory_data[index]) continue; - + if(itemdb_type(id) != IT_CARD) { if (sd->inventory_data[index]->nameid == id) ret+= sd->status.inventory[index].amount; @@ -12857,7 +13466,7 @@ BUILDIN(cardscnt) { } } script_pushint(st,ret); - // script_pushint(st,status->current_equip_item_index); + // script_pushint(st,status->current_equip_item_index); return true; } @@ -12894,7 +13503,7 @@ BUILDIN(unequip) int i; size_t num; TBL_PC *sd; - + num = script_getnum(st,2); sd = script->rid2sd(st); if( sd != NULL && num >= 1 && num <= ARRAYLENGTH(script->equip) ) @@ -12911,19 +13520,19 @@ BUILDIN(equip) int nameid=0,i; TBL_PC *sd; struct item_data *item_data; - + sd = script->rid2sd(st); - + nameid=script_getnum(st,2); if((item_data = itemdb->exists(nameid)) == NULL) { ShowError("wrong item ID : equipitem(%i)\n",nameid); return false; } - ARR_FIND( 0, MAX_INVENTORY, i, sd->status.inventory[i].nameid == nameid ); + ARR_FIND( 0, MAX_INVENTORY, i, sd->status.inventory[i].nameid == nameid && sd->status.inventory[i].equip == 0 ); if( i < MAX_INVENTORY ) pc->equipitem(sd,i,item_data->equip); - + return true; } @@ -12933,19 +13542,19 @@ BUILDIN(autoequip) struct item_data *item_data; nameid=script_getnum(st,2); flag=script_getnum(st,3); - + if( ( item_data = itemdb->exists(nameid) ) == NULL ) { ShowError("buildin_autoequip: Invalid item '%d'.\n", nameid); return false; } - + if( !itemdb->isequip2(item_data) ) { ShowError("buildin_autoequip: Item '%d' cannot be equipped.\n", nameid); return false; } - + item_data->flag.autoequip = flag>0?1:0; return true; } @@ -12953,15 +13562,15 @@ BUILDIN(autoequip) BUILDIN(setbattleflag) { const char *flag, *value; - + flag = script_getstr(st,2); value = script_getstr(st,3); // HACK: Retrieve number as string (auto-converted) for battle_set_value - + if (battle->config_set_value(flag, value) == 0) ShowWarning("buildin_setbattleflag: unknown battle_config flag '%s'\n",flag); else ShowInfo("buildin_setbattleflag: battle_config flag '%s' is now set to '%s'.\n",flag,value); - + return true; } @@ -12978,10 +13587,10 @@ BUILDIN(getbattleflag) //------------------------------------------------------- BUILDIN(getstrlen) { - + const char *str = script_getstr(st,2); int len = (str) ? (int)strlen(str) : 0; - + script_pushint(st,len); return true; } @@ -12993,9 +13602,9 @@ BUILDIN(charisalpha) { const char *str=script_getstr(st,2); int pos=script_getnum(st,3); - + int val = ( str && pos >= 0 && (unsigned int)pos < strlen(str) ) ? ISALPHA( str[pos] ) != 0 : 0; - + script_pushint(st,val); return true; } @@ -13007,9 +13616,9 @@ BUILDIN(charisupper) { const char *str = script_getstr(st,2); int pos = script_getnum(st,3); - + int val = ( str && pos >= 0 && (unsigned int)pos < strlen(str) ) ? ISUPPER( str[pos] ) : 0; - + script_pushint(st,val); return true; } @@ -13021,9 +13630,9 @@ BUILDIN(charislower) { const char *str = script_getstr(st,2); int pos = script_getnum(st,3); - + int val = ( str && pos >= 0 && (unsigned int)pos < strlen(str) ) ? ISLOWER( str[pos] ) : 0; - + script_pushint(st,val); return true; } @@ -13034,7 +13643,7 @@ BUILDIN(charislower) BUILDIN(charat) { const char *str = script_getstr(st,2); int pos = script_getnum(st,3); - + if( pos >= 0 && (unsigned int)pos < strlen(str) ) { char output[2]; output[0] = str[pos]; @@ -13054,10 +13663,10 @@ BUILDIN(setchar) const char *c = script_getstr(st,3); int index = script_getnum(st,4); char *output = aStrdup(str); - + if(index >= 0 && index < strlen(output)) output[index] = *c; - + script_pushstr(st, output); return true; } @@ -13072,19 +13681,19 @@ BUILDIN(insertchar) int index = script_getnum(st,4); char *output; size_t len = strlen(str); - + if(index < 0) index = 0; else if(index > len) - index = len; - + index = (int)len; + output = (char*)aMalloc(len + 2); - + memcpy(output, str, index); output[index] = c[0]; memcpy(&output[index+1], &str[index], len - index); output[len+1] = '\0'; - + script_pushstr(st, output); return true; } @@ -13098,19 +13707,19 @@ BUILDIN(delchar) int index = script_getnum(st,3); char *output; size_t len = strlen(str); - + if(index < 0 || index > len) { //return original output = aStrdup(str); script_pushstr(st, output); return true; } - + output = (char*)aMalloc(len); - + memcpy(output, str, index); memcpy(&output[index], &str[index+1], len - index); - + script_pushstr(st, output); return true; } @@ -13123,12 +13732,12 @@ BUILDIN(strtoupper) const char *str = script_getstr(st,2); char *output = aStrdup(str); char *cursor = output; - + while (*cursor != '\0') { *cursor = TOUPPER(*cursor); cursor++; } - + script_pushstr(st, output); return true; } @@ -13141,12 +13750,12 @@ BUILDIN(strtolower) const char *str = script_getstr(st,2); char *output = aStrdup(str); char *cursor = output; - + while (*cursor != '\0') { *cursor = TOLOWER(*cursor); cursor++; } - + script_pushstr(st, output); return true; } @@ -13160,18 +13769,18 @@ BUILDIN(substr) char *output; int start = script_getnum(st,3); int end = script_getnum(st,4); - + int len = 0; - + if(start >= 0 && end < strlen(str) && start <= end) { len = end - start + 1; output = (char*)aMalloc(len + 1); memcpy(output, &str[start], len); } else output = (char*)aMalloc(1); - + output[len] = '\0'; - + script_pushstr(st, output); return true; } @@ -13189,15 +13798,15 @@ BUILDIN(explode) size_t len = strlen(str); int i = 0, j = 0; int start; - - + + char *temp; const char* name; - + TBL_PC* sd = NULL; - + temp = (char*)aMalloc(len + 1); - + if( !data_isreference(data) ) { ShowError("script:explode: not a variable\n"); @@ -13205,19 +13814,11 @@ BUILDIN(explode) st->state = END; return false;// not a variable } - + id = reference_getid(data); start = reference_getindex(data); name = reference_getname(data); - - if( not_array_variable(*name) ) - { - ShowError("script:explode: illegal scope\n"); - script->reportdata(data); - st->state = END; - return false;// not supported - } - + if( !is_string_variable(name) ) { ShowError("script:explode: not string array\n"); @@ -13225,14 +13826,14 @@ BUILDIN(explode) st->state = END; return false;// data type mismatch } - + if( not_server_variable(*name) ) { sd = script->rid2sd(st); if( sd == NULL ) return true;// no player attached } - + while(str[i] != '\0') { if(str[i] == delimiter && start < SCRIPT_MAX_ARRAYSIZE-1) { //break at delimiter but ignore after reaching last array index temp[j] = '\0'; @@ -13246,7 +13847,7 @@ BUILDIN(explode) //set last string temp[j] = '\0'; script->set_reg(st, sd, reference_uid(id, start), name, (void*)temp, reference_getref(data)); - + aFree(temp); return true; } @@ -13259,14 +13860,14 @@ BUILDIN(implode) { struct script_data* data = script_getdata(st, 2); const char *glue = NULL, *name, *temp; - int32 glue_len = 0, array_size, id; - size_t len = 0; - int i, k = 0; - + uint32 array_size, id; + size_t len = 0, glue_len = 0, k = 0; + int i; + TBL_PC* sd = NULL; - + char *output; - + if( !data_isreference(data) ) { ShowError("script:implode: not a variable\n"); @@ -13274,18 +13875,10 @@ BUILDIN(implode) st->state = END; return false;// not a variable } - + id = reference_getid(data); name = reference_getname(data); - - if( not_array_variable(*name) ) - { - ShowError("script:implode: illegal scope\n"); - script->reportdata(data); - st->state = END; - return false;// not supported - } - + if( !is_string_variable(name) ) { ShowError("script:implode: not string array\n"); @@ -13293,29 +13886,29 @@ BUILDIN(implode) st->state = END; return false;// data type mismatch } - + if( not_server_variable(*name) ) { sd = script->rid2sd(st); if( sd == NULL ) return true;// no player attached } - + //count chars - array_size = script->getarraysize(st, id, reference_getindex(data), is_string_variable(name), reference_getref(data)) - 1; - - if(array_size == -1) //empty array check (AmsTaff) - { - ShowWarning("script:implode: array length = 0\n"); - output = (char*)aMalloc(sizeof(char)*5); - sprintf(output,"%s","NULL"); + array_size = script->array_highest_key(st,sd,name,reference_getref(data)) - 1; + + if(array_size == -1) { + //empty array check (AmsTaff) + ShowWarning("script:implode: array length = 0\n"); + output = (char*)aMalloc(sizeof(char)*5); + sprintf(output,"%s","NULL"); } else { for(i = 0; i <= array_size; ++i) { temp = (char*) script->get_val2(st, reference_uid(id, i), reference_getref(data)); len += strlen(temp); script_removetop(st, -1, 0); } - + //allocate mem if( script_hasdata(st,3) ) { glue = script_getstr(st,3); @@ -13323,7 +13916,7 @@ BUILDIN(implode) len += glue_len * (array_size); } output = (char*)aMalloc(len + 1); - + //build output for(i = 0; i < array_size; ++i) { temp = (char*) script->get_val2(st, reference_uid(id, i), reference_getref(data)); @@ -13341,10 +13934,10 @@ BUILDIN(implode) memcpy(&output[k], temp, len); k += len; script_removetop(st, -1, 0); - + output[k] = '\0'; } - + script_pushstr(st, output); return true; } @@ -13354,232 +13947,242 @@ BUILDIN(implode) // Implements C sprintf, except format %n. The resulting string is // returned, instead of being saved in variable by reference. //------------------------------------------------------- -BUILDIN(sprintf) -{ - unsigned int len, argc = 0, arg = 0, buf2_len = 0; - const char* format; - char* p; - char* q; - char* buf = NULL; - char* buf2 = NULL; - struct script_data* data; - StringBuf final_buf; - - // Fetch init data - format = script_getstr(st, 2); - argc = script_lastdata(st)-2; - len = strlen(format); - - // Skip parsing, where no parsing is required. - if(len==0){ - script_pushconststr(st,""); - return true; - } - - // Pessimistic alloc - CREATE(buf, char, len+1); - - // Need not be parsed, just solve stuff like %%. - if(argc==0){ +BUILDIN(sprintf) { + unsigned int argc = 0, arg = 0; + const char* format; + char* p; + char* q; + char* buf = NULL; + char* buf2 = NULL; + struct script_data* data; + size_t len, buf2_len = 0; + StringBuf final_buf; + + // Fetch init data + format = script_getstr(st, 2); + argc = script_lastdata(st)-2; + len = strlen(format); + + // Skip parsing, where no parsing is required. + if(len==0) { + script_pushconststr(st,""); + return true; + } + + // Pessimistic alloc + CREATE(buf, char, len+1); + + // Need not be parsed, just solve stuff like %%. + if(argc==0) { memcpy(buf,format,len+1); - script_pushstrcopy(st, buf); - aFree(buf); - return true; - } - - safestrncpy(buf, format, len+1); - - // Issue sprintf for each parameter - StrBuf->Init(&final_buf); - q = buf; - while((p = strchr(q, '%'))!=NULL){ - if(p!=q){ - len = p-q+1; - if(buf2_len<len){ - RECREATE(buf2, char, len); - buf2_len = len; - } - safestrncpy(buf2, q, len); - StrBuf->AppendStr(&final_buf, buf2); - q = p; - } - p = q+1; - if(*p=='%'){ // %% - StrBuf->AppendStr(&final_buf, "%"); - q+=2; - continue; - } - if(*p=='n'){ // %n - ShowWarning("buildin_sprintf: Format %%n not supported! Skipping...\n"); - script->reportsrc(st); - q+=2; - continue; - } - if(arg>=argc){ - ShowError("buildin_sprintf: Not enough arguments passed!\n"); - if(buf) aFree(buf); - if(buf2) aFree(buf2); - StrBuf->Destroy(&final_buf); - script_pushconststr(st,""); - return false; - } - if((p = strchr(q+1, '%'))==NULL){ - p = strchr(q, 0); // EOS - } - len = p-q+1; - if(buf2_len<len){ - RECREATE(buf2, char, len); - buf2_len = len; - } - safestrncpy(buf2, q, len); - q = p; - - // Note: This assumes the passed value being the correct - // type to the current format specifier. If not, the server - // probably crashes or returns anything else, than expected, - // but it would behave in normal code the same way so it's - // the scripter's responsibility. - data = script_getdata(st, arg+3); - if(data_isstring(data)){ // String - StrBuf->Printf(&final_buf, buf2, script_getstr(st, arg+3)); - }else if(data_isint(data)){ // Number - StrBuf->Printf(&final_buf, buf2, script_getnum(st, arg+3)); - }else if(data_isreference(data)){ // Variable - char* name = reference_getname(data); - if(name[strlen(name)-1]=='$'){ // var Str - StrBuf->Printf(&final_buf, buf2, script_getstr(st, arg+3)); - }else{ // var Int - StrBuf->Printf(&final_buf, buf2, script_getnum(st, arg+3)); - } - }else{ // Unsupported type - ShowError("buildin_sprintf: Unknown argument type!\n"); - if(buf) aFree(buf); - if(buf2) aFree(buf2); - StrBuf->Destroy(&final_buf); - script_pushconststr(st,""); - return false; - } - arg++; - } - - // Append anything left - if(*q){ - StrBuf->AppendStr(&final_buf, q); - } - - // Passed more, than needed - if(arg<argc){ - ShowWarning("buildin_sprintf: Unused arguments passed.\n"); - script->reportsrc(st); - } - - script_pushstrcopy(st, StrBuf->Value(&final_buf)); - - if(buf) aFree(buf); - if(buf2) aFree(buf2); - StrBuf->Destroy(&final_buf); - - return true; + script_pushstrcopy(st, buf); + aFree(buf); + return true; + } + + safestrncpy(buf, format, len+1); + + // Issue sprintf for each parameter + StrBuf->Init(&final_buf); + q = buf; + while((p = strchr(q, '%'))!=NULL) { + if(p!=q) { + len = p-q+1; + if(buf2_len<len) { + RECREATE(buf2, char, len); + buf2_len = len; + } + safestrncpy(buf2, q, len); + StrBuf->AppendStr(&final_buf, buf2); + q = p; + } + p = q+1; + if(*p=='%') { // %% + StrBuf->AppendStr(&final_buf, "%"); + q+=2; + continue; + } + if(*p=='n') { // %n + ShowWarning("buildin_sprintf: Format %%n not supported! Skipping...\n"); + script->reportsrc(st); + q+=2; + continue; + } + if(arg>=argc) { + ShowError("buildin_sprintf: Not enough arguments passed!\n"); + if(buf) aFree(buf); + if(buf2) aFree(buf2); + StrBuf->Destroy(&final_buf); + script_pushconststr(st,""); + return false; + } + if((p = strchr(q+1, '%'))==NULL) { + p = strchr(q, 0); // EOS + } + len = p-q+1; + if(buf2_len<len) { + RECREATE(buf2, char, len); + buf2_len = len; + } + safestrncpy(buf2, q, len); + q = p; + + // Note: This assumes the passed value being the correct + // type to the current format specifier. If not, the server + // probably crashes or returns anything else, than expected, + // but it would behave in normal code the same way so it's + // the scripter's responsibility. + data = script_getdata(st, arg+3); + if(data_isstring(data)) { // String + StrBuf->Printf(&final_buf, buf2, script_getstr(st, arg+3)); + } else if(data_isint(data)) { // Number + StrBuf->Printf(&final_buf, buf2, script_getnum(st, arg+3)); + } else if(data_isreference(data)) { // Variable + char* name = reference_getname(data); + if(name[strlen(name)-1]=='$') { // var Str + StrBuf->Printf(&final_buf, buf2, script_getstr(st, arg+3)); + } else { // var Int + StrBuf->Printf(&final_buf, buf2, script_getnum(st, arg+3)); + } + } else { // Unsupported type + ShowError("buildin_sprintf: Unknown argument type!\n"); + if(buf) aFree(buf); + if(buf2) aFree(buf2); + StrBuf->Destroy(&final_buf); + script_pushconststr(st,""); + return false; + } + arg++; + } + + // Append anything left + if(*q) { + StrBuf->AppendStr(&final_buf, q); + } + + // Passed more, than needed + if(arg<argc) { + ShowWarning("buildin_sprintf: Unused arguments passed.\n"); + script->reportsrc(st); + } + + script_pushstrcopy(st, StrBuf->Value(&final_buf)); + + if(buf) aFree(buf); + if(buf2) aFree(buf2); + StrBuf->Destroy(&final_buf); + + return true; } //======================================================= // sscanf(<str>, <format>, ...); // Implements C sscanf. //------------------------------------------------------- -BUILDIN(sscanf){ - unsigned int argc, arg = 0, len; - struct script_data* data; - struct map_session_data* sd = NULL; - const char* str; - const char* format; - const char* p; - const char* q; - char* buf = NULL; - char* buf_p; - char* ref_str = NULL; - int ref_int; - - // Get data - str = script_getstr(st, 2); - format = script_getstr(st, 3); - argc = script_lastdata(st)-3; - - len = strlen(format); - CREATE(buf, char, len*2+1); - - // Issue sscanf for each parameter - *buf = 0; - q = format; - while((p = strchr(q, '%'))){ - if(p!=q){ - strncat(buf, q, (size_t)(p-q)); - q = p; - } - p = q+1; - if(*p=='*' || *p=='%'){ // Skip - strncat(buf, q, 2); - q+=2; - continue; - } - if(arg>=argc){ - ShowError("buildin_sscanf: Not enough arguments passed!\n"); - script_pushint(st, -1); - if(buf) aFree(buf); - if(ref_str) aFree(ref_str); - return false; - } - if((p = strchr(q+1, '%'))==NULL){ - p = strchr(q, 0); // EOS - } - len = p-q; - strncat(buf, q, len); - q = p; - - // Validate output - data = script_getdata(st, arg+4); - if(!data_isreference(data) || !reference_tovariable(data)){ - ShowError("buildin_sscanf: Target argument is not a variable!\n"); - script_pushint(st, -1); - if(buf) aFree(buf); - if(ref_str) aFree(ref_str); - return false; - } - buf_p = reference_getname(data); - if(not_server_variable(*buf_p) && (sd = script->rid2sd(st))==NULL){ - script_pushint(st, -1); - if(buf) aFree(buf); - if(ref_str) aFree(ref_str); - return true; - } - - // Save value if any - if(buf_p[strlen(buf_p)-1]=='$'){ // String - if(ref_str==NULL){ - CREATE(ref_str, char, strlen(str)+1); - } - if(sscanf(str, buf, ref_str)==0){ - break; - } +BUILDIN(sscanf) { + unsigned int argc, arg = 0; + struct script_data* data; + struct map_session_data* sd = NULL; + const char* str; + const char* format; + const char* p; + const char* q; + char* buf = NULL; + char* buf_p; + char* ref_str = NULL; + int ref_int; + size_t len; + + // Get data + str = script_getstr(st, 2); + format = script_getstr(st, 3); + argc = script_lastdata(st)-3; + + len = strlen(format); + + if (len != 0 && strlen(str) == 0) { + // If the source string is empty but the format string is not, we return -1 + // according to the C specs. (if the format string is also empty, we shall + // continue and return 0: 0 conversions took place out of the 0 attempted.) + script_pushint(st, -1); + return true; + } + + CREATE(buf, char, len*2+1); + + // Issue sscanf for each parameter + *buf = 0; + q = format; + while((p = strchr(q, '%'))) { + if(p!=q) { + strncat(buf, q, (size_t)(p-q)); + q = p; + } + p = q+1; + if(*p=='*' || *p=='%') { // Skip + strncat(buf, q, 2); + q+=2; + continue; + } + if(arg>=argc) { + ShowError("buildin_sscanf: Not enough arguments passed!\n"); + script_pushint(st, -1); + if(buf) aFree(buf); + if(ref_str) aFree(ref_str); + return false; + } + if((p = strchr(q+1, '%'))==NULL) { + p = strchr(q, 0); // EOS + } + len = p-q; + strncat(buf, q, len); + q = p; + + // Validate output + data = script_getdata(st, arg+4); + if(!data_isreference(data) || !reference_tovariable(data)) { + ShowError("buildin_sscanf: Target argument is not a variable!\n"); + script_pushint(st, -1); + if(buf) aFree(buf); + if(ref_str) aFree(ref_str); + return false; + } + buf_p = reference_getname(data); + if(not_server_variable(*buf_p) && (sd = script->rid2sd(st))==NULL) { + script_pushint(st, -1); + if(buf) aFree(buf); + if(ref_str) aFree(ref_str); + return true; + } + + // Save value if any + if(buf_p[strlen(buf_p)-1]=='$') { // String + if(ref_str==NULL) { + CREATE(ref_str, char, strlen(str)+1); + } + if(sscanf(str, buf, ref_str)==0) { + break; + } script->set_reg(st, sd, reference_uid( reference_getid(data), reference_getindex(data) ), buf_p, (void *)(ref_str), reference_getref(data)); - } else { // Number - if(sscanf(str, buf, &ref_int)==0){ - break; - } + } else { // Number + if(sscanf(str, buf, &ref_int)==0) { + break; + } script->set_reg(st, sd, reference_uid( reference_getid(data), reference_getindex(data) ), buf_p, (void *)__64BPTRSIZE(ref_int), reference_getref(data)); - } - arg++; - - // Disable used format (%... -> %*...) - buf_p = strchr(buf, 0); - memmove(buf_p-len+2, buf_p-len+1, len); - *(buf_p-len+1) = '*'; - } - - script_pushint(st, arg); - if(buf) aFree(buf); - if(ref_str) aFree(ref_str); - - return true; + } + arg++; + + // Disable used format (%... -> %*...) + buf_p = strchr(buf, 0); + memmove(buf_p-len+2, buf_p-len+1, len); + *(buf_p-len+1) = '*'; + } + + script_pushint(st, arg); + if(buf) aFree(buf); + if(ref_str) aFree(ref_str); + + return true; } //======================================================= @@ -13594,17 +14197,17 @@ BUILDIN(strpos) { const char *needle = script_getstr(st,3); int i; size_t len; - + if( script_hasdata(st,4) ) i = script_getnum(st,4); else i = 0; - + if (needle[0] == '\0') { script_pushint(st, -1); return true; } - + len = strlen(haystack); for ( ; i < len; ++i ) { if ( haystack[i] == *needle ) { @@ -13642,48 +14245,47 @@ BUILDIN(replacestr) size_t findlen = strlen(find); struct StringBuf output; bool usecase = true; - + int count = 0; int numFinds = 0; int i = 0, f = 0; - + if(findlen == 0) { ShowError("script:replacestr: Invalid search length.\n"); st->state = END; return false; } - + if(script_hasdata(st, 5)) { - if( !script_isstring(st,5) ) + if( script_isinttype(st,5) ) { usecase = script_getnum(st, 5) != 0; - else { - ShowError("script:replacestr: Invalid usecase value. Expected int got string\n"); + } else { + ShowError("script:replacestr: Invalid usecase value. Expected int.\n"); st->state = END; return false; } } - + if(script_hasdata(st, 6)) { - count = script_getnum(st, 6); - if(count == 0) { - ShowError("script:replacestr: Invalid count value. Expected int got string\n"); + if (!script_isinttype(st, 5) || (count = script_getnum(st, 6) == 0)) { + ShowError("script:replacestr: Invalid count value. Expected int.\n"); st->state = END; return false; } } - + StrBuf->Init(&output); - + for(; i < inputlen; i++) { - if(count && count == numFinds) { //found enough, stop looking - break; + if(count && count == numFinds) { + break; //found enough, stop looking } - + for(f = 0; f <= findlen; f++) { if(f == findlen) { //complete match numFinds++; StrBuf->AppendStr(&output, replace); - + i += findlen - 1; break; } else { @@ -13701,11 +14303,11 @@ BUILDIN(replacestr) } } } - + //append excess after enough found if(i < inputlen) StrBuf->AppendStr(&output, &(input[i])); - + script_pushstrcopy(st, StrBuf->Value(&output)); StrBuf->Destroy(&output); return true; @@ -13724,26 +14326,26 @@ BUILDIN(countstr) size_t inputlen = strlen(input); size_t findlen = strlen(find); bool usecase = true; - + int numFinds = 0; int i = 0, f = 0; - + if(findlen == 0) { ShowError("script:countstr: Invalid search length.\n"); st->state = END; return false; } - + if(script_hasdata(st, 4)) { - if( !script_isstring(st,4) ) + if( script_isinttype(st,4) ) usecase = script_getnum(st, 4) != 0; else { - ShowError("script:countstr: Invalid usecase value. Expected int got string\n"); + ShowError("script:countstr: Invalid usecase value. Expected int.\n"); st->state = END; return false; } } - + for(; i < inputlen; i++) { for(f = 0; f <= findlen; f++) { if(f == findlen) { //complete match @@ -13775,50 +14377,40 @@ BUILDIN(countstr) /// setnpcdisplay("<npc name>", "<new display name>", <new class id>) -> <int> /// setnpcdisplay("<npc name>", "<new display name>") -> <int> /// setnpcdisplay("<npc name>", <new class id>) -> <int> -BUILDIN(setnpcdisplay) -{ +BUILDIN(setnpcdisplay) { const char* name; const char* newname = NULL; int class_ = -1, size = -1; - struct script_data* data; struct npc_data* nd; - + name = script_getstr(st,2); - data = script_getdata(st,3); - + if( script_hasdata(st,4) ) class_ = script_getnum(st,4); if( script_hasdata(st,5) ) size = script_getnum(st,5); - - script->get_val(st, data); - if( data_isstring(data) ) - newname = script->conv_str(st,data); - else if( data_isint(data) ) - class_ = script->conv_num(st,data); + + if( script_isstringtype(st, 3) ) + newname = script_getstr(st, 3); else - { - ShowError("script:setnpcdisplay: expected string or number\n"); - script->reportdata(data); - return false; - } - + class_ = script_getnum(st, 3); + nd = npc->name2id(name); if( nd == NULL ) {// not found script_pushint(st,1); return true; } - + // update npc if( newname ) npc->setdisplayname(nd, newname); - + if( size != -1 && size != (int)nd->size ) nd->size = size; else size = -1; - + if( class_ != -1 && nd->class_ != class_ ) npc->setclass(nd, class_); else if( size != -1 ) @@ -13826,19 +14418,39 @@ BUILDIN(setnpcdisplay) clif->clearunit_area(&nd->bl, CLR_OUTSIGHT); clif->spawn(&nd->bl); } - + script_pushint(st,0); return true; } -BUILDIN(atoi) -{ +BUILDIN(atoi) { const char *value; value = script_getstr(st,2); script_pushint(st,atoi(value)); return true; } +BUILDIN(axtoi) { + const char *hex = script_getstr(st,2); + long value = strtol(hex, NULL, 16); +#if LONG_MAX > INT_MAX || LONG_MIN < INT_MIN + value = cap_value(value, INT_MIN, INT_MAX); +#endif + script_pushint(st, (int)value); + return true; +} + +BUILDIN(strtol) { + const char *string = script_getstr(st, 2); + int base = script_getnum(st, 3); + long value = strtol(string, NULL, base); +#if LONG_MAX > INT_MAX || LONG_MIN < INT_MIN + value = cap_value(value, INT_MIN, INT_MAX); +#endif + script_pushint(st, (int)value); + return true; +} + // case-insensitive substring search [lordalfa] BUILDIN(compare) { @@ -13873,12 +14485,12 @@ BUILDIN(pow) BUILDIN(distance) { int x0, y0, x1, y1; - + x0 = script_getnum(st,2); y0 = script_getnum(st,3); x1 = script_getnum(st,4); y1 = script_getnum(st,5); - + script_pushint(st,distance_xy(x0,y0,x1,y1)); return true; } @@ -13889,7 +14501,7 @@ BUILDIN(md5) { const char *tmpstr; char *md5str; - + tmpstr = script_getstr(st,2); md5str = (char *)aMalloc((32+1)*sizeof(char)); MD5_String(tmpstr, md5str); @@ -13906,10 +14518,10 @@ BUILDIN(setd) const char *buffer; int elem; buffer = script_getstr(st, 2); - + if(sscanf(buffer, "%99[^[][%d]", varname, &elem) < 2) elem = 0; - + if( not_server_variable(*varname) ) { sd = script->rid2sd(st); @@ -13919,13 +14531,13 @@ BUILDIN(setd) return true; } } - + if( is_string_variable(varname) ) { script->setd_sub(st, sd, varname, elem, (void *)script_getstr(st, 3), NULL); } else { script->setd_sub(st, sd, varname, elem, (void *)__64BPTRSIZE(script_getnum(st, 3)), NULL); } - + return true; } @@ -13936,10 +14548,10 @@ int buildin_query_sql_sub(struct script_state* st, Sql* handle) const char* query; struct script_data* data; const char* name; - int max_rows = SCRIPT_MAX_ARRAYSIZE; // maximum number of rows + unsigned int max_rows = SCRIPT_MAX_ARRAYSIZE; // maximum number of rows int num_vars; int num_cols; - + // check target variables for( i = 3; script_hasdata(st,i); ++i ) { data = script_getdata(st, i); @@ -13953,8 +14565,6 @@ int buildin_query_sql_sub(struct script_state* st, Sql* handle) return false; } } - if( not_array_variable(*name) ) - max_rows = 1;// not an array, limit to one row } else { ShowError("script:query_sql: not a variable\n"); script->reportdata(data); @@ -13963,22 +14573,22 @@ int buildin_query_sql_sub(struct script_state* st, Sql* handle) } } num_vars = i - 3; - + // Execute the query query = script_getstr(st,2); - + if( SQL_ERROR == SQL->QueryStr(handle, query) ) { Sql_ShowDebug(handle); - script_pushint(st, 0); + st->state = END; return false; } - + if( SQL->NumRows(handle) == 0 ) { // No data received SQL->FreeResult(handle); script_pushint(st, 0); return true; } - + // Count the number of columns to store num_cols = SQL->NumColumns(handle); if( num_vars < num_cols ) { @@ -13988,15 +14598,15 @@ int buildin_query_sql_sub(struct script_state* st, Sql* handle) ShowWarning("script:query_sql: Too many variables (%u extra).\n", (unsigned int)(num_vars-num_cols)); script->reportsrc(st); } - + // Store data for( i = 0; i < max_rows && SQL_SUCCESS == SQL->NextRow(handle); ++i ) { for( j = 0; j < num_vars; ++j ) { char* str = NULL; - + if( j < num_cols ) SQL->GetData(handle, j, &str, NULL); - + data = script_getdata(st, j+3); name = reference_getname(data); if( is_string_variable(name) ) @@ -14009,11 +14619,11 @@ int buildin_query_sql_sub(struct script_state* st, Sql* handle) ShowWarning("script:query_sql: Only %d/%u rows have been stored.\n", max_rows, (unsigned int)SQL->NumRows(handle)); script->reportsrc(st); } - + // Free data SQL->FreeResult(handle); script_pushint(st, i); - + return true; } BUILDIN(query_sql) { @@ -14035,7 +14645,7 @@ BUILDIN(escape_sql) const char *str; char *esc_str; size_t len; - + str = script_getstr(st,2); len = strlen(str); esc_str = (char*)aMalloc(len*2+1); @@ -14049,15 +14659,15 @@ BUILDIN(getd) char varname[100]; const char *buffer; int elem; - + buffer = script_getstr(st, 2); - + if(sscanf(buffer, "%[^[][%d]", varname, &elem) < 2) elem = 0; - + // Push the 'pointer' so it's more flexible [Lance] script->push_val(st->stack, C_NAME, reference_uid(script->add_str(varname), elem),NULL); - + return true; } @@ -14069,7 +14679,7 @@ BUILDIN(petstat) struct pet_data *pd; int flag = script_getnum(st,2); sd = script->rid2sd(st); - if(!sd || !sd->status.pet_id || !sd->pd){ + if(!sd || !sd->status.pet_id || !sd->pd) { if(flag == 2) script_pushconststr(st, ""); else @@ -14077,7 +14687,7 @@ BUILDIN(petstat) return true; } pd = sd->pd; - switch(flag){ + switch(flag) { case 1: script_pushint(st,(int)pd->pet.class_); break; case 2: script_pushstrcopy(st, pd->pet.name); break; case 3: script_pushint(st,(int)pd->pet.level); break; @@ -14111,12 +14721,12 @@ BUILDIN(callshop) script_pushint(st,0); return false; } - + if( nd->subtype == SHOP ) { // flag the user as using a valid script call for opening the shop (for floating NPCs) sd->state.callshop = 1; - + switch( flag ) { case 1: npc->buysellsel(sd,nd->bl.id,0); break; //Buy window @@ -14126,7 +14736,7 @@ BUILDIN(callshop) } else clif->cashshop_show(sd, nd); - + sd->npc_shopid = nd->bl.id; script_pushint(st,1); return true; @@ -14138,16 +14748,16 @@ BUILDIN(npcshopitem) struct npc_data* nd = npc->name2id(npcname); int n, i; int amount; - - if( !nd || ( nd->subtype != SHOP && nd->subtype != CASHSHOP ) ) - { //Not found. + + if( !nd || ( nd->subtype != SHOP && nd->subtype != CASHSHOP ) ) { + //Not found. script_pushint(st,0); return true; } - + // get the count of new entries amount = (script_lastdata(st)-2)/2; - + // generate new shop item list RECREATE(nd->u.shop.shop_item, struct npc_item_list, amount); for( n = 0, i = 3; n < amount; n++, i+=2 ) @@ -14156,7 +14766,7 @@ BUILDIN(npcshopitem) nd->u.shop.shop_item[n].value = script_getnum(st,i+1); } nd->u.shop.count = n; - + script_pushint(st,1); return true; } @@ -14167,16 +14777,16 @@ BUILDIN(npcshopadditem) struct npc_data* nd = npc->name2id(npcname); int n, i; int amount; - - if( !nd || ( nd->subtype != SHOP && nd->subtype != CASHSHOP ) ) - { //Not found. + + if( !nd || ( nd->subtype != SHOP && nd->subtype != CASHSHOP ) ) { + //Not found. script_pushint(st,0); return true; } - + // get the count of new entries amount = (script_lastdata(st)-2)/2; - + // append new items to existing shop item list RECREATE(nd->u.shop.shop_item, struct npc_item_list, nd->u.shop.count+amount); for( n = nd->u.shop.count, i = 3; n < nd->u.shop.count+amount; n++, i+=2 ) @@ -14185,7 +14795,7 @@ BUILDIN(npcshopadditem) nd->u.shop.shop_item[n].value = script_getnum(st,i+1); } nd->u.shop.count = n; - + script_pushint(st,1); return true; } @@ -14198,21 +14808,21 @@ BUILDIN(npcshopdelitem) int n, i; int amount; int size; - - if( !nd || ( nd->subtype != SHOP && nd->subtype != CASHSHOP ) ) - { //Not found. + + if( !nd || ( nd->subtype != SHOP && nd->subtype != CASHSHOP ) ) { + //Not found. script_pushint(st,0); return true; } - + amount = script_lastdata(st)-2; size = nd->u.shop.count; - + // remove specified items from the shop item list for( i = 3; i < 3 + amount; i++ ) { nameid = script_getnum(st,i); - + ARR_FIND( 0, size, n, nd->u.shop.shop_item[n].nameid == nameid ); if( n < size ) { @@ -14220,10 +14830,10 @@ BUILDIN(npcshopdelitem) size--; } } - + RECREATE(nd->u.shop.shop_item, struct npc_item_list, size); nd->u.shop.count = size; - + script_pushint(st,1); return true; } @@ -14233,21 +14843,21 @@ BUILDIN(npcshopattach) { const char* npcname = script_getstr(st,2); struct npc_data* nd = npc->name2id(npcname); int flag = 1; - + if( script_hasdata(st,3) ) flag = script_getnum(st,3); - - if( !nd || nd->subtype != SHOP ) - { //Not found. + + if( !nd || nd->subtype != SHOP ) { + //Not found. script_pushint(st,0); return true; } - + if (flag) nd->master_nd = ((struct npc_data *)map->id2bl(st->oid)); else nd->master_nd = NULL; - + script_pushint(st,1); return true; } @@ -14255,11 +14865,11 @@ BUILDIN(npcshopattach) { /*========================================== * Returns some values of an item [Lupus] * Price, Weight, etc... - setitemscript(itemID,"{new item bonus script}",[n]); - Where n: - 0 - script - 1 - Equip script - 2 - Unequip script + * setitemscript(itemID,"{new item bonus script}",[n]); + * Where n: + * 0 - script + * 1 - Equip script + * 2 - Unequip script *------------------------------------------*/ BUILDIN(setitemscript) { @@ -14267,13 +14877,13 @@ BUILDIN(setitemscript) const char *new_bonus_script; struct item_data *i_data; struct script_code **dstscript; - - item_id = script_getnum(st,2); + + item_id = script_getnum(st,2); new_bonus_script = script_getstr(st,3); if( script_hasdata(st,4) ) n=script_getnum(st,4); i_data = itemdb->exists(item_id); - + if (!i_data || new_bonus_script==NULL || ( new_bonus_script[0] && new_bonus_script[0]!='{' )) { script_pushint(st,0); return true; @@ -14291,50 +14901,130 @@ BUILDIN(setitemscript) } if(*dstscript) script->free_code(*dstscript); - + *dstscript = new_bonus_script[0] ? script->parse(new_bonus_script, "script_setitemscript", 0, 0) : NULL; script_pushint(st,1); return true; } -/* Work In Progress [Lupus] - BUILDIN(addmonsterdrop) - { - int class_,item_id,chance; - class_=script_getnum(st,2); - item_id=script_getnum(st,3); - chance=script_getnum(st,4); - if(class_>1000 && item_id>500 && chance>0) { - script_pushint(st,1); - } else { - script_pushint(st,0); - } - } - - BUILDIN(delmonsterdrop) - { - int class_,item_id; - class_=script_getnum(st,2); - item_id=script_getnum(st,3); - if(class_>1000 && item_id>500) { - script_pushint(st,1); - } else { - script_pushint(st,0); - } - } - */ +/*======================================================= + * Temporarily add or update a mob drop + * Original Idea By: [Lupus], [Akinari] + * + * addmonsterdrop <mob_id or name>,<item_id>,<rate>; + * + * If given an item the mob already drops, the rate + * is updated to the new rate. Rate must be in the range [1:10000] + * Returns 1 if succeeded (added/updated a mob drop) + *-------------------------------------------------------*/ +BUILDIN(addmonsterdrop) { + struct mob_db *monster; + int item_id, rate, i, c = MAX_MOB_DROP; + + if( script_isstringtype(st,2) ) + monster = mob->db(mob->db_searchname(script_getstr(st,2))); + else + monster = mob->db(script_getnum(st,2)); + + if( monster == mob->dummy ) { + if( script_isstringtype(st,2) ) { + ShowError("buildin_addmonsterdrop: invalid mob name: '%s'.\n", script_getstr(st,2)); + } else { + ShowError("buildin_addmonsterdrop: invalid mob id: '%d'.\n", script_getnum(st,2)); + } + return false; + } + + item_id = script_getnum(st,3); + if( !itemdb->exists(item_id) ) { + ShowError("buildin_addmonsterdrop: Invalid item ID: '%d'.\n", item_id); + return false; + } + + rate = script_getnum(st,4); + if( rate < 1 || rate > 10000 ) { + ShowWarning("buildin_addmonsterdrop: Invalid drop rate '%d'. Capping to the [1:10000] range.\n", rate); + rate = cap_value(rate,1,10000); + } + + for( i = 0; i < MAX_MOB_DROP; i++ ) { + if( monster->dropitem[i].nameid == item_id ) // Item ID found + break; + if( c == MAX_MOB_DROP && monster->dropitem[i].nameid < 1 ) // First empty slot + c = i; + } + if( i < MAX_MOB_DROP ) // If the item ID was found, prefer it + c = i; + + if( c < MAX_MOB_DROP ) { + // Fill in the slot with the item and rate + monster->dropitem[c].nameid = item_id; + monster->dropitem[c].p = rate; + script_pushint(st,1); + } else { + //No place to put the new drop + script_pushint(st,0); + } + + return true; +} + +/*======================================================= + * Temporarily remove a mob drop + * Original Idea By: [Lupus], [Akinari] + * + * delmonsterdrop <mob_id or name>,<item_id>; + * + * Returns 1 if succeeded (deleted a mob drop) + *-------------------------------------------------------*/ +BUILDIN(delmonsterdrop) { + struct mob_db *monster; + int item_id, i; + + if( script_isstringtype(st, 2) ) + monster = mob->db(mob->db_searchname(script_getstr(st, 2))); + else + monster = mob->db(script_getnum(st, 2)); + + if( monster == mob->dummy ) { + if( script_isstringtype(st, 2) ) { + ShowError("buildin_delmonsterdrop: invalid mob name: '%s'.\n", script_getstr(st,2)); + } else { + ShowError("buildin_delmonsterdrop: invalid mob id: '%d'.\n", script_getnum(st,2)); + } + return false; + } + + item_id = script_getnum(st,3); + if( !itemdb->exists(item_id) ) { + ShowError("buildin_delmonsterdrop: Invalid item ID: '%d'.\n", item_id); + return false; + } + + for( i = 0; i < MAX_MOB_DROP; i++ ) { + if( monster->dropitem[i].nameid == item_id ) { + monster->dropitem[i].nameid = 0; + monster->dropitem[i].p = 0; + script_pushint(st,1); + return true; + } + } + // No drop on that monster + script_pushint(st,0); + return true; +} /*========================================== * Returns some values of a monster [Lupus] * Name, Level, race, size, etc... - getmonsterinfo(monsterID,queryIndex); + * getmonsterinfo(monsterID,queryIndex); *------------------------------------------*/ BUILDIN(getmonsterinfo) { struct mob_db *monster; int mob_id; - - mob_id = script_getnum(st,2); + + mob_id = script_getnum(st,2); if (!mob->db_checkid(mob_id)) { ShowError("buildin_getmonsterinfo: Wrong Monster ID: %i\n", mob_id); if ( !script_getnum(st,3) ) //requested a string @@ -14376,17 +15066,17 @@ BUILDIN(getmonsterinfo) BUILDIN(checkvending) // check vending [Nab4] { TBL_PC *sd = NULL; - + if(script_hasdata(st,2)) sd = map->nick2sd(script_getstr(st,2)); else sd = script->rid2sd(st); - + if(sd) script_pushint(st, sd->state.autotrade ? 2 : sd->state.vending); else script_pushint(st,0); - + return true; } @@ -14394,33 +15084,33 @@ BUILDIN(checkvending) // check vending [Nab4] // check chatting [Marka] BUILDIN(checkchatting) { TBL_PC *sd = NULL; - + if(script_hasdata(st,2)) sd = map->nick2sd(script_getstr(st,2)); else sd = script->rid2sd(st); - + if(sd) script_pushint(st,(sd->chatID != 0)); else script_pushint(st,0); - + return true; } BUILDIN(checkidle) { TBL_PC *sd = NULL; - + if (script_hasdata(st, 2)) sd = map->nick2sd(script_getstr(st, 2)); else sd = script->rid2sd(st); - + if (sd) - script_pushint(st, DIFF_TICK(last_tick, sd->idletime)); + script_pushint(st, DIFF_TICK32(sockt->last_tick, sd->idletime)); // TODO: change this to int64 when we'll support 64 bit script values else script_pushint(st, 0); - + return true; } @@ -14430,25 +15120,25 @@ BUILDIN(searchitem) const char *itemname = script_getstr(st,3); struct item_data *items[MAX_SEARCH]; int count; - + char* name; int32 start; int32 id; int32 i; TBL_PC* sd = NULL; - + if ((items[0] = itemdb->exists(atoi(itemname)))) count = 1; else { count = itemdb->search_name_array(items, ARRAYLENGTH(items), itemname, 0); if (count > MAX_SEARCH) count = MAX_SEARCH; } - + if (!count) { script_pushint(st, 0); return true; } - + if( !data_isreference(data) ) { ShowError("script:searchitem: not a variable\n"); @@ -14456,25 +15146,18 @@ BUILDIN(searchitem) st->state = END; return false;// not a variable } - + id = reference_getid(data); start = reference_getindex(data); name = reference_getname(data); - if( not_array_variable(*name) ) - { - ShowError("script:searchitem: illegal scope\n"); - script->reportdata(data); - st->state = END; - return false;// not supported - } - + if( not_server_variable(*name) ) { sd = script->rid2sd(st); if( sd == NULL ) return true;// no player attached } - + if( is_string_variable(name) ) {// string array ShowError("script:searchitem: not an integer array reference\n"); @@ -14482,55 +15165,14 @@ BUILDIN(searchitem) st->state = END; return false;// not supported } - + for( i = 0; i < count; ++start, ++i ) {// Set array void* v = (void*)__64BPTRSIZE((int)items[i]->nameid); script->set_reg(st, sd, reference_uid(id, start), name, v, reference_getref(data)); } - - script_pushint(st, count); - return true; -} -int axtoi(const char *hexStg) -{ - int n = 0; // position in string - int16 m = 0; // position in digit[] to shift - int count; // loop index - int intValue = 0; // integer value of hex string - int digit[11]; // hold values to convert - while (n < 10) { - if (hexStg[n]=='\0') - break; - if (hexStg[n] > 0x29 && hexStg[n] < 0x40 ) //if 0 to 9 - digit[n] = hexStg[n] & 0x0f; //convert to int - else if (hexStg[n] >='a' && hexStg[n] <= 'f') //if a to f - digit[n] = (hexStg[n] & 0x0f) + 9; //convert to int - else if (hexStg[n] >='A' && hexStg[n] <= 'F') //if A to F - digit[n] = (hexStg[n] & 0x0f) + 9; //convert to int - else break; - n++; - } - count = n; - m = n - 1; - n = 0; - while(n < count) { - // digit[n] is value of hex digit at position n - // (m << 2) is the number of positions to shift - // OR the bits into return value - intValue = intValue | (digit[n] << (m << 2)); - m--; // adjust the position to set - n++; // next digit to process - } - return (intValue); -} - -// [Lance] Hex string to integer converter -BUILDIN(axtoi) -{ - const char *hex = script_getstr(st,2); - script_pushint(st,script->axtoi(hex)); + script_pushint(st, count); return true; } @@ -14561,56 +15203,56 @@ BUILDIN(rid2name) { BUILDIN(pcblockmove) { int id, flag; TBL_PC *sd = NULL; - + id = script_getnum(st,2); flag = script_getnum(st,3); - + if(id) sd = map->id2sd(id); else sd = script->rid2sd(st); - + if(sd) sd->state.blockedmove = flag > 0; - + return true; } BUILDIN(pcfollow) { int id, targetid; TBL_PC *sd = NULL; - - + + id = script_getnum(st,2); targetid = script_getnum(st,3); - + if(id) sd = map->id2sd(id); else sd = script->rid2sd(st); - + if(sd) pc->follow(sd, targetid); - - return true; + + return true; } BUILDIN(pcstopfollow) { int id; TBL_PC *sd = NULL; - - + + id = script_getnum(st,2); - + if(id) sd = map->id2sd(id); else sd = script->rid2sd(st); - + if(sd) pc->stop_following(sd); - + return true; } // <--- [zBuffer] List of player cont commands @@ -14624,7 +15266,7 @@ BUILDIN(pcstopfollow) /// unitwalk(<unit_id>,<map_id>) -> <bool> BUILDIN(unitwalk) { struct block_list* bl; - + bl = map->id2bl(script_getnum(st,2)); if( bl == NULL ) { script_pushint(st, 0); @@ -14642,7 +15284,7 @@ BUILDIN(unitwalk) { int map_id = script_getnum(st,3); script_pushint(st, unit->walktobl(bl,map->id2bl(map_id),65025,1)); } - + return true; } @@ -14654,7 +15296,7 @@ BUILDIN(unitkill) struct block_list* bl = map->id2bl(script_getnum(st,2)); if( bl != NULL ) status_kill(bl); - + return true; } @@ -14669,29 +15311,29 @@ BUILDIN(unitwarp) { short y; struct block_list* bl; const char *mapname; - + unit_id = script_getnum(st,2); mapname = script_getstr(st, 3); x = (short)script_getnum(st,4); y = (short)script_getnum(st,5); - + if (!unit_id) //Warp the script's runner bl = map->id2bl(st->rid); else bl = map->id2bl(unit_id); - + if( strcmp(mapname,"this") == 0 ) mapid = bl?bl->m:-1; else mapid = map->mapname2mapid(mapname); - + if( mapid >= 0 && bl != NULL ) { unit->bl2ud2(bl); // ensure ((TBL_NPC*)bl)->ud is safe to edit script_pushint(st, unit->warp(bl,mapid,x,y,CLR_OUTSIGHT)); } else { script_pushint(st, 0); } - + return true; } @@ -14705,35 +15347,32 @@ BUILDIN(unitwarp) { BUILDIN(unitattack) { struct block_list* unit_bl; struct block_list* target_bl = NULL; - struct script_data* data; int actiontype = 0; - + // get unit unit_bl = map->id2bl(script_getnum(st,2)); if( unit_bl == NULL ) { script_pushint(st, 0); return true; } - - data = script_getdata(st, 3); - script->get_val(st, data); - if( data_isstring(data) ) { - TBL_PC* sd = map->nick2sd(script->conv_str(st, data)); + + if( script_isstringtype(st, 3) ) { + TBL_PC* sd = map->nick2sd(script_getstr(st, 3)); if( sd != NULL ) target_bl = &sd->bl; } else - target_bl = map->id2bl(script->conv_num(st, data)); + target_bl = map->id2bl(script_getnum(st, 3)); // request the attack if( target_bl == NULL ) { script_pushint(st, 0); return true; } - + // get actiontype if( script_hasdata(st,4) ) actiontype = script_getnum(st,4); - + switch( unit_bl->type ) { case BL_PC: @@ -14761,9 +15400,9 @@ BUILDIN(unitattack) { BUILDIN(unitstop) { int unit_id; struct block_list* bl; - + unit_id = script_getnum(st,2); - + bl = map->id2bl(unit_id); if( bl != NULL ) { unit->bl2ud2(bl); // ensure ((TBL_NPC*)bl)->ud is safe to edit @@ -14772,7 +15411,7 @@ BUILDIN(unitstop) { if( bl->type == BL_MOB ) ((TBL_MOB*)bl)->target_id = 0; } - + return true; } @@ -14783,10 +15422,10 @@ BUILDIN(unittalk) { int unit_id; const char* message; struct block_list* bl; - + unit_id = script_getnum(st,2); message = script_getstr(st, 3); - + bl = map->id2bl(unit_id); if( bl != NULL ) { struct StringBuf sbuf; @@ -14797,7 +15436,7 @@ BUILDIN(unittalk) { clif->message(((TBL_PC*)bl)->fd, StrBuf->Value(&sbuf)); StrBuf->Destroy(&sbuf); } - + return true; } @@ -14810,13 +15449,13 @@ BUILDIN(unitemote) { int unit_id; int emotion; struct block_list* bl; - + unit_id = script_getnum(st,2); emotion = script_getnum(st,3); bl = map->id2bl(unit_id); if( bl != NULL ) clif->emotion(bl, emotion); - + return true; } @@ -14830,25 +15469,25 @@ BUILDIN(unitskilluseid) { uint16 skill_lv; int target_id; struct block_list* bl; - + unit_id = script_getnum(st,2); - skill_id = ( script_isstring(st,3) ? skill->name2id(script_getstr(st,3)) : script_getnum(st,3) ); + skill_id = ( script_isstringtype(st, 3) ? skill->name2id(script_getstr(st, 3)) : script_getnum(st, 3) ); skill_lv = script_getnum(st,4); target_id = ( script_hasdata(st,5) ? script_getnum(st,5) : unit_id ); - + bl = map->id2bl(unit_id); - + if( bl != NULL ) { if( bl->type == BL_NPC ) { if (!((TBL_NPC*)bl)->status.hp) { - status_calc_npc(((TBL_NPC*)bl), true); + status_calc_npc(((TBL_NPC*)bl), SCO_FIRST); } else { - status_calc_npc(((TBL_NPC*)bl), false); + status_calc_npc(((TBL_NPC*)bl), SCO_NONE); } } unit->skilluse_id(bl, target_id, skill_id, skill_lv); } - + return true; } @@ -14863,26 +15502,26 @@ BUILDIN(unitskillusepos) { int skill_x; int skill_y; struct block_list* bl; - + unit_id = script_getnum(st,2); - skill_id = ( script_isstring(st,3) ? skill->name2id(script_getstr(st,3)) : script_getnum(st,3) ); + skill_id = ( script_isstringtype(st, 3) ? skill->name2id(script_getstr(st, 3)) : script_getnum(st, 3) ); skill_lv = script_getnum(st,4); skill_x = script_getnum(st,5); skill_y = script_getnum(st,6); - + bl = map->id2bl(unit_id); - + if( bl != NULL ) { if( bl->type == BL_NPC ) { if (!((TBL_NPC*)bl)->status.hp) { - status_calc_npc(((TBL_NPC*)bl), true); + status_calc_npc(((TBL_NPC*)bl), SCO_FIRST); } else { - status_calc_npc(((TBL_NPC*)bl), false); + status_calc_npc(((TBL_NPC*)bl), SCO_NONE); } } unit->skilluse_pos(bl, skill_x, skill_y, skill_id, skill_lv); } - + return true; } @@ -14894,12 +15533,12 @@ BUILDIN(unitskillusepos) { BUILDIN(sleep) { int ticks; - + ticks = script_getnum(st,2); - + // detach the player script->detach_rid(st); - + if( ticks <= 0 ) {// do nothing } @@ -14922,9 +15561,9 @@ BUILDIN(sleep) /// sleep2(<mili secconds>) -> <bool> BUILDIN(sleep2) { int ticks; - + ticks = script_getnum(st,2); - + if( ticks <= 0 ) { // do nothing script_pushint(st, (map->id2sd(st->rid)!=NULL)); @@ -14948,18 +15587,18 @@ BUILDIN(awake) { DBIterator *iter; struct script_state *tst; struct npc_data* nd; - + if( ( nd = npc->name2id(script_getstr(st, 2)) ) == NULL ) { ShowError("awake: NPC \"%s\" not found\n", script_getstr(st, 2)); return false; } - + iter = db_iterator(script->st_db); - + for( tst = dbi_first(iter); dbi_exists(iter); tst = dbi_next(iter) ) { if( tst->oid == nd->bl.id ) { TBL_PC* sd = map->id2sd(tst->rid); - + if( tst->sleep.timer == INVALID_TIMER ) {// already awake ??? continue; } @@ -14968,7 +15607,7 @@ BUILDIN(awake) { tst->state = END; tst->rid = 0; } - + timer->delete(tst->sleep.timer, script->run_timer); tst->sleep.timer = INVALID_TIMER; if(tst->state != RERUNLINE) @@ -14976,9 +15615,9 @@ BUILDIN(awake) { script->run_main(tst); } } - + dbi_destroy(iter); - + return true; } @@ -14991,7 +15630,7 @@ BUILDIN(getvariableofnpc) struct script_data* data; const char* name; struct npc_data* nd; - + data = script_getdata(st,2); if( !data_isreference(data) ) {// Not a reference (aka varaible name) @@ -15001,7 +15640,7 @@ BUILDIN(getvariableofnpc) st->state = END; return false; } - + name = reference_getname(data); if( *name != '.' || name[1] == '@' ) {// not a npc variable @@ -15011,7 +15650,7 @@ BUILDIN(getvariableofnpc) st->state = END; return false; } - + nd = npc->name2id(script_getstr(st,3)); if( nd == NULL || nd->subtype != SCRIPT || nd->u.scr.script == NULL ) {// NPC not found or has no script @@ -15020,7 +15659,7 @@ BUILDIN(getvariableofnpc) st->state = END; return false; } - + script->push_val(st->stack, C_NAME, reference_getuid(data), &nd->u.scr.script->script_vars ); return true; } @@ -15034,61 +15673,61 @@ BUILDIN(getvariableofnpc) BUILDIN(warpportal) { int spx; int spy; - unsigned short mapindex; + unsigned short map_index; int tpx; int tpy; struct skill_unit_group* group; struct block_list* bl; - + bl = map->id2bl(st->oid); if( bl == NULL ) { ShowError("script:warpportal: npc is needed\n"); return false; } - + spx = script_getnum(st,2); spy = script_getnum(st,3); - mapindex = mapindex_name2id(script_getstr(st, 4)); + map_index = mapindex->name2id(script_getstr(st, 4)); tpx = script_getnum(st,5); tpy = script_getnum(st,6); - - if( mapindex == 0 ) + + if( map_index == 0 ) return true;// map not found - + group = skill->unitsetting(bl, AL_WARP, 4, spx, spy, 0); if( group == NULL ) return true;// failed group->val1 = (group->val1<<16)|(short)0; group->val2 = (tpx<<16) | tpy; - group->val3 = mapindex; - + group->val3 = map_index; + return true; } BUILDIN(openmail) { TBL_PC* sd; - + sd = script->rid2sd(st); if( sd == NULL ) return true; - + mail->openmail(sd); - + return true; } BUILDIN(openauction) { TBL_PC* sd; - + sd = script->rid2sd(st); if( sd == NULL ) return true; - + clif->auction_openwindow(sd); - + return true; } @@ -15102,14 +15741,14 @@ BUILDIN(checkcell) { int16 x = script_getnum(st,3); int16 y = script_getnum(st,4); cell_chk type = (cell_chk)script_getnum(st,5); - + if ( m == -1 ) { ShowWarning("checkcell: Attempted to run on unexsitent map '%s', type %d, x/y %d,%d\n",script_getstr(st,2),type,x,y); return true; } - + script_pushint(st, map->getcell(m, x, y, type)); - + return true; } @@ -15126,21 +15765,21 @@ BUILDIN(setcell) { int16 y2 = script_getnum(st,6); cell_t type = (cell_t)script_getnum(st,7); bool flag = (bool)script_getnum(st,8); - + int x,y; - + if ( m == -1 ) { ShowWarning("setcell: Attempted to run on unexistent map '%s', type %d, x1/y1 - %d,%d | x2/y2 - %d,%d\n",script_getstr(st, 2),type,x1,y1,x2,y2); return true; } - + if( x1 > x2 ) swap(x1,x2); if( y1 > y2 ) swap(y1,y2); - + for( y = y1; y <= y2; ++y ) for( x = x1; x <= x2; ++x ) map->list[m].setcell(m, x, y, type, flag); - + return true; } @@ -15151,15 +15790,15 @@ BUILDIN(mercenary_create) { struct map_session_data *sd; int class_, contract_time; - + if( (sd = script->rid2sd(st)) == NULL || sd->md || sd->status.mer_id != 0 ) return true; - + class_ = script_getnum(st,2); - + if( !mercenary->class(class_) ) return true; - + contract_time = script_getnum(st,3); mercenary->create(sd, class_, contract_time); return true; @@ -15168,12 +15807,12 @@ BUILDIN(mercenary_create) BUILDIN(mercenary_heal) { struct map_session_data *sd = script->rid2sd(st); int hp, sp; - + if( sd == NULL || sd->md == NULL ) return true; hp = script_getnum(st,2); sp = script_getnum(st,3); - + status->heal(&sd->md->bl, hp, sp, 0); return true; } @@ -15182,25 +15821,25 @@ BUILDIN(mercenary_sc_start) { struct map_session_data *sd = script->rid2sd(st); enum sc_type type; int tick, val1; - + if( sd == NULL || sd->md == NULL ) return true; - + type = (sc_type)script_getnum(st,2); tick = script_getnum(st,3); val1 = script_getnum(st,4); - - status->change_start(&sd->md->bl, type, 10000, val1, 0, 0, 0, tick, 2); + + status->change_start(NULL, &sd->md->bl, type, 10000, val1, 0, 0, 0, tick, 2); return true; } BUILDIN(mercenary_get_calls) { struct map_session_data *sd = script->rid2sd(st); int guild_id; - + if( sd == NULL ) return true; - + guild_id = script_getnum(st,2); switch( guild_id ) { case ARCH_MERC_GUILD: @@ -15216,20 +15855,20 @@ BUILDIN(mercenary_get_calls) { script_pushint(st,0); break; } - + return true; } BUILDIN(mercenary_set_calls) { struct map_session_data *sd = script->rid2sd(st); int guild_id, value, *calls; - + if( sd == NULL ) return true; - + guild_id = script_getnum(st,2); value = script_getnum(st,3); - + switch( guild_id ) { case ARCH_MERC_GUILD: calls = &sd->status.arch_calls; @@ -15243,20 +15882,20 @@ BUILDIN(mercenary_set_calls) { default: return true; // Invalid Guild } - + *calls += value; *calls = cap_value(*calls, 0, INT_MAX); - + return true; } BUILDIN(mercenary_get_faith) { struct map_session_data *sd = script->rid2sd(st); int guild_id; - + if( sd == NULL ) return true; - + guild_id = script_getnum(st,2); switch( guild_id ) { case ARCH_MERC_GUILD: @@ -15272,20 +15911,20 @@ BUILDIN(mercenary_get_faith) { script_pushint(st,0); break; } - + return true; } BUILDIN(mercenary_set_faith) { struct map_session_data *sd = script->rid2sd(st); int guild_id, value, *calls; - + if( sd == NULL ) return true; - + guild_id = script_getnum(st,2); value = script_getnum(st,3); - + switch( guild_id ) { case ARCH_MERC_GUILD: calls = &sd->status.arch_faith; @@ -15299,12 +15938,12 @@ BUILDIN(mercenary_set_faith) { default: return true; // Invalid Guild } - + *calls += value; *calls = cap_value(*calls, 0, INT_MAX); if( mercenary->get_guild(sd->md) == guild_id ) clif->mercenary_updatestatus(sd,SP_MERCFAITH); - + return true; } @@ -15315,86 +15954,167 @@ BUILDIN(readbook) { struct map_session_data *sd; int book_id, page; - + if( (sd = script->rid2sd(st)) == NULL ) return true; - + book_id = script_getnum(st,2); page = script_getnum(st,3); - + clif->readbook(sd->fd, book_id, page); return true; } -/****************** - Questlog script commands - *******************/ +/**************************** + * Questlog script commands * + ****************************/ -BUILDIN(setquest) +BUILDIN(questinfo) { + struct npc_data *nd = map->id2nd(st->oid); + int quest_id, icon, job, color = 0; + struct questinfo qi; + + if( nd == NULL || nd->bl.m == -1 ) + return true; + + quest_id = script_getnum(st, 2); + icon = script_getnum(st, 3); + + #if PACKETVER >= 20120410 + if(icon < 0 || (icon > 8 && icon != 9999) || icon == 7) + icon = 9999; // Default to nothing if icon id is invalid. + #else + if(icon < 0 || icon > 7) + icon = 0; + else + icon = icon + 1; + #endif + + qi.quest_id = quest_id; + qi.icon = (unsigned char)icon; + qi.nd = nd; + + if( script_hasdata(st, 4) ) { + color = script_getnum(st, 4); + if( color < 0 || color > 3 ) { + ShowWarning("buildin_questinfo: invalid color '%d', changing to 0\n",color); + script->reportfunc(st); + color = 0; + } + qi.color = (unsigned char)color; + } + + qi.hasJob = false; + + if(script_hasdata(st, 5)) { + job = script_getnum(st, 5); + + if (!pcdb_checkid(job)) + ShowError("buildin_questinfo: Nonexistant Job Class.\n"); + else { + qi.hasJob = true; + qi.job = (unsigned short)job; + } + } + + map->add_questinfo(nd->bl.m,&qi); + + return true; +} + +BUILDIN(setquest) { struct map_session_data *sd = script->rid2sd(st); - nullpo_ret(sd); - - quest->add(sd, script_getnum(st, 2)); + unsigned short i; + int quest_id; + nullpo_retr(false,sd); + + quest_id = script_getnum(st, 2); + + quest->add(sd, quest_id); + + // If questinfo is set, remove quest bubble once quest is set. + for(i = 0; i < map->list[sd->bl.m].qi_count; i++) { + struct questinfo *qi = &map->list[sd->bl.m].qi_data[i]; + if( qi->quest_id == quest_id ) { +#if PACKETVER >= 20120410 + clif->quest_show_event(sd, &qi->nd->bl, 9999, 0); +#else + clif->quest_show_event(sd, &qi->nd->bl, 0, 0); +#endif + } + } + return true; } -BUILDIN(erasequest) -{ +BUILDIN(erasequest) { struct map_session_data *sd = script->rid2sd(st); - nullpo_ret(sd); - + nullpo_retr(false,sd); + quest->delete(sd, script_getnum(st, 2)); return true; } -BUILDIN(completequest) -{ +BUILDIN(completequest) { struct map_session_data *sd = script->rid2sd(st); - nullpo_ret(sd); - + nullpo_retr(false,sd); + quest->update_status(sd, script_getnum(st, 2), Q_COMPLETE); return true; } -BUILDIN(changequest) -{ +BUILDIN(changequest) { struct map_session_data *sd = script->rid2sd(st); - nullpo_ret(sd); - + nullpo_retr(false,sd); + quest->change(sd, script_getnum(st, 2),script_getnum(st, 3)); return true; } -BUILDIN(checkquest) -{ +BUILDIN(checkquest) { struct map_session_data *sd = script->rid2sd(st); - quest_check_type type = HAVEQUEST; - - nullpo_ret(sd); - + enum quest_check_type type = HAVEQUEST; + + nullpo_retr(false,sd); + if( script_hasdata(st, 3) ) - type = (quest_check_type)script_getnum(st, 3); - + type = (enum quest_check_type)script_getnum(st, 3); + script_pushint(st, quest->check(sd, script_getnum(st, 2), type)); - + return true; } BUILDIN(showevent) { TBL_PC *sd = script->rid2sd(st); struct npc_data *nd = map->id2nd(st->oid); - int state, color; - + int icon, color = 0; + if( sd == NULL || nd == NULL ) return true; - state = script_getnum(st, 2); - color = script_getnum(st, 3); - - if( color < 0 || color > 3 ) - color = 0; // set default color - - clif->quest_show_event(sd, &nd->bl, state, color); + + icon = script_getnum(st, 2); + if( script_hasdata(st, 3) ) { + color = script_getnum(st, 3); + if( color < 0 || color > 3 ) { + ShowWarning("buildin_showevent: invalid color '%d', changing to 0\n",color); + script->reportfunc(st); + color = 0; + } + } + + #if PACKETVER >= 20120410 + if(icon < 0 || (icon > 8 && icon != 9999) || icon == 7) + icon = 9999; // Default to nothing if icon id is invalid. + #else + if(icon < 0 || icon > 7) + icon = 0; + else + icon = icon + 1; + #endif + + clif->quest_show_event(sd, &nd->bl, icon, color); return true; } @@ -15405,41 +16125,41 @@ BUILDIN(waitingroom2bg) { struct npc_data *nd; struct chat_data *cd; const char *map_name, *ev = "", *dev = ""; - int x, y, i, mapindex = 0, bg_id, n; + int x, y, i, map_index = 0, bg_id, n; struct map_session_data *sd; - + if( script_hasdata(st,7) ) nd = npc->name2id(script_getstr(st,7)); else nd = (struct npc_data *)map->id2bl(st->oid); - + if( nd == NULL || (cd = (struct chat_data *)map->id2bl(nd->chat_id)) == NULL ) { script_pushint(st,0); return true; } - + map_name = script_getstr(st,2); if( strcmp(map_name,"-") != 0 ) { - mapindex = mapindex_name2id(map_name); - if( mapindex == 0 ) + map_index = mapindex->name2id(map_name); + if( map_index == 0 ) { // Invalid Map script_pushint(st,0); return true; } } - + x = script_getnum(st,3); y = script_getnum(st,4); ev = script_getstr(st,5); // Logout Event dev = script_getstr(st,6); // Die Event - - if( (bg_id = bg->create(mapindex, x, y, ev, dev)) == 0 ) + + if( (bg_id = bg->create(map_index, x, y, ev, dev)) == 0 ) { // Creation failed script_pushint(st,0); return true; } - + n = cd->users; for( i = 0; i < n && i < MAX_BG_MEMBERS; i++ ) { @@ -15448,7 +16168,7 @@ BUILDIN(waitingroom2bg) { else mapreg->setreg(reference_uid(script->add_str("$@arenamembers"), i), 0); } - + mapreg->setreg(script->add_str("$@arenamembersnum"), i); script_pushint(st,bg_id); return true; @@ -15459,31 +16179,31 @@ BUILDIN(waitingroom2bg_single) { struct npc_data *nd; struct chat_data *cd; struct map_session_data *sd; - int x, y, mapindex, bg_id; - + int x, y, map_index, bg_id; + bg_id = script_getnum(st,2); map_name = script_getstr(st,3); - if( (mapindex = mapindex_name2id(map_name)) == 0 ) + if( (map_index = mapindex->name2id(map_name)) == 0 ) return true; // Invalid Map - + x = script_getnum(st,4); y = script_getnum(st,5); nd = npc->name2id(script_getstr(st,6)); - + if( nd == NULL || (cd = (struct chat_data *)map->id2bl(nd->chat_id)) == NULL || cd->users <= 0 ) return true; - + if( (sd = cd->usersd[0]) == NULL ) return true; - + if( bg->team_join(bg_id, sd) ) { - pc->setpos(sd, mapindex, x, y, CLR_TELEPORT); + pc->setpos(sd, map_index, x, y, CLR_TELEPORT); script_pushint(st,1); } else script_pushint(st,0); - + return true; } @@ -15491,11 +16211,11 @@ BUILDIN(bg_team_setxy) { struct battleground_data *bgd; int bg_id; - + bg_id = script_getnum(st,2); if( (bgd = bg->team_search(bg_id)) == NULL ) return true; - + bgd->x = script_getnum(st,3); bgd->y = script_getnum(st,4); return true; @@ -15503,16 +16223,16 @@ BUILDIN(bg_team_setxy) BUILDIN(bg_warp) { - int x, y, mapindex, bg_id; + int x, y, map_index, bg_id; const char* map_name; - + bg_id = script_getnum(st,2); map_name = script_getstr(st,3); - if( (mapindex = mapindex_name2id(map_name)) == 0 ) + if( (map_index = mapindex->name2id(map_name)) == 0 ) return true; // Invalid Map x = script_getnum(st,4); y = script_getnum(st,5); - bg->team_warp(bg_id, mapindex, x, y); + bg->team_warp(bg_id, map_index, x, y); return true; } @@ -15520,7 +16240,7 @@ BUILDIN(bg_monster) { int class_ = 0, x = 0, y = 0, bg_id = 0; const char *str, *mapname, *evt=""; - + bg_id = script_getnum(st,2); mapname = script_getstr(st,3); x = script_getnum(st,4); @@ -15538,17 +16258,17 @@ BUILDIN(bg_monster_set_team) { struct block_list *mbl; int id = script_getnum(st,2), bg_id = script_getnum(st,3); - + if( (mbl = map->id2bl(id)) == NULL || mbl->type != BL_MOB ) return true; md = (TBL_MOB *)mbl; md->bg_id = bg_id; - + mob_stop_attack(md); mob_stop_walking(md, 0); md->target_id = md->attacked_id = 0; clif->charnameack(0, &md->bl); - + return true; } @@ -15557,7 +16277,7 @@ BUILDIN(bg_leave) struct map_session_data *sd = script->rid2sd(st); if( sd == NULL || !sd->bg_id ) return true; - + bg->team_leave(sd,0); return true; } @@ -15576,20 +16296,20 @@ BUILDIN(bg_getareausers) { int i = 0, c = 0; struct battleground_data *bgd = NULL; struct map_session_data *sd; - + bg_id = script_getnum(st,2); str = script_getstr(st,3); - + if( (bgd = bg->team_search(bg_id)) == NULL || (m = map->mapname2mapid(str)) < 0 ) { script_pushint(st,0); return true; } - + x0 = script_getnum(st,4); y0 = script_getnum(st,5); x1 = script_getnum(st,6); y1 = script_getnum(st,7); - + for( i = 0; i < MAX_BG_MEMBERS; i++ ) { if( (sd = bgd->members[i].sd) == NULL ) @@ -15598,7 +16318,7 @@ BUILDIN(bg_getareausers) { continue; c++; } - + script_pushint(st,c); return true; } @@ -15606,14 +16326,14 @@ BUILDIN(bg_getareausers) { BUILDIN(bg_updatescore) { const char *str; int16 m; - + str = script_getstr(st,2); if( (m = map->mapname2mapid(str)) < 0 ) return true; - + map->list[m].bgscore_lion = script_getnum(st,3); map->list[m].bgscore_eagle = script_getnum(st,4); - + clif->bg_updatescore(m); return true; } @@ -15623,13 +16343,13 @@ BUILDIN(bg_get_data) struct battleground_data *bgd; int bg_id = script_getnum(st,2), type = script_getnum(st,3); - + if( (bgd = bg->team_search(bg_id)) == NULL ) { script_pushint(st,0); return true; } - + switch( type ) { case 0: script_pushint(st, bgd->count); break; @@ -15637,7 +16357,7 @@ BUILDIN(bg_get_data) ShowError("script:bg_get_data: unknown data identifier %d\n", type); break; } - + return true; } @@ -15649,7 +16369,7 @@ BUILDIN(instance_create) { const char *name; int owner_id, res; int type = IOT_PARTY; - + name = script_getstr(st, 2); owner_id = script_getnum(st, 3); if( script_hasdata(st,4) ) { @@ -15659,9 +16379,9 @@ BUILDIN(instance_create) { return true; } } - + res = instance->create(owner_id, name, (enum instance_owner_type) type); - if( res == -4 ) { // Already exists + if( res == -4 ) { // Already exists script_pushint(st, -1); return true; } else if( res < 0 ) { @@ -15676,25 +16396,25 @@ BUILDIN(instance_create) { script_pushint(st, -2); return true; } - + script_pushint(st, res); return true; } BUILDIN(instance_destroy) { int instance_id = -1; - + if( script_hasdata(st, 2) ) instance_id = script_getnum(st, 2); else if( st->instance_id >= 0 ) instance_id = st->instance_id; else return true; - + if( !instance->valid(instance_id) ) { ShowError("buildin_instance_destroy: Trying to destroy invalid instance %d.\n", instance_id); return true; } - + instance->destroy(instance_id); return true; } @@ -15704,22 +16424,22 @@ BUILDIN(instance_attachmap) { int16 m; int instance_id = -1; bool usebasename = false; - + name = script_getstr(st,2); instance_id = script_getnum(st,3); if( script_hasdata(st,4) && script_getnum(st,4) > 0 ) usebasename = true; - + if( script_hasdata(st, 5) ) map_name = script_getstr(st, 5); - + if( (m = instance->add_map(name, instance_id, usebasename, map_name)) < 0 ) { // [Saithis] ShowError("buildin_instance_attachmap: instance creation failed (%s): %d\n", name, m); script_pushconststr(st, ""); return true; } script_pushconststr(st, map->list[m].name); - + return true; } @@ -15727,30 +16447,30 @@ BUILDIN(instance_detachmap) { const char *str; int16 m; int instance_id = -1; - + str = script_getstr(st, 2); if( script_hasdata(st, 3) ) instance_id = script_getnum(st, 3); else if( st->instance_id >= 0 ) instance_id = st->instance_id; else return true; - + if( (m = map->mapname2mapid(str)) < 0 || (m = instance->map2imap(m,instance_id)) < 0 ) { ShowError("buildin_instance_detachmap: Trying to detach invalid map %s\n", str); return true; } - + instance->del_map(m); return true; } BUILDIN(instance_attach) { int instance_id = -1; - + instance_id = script_getnum(st, 2); if( !instance->valid(instance_id) ) return true; - + st->instance_id = instance_id; return true; } @@ -15764,35 +16484,35 @@ BUILDIN(instance_set_timeout) { int progress_timeout, idle_timeout; int instance_id = -1; - + progress_timeout = script_getnum(st, 2); idle_timeout = script_getnum(st, 3); - + if( script_hasdata(st, 4) ) instance_id = script_getnum(st, 4); else if( st->instance_id >= 0 ) instance_id = st->instance_id; else return true; - + if( instance_id >= 0 ) instance->set_timeout(instance_id, progress_timeout, idle_timeout); - + return true; } BUILDIN(instance_init) { int instance_id = script_getnum(st, 2); - + if( !instance->valid(instance_id) ) { ShowError("instance_init: invalid instance id %d.\n",instance_id); return true; } - + if( instance->list[instance_id].state != INSTANCE_IDLE ) { ShowError("instance_init: instance already initialized.\n"); return true; } - + instance->start(instance_id); return true; } @@ -15806,23 +16526,23 @@ BUILDIN(instance_announce) { int fontSize = script_hasdata(st,7) ? script_getnum(st,7) : 12; // default fontSize int fontAlign = script_hasdata(st,8) ? script_getnum(st,8) : 0; // default fontAlign int fontY = script_hasdata(st,9) ? script_getnum(st,9) : 0; // default fontY - + int i; - + if( instance_id == -1 ) { if( st->instance_id >= 0 ) instance_id = st->instance_id; else return true; } - + if( !instance->valid(instance_id) ) return true; - + for( i = 0; i < instance->list[instance_id].num_map; i++ ) map->foreachinmap(script->buildin_announce_sub, instance->list[instance_id].map[i], BL_PC, mes, strlen(mes)+1, flag&BC_COLOR_MASK, fontColor, fontType, fontSize, fontAlign, fontY); - + return true; } @@ -15830,39 +16550,43 @@ BUILDIN(instance_npcname) { const char *str; int instance_id = -1; struct npc_data *nd; - + str = script_getstr(st, 2); if( script_hasdata(st, 3) ) instance_id = script_getnum(st, 3); else if( st->instance_id >= 0 ) instance_id = st->instance_id; - + if( instance_id >= 0 && (nd = npc->name2id(str)) != NULL ) { static char npcname[NAME_LENGTH]; snprintf(npcname, sizeof(npcname), "dup_%d_%d", instance_id, nd->bl.id); - script_pushconststr(st,npcname); + script_pushconststr(st,npcname); } else { ShowError("script:instance_npcname: invalid instance NPC (instance_id: %d, NPC name: \"%s\".)\n", instance_id, str); st->state = END; return false; } - + return true; } BUILDIN(has_instance) { struct map_session_data *sd; - const char *str; + const char *str; int16 m; int instance_id = -1; + bool type = strcmp(script->getfuncname(st),"has_instance2") == 0 ? true : false; - str = script_getstr(st, 2); - + str = script_getstr(st, 2); + if( (m = map->mapname2mapid(str)) < 0 ) { - script_pushconststr(st, ""); + if( type ) + script_pushint(st, -1); + else + script_pushconststr(st, ""); return true; } - + if( script_hasdata(st, 3) ) instance_id = script_getnum(st, 3); else if( st->instance_id >= 0 ) @@ -15904,23 +16628,29 @@ BUILDIN(has_instance) { instance_id = sd->guild->instance[i]; } } - + if( !instance->valid(instance_id) || (m = instance->map2imap(m, instance_id)) < 0 ) { - script_pushconststr(st, ""); + if( type ) + script_pushint(st, -1); + else + script_pushconststr(st, ""); return true; } - - script_pushconststr(st, map->list[m].name); + + if( type ) + script_pushint(st, instance_id); + else + script_pushconststr(st, map->list[m].name); return true; } int buildin_instance_warpall_sub(struct block_list *bl,va_list ap) { struct map_session_data *sd = ((TBL_PC*)bl); - int mapindex = va_arg(ap,int); + int map_index = va_arg(ap,int); int x = va_arg(ap,int); int y = va_arg(ap,int); - - pc->setpos(sd,mapindex,x,y,CLR_TELEPORT); - + + pc->setpos(sd,map_index,x,y,CLR_TELEPORT); + return 0; } BUILDIN(instance_warpall) { @@ -15928,25 +16658,25 @@ BUILDIN(instance_warpall) { int instance_id = -1; const char *mapn; int x, y; - int mapindex; - + int map_index; + mapn = script_getstr(st,2); x = script_getnum(st,3); y = script_getnum(st,4); - + if( script_hasdata(st,5) ) instance_id = script_getnum(st,5); else if( st->instance_id >= 0 ) instance_id = st->instance_id; else return true; - + if( (m = map->mapname2mapid(mapn)) < 0 || (map->list[m].flag.src4instance && (m = instance->mapid2imapid(m, instance_id)) < 0) ) return true; - - mapindex = map_id2index(m); - - map->foreachininstance(script->buildin_instance_warpall_sub, instance_id, BL_PC,mapindex,x,y); + + map_index = map_id2index(m); + + map->foreachininstance(script->buildin_instance_warpall_sub, instance_id, BL_PC,map_index,x,y); return true; } @@ -15965,46 +16695,46 @@ BUILDIN(instance_check_party) { struct map_session_data *pl_sd; int amount, min, max, i, party_id, c = 0; struct party_data *p = NULL; - + amount = script_hasdata(st,3) ? script_getnum(st,3) : 1; // Amount of needed Partymembers for the Instance. min = script_hasdata(st,4) ? script_getnum(st,4) : 1; // Minimum Level needed to join the Instance. max = script_hasdata(st,5) ? script_getnum(st,5) : MAX_LEVEL; // Maxium Level allowed to join the Instance. - - if( min < 1 || min > MAX_LEVEL){ + + if( min < 1 || min > MAX_LEVEL) { ShowError("instance_check_party: Invalid min level, %d\n", min); return true; - } else if( max < 1 || max > MAX_LEVEL){ + } else if( max < 1 || max > MAX_LEVEL) { ShowError("instance_check_party: Invalid max level, %d\n", max); return true; } - + if( script_hasdata(st,2) ) party_id = script_getnum(st,2); else return true; - - if( !(p = party->search(party_id)) ){ + + if( !(p = party->search(party_id)) ) { script_pushint(st, 0); // Returns false if party does not exist. return true; } - + for( i = 0; i < MAX_PARTY; i++ ) if( (pl_sd = p->data[i].sd) ) - if(map->id2bl(pl_sd->bl.id)){ - if(pl_sd->status.base_level < min){ + if(map->id2bl(pl_sd->bl.id)) { + if(pl_sd->status.base_level < min) { script_pushint(st, 0); return true; - }else if(pl_sd->status.base_level > max){ + } else if(pl_sd->status.base_level > max) { script_pushint(st, 0); return true; } c++; } - - if(c < amount){ + + if(c < amount) { script_pushint(st, 0); // Not enough Members in the Party to join Instance. - }else + } else script_pushint(st, 1); - + return true; } @@ -16017,53 +16747,53 @@ BUILDIN(setfont) int font = script_getnum(st,2); if( sd == NULL ) return true; - - if( sd->user_font != font ) - sd->user_font = font; + + if( sd->status.font != font ) + sd->status.font = font; else - sd->user_font = 0; - + sd->status.font = 0; + clif->font(sd); return true; } int buildin_mobuseskill_sub(struct block_list *bl,va_list ap) { - TBL_MOB* md = (TBL_MOB*)bl; + TBL_MOB* md = (TBL_MOB*)bl; struct block_list *tbl; - int mobid = va_arg(ap,int); - uint16 skill_id = va_arg(ap,int); - uint16 skill_lv = va_arg(ap,int); - int casttime = va_arg(ap,int); - int cancel = va_arg(ap,int); - int emotion = va_arg(ap,int); - int target = va_arg(ap,int); - + int mobid = va_arg(ap,int); + uint16 skill_id = va_arg(ap,int); + uint16 skill_lv = va_arg(ap,int); + int casttime = va_arg(ap,int); + int cancel = va_arg(ap,int); + int emotion = va_arg(ap,int); + int target = va_arg(ap,int); + if( md->class_ != mobid ) return 0; - + // 0:self, 1:target, 2:master, default:random switch( target ) { - case 0: tbl = map->id2bl(md->bl.id); break; - case 1: tbl = map->id2bl(md->target_id); break; - case 2: tbl = map->id2bl(md->master_id); break; - default:tbl = battle->get_enemy(&md->bl, DEFAULT_ENEMY_TYPE(md),skill->get_range2(&md->bl, skill_id, skill_lv)); break; + case 0: tbl = map->id2bl(md->bl.id); break; + case 1: tbl = map->id2bl(md->target_id); break; + case 2: tbl = map->id2bl(md->master_id); break; + default: tbl = battle->get_enemy(&md->bl, DEFAULT_ENEMY_TYPE(md),skill->get_range2(&md->bl, skill_id, skill_lv)); break; } - + if( !tbl ) return 0; - + if( md->ud.skilltimer != INVALID_TIMER ) // Cancel the casting skill. unit->skillcastcancel(bl,0); - + if( skill->get_casttype(skill_id) == CAST_GROUND ) unit->skilluse_pos2(&md->bl, tbl->x, tbl->y, skill_id, skill_lv, casttime, cancel); else unit->skilluse_id2(&md->bl, tbl->id, skill_id, skill_lv, casttime, cancel); - + clif->emotion(&md->bl, emotion); - + return 0; } /*========================================== @@ -16073,27 +16803,27 @@ BUILDIN(areamobuseskill) { struct block_list center; int16 m; int range,mobid,skill_id,skill_lv,casttime,emotion,target,cancel; - + if( (m = map->mapname2mapid(script_getstr(st,2))) < 0 ) { ShowError("areamobuseskill: invalid map name.\n"); return true; } - + if( map->list[m].flag.src4instance && st->instance_id >= 0 && (m = instance->mapid2imapid(m, st->instance_id)) < 0 ) return true; - + center.m = m; center.x = script_getnum(st,3); center.y = script_getnum(st,4); range = script_getnum(st,5); mobid = script_getnum(st,6); - skill_id = ( script_isstring(st,7) ? skill->name2id(script_getstr(st,7)) : script_getnum(st,7) ); + skill_id = ( script_isstringtype(st, 7) ? skill->name2id(script_getstr(st, 7)) : script_getnum(st, 7) ); skill_lv = script_getnum(st,8); casttime = script_getnum(st,9); cancel = script_getnum(st,10); emotion = script_getnum(st,11); target = script_getnum(st,12); - + map->foreachinrange(script->buildin_mobuseskill_sub, ¢er, range, BL_MOB, mobid, skill_id, skill_lv, casttime, cancel, emotion, target); return true; } @@ -16104,21 +16834,21 @@ BUILDIN(progressbar) struct map_session_data * sd = script->rid2sd(st); const char * color; unsigned int second; - + if( !st || !sd ) return true; - + st->state = STOP; - + color = script_getstr(st,2); second = script_getnum(st,3); - + sd->progressbar.npc_id = st->oid; sd->progressbar.timeout = timer->gettick() + second*1000; sd->state.workinprogress = 3; - - clif->progressbar(sd, strtol(color, (char **)NULL, 0), second); - return true; + + clif->progressbar(sd, (unsigned int)strtoul(color, (char **)NULL, 0), second); + return true; } BUILDIN(pushpc) @@ -16126,23 +16856,23 @@ BUILDIN(pushpc) uint8 dir; int cells, dx, dy; struct map_session_data* sd; - + if((sd = script->rid2sd(st))==NULL) { return true; } - + dir = script_getnum(st,2); cells = script_getnum(st,3); - + if(dir>7) { ShowWarning("buildin_pushpc: Invalid direction %d specified.\n", dir); script->reportsrc(st); - + dir%= 8; // trim spin-over } - + if(!cells) {// zero distance return true; @@ -16152,10 +16882,10 @@ BUILDIN(pushpc) dir = (dir+4)%8; // turn around cells = -cells; } - + dx = dirx[dir]; dy = diry[dir]; - + unit->blown(&sd->bl, dx, dy, cells, 0); return true; } @@ -16166,11 +16896,11 @@ BUILDIN(pushpc) BUILDIN(buyingstore) { struct map_session_data* sd; - + if( ( sd = script->rid2sd(st) ) == NULL ) { return true; } - + buyingstore->setup(sd, script_getnum(st,2)); return true; } @@ -16183,27 +16913,27 @@ BUILDIN(searchstores) unsigned short effect; unsigned int uses; struct map_session_data* sd; - + if( ( sd = script->rid2sd(st) ) == NULL ) { return true; } - + uses = script_getnum(st,2); effect = script_getnum(st,3); - + if( !uses ) { ShowError("buildin_searchstores: Amount of uses cannot be zero.\n"); return false; } - + if( effect > 1 ) { ShowError("buildin_searchstores: Invalid effect id %hu, specified.\n", effect); return false; } - + searchstore->open(sd, uses, effect); return true; } @@ -16214,25 +16944,25 @@ BUILDIN(showdigit) unsigned int type = 0; int value; struct map_session_data* sd; - + if( ( sd = script->rid2sd(st) ) == NULL ) { return true; } - + value = script_getnum(st,2); - + if( script_hasdata(st,3) ) { type = script_getnum(st,3); - + if( type > 3 ) { ShowError("buildin_showdigit: Invalid type %u.\n", type); return false; } } - + clif->showdigit(sd, (unsigned char)type, value); return true; } @@ -16273,7 +17003,7 @@ BUILDIN(checkdragon) { BUILDIN(setdragon) { TBL_PC* sd; int color = script_hasdata(st,2) ? script_getnum(st,2) : 0; - + if( (sd = script->rid2sd(st)) == NULL ) return true; if( !pc->checkskill(sd,RK_DRAGONTRAINING) || (sd->class_&MAPID_THIRDMASK) != MAPID_RUNE_KNIGHT ) @@ -16285,10 +17015,10 @@ BUILDIN(setdragon) { unsigned int option = OPTION_DRAGON1; if( color ) { option = ( color == 1 ? OPTION_DRAGON1 : - color == 2 ? OPTION_DRAGON2 : - color == 3 ? OPTION_DRAGON3 : - color == 4 ? OPTION_DRAGON4 : - color == 5 ? OPTION_DRAGON5 : 0); + color == 2 ? OPTION_DRAGON2 : + color == 3 ? OPTION_DRAGON3 : + color == 4 ? OPTION_DRAGON4 : + color == 5 ? OPTION_DRAGON5 : 0); if( !option ) { ShowWarning("script_setdragon: Unknown Color %d used; changing to green (1)\n",color); option = OPTION_DRAGON1; @@ -16324,14 +17054,14 @@ BUILDIN(setmounting) { TBL_PC* sd; if( (sd = script->rid2sd(st)) == NULL ) return true; - if( sd->sc.option&(OPTION_WUGRIDER|OPTION_RIDING|OPTION_DRAGON|OPTION_MADOGEAR) ){ + if( sd->sc.option&(OPTION_WUGRIDER|OPTION_RIDING|OPTION_DRAGON|OPTION_MADOGEAR) ) { clif->msgtable(sd->fd, 0X78b); script_pushint(st,0);//can't mount with one of these - }else { + } else { if( sd->sc.data[SC_ALL_RIDING] ) status_change_end(&sd->bl, SC_ALL_RIDING, INVALID_TIMER); else - sc_start(&sd->bl, SC_ALL_RIDING, 100, 0, -1); + sc_start(NULL,&sd->bl, SC_ALL_RIDING, 100, 0, -1); script_pushint(st,1);//in both cases, return 1. } return true; @@ -16342,16 +17072,16 @@ BUILDIN(setmounting) { **/ BUILDIN(getargcount) { struct script_retinfo* ri; - + if( st->stack->defsp < 1 || st->stack->stack_data[st->stack->defsp - 1].type != C_RETINFO ) { ShowError("script:getargcount: used out of function or callsub label!\n"); st->state = END; return false; } ri = st->stack->stack_data[st->stack->defsp - 1].u.ri; - + script_pushint(st, ri->nargs); - + return true; } /** @@ -16359,40 +17089,39 @@ BUILDIN(getargcount) { **/ BUILDIN(getcharip) { struct map_session_data* sd = NULL; - + /* check if a character name is specified */ if( script_hasdata(st, 2) ) { - if (script_isstring(st, 2)) + if (script_isstringtype(st, 2)) { sd = map->nick2sd(script_getstr(st, 2)); - else if (script_isint(st, 2) || script_getnum(st, 2)) { - int id; - id = script_getnum(st, 2); + } else { + int id = script_getnum(st, 2); sd = (map->id2sd(id) ? map->id2sd(id) : map->charid2sd(id)); } - } - else + } else { sd = script->rid2sd(st); - + } + /* check for sd and IP */ if (!sd || !session[sd->fd]->client_addr) { script_pushconststr(st, ""); return true; } - + /* return the client ip_addr converted for output */ if (sd && sd->fd && session[sd->fd]) { /* initiliaze */ const char *ip_addr = NULL; uint32 ip; - + /* set ip, ip_addr and convert to ip and push str */ ip = session[sd->fd]->client_addr; ip_addr = ip2str(ip, NULL); script_pushstrcopy(st, ip_addr); } - + return true; } /** @@ -16400,12 +17129,12 @@ BUILDIN(getcharip) { **/ BUILDIN(is_function) { const char* str = script_getstr(st,2); - + if( strdb_exists(script->userfunc_db, str) ) script_pushint(st,1); else script_pushint(st,0); - + return true; } /** @@ -16413,35 +17142,35 @@ BUILDIN(is_function) { **/ BUILDIN(get_revision) { const char *svn = get_svn_revision(); - + if ( svn[0] != HERC_UNKNOWN_VER ) script_pushint(st,atoi(svn)); else script_pushint(st,-1);//unknown - + return true; } /** * freeloop(<toggle>) -> toggles this script instance's looping-check ability **/ BUILDIN(freeloop) { - + if( script_getnum(st,2) ) st->freeloop = 1; else st->freeloop = 0; - + script_pushint(st, st->freeloop); - + return true; } BUILDIN(sit) { struct map_session_data *sd = NULL; - + if (script_hasdata(st, 2)) sd = map->nick2sd(script_getstr(st, 2)); - + if (sd == NULL) sd = script->rid2sd(st); @@ -16456,13 +17185,13 @@ BUILDIN(sit) { BUILDIN(stand) { struct map_session_data *sd = NULL; - + if (script_hasdata(st, 2)) sd = map->nick2sd(script_getstr(st, 2)); - + if (sd == NULL) sd = script->rid2sd(st); - + if (pc_issit(sd)) { pc->setstand(sd); @@ -16474,10 +17203,10 @@ BUILDIN(stand) { BUILDIN(issit) { struct map_session_data *sd = NULL; - + if (script_hasdata(st, 2)) sd = map->nick2sd(script_getstr(st, 2)); - + if (sd == NULL) sd = script->rid2sd(st); @@ -16497,21 +17226,21 @@ BUILDIN(bindatcmd) { int i, group_lv = 0, group_lv_char = 99; bool log = false; bool create = false; - + atcmd = script_getstr(st,2); eventName = script_getstr(st,3); - + if( *atcmd == atcommand->at_symbol || *atcmd == atcommand->char_symbol ) atcmd++; - + if( script_hasdata(st,4) ) group_lv = script_getnum(st,4); if( script_hasdata(st,5) ) group_lv_char = script_getnum(st,5); if( script_hasdata(st,6) ) log = script_getnum(st,6) ? true : false; - + if( atcommand->binding_count == 0 ) { CREATE(atcommand->binding,struct atcmd_binding_data*,1); - + create = true; } else { ARR_FIND(0, atcommand->binding_count, i, strcmp(atcommand->binding[i]->command,atcmd) == 0); @@ -16523,39 +17252,39 @@ BUILDIN(bindatcmd) { } else create = true; } - + if( create ) { i = atcommand->binding_count; - + if( atcommand->binding_count++ != 0 ) RECREATE(atcommand->binding,struct atcmd_binding_data*,atcommand->binding_count); - + CREATE(atcommand->binding[i],struct atcmd_binding_data,1); - + safestrncpy(atcommand->binding[i]->command, atcmd, 50); safestrncpy(atcommand->binding[i]->npc_event, eventName, 50); atcommand->binding[i]->group_lv = group_lv; atcommand->binding[i]->group_lv_char = group_lv_char; atcommand->binding[i]->log = log; } - + return true; } BUILDIN(unbindatcmd) { const char* atcmd; int i = 0; - + atcmd = script_getstr(st, 2); - + if( *atcmd == atcommand->at_symbol || *atcmd == atcommand->char_symbol ) atcmd++; - + if( atcommand->binding_count == 0 ) { script_pushint(st, 0); return true; } - + ARR_FIND(0, atcommand->binding_count, i, strcmp(atcommand->binding[i]->command, atcmd) == 0); if( i < atcommand->binding_count ) { int cursor = 0; @@ -16565,21 +17294,21 @@ BUILDIN(unbindatcmd) { for( i = 0, cursor = 0; i < atcommand->binding_count; i++ ) { if( atcommand->binding[i] == NULL ) continue; - + if( cursor != i ) { memmove(&atcommand->binding[cursor], &atcommand->binding[i], sizeof(struct atcmd_binding_data*)); } - + cursor++; } - + if( (atcommand->binding_count = cursor) == 0 ) aFree(atcommand->binding); - + script_pushint(st, 1); } else script_pushint(st, 0);/* not found */ - + return true; } @@ -16587,9 +17316,9 @@ BUILDIN(useatcmd) { TBL_PC *sd, *dummy_sd = NULL; int fd; const char* cmd; - + cmd = script_getstr(st,2); - + if( st->rid ) { sd = script->rid2sd(st); fd = sd->fd; @@ -16597,7 +17326,7 @@ BUILDIN(useatcmd) { // Use a dummy character. sd = dummy_sd = pc->get_dummy_sd(); fd = 0; - + if( st->oid ) { struct block_list* bl = map->id2bl(st->oid); memcpy(&sd->bl, bl, sizeof(struct block_list)); @@ -16605,15 +17334,15 @@ BUILDIN(useatcmd) { safestrncpy(sd->status.name, ((TBL_NPC*)bl)->name, NAME_LENGTH); } } - + // compatibility with previous implementation (deprecated!) if( cmd[0] != atcommand->at_symbol ) { cmd += strlen(sd->status.name); while( *cmd != atcommand->at_symbol && *cmd != 0 ) cmd++; } - - atcommand->parse(fd, sd, cmd, 1); + + atcommand->exec(fd, sd, cmd, true); if (dummy_sd) aFree(dummy_sd); return true; } @@ -16621,9 +17350,9 @@ BUILDIN(useatcmd) { BUILDIN(checkre) { int num; - + num=script_getnum(st,2); - switch(num){ + switch(num) { case 0: #ifdef RENEWAL script_pushint(st, 1); @@ -16686,7 +17415,7 @@ BUILDIN(getrandgroupitem) { struct map_session_data *sd = NULL; int nameid = script_getnum(st, 2); int count = script_getnum(st, 3); - + if( !(data = itemdb->exists(nameid)) ) { ShowWarning("buildin_getrandgroupitem: unknown item id %d\n",nameid); script_pushint(st, 1); @@ -16702,19 +17431,19 @@ BUILDIN(getrandgroupitem) { } else { int i, get_count, flag; struct item it; - + memset(&it,0,sizeof(it)); nameid = itemdb->group_item(data->group); it.nameid = nameid; it.identify = itemdb->isidentified(nameid); - + if (!itemdb->isstackable(nameid)) get_count = 1; else get_count = count; - + for (i = 0; i < count; i += get_count) { // if not pet egg if (!pet->create_egg(sd, nameid)) { @@ -16725,10 +17454,10 @@ BUILDIN(getrandgroupitem) { } } } - + script_pushint(st, 0); } - + return true; } @@ -16737,7 +17466,7 @@ BUILDIN(getrandgroupitem) { int script_cleanfloor_sub(struct block_list *bl, va_list ap) { nullpo_ret(bl); map->clearflooritem(bl); - + return 0; } @@ -16745,12 +17474,12 @@ BUILDIN(cleanmap) { const char *mapname; int16 m = -1; int16 x0 = 0, y0 = 0, x1 = 0, y1 = 0; - + mapname = script_getstr(st, 2); m = map->mapname2mapid(mapname); if ( m == -1 ) return false; - + if ((script_lastdata(st) - 2) < 4) { map->foreachinmap(script->cleanfloor_sub, m, BL_ITEM); } else { @@ -16765,7 +17494,7 @@ BUILDIN(cleanmap) { return false; } } - + return true; } /* Cast a skill on the attached player. @@ -16778,14 +17507,14 @@ BUILDIN(npcskill) { unsigned int npc_level; struct npc_data *nd; struct map_session_data *sd; - - skill_id = script_isstring(st, 2) ? skill->name2id(script_getstr(st, 2)) : script_getnum(st, 2); + + skill_id = script_isstringtype(st, 2) ? skill->name2id(script_getstr(st, 2)) : script_getnum(st, 2); skill_level = script_getnum(st, 3); stat_point = script_getnum(st, 4); npc_level = script_getnum(st, 5); sd = script->rid2sd(st); nd = (struct npc_data *)map->id2bl(sd->npc_id); - + if (stat_point > battle_config.max_third_parameter) { ShowError("npcskill: stat point exceeded maximum of %d.\n",battle_config.max_third_parameter ); return false; @@ -16797,24 +17526,98 @@ BUILDIN(npcskill) { if (sd == NULL || nd == NULL) { //ain't possible, but I don't trust people. return false; } - + nd->level = npc_level; nd->stat_point = stat_point; - + if (!nd->status.hp) { - status_calc_npc(nd, true); + status_calc_npc(nd, SCO_FIRST); } else { - status_calc_npc(nd, false); + status_calc_npc(nd, SCO_NONE); } - + if (skill->get_inf(skill_id)&INF_GROUND_SKILL) { unit->skilluse_pos(&nd->bl, sd->bl.x, sd->bl.y, skill_id, skill_level); } else { unit->skilluse_id(&nd->bl, sd->bl.id, skill_id, skill_level); } - + return true; } + +/* Turns a player into a monster and grants SC attribute effect. [malufett/Hercules] + * montransform <monster name/id>, <duration>, <sc type>, <val1>, <val2>, <val3>, <val4>; */ +BUILDIN(montransform) { + int tick; + enum sc_type type; + struct block_list* bl; + char msg[CHAT_SIZE_MAX]; + int mob_id, val1, val2, val3, val4; + + if( (bl = map->id2bl(st->rid)) == NULL ) + return true; + + if( script_isstringtype(st, 2) ) { + mob_id = mob->db_searchname(script_getstr(st, 2)); + } else { + mob_id = mob->db_checkid(script_getnum(st, 2)); + } + + if( mob_id == 0 ) { + if( script_isstringtype(st, 2) ) + ShowWarning("buildin_montransform: Attempted to use non-existing monster '%s'.\n", script_getstr(st, 2)); + else + ShowWarning("buildin_montransform: Attempted to use non-existing monster of ID '%d'.\n", script_getnum(st, 2)); + return false; + } + + tick = script_getnum(st, 3); + type = (sc_type)script_getnum(st, 4); + val1 = val2 = val3 = val4 = 0; + + if( !(type > SC_NONE && type < SC_MAX) ) { + ShowWarning("buildin_montransform: Unsupported status change id %d\n", type); + return false; + } + + if (script_hasdata(st, 5)) + val1 = script_getnum(st, 5); + + if (script_hasdata(st, 6)) + val2 = script_getnum(st, 6); + + if (script_hasdata(st, 7)) + val3 = script_getnum(st, 7); + + if (script_hasdata(st, 8)) + val4 = script_getnum(st, 8); + + if( tick != 0 ) { + struct map_session_data *sd = map->id2sd(bl->id); + struct mob_db *monster = mob->db(mob_id); + + if( !sd ) + return true; + + if( battle_config.mon_trans_disable_in_gvg && map_flag_gvg2(sd->bl.m) ) { + clif->message(sd->fd, msg_txt(1488)); // Transforming into monster is not allowed in Guild Wars. + return true; + } + + if( sd->disguise != -1 ) { + clif->message(sd->fd, msg_txt(1486)); // Cannot transform into monster while in disguise. + return true; + } + + sprintf(msg, msg_txt(1485), monster->name); // Traaaansformation-!! %s form!! + clif->ShowScript(&sd->bl, msg); + status_change_end(bl, SC_MONSTER_TRANSFORM, INVALID_TIMER); // Clear previous + sc_start2(NULL, bl, SC_MONSTER_TRANSFORM, 100, mob_id, type, tick); + sc_start4(NULL, bl, type, 100, val1, val2, val3, val4, tick); + } + return true; +} + struct hQueue *script_hqueue_get(int idx) { if( idx < 0 || idx >= script->hqs || script->hq[idx].size == -1 ) return NULL; @@ -16823,19 +17626,19 @@ struct hQueue *script_hqueue_get(int idx) { int script_hqueue_create(void) { int idx = script->hqs; int i; - + for(i = 0; i < script->hqs; i++) { if( script->hq[i].size == -1 ) { break; } } - + if( i == script->hqs ) { RECREATE(script->hq, struct hQueue, ++script->hqs); script->hq[ idx ].item = NULL; } else idx = i; - + script->hq[ idx ].id = idx; script->hq[ idx ].size = 0; script->hq[ idx ].items = 0; @@ -16854,14 +17657,14 @@ BUILDIN(queue) { /* returns queue length */ BUILDIN(queuesize) { int idx = script_getnum(st, 2); - + if( idx < 0 || idx >= script->hqs || script->hq[idx].size == -1 ) { ShowWarning("buildin_queuesize: unknown queue id %d\n",idx); script_pushint(st, 0); } else { script_pushint(st, script->hq[ idx ].items); } - + return true; } bool script_hqueue_add(int idx, int var) { @@ -16871,24 +17674,24 @@ bool script_hqueue_add(int idx, int var) { } else { struct map_session_data *sd; int i; - + for(i = 0; i < script->hq[idx].size; i++) { if( script->hq[idx].item[i] == var ) { return true; } } - + if( i == script->hq[idx].size ) { - + for(i = 0; i < script->hq[idx].size; i++) { if( script->hq[idx].item[i] == 0 ) { break; } } - + if( i == script->hq[idx].size ) RECREATE(script->hq[idx].item, int, ++script->hq[idx].size); - + script->hq[idx].item[i] = var; script->hq[idx].items++; if( var >= START_ACCOUNT_NUM && (sd = map->id2sd(var)) ) { @@ -16897,13 +17700,13 @@ bool script_hqueue_add(int idx, int var) { break; } } - + if( i == sd->queues_count ) RECREATE(sd->queues, int, ++sd->queues_count); - + sd->queues[i] = idx; } - + } } return false; @@ -16913,9 +17716,9 @@ bool script_hqueue_add(int idx, int var) { BUILDIN(queueadd) { int idx = script_getnum(st, 2); int var = script_getnum(st, 3); - + script_pushint(st,script->queue_add(idx,var)?1:0); - + return true; } bool script_hqueue_remove(int idx, int var) { @@ -16924,30 +17727,30 @@ bool script_hqueue_remove(int idx, int var) { return true; } else { int i; - + for(i = 0; i < script->hq[idx].size; i++) { if( script->hq[idx].item[i] == var ) { break; } } - + if( i != script->hq[idx].size ) { struct map_session_data *sd; - + script->hq[idx].item[i] = -1; script->hq[idx].items--; - + if( var >= START_ACCOUNT_NUM && (sd = map->id2sd(var)) ) { for(i = 0; i < sd->queues_count; i++) { if( sd->queues[i] == idx ) { break; } } - + if( i != sd->queues_count ) sd->queues[i] = -1; } - + } } return false; @@ -16959,7 +17762,7 @@ BUILDIN(queueremove) { int var = script_getnum(st, 3); script_pushint(st, script->queue_remove(idx,var)?1:0); - + return true; } @@ -16970,7 +17773,7 @@ BUILDIN(queueremove) { BUILDIN(queueopt) { int idx = script_getnum(st, 2); int var = script_getnum(st, 3); - + if( idx < 0 || idx >= script->hqs || script->hq[idx].size == -1 ) { ShowWarning("buildin_queueopt: unknown queue id %d\n",idx); script_pushint(st, 1); @@ -17003,7 +17806,7 @@ BUILDIN(queueopt) { break; } } - + return true; } bool script_hqueue_del(int idx) { @@ -17013,7 +17816,7 @@ bool script_hqueue_del(int idx) { } else { struct map_session_data *sd; int i; - + for(i = 0; i < script->hq[idx].size; i++) { if( script->hq[idx].item[i] >= START_ACCOUNT_NUM && (sd = map->id2sd(script->hq[idx].item[i])) ) { int j; @@ -17022,13 +17825,13 @@ bool script_hqueue_del(int idx) { break; } } - + if( j != sd->queues_count ) sd->queues[j] = -1; } script->hq[idx].item[i] = 0; } - + script->hq[idx].size = -1; script->hq[idx].items = 0; } @@ -17038,9 +17841,9 @@ bool script_hqueue_del(int idx) { /* deletes queue of id .@queue_id, returns 1 if id not found, 0 otherwise */ BUILDIN(queuedel) { int idx = script_getnum(st, 2); - + script_pushint(st,script->queue_del(idx)?1:0); - + return true; } void script_hqueue_clear(int idx) { @@ -17050,7 +17853,7 @@ void script_hqueue_clear(int idx) { } else { struct map_session_data *sd; int i, j; - + for(i = 0; i < script->hq[idx].size; i++) { if( script->hq[idx].item[i] > 0 ) { @@ -17060,7 +17863,7 @@ void script_hqueue_clear(int idx) { break; } } - + if( j != sd->queues_count ) sd->queues[j] = -1; } @@ -17078,37 +17881,37 @@ BUILDIN(queueiterator) { struct hQueue *queue = NULL; int idx = script->hqis; int i; - + if( qid < 0 || qid >= script->hqs || script->hq[qid].size == -1 || !(queue = script->queue(qid)) ) { ShowWarning("queueiterator: invalid queue id %d\n",qid); return true; } - + /* what if queue->size is 0? (iterating a empty queue?) */ if( queue->size <= 0 ) { ShowWarning("queueiterator: attempting to iterate on on empty queue id %d!\n",qid); return true; } - + for(i = 0; i < script->hqis; i++) { if( script->hqi[i].items == -1 ) { break; } } - + if( i == script->hqis ) { RECREATE(script->hqi, struct hQueueIterator, ++script->hqis); script->hqi[ idx ].item = NULL; } else idx = i; - + RECREATE(script->hqi[ idx ].item, int, queue->size); memcpy(script->hqi[idx].item, queue->item, sizeof(int)*queue->size); - + script->hqi[ idx ].items = queue->size; script->hqi[ idx ].pos = 0; - + script_pushint(st,idx); return true; } @@ -17116,7 +17919,7 @@ BUILDIN(queueiterator) { /* returns next/first member in the iterator, 0 if none */ BUILDIN(qiget) { int idx = script_getnum(st, 2); - + if( idx < 0 || idx >= script->hqis ) { ShowWarning("buildin_qiget: unknown queue iterator id %d\n",idx); script_pushint(st, 0); @@ -17133,7 +17936,7 @@ BUILDIN(qiget) { /* returns 1:0 if there is a next member in the iterator */ BUILDIN(qicheck) { int idx = script_getnum(st, 2); - + if( idx < 0 || idx >= script->hqis ) { ShowWarning("buildin_qicheck: unknown queue iterator id %d\n",idx); script_pushint(st, 0); @@ -17142,13 +17945,13 @@ BUILDIN(qicheck) { } else { script_pushint(st, 1); } - + return true; } /* Queue Iterator Check */ BUILDIN(qiclear) { int idx = script_getnum(st, 2); - + if( idx < 0 || idx >= script->hqis ) { ShowWarning("buildin_qiclear: unknown queue iterator id %d\n",idx); script_pushint(st, 1); @@ -17156,7 +17959,7 @@ BUILDIN(qiclear) { script->hqi[idx].items = -1; script_pushint(st, 0); } - + return true; } /** @@ -17177,7 +17980,7 @@ BUILDIN(packageitem) { script_pushint(st, 1); return true; } - + if( !(data = itemdb->exists(nameid)) ) { ShowWarning("buildin_packageitem: unknown item id %d\n",nameid); script_pushint(st, 1); @@ -17191,7 +17994,7 @@ BUILDIN(packageitem) { itemdb->package_item(sd,data->package); script_pushint(st, 0); } - + return true; } /* New Battlegrounds Stuff */ @@ -17199,25 +18002,25 @@ BUILDIN(packageitem) { /* returns created team id or -1 when fails */ BUILDIN(bg_create_team) { const char *map_name, *ev = "", *dev = "";//ev and dev will be dropped. - int x, y, mapindex = 0, bg_id; - + int x, y, map_index = 0, bg_id; + map_name = script_getstr(st,2); if( strcmp(map_name,"-") != 0 ) { - mapindex = mapindex_name2id(map_name); - if( mapindex == 0 ) { // Invalid Map + map_index = mapindex->name2id(map_name); + if( map_index == 0 ) { // Invalid Map script_pushint(st,0); return true; } } - + x = script_getnum(st,3); y = script_getnum(st,4); - - if( (bg_id = bg->create(mapindex, x, y, ev, dev)) == 0 ) { // Creation failed + + if( (bg_id = bg->create(map_index, x, y, ev, dev)) == 0 ) { // Creation failed script_pushint(st,-1); } else script_pushint(st,bg_id); - + return true; } @@ -17227,33 +18030,402 @@ BUILDIN(bg_create_team) { BUILDIN(bg_join_team) { struct map_session_data *sd; int team_id = script_getnum(st, 2); - + if( script_hasdata(st, 3) ) sd = map->id2sd(script_getnum(st, 3)); else sd = script->rid2sd(st); - + if( !sd ) script_pushint(st, 1); else script_pushint(st,bg->team_join(team_id, sd)?0:1); - + return true; } +/*==============[Mhalicot]================== + * countbound {<type>}; + * Creates an array of bounded item IDs + * Returns amount of items found + * Type: + * 1 - Account Bound + * 2 - Guild Bound + * 3 - Party Bound + * 4 - Character Bound + *------------------------------------------*/ +BUILDIN(countbound) +{ + int i, type, j=0, k=0; + TBL_PC *sd; + + if( (sd = script->rid2sd(st)) == NULL ) + return false; + + type = script_hasdata(st,2)?script_getnum(st,2):0; + + for(i=0;i<MAX_INVENTORY;i++) { + if(sd->status.inventory[i].nameid > 0 && ( + (!type && sd->status.inventory[i].bound > 0) || + (type && sd->status.inventory[i].bound == type) + )) { + pc->setreg(sd,reference_uid(script->add_str("@bound_items"), k),sd->status.inventory[i].nameid); + k++; + j += sd->status.inventory[i].amount; + } + } + + script_pushint(st,j); + return 0; +} + /* bg_match_over( arena_name {, optional canceled } ) */ /* returns 0 when successful, 1 otherwise */ BUILDIN(bg_match_over) { bool canceled = script_hasdata(st,3) ? true : false; struct bg_arena *arena = bg->name2arena((char*)script_getstr(st, 2)); - + if( arena ) { bg->match_over(arena,canceled); script_pushint(st, 0); } else script_pushint(st, 1); - + + return true; +} + +BUILDIN(instance_mapname) { + const char *map_name; + int m; + short instance_id = -1; + + map_name = script_getstr(st,2); + + if( script_hasdata(st,3) ) + instance_id = script_getnum(st,3); + else + instance_id = st->instance_id; + + // Check that instance mapname is a valid map + if( instance_id == -1 || (m = instance->mapname2imap(map_name,instance_id)) == -1 ) + script_pushconststr(st, ""); + else + script_pushconststr(st, map->list[m].name); + + return true; +} +/* modify an instances' reload-spawn point */ +/* instance_set_respawn <map_name>,<x>,<y>{,<instance_id>} */ +/* returns 1 when successful, 0 otherwise. */ +BUILDIN(instance_set_respawn) { + const char *map_name; + short instance_id = -1; + short mid; + short x,y; + + map_name = script_getstr(st,2); + x = script_getnum(st, 3); + y = script_getnum(st, 4); + + if( script_hasdata(st, 5) ) + instance_id = script_getnum(st, 5); + else + instance_id = st->instance_id; + + if( instance_id == -1 || !instance->valid(instance_id) ) + script_pushint(st, 0); + else if( (mid = map->mapname2mapid(map_name)) == -1 ) { + ShowError("buildin_instance_set_respawn: unknown map '%s'\n",map_name); + script_pushint(st, 0); + } else { + int i; + + for(i = 0; i < instance->list[instance_id].num_map; i++) { + if( map->list[instance->list[instance_id].map[i]].m == mid ) { + instance->list[instance_id].respawn.map = map_id2index(mid); + instance->list[instance_id].respawn.x = x; + instance->list[instance_id].respawn.y = y; + break; + } + } + + if( i != instance->list[instance_id].num_map ) + script_pushint(st, 1); + else { + ShowError("buildin_instance_set_respawn: map '%s' not part of instance '%s'\n",map_name,instance->list[instance_id].name); + script_pushint(st, 0); + } + } + + + return true; +} +/** + * @call openshop({NPC Name}); + * + * @return 1 on success, 0 otherwise. + **/ +BUILDIN(openshop) { + struct npc_data *nd; + struct map_session_data *sd; + const char *name = NULL; + + if( script_hasdata(st, 2) ) { + name = script_getstr(st, 2); + if( !(nd = npc->name2id(name)) || nd->subtype != SCRIPT ) { + ShowWarning("buildin_openshop(\"%s\"): trying to run without a proper NPC!\n",name); + return false; + } + } else if( !(nd = map->id2nd(st->oid)) ) { + ShowWarning("buildin_openshop: trying to run without a proper NPC!\n"); + return false; + } + if( !( sd = script->rid2sd(st) ) ) { + ShowWarning("buildin_openshop: trying to run without a player attached!\n"); + return false; + } else if ( !nd->u.scr.shop || !nd->u.scr.shop->items ) { + ShowWarning("buildin_openshop: trying to open without any items!\n"); + return false; + } + + if( !npc->trader_open(sd,nd) ) + script_pushint(st, 0); + else + script_pushint(st, 1); + + return true; +} +/** + * @call sellitem <Item_ID>,{,price{,qty}}; + * + * adds <Item_ID> (or modifies if present) to shop + * if price not provided (or -1) uses the item's value_sell + **/ +BUILDIN(sellitem) { + struct npc_data *nd; + struct item_data *it; + int i = 0, id = script_getnum(st,2); + int value = 0; + int qty = 0; + + if( !(nd = map->id2nd(st->oid)) ) { + ShowWarning("buildin_sellitem: trying to run without a proper NPC!\n"); + return false; + } else if ( !(it = itemdb->exists(id)) ) { + ShowWarning("buildin_sellitem: unknown item id '%d'!\n",id); + return false; + } + + value = script_hasdata(st,3) ? script_getnum(st, 3) : it->value_buy; + if( value == -1 ) + value = it->value_buy; + + if( !nd->u.scr.shop ) + npc->trader_update(nd->src_id?nd->src_id:nd->bl.id); + else {/* no need to run this if its empty */ + for( i = 0; i < nd->u.scr.shop->items; i++ ) { + if( nd->u.scr.shop->item[i].nameid == id ) + break; + } + } + + if( nd->u.scr.shop->type == NST_MARKET ) { + if( !script_hasdata(st,4) || ( qty = script_getnum(st, 4) ) <= 0 ) { + ShowError("buildin_sellitem: invalid 'qty' for market-type shop!\n"); + return false; + } + } + + if( ( nd->u.scr.shop->type == NST_ZENY || nd->u.scr.shop->type == NST_MARKET ) && value*0.75 < it->value_sell*1.24 ) { + ShowWarning("buildin_sellitem: Item %s [%d] discounted buying price (%d->%d) is less than overcharged selling price (%d->%d) in NPC %s (%s)\n", + it->name, id, value, (int)(value*0.75), it->value_sell, (int)(it->value_sell*1.24), nd->exname, nd->path); + } + + if( i != nd->u.scr.shop->items ) { + nd->u.scr.shop->item[i].value = value; + nd->u.scr.shop->item[i].qty = qty; + if( nd->u.scr.shop->type == NST_MARKET ) /* has been manually updated, make it reflect on sql */ + npc->market_tosql(nd,i); + } else { + for( i = 0; i < nd->u.scr.shop->items; i++ ) { + if( nd->u.scr.shop->item[i].nameid == 0 ) + break; + } + + if( i == nd->u.scr.shop->items ) { + if( nd->u.scr.shop->items == USHRT_MAX ) { + ShowWarning("buildin_sellitem: Can't add %s (%s/%s), shop list is full!\n", it->name, nd->exname, nd->path); + return false; + } + i = nd->u.scr.shop->items; + RECREATE(nd->u.scr.shop->item, struct npc_item_list, ++nd->u.scr.shop->items); + } + + nd->u.scr.shop->item[i].nameid = it->nameid; + nd->u.scr.shop->item[i].value = value; + nd->u.scr.shop->item[i].qty = qty; + } + return true; } +/** + * @call stopselling <Item_ID>; + * + * removes <Item_ID> from the current npc shop + * + * @return 1 on success, 0 otherwise + **/ +BUILDIN(stopselling) { + struct npc_data *nd; + int i, id = script_getnum(st,2); + + if( !(nd = map->id2nd(st->oid)) || !nd->u.scr.shop ) { + ShowWarning("buildin_stopselling: trying to run without a proper NPC!\n"); + return false; + } + + for( i = 0; i < nd->u.scr.shop->items; i++ ) { + if( nd->u.scr.shop->item[i].nameid == id ) + break; + } + + if( i != nd->u.scr.shop->items ) { + int cursor; + + if( nd->u.scr.shop->type == NST_MARKET ) + npc->market_delfromsql(nd,i); + + nd->u.scr.shop->item[i].nameid = 0; + nd->u.scr.shop->item[i].value = 0; + nd->u.scr.shop->item[i].qty = 0; + + for( i = 0, cursor = 0; i < nd->u.scr.shop->items; i++ ) { + if( nd->u.scr.shop->item[i].nameid == 0 ) + continue; + + if( cursor != i ) { + nd->u.scr.shop->item[cursor].nameid = nd->u.scr.shop->item[i].nameid; + nd->u.scr.shop->item[cursor].value = nd->u.scr.shop->item[i].value; + nd->u.scr.shop->item[cursor].qty = nd->u.scr.shop->item[i].qty; + } + + cursor++; + } + + script_pushint(st, 1); + } else + script_pushint(st, 0); + + return true; +} +/** + * @call setcurrency <Val1>{,<Val2>}; + * + * updates currently-attached player shop currency + **/ +/* setcurrency(<Val1>,{<Val2>}) */ +BUILDIN(setcurrency) { + int val1 = script_getnum(st,2), + val2 = script_hasdata(st, 3) ? script_getnum(st,3) : 0; + struct npc_data *nd; + + if( !(nd = map->id2nd(st->oid)) ) { + ShowWarning("buildin_setcurrency: trying to run without a proper NPC!\n"); + return false; + } + + npc->trader_funds[0] = val1; + npc->trader_funds[1] = val2; + + return true; +} +/** + * @call tradertype(<type>); + * + * defaults to 0, so no need to call when you're doing zeny + * check enum npc_shop_types for list + * cleans shop list on use + **/ +BUILDIN(tradertype) { + int type = script_getnum(st, 2); + struct npc_data *nd; + + if( !(nd = map->id2nd(st->oid)) ) { + ShowWarning("buildin_tradertype: trying to run without a proper NPC!\n"); + return false; + } else if ( type < 0 || type > NST_MAX ) { + ShowWarning("buildin_tradertype: invalid type param %d!\n",type); + return false; + } + + if( !nd->u.scr.shop ) + npc->trader_update(nd->src_id?nd->src_id:nd->bl.id); + else {/* clear list */ + int i; + for( i = 0; i < nd->u.scr.shop->items; i++ ) { + nd->u.scr.shop->item[i].nameid = 0; + nd->u.scr.shop->item[i].value = 0; + nd->u.scr.shop->item[i].qty = 0; + } + npc->market_delfromsql(nd,USHRT_MAX); + } + + nd->u.scr.shop->type = type; + + return true; +} +/** + * @call purchaseok(); + * + * signs the transaction can proceed + **/ +BUILDIN(purchaseok) { + struct npc_data *nd; + + if( !(nd = map->id2nd(st->oid)) || !nd->u.scr.shop ) { + ShowWarning("buildin_purchaseok: trying to run without a proper NPC!\n"); + return false; + } + + npc->trader_ok = true; + + return true; +} +/** + * @call shopcount(<Item_ID>); + * + * @return number of available items in the script's attached shop + **/ +BUILDIN(shopcount) { + struct npc_data *nd; + int id = script_getnum(st, 2); + unsigned short i; + + if( !(nd = map->id2nd(st->oid)) ) { + ShowWarning("buildin_shopcount(%d): trying to run without a proper NPC!\n",id); + return false; + } else if ( !nd->u.scr.shop || !nd->u.scr.shop->items ) { + ShowWarning("buildin_shopcount(%d): trying to use without any items!\n",id); + return false; + } else if ( nd->u.scr.shop->type != NST_MARKET ) { + ShowWarning("buildin_shopcount(%d): trying to use on a non-NST_MARKET shop!\n",id); + return false; + } + + /* lookup */ + for(i = 0; i < nd->u.scr.shop->items; i++) { + if( nd->u.scr.shop->item[i].nameid == id ) { + script_pushint(st, nd->u.scr.shop->item[i].qty); + break; + } + } + + /* didn't find it */ + if( i == nd->u.scr.shop->items ) + script_pushint(st, 0); + + return true; +} + // declarations that were supposed to be exported from npc_chat.c #ifdef PCRE_SUPPORT BUILDIN(defpattern); @@ -17262,45 +18434,99 @@ BUILDIN(bg_match_over) { BUILDIN(deletepset); #endif -bool script_hp_add(char *name, char *args, bool (*func)(struct script_state *st)) { - int n = script->add_str(name), i = 0; - - if( script->str_data[n].type == C_FUNC ) { - script->str_data[n].func = func; - i = script->str_data[n].val; - if( args ) { - int slen = strlen(args); - if( script->buildin[i] ) { - aFree(script->buildin[i]); - } - CREATE(script->buildin[i], char, slen + 1); - safestrncpy(script->buildin[i], args, slen + 1); - } else { - if( script->buildin[i] ) - aFree(script->buildin[i]); - script->buildin[i] = NULL; +/** + * Adds a built-in script function. + * + * @param buildin Script function data + * @param force Whether to override an existing function with the same name + * (i.e. a plugin overriding a built-in function) + * @return Whether the function was successfully added. + */ +bool script_add_builtin(const struct script_function *buildin, bool override) { + int n = 0, offset = 0; + size_t slen; + if( !buildin ) { + return false; + } + if( buildin->arg ) { + // arg must follow the pattern: (v|s|i|r|l)*\?*\*? + // 'v' - value (either string or int or reference) + // 's' - string + // 'i' - int + // 'r' - reference (of a variable) + // 'l' - label + // '?' - one optional parameter + // '*' - unknown number of optional parameters + char *p = buildin->arg; + while( *p == 'v' || *p == 's' || *p == 'i' || *p == 'r' || *p == 'l' ) ++p; + while( *p == '?' ) ++p; + if( *p == '*' ) ++p; + if( *p != 0 ) { + ShowWarning("add_builtin: ignoring function \"%s\" with invalid arg \"%s\".\n", buildin->name, buildin->arg); + return false; } + } + if( !buildin->name || *script->skip_word(buildin->name) != 0 ) { + ShowWarning("add_builtin: ignoring function with invalid name \"%s\" (must be a word).\n", buildin->name); + return false; + } + if ( !buildin->func ) { + ShowWarning("add_builtin: ignoring function \"%s\" with invalid source function.\n", buildin->name); + return false; + } + slen = buildin->arg ? strlen(buildin->arg) : 0; + n = script->add_str(buildin->name); + if( !override && script->str_data[n].func && script->str_data[n].func != buildin->func ) { + return false; /* something replaced it, skip. */ + } + + if( override && script->str_data[n].type == C_FUNC ) { + // Overriding + offset = script->str_data[n].val; + if( script->buildin[offset] ) + aFree(script->buildin[offset]); + script->buildin[offset] = NULL; } else { - i = script->buildin_count; + // Adding new function + if( strcmp(buildin->name, "setr") == 0 ) script->buildin_set_ref = n; + else if( strcmp(buildin->name, "callsub") == 0 ) script->buildin_callsub_ref = n; + else if( strcmp(buildin->name, "callfunc") == 0 ) script->buildin_callfunc_ref = n; + else if( strcmp(buildin->name, "getelementofarray") == 0 ) script->buildin_getelementofarray_ref = n; + + offset = script->buildin_count; + script->str_data[n].type = C_FUNC; - script->str_data[n].val = i; - script->str_data[n].func = func; - + script->str_data[n].val = offset; + + // Note: This is a no-op if script->buildin is already large enough + // (it'll only have effect when a plugin adds a new command) RECREATE(script->buildin, char *, ++script->buildin_count); - - /* we only store the arguments, its the only thing used out of this */ - if( args != NULL ) { - int slen = strlen(args); - CREATE(script->buildin[i], char, slen + 1); - safestrncpy(script->buildin[i], args, slen + 1); - } else - script->buildin[i] = NULL; } - + + script->str_data[n].func = buildin->func; + + /* we only store the arguments, its the only thing used out of this */ + if( slen ) { + CREATE(script->buildin[offset], char, slen + 1); + safestrncpy(script->buildin[offset], buildin->arg, slen + 1); + } else { + script->buildin[offset] = NULL; + } + return true; } +bool script_hp_add(char *name, char *args, bool (*func)(struct script_state *st)) { + struct script_function buildin; + buildin.name = name; + buildin.arg = args; + buildin.func = func; + return script->add_builtin(&buildin, true); +} + +#define BUILDIN_DEF(x,args) { buildin_ ## x , #x , args } +#define BUILDIN_DEF2(x,x2,args) { buildin_ ## x , x2 , args } void script_parse_builtin(void) { struct script_function BUILDIN[] = { // NPC interaction @@ -17327,7 +18553,8 @@ void script_parse_builtin(void) { BUILDIN_DEF(warpguild,"siii"), // [Fredzilla] BUILDIN_DEF(setlook,"ii"), BUILDIN_DEF(changelook,"ii"), // Simulates but don't Store it - BUILDIN_DEF(set,"rv"), + BUILDIN_DEF2(setr,"set","rv"), + BUILDIN_DEF(setr,"rv?"), // Not meant to be used directly, required for var++/var-- BUILDIN_DEF(setarray,"rv*"), BUILDIN_DEF(cleararray,"rvi"), BUILDIN_DEF(copyarray,"rri"), @@ -17376,7 +18603,7 @@ void script_parse_builtin(void) { BUILDIN_DEF(getequiprefinerycnt,"i"), BUILDIN_DEF(getequipweaponlv,"i"), BUILDIN_DEF(getequippercentrefinery,"i"), - BUILDIN_DEF(successrefitem,"i"), + BUILDIN_DEF(successrefitem,"i?"), BUILDIN_DEF(failedrefitem,"i"), BUILDIN_DEF(downrefitem,"i?"), BUILDIN_DEF(statusup,"i"), @@ -17457,7 +18684,7 @@ void script_parse_builtin(void) { BUILDIN_DEF(sc_end,"i?"), BUILDIN_DEF(getstatus, "i?"), BUILDIN_DEF(getscrate,"ii?"), - BUILDIN_DEF(debugmes,"s"), + BUILDIN_DEF(debugmes,"v"), BUILDIN_DEF2(catchpet,"pet","i"), BUILDIN_DEF2(birthpet,"bpet",""), BUILDIN_DEF(resetlvl,"i"), @@ -17471,8 +18698,8 @@ void script_parse_builtin(void) { BUILDIN_DEF2(waitingroomkickall,"kickwaitingroomall","?"), BUILDIN_DEF(enablewaitingroomevent,"?"), BUILDIN_DEF(disablewaitingroomevent,"?"), - BUILDIN_DEF2(enablewaitingroomevent,"enablearena",""), // Added by RoVeRT - BUILDIN_DEF2(disablewaitingroomevent,"disablearena",""), // Added by RoVeRT + BUILDIN_DEF2(enablewaitingroomevent,"enablearena",""), // Added by RoVeRT + BUILDIN_DEF2(disablewaitingroomevent,"disablearena",""), // Added by RoVeRT BUILDIN_DEF(getwaitingroomstate,"i?"), BUILDIN_DEF(warpwaitingpc,"sii?"), BUILDIN_DEF(attachrid,"i"), @@ -17488,10 +18715,10 @@ void script_parse_builtin(void) { BUILDIN_DEF(gvgoff,"s"), BUILDIN_DEF(emotion,"i??"), BUILDIN_DEF(maprespawnguildid,"sii"), - BUILDIN_DEF(agitstart,""), // <Agit> + BUILDIN_DEF(agitstart,""), // <Agit> BUILDIN_DEF(agitend,""), BUILDIN_DEF(agitcheck,""), // <Agitcheck> - BUILDIN_DEF(flagemblem,"i"), // Flag Emblem + BUILDIN_DEF(flagemblem,"i"), // Flag Emblem BUILDIN_DEF(getcastlename,"s"), BUILDIN_DEF(getcastledata,"si"), BUILDIN_DEF(setcastledata,"sii"), @@ -17517,13 +18744,13 @@ void script_parse_builtin(void) { BUILDIN_DEF(clearitem,""), BUILDIN_DEF(classchange,"ii"), BUILDIN_DEF(misceffect,"i"), - BUILDIN_DEF(playBGM,"s"), - BUILDIN_DEF(playBGMall,"s?????"), + BUILDIN_DEF(playbgm,"s"), + BUILDIN_DEF(playbgmall,"s?????"), BUILDIN_DEF(soundeffect,"si"), - BUILDIN_DEF(soundeffectall,"si?????"), // SoundEffectAll [Codemaster] - BUILDIN_DEF(strmobinfo,"ii"), // display mob data [Valaris] - BUILDIN_DEF(guardian,"siisi??"), // summon guardians - BUILDIN_DEF(guardianinfo,"sii"), // display guardian data [Valaris] + BUILDIN_DEF(soundeffectall,"si?????"), // SoundEffectAll [Codemaster] + BUILDIN_DEF(strmobinfo,"ii"), // display mob data [Valaris] + BUILDIN_DEF(guardian,"siisi??"), // summon guardians + BUILDIN_DEF(guardianinfo,"sii"), // display guardian data [Valaris] BUILDIN_DEF(petskillbonus,"iiii"), // [Valaris] BUILDIN_DEF(petrecovery,"ii"), // [Valaris] BUILDIN_DEF(petloot,"i"), // [Valaris] @@ -17536,7 +18763,7 @@ void script_parse_builtin(void) { BUILDIN_DEF(specialeffect,"i??"), // npc skill effect [Valaris] BUILDIN_DEF(specialeffect2,"i??"), // skill effect on players[Valaris] BUILDIN_DEF(nude,""), // nude command [Valaris] - BUILDIN_DEF(mapwarp,"ssii??"), // Added by RoVeRT + BUILDIN_DEF(mapwarp,"ssii??"), // Added by RoVeRT BUILDIN_DEF(atcommand,"s"), // [MouseJstr] BUILDIN_DEF2(atcommand,"charcommand","s"), // [MouseJstr] BUILDIN_DEF(movenpc,"sii?"), // [MouseJstr] @@ -17548,7 +18775,7 @@ void script_parse_builtin(void) { BUILDIN_DEF(npcspeed,"i"), // [Valaris] BUILDIN_DEF(npcwalkto,"ii"), // [Valaris] BUILDIN_DEF(npcstop,""), // [Valaris] - BUILDIN_DEF(getmapxy,"rrri?"), //by Lorky [Lupus] + BUILDIN_DEF(getmapxy,"rrri?"), //by Lorky [Lupus] BUILDIN_DEF(checkoption1,"i"), BUILDIN_DEF(checkoption2,"i"), BUILDIN_DEF(guildgetexp,"i"), @@ -17626,11 +18853,14 @@ void script_parse_builtin(void) { BUILDIN_DEF(disguise,"i"), //disguise player. Lupus BUILDIN_DEF(undisguise,""), //undisguise player. Lupus BUILDIN_DEF(getmonsterinfo,"ii"), //Lupus + BUILDIN_DEF(addmonsterdrop,"vii"), + BUILDIN_DEF(delmonsterdrop,"vi"), BUILDIN_DEF(axtoi,"s"), BUILDIN_DEF(query_sql,"s*"), BUILDIN_DEF(query_logsql,"s*"), BUILDIN_DEF(escape_sql,"v"), BUILDIN_DEF(atoi,"s"), + BUILDIN_DEF(strtol,"si"), // [zBuffer] List of player cont commands ---> BUILDIN_DEF(rid2name,"i"), BUILDIN_DEF(pcfollow,"ii"), @@ -17653,12 +18883,13 @@ void script_parse_builtin(void) { BUILDIN_DEF(awake,"s"), BUILDIN_DEF(getvariableofnpc,"rs"), BUILDIN_DEF(warpportal,"iisii"), - BUILDIN_DEF2(homunculus_evolution,"homevolution",""), //[orn] + BUILDIN_DEF2(homunculus_evolution,"homevolution",""), //[orn] BUILDIN_DEF2(homunculus_mutate,"hommutate","?"), - BUILDIN_DEF2(homunculus_shuffle,"homshuffle",""), //[Zephyrus] - BUILDIN_DEF(checkhomcall,""), - BUILDIN_DEF(eaclass,"?"), //[Skotlex] - BUILDIN_DEF(roclass,"i?"), //[Skotlex] + BUILDIN_DEF2(homunculus_morphembryo,"morphembryo",""), + BUILDIN_DEF2(homunculus_checkcall,"checkhomcall",""), + BUILDIN_DEF2(homunculus_shuffle,"homshuffle",""), //[Zephyrus] + BUILDIN_DEF(eaclass,"?"), //[Skotlex] + BUILDIN_DEF(roclass,"i?"), //[Skotlex] BUILDIN_DEF(checkvending,"?"), BUILDIN_DEF(checkchatting,"?"), BUILDIN_DEF(checkidle,"?"), @@ -17701,7 +18932,7 @@ void script_parse_builtin(void) { BUILDIN_DEF(bg_get_data,"ii"), BUILDIN_DEF(bg_getareausers,"isiiii"), BUILDIN_DEF(bg_updatescore,"sii"), - + // Instancing BUILDIN_DEF(instance_create,"si?"), BUILDIN_DEF(instance_destroy,"?"), @@ -17716,6 +18947,10 @@ void script_parse_builtin(void) { BUILDIN_DEF(has_instance,"s?"), BUILDIN_DEF(instance_warpall,"sii?"), BUILDIN_DEF(instance_check_party,"i???"), + BUILDIN_DEF(instance_mapname,"s?"), + BUILDIN_DEF(instance_set_respawn,"sii?"), + BUILDIN_DEF2(has_instance,"has_instance2","s"), + /** * 3rd-related **/ @@ -17746,15 +18981,23 @@ void script_parse_builtin(void) { BUILDIN_DEF(bindatcmd, "ss???"), BUILDIN_DEF(unbindatcmd, "s"), BUILDIN_DEF(useatcmd, "s"), - + + /** + * Item bound [Xantara] [Akinari] [Mhalicot/Hercules] + **/ + BUILDIN_DEF2(getitem,"getitembound","vii?"), + BUILDIN_DEF2(getitem2,"getitembound2","viiiiiiiii?"), + BUILDIN_DEF(countbound, "?"), + //Quest Log System [Inkfish] + BUILDIN_DEF(questinfo, "ii??"), BUILDIN_DEF(setquest, "i"), BUILDIN_DEF(erasequest, "i"), BUILDIN_DEF(completequest, "i"), BUILDIN_DEF(checkquest, "i?"), BUILDIN_DEF(changequest, "ii"), - BUILDIN_DEF(showevent, "ii"), - + BUILDIN_DEF(showevent, "i?"), + /** * hQueue [Ind/Hercules] **/ @@ -17768,75 +19011,47 @@ void script_parse_builtin(void) { BUILDIN_DEF(qicheck,"i"), BUILDIN_DEF(qiget,"i"), BUILDIN_DEF(qiclear,"i"), - + BUILDIN_DEF(packageitem,"?"), - + BUILDIN_DEF(sit, "?"), BUILDIN_DEF(stand, "?"), BUILDIN_DEF(issit, "?"), - + + BUILDIN_DEF(montransform, "vii????"), // Monster Transform [malufett/Hercules] + /* New BG Commands [Hercules] */ BUILDIN_DEF(bg_create_team,"sii"), BUILDIN_DEF(bg_join_team,"i?"), BUILDIN_DEF(bg_match_over,"s?"), + + /* New Shop Support */ + BUILDIN_DEF(openshop,"?"), + BUILDIN_DEF(sellitem,"i??"), + BUILDIN_DEF(stopselling,"i"), + BUILDIN_DEF(setcurrency,"i?"), + BUILDIN_DEF(tradertype,"i"), + BUILDIN_DEF(purchaseok,""), + BUILDIN_DEF(shopcount, "i"), }; - int i,n, len = ARRAYLENGTH(BUILDIN), start = script->buildin_count; - char* p; - RECREATE(script->buildin, char *, start + len); + int i, len = ARRAYLENGTH(BUILDIN); + RECREATE(script->buildin, char *, script->buildin_count + len); // Pre-alloc to speed up + memset(script->buildin + script->buildin_count, '\0', sizeof(char *) * len); for( i = 0; i < len; i++ ) { - // arg must follow the pattern: (v|s|i|r|l)*\?*\*? - // 'v' - value (either string or int or reference) - // 's' - string - // 'i' - int - // 'r' - reference (of a variable) - // 'l' - label - // '?' - one optional parameter - // '*' - unknown number of optional parameters - p = BUILDIN[i].arg; - while( *p == 'v' || *p == 's' || *p == 'i' || *p == 'r' || *p == 'l' ) ++p; - while( *p == '?' ) ++p; - if( *p == '*' ) ++p; - if( *p != 0 ){ - ShowWarning("parse_builtin: ignoring function \"%s\" with invalid arg \"%s\".\n", BUILDIN[i].name, BUILDIN[i].arg); - } else if( *script->skip_word(BUILDIN[i].name) != 0 ){ - ShowWarning("parse_builtin: ignoring function with invalid name \"%s\" (must be a word).\n", BUILDIN[i].name); - } else { - int slen = strlen(BUILDIN[i].arg), offset = start + i; - n = script->add_str(BUILDIN[i].name); - - if (!strcmp(BUILDIN[i].name, "set")) script->buildin_set_ref = n; - else if (!strcmp(BUILDIN[i].name, "callsub")) script->buildin_callsub_ref = n; - else if (!strcmp(BUILDIN[i].name, "callfunc")) script->buildin_callfunc_ref = n; - else if (!strcmp(BUILDIN[i].name, "getelementofarray") ) script->buildin_getelementofarray_ref = n; - - if( script->str_data[n].func && script->str_data[n].func != BUILDIN[i].func ) - continue;/* something replaced it, skip. */ - - script->str_data[n].type = C_FUNC; - script->str_data[n].val = offset; - script->str_data[n].func = BUILDIN[i].func; - - /* we only store the arguments, its the only thing used out of this */ - if( slen ) { - CREATE(script->buildin[offset], char, slen + 1); - safestrncpy(script->buildin[offset], BUILDIN[i].arg, slen + 1); - } else - script->buildin[offset] = NULL; - - script->buildin_count++; - - } + script->add_builtin(&BUILDIN[i], false); } } +#undef BUILDIN_DEF +#undef BUILDIN_DEF2 void script_label_add(int key, int pos) { int idx = script->label_count; - + if( script->labels_size == script->label_count ) { script->labels_size += 1024; RECREATE(script->labels, struct script_label_entry, script->labels_size); } - + script->labels[idx].key = key; script->labels[idx].pos = pos; script->label_count++; @@ -17844,24 +19059,24 @@ void script_label_add(int key, int pos) { void script_defaults(void) { // aegis->athena slot position conversion table - unsigned int equip[SCRIPT_EQUIP_TABLE_SIZE] = {EQP_HEAD_TOP,EQP_ARMOR,EQP_HAND_L,EQP_HAND_R,EQP_GARMENT,EQP_SHOES,EQP_ACC_L,EQP_ACC_R,EQP_HEAD_MID,EQP_HEAD_LOW,EQP_COSTUME_HEAD_LOW,EQP_COSTUME_HEAD_MID,EQP_COSTUME_HEAD_TOP,EQP_COSTUME_GARMENT}; + unsigned int equip[SCRIPT_EQUIP_TABLE_SIZE] = {EQP_HEAD_TOP,EQP_ARMOR,EQP_HAND_L,EQP_HAND_R,EQP_GARMENT,EQP_SHOES,EQP_ACC_L,EQP_ACC_R,EQP_HEAD_MID,EQP_HEAD_LOW,EQP_COSTUME_HEAD_LOW,EQP_COSTUME_HEAD_MID,EQP_COSTUME_HEAD_TOP,EQP_COSTUME_GARMENT,EQP_SHADOW_ARMOR, EQP_SHADOW_WEAPON, EQP_SHADOW_SHIELD, EQP_SHADOW_SHOES, EQP_SHADOW_ACC_R, EQP_SHADOW_ACC_L}; script = &script_s; - + script->st_db = NULL; script->active_scripts = 0; script->next_id = 0; script->st_ers = NULL; script->stack_ers = NULL; + script->array_ers = NULL; script->hq = NULL; script->hqi = NULL; script->hqs = script->hqis = 0; - memset(&script->hqe, 0, sizeof(script->hqe)); - + script->buildin = NULL; script->buildin_count = 0; - + script->str_data = NULL; script->str_data_size = 0; script->str_num = LABEL_START; @@ -17869,19 +19084,19 @@ void script_defaults(void) { script->str_size = 0; script->str_pos = 0; memset(script->str_hash, 0, sizeof(script->str_hash)); - + script->word_buf = NULL; script->word_size = 0; - + script->current_item_id = 0; - + script->labels = NULL; script->label_count = 0; script->labels_size = 0; - + script->buf = NULL; script->pos = 0, script->size = 0; - + script->parse_options = 0; script->buildin_set_ref = 0; script->buildin_callsub_ref = 0; @@ -17895,33 +19110,37 @@ void script_defaults(void) { script->parser_current_src = NULL; script->parser_current_file = NULL; script->parser_current_line = 0; - + memset(&script->syntax,0,sizeof(script->syntax)); - + script->parse_syntax_for_flag = 0; - + memcpy(script->equip, &equip, sizeof(script->equip)); - + memset(&script->config, 0, sizeof(script->config)); - + script->autobonus_db = NULL; script->userfunc_db = NULL; - + script->potion_flag = script->potion_hp = script->potion_per_hp = script->potion_sp = script->potion_per_sp = script->potion_target = 0; - + + script->generic_ui_array = NULL; + script->generic_ui_array_size = 0; + /* */ script->init = do_init_script; script->final = do_final_script; script->reload = script_reload; - + /* parse */ script->parse = parse_script; + script->add_builtin = script_add_builtin; script->parse_builtin = script_parse_builtin; script->skip_space = script_skip_space; script->error = script_error; script->warning = script_warning; script->parse_subexpr = script_parse_subexpr; - + script->addScript = script_hp_add; script->conv_num = conv_num; script->conv_str = conv_str; @@ -17935,8 +19154,7 @@ void script_defaults(void) { script->pop_stack = pop_stack; script->set_constant = script_set_constant; script->set_constant2 = script_set_constant2; - script->set_constant_force = script_set_constant_force; - script->get_constant = script_get_constant; + script->get_constant = script_get_constant; script->label_add = script_label_add; script->run = run_script; script->run_main = run_script_main; @@ -17956,14 +19174,14 @@ void script_defaults(void) { script->search_str = script_search_str; script->setd_sub = setd_sub; script->attach_state = script_attach_state; - + script->queue = script_hqueue_get; script->queue_add = script_hqueue_add; script->queue_del = script_hqueue_del; script->queue_remove = script_hqueue_remove; script->queue_create = script_hqueue_create; script->queue_clear = script_hqueue_clear; - + script->parse_curly_close = parse_curly_close; script->parse_syntax_close = parse_syntax_close; script->parse_syntax_close_sub = parse_syntax_close_sub; @@ -17974,7 +19192,6 @@ void script_defaults(void) { script->reportsrc = script_reportsrc; script->reportdata = script_reportdata; script->reportfunc = script_reportfunc; - script->disp_error_message2 = disp_error_message2; script->disp_warning_message = disp_warning_message; script->check_event = check_event; script->calc_hash = calc_hash; @@ -17997,7 +19214,6 @@ void script_defaults(void) { script->set_reg = set_reg; script->stack_expand = stack_expand; script->push_retinfo = push_retinfo; - script->pop_val = pop_val; script->op_3 = op_3; script->op_2str = op_2str; script->op_2num = op_2num; @@ -18010,7 +19226,6 @@ void script_defaults(void) { script->menu_countoptions = menu_countoptions; script->buildin_areawarp_sub = buildin_areawarp_sub; script->buildin_areapercentheal_sub = buildin_areapercentheal_sub; - script->getarraysize = getarraysize; script->buildin_delitem_delete = buildin_delitem_delete; script->buildin_delitem_search = buildin_delitem_search; script->buildin_killmonster_sub_strip = buildin_killmonster_sub_strip; @@ -18025,16 +19240,16 @@ void script_defaults(void) { script->buildin_maprespawnguildid_sub_pc = buildin_maprespawnguildid_sub_pc; script->buildin_maprespawnguildid_sub_mob = buildin_maprespawnguildid_sub_mob; script->buildin_mobcount_sub = buildin_mobcount_sub; - script->playBGM_sub = playBGM_sub; - script->playBGM_foreachpc_sub = playBGM_foreachpc_sub; + script->playbgm_sub = playbgm_sub; + script->playbgm_foreachpc_sub = playbgm_foreachpc_sub; script->soundeffect_sub = soundeffect_sub; script->buildin_query_sql_sub = buildin_query_sql_sub; - script->axtoi = axtoi; script->buildin_instance_warpall_sub = buildin_instance_warpall_sub; script->buildin_mobuseskill_sub = buildin_mobuseskill_sub; script->cleanfloor_sub = script_cleanfloor_sub; script->run_func = run_func; - + script->getfuncname = script_getfuncname; + /* script_config base */ script->config.warn_func_mismatch_argtypes = 1; script->config.warn_func_mismatch_paramnum = 1; @@ -18052,4 +19267,46 @@ void script_defaults(void) { script->config.joblvup_event_name = "OnPCJobLvUpEvent"; script->config.ontouch_name = "OnTouch_";//ontouch_name (runs on first visible char to enter area, picks another char if the first char leaves) script->config.ontouch2_name = "OnTouch";//ontouch2_name (run whenever a char walks into the OnTouch area) + + // for ENABLE_CASE_CHECK + script->calc_hash_ci = calc_hash_ci; + script->local_casecheck.add_str = script_local_casecheck_add_str; + script->local_casecheck.clear = script_local_casecheck_clear; + script->local_casecheck.str_data = NULL; + script->local_casecheck.str_data_size = 0; + script->local_casecheck.str_num = 1; + script->local_casecheck.str_buf = NULL; + script->local_casecheck.str_size = 0; + script->local_casecheck.str_pos = 0; + memset(script->local_casecheck.str_hash, 0, sizeof(script->local_casecheck.str_hash)); + script->global_casecheck.add_str = script_global_casecheck_add_str; + script->global_casecheck.clear = script_global_casecheck_clear; + script->global_casecheck.str_data = NULL; + script->global_casecheck.str_data_size = 0; + script->global_casecheck.str_num = 1; + script->global_casecheck.str_buf = NULL; + script->global_casecheck.str_size = 0; + script->global_casecheck.str_pos = 0; + memset(script->global_casecheck.str_hash, 0, sizeof(script->global_casecheck.str_hash)); + // end ENABLE_CASE_CHECK + + /** + * Array Handling + **/ + script->array_src = script_array_src; + script->array_update = script_array_update; + script->array_add_member = script_array_add_member; + script->array_remove_member = script_array_remove_member; + script->array_delete = script_array_delete; + script->array_size = script_array_size; + script->array_free_db = script_free_array_db; + script->array_highest_key = script_array_highest_key; + script->array_ensure_zero = script_array_ensure_zero; + /* */ + script->reg_destroy_single = script_reg_destroy_single; + script->reg_destroy = script_reg_destroy; + /* */ + script->generic_ui_array_expand = script_generic_ui_array_expand; + script->array_cpy_list = script_array_cpy_list; + } diff --git a/src/map/script.h b/src/map/script.h index c00086ef9..3835a130b 100644 --- a/src/map/script.h +++ b/src/map/script.h @@ -2,10 +2,11 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _SCRIPT_H_ -#define _SCRIPT_H_ +#ifndef _MAP_SCRIPT_H_ +#define _MAP_SCRIPT_H_ #include "../common/strlib.h" //StringBuf +#include "../common/cbasetypes.h" #include "map.h" //EVENT_NAME_LENGTH #include <setjmp.h> @@ -20,10 +21,17 @@ struct eri; /** * Defines **/ +// TODO: Remove temporary code +#define ENABLE_CASE_CHECK +#define get_script_source(source) ((source) ? (source) : "Unknown (Possibly source or variables stored in database") +#define DeprecationWarning(func, bad, good, file, line) ShowError("%s: use of deprecated keyword '%s' (use '%s' instead) in file '%s', line '%d'.\n", (func), (bad), (good), get_script_source(file), (line)); +#define DeprecationWarning2(func, bad, good, where) ShowError("%s: detected possible use of wrong case in a script. Found '%s', probably meant to be '%s' (in '%s').\n", (func), (bad), (good), get_script_source(where)); +#define disp_deprecation_message(func, good, p) disp_warning_message(func": use of deprecated keyword (use '"good"' instead).", (p)); + #define NUM_WHISPER_VAR 10 -/// Maximum amount of elements in script arrays (soon getting ducked) -#define SCRIPT_MAX_ARRAYSIZE 128 +/// Maximum amount of elements in script arrays +#define SCRIPT_MAX_ARRAYSIZE (UINT_MAX - 1) #define SCRIPT_BLOCK_SIZE 512 @@ -35,7 +43,7 @@ struct eri; //#define SCRIPT_HASH_SDBM #define SCRIPT_HASH_ELF -#define SCRIPT_EQUIP_TABLE_SIZE 14 +#define SCRIPT_EQUIP_TABLE_SIZE 20 //#define SCRIPT_DEBUG_DISP //#define SCRIPT_DEBUG_DISASM @@ -65,24 +73,26 @@ struct eri; /// Returns the index of the last data in the stack #define script_lastdata(st) ( (st)->end - (st)->start - 1 ) /// Pushes an int into the stack -#define script_pushint(st,val) script->push_val((st)->stack, C_INT, (val),NULL) +#define script_pushint(st,val) (script->push_val((st)->stack, C_INT, (val),NULL)) /// Pushes a string into the stack (script engine frees it automatically) -#define script_pushstr(st,val) script->push_str((st)->stack, C_STR, (val)) +#define script_pushstr(st,val) (script->push_str((st)->stack, C_STR, (val))) /// Pushes a copy of a string into the stack -#define script_pushstrcopy(st,val) script->push_str((st)->stack, C_STR, aStrdup(val)) +#define script_pushstrcopy(st,val) (script->push_str((st)->stack, C_STR, aStrdup(val))) /// Pushes a constant string into the stack (must never change or be freed) -#define script_pushconststr(st,val) script->push_str((st)->stack, C_CONSTSTR, (val)) +#define script_pushconststr(st,val) (script->push_str((st)->stack, C_CONSTSTR, (val))) /// Pushes a nil into the stack -#define script_pushnil(st) script->push_val((st)->stack, C_NOP, 0,NULL) +#define script_pushnil(st) (script->push_val((st)->stack, C_NOP, 0,NULL)) /// Pushes a copy of the data in the target index -#define script_pushcopy(st,i) script->push_copy((st)->stack, (st)->start + (i)) +#define script_pushcopy(st,i) (script->push_copy((st)->stack, (st)->start + (i))) -#define script_isstring(st,i) data_isstring(script_getdata(st,i)) -#define script_isint(st,i) data_isint(script_getdata(st,i)) +#define script_isstring(st,i) data_isstring(script_getdata((st),(i))) +#define script_isint(st,i) data_isint(script_getdata((st),(i))) +#define script_isstringtype(st,i) data_isstring(script->get_val((st), script_getdata((st),(i)))) +#define script_isinttype(st,i) data_isint(script->get_val((st), script_getdata((st),(i)))) -#define script_getnum(st,val) script->conv_num(st, script_getdata(st,val)) -#define script_getstr(st,val) script->conv_str(st, script_getdata(st,val)) -#define script_getref(st,val) ( script_getdata(st,val)->ref ) +#define script_getnum(st,val) (script->conv_num((st), script_getdata((st),(val)))) +#define script_getstr(st,val) (script->conv_str((st), script_getdata((st),(val)))) +#define script_getref(st,val) ( script_getdata((st),(val))->ref ) // Note: "top" functions/defines use indexes relative to the top of the stack // -1 is the index of the data at the top @@ -119,9 +129,9 @@ struct eri; /// Returns the unique id of the reference (id and index) #define reference_getuid(data) ( (data)->u.num ) /// Returns the id of the reference -#define reference_getid(data) ( (int32)(reference_getuid(data) & 0x00ffffff) ) +#define reference_getid(data) ( (int32)(int64)(reference_getuid(data) & 0xFFFFFFFF) ) /// Returns the array index of the reference -#define reference_getindex(data) ( (int32)(((uint32)(reference_getuid(data) & 0xff000000)) >> 24) ) +#define reference_getindex(data) ( (uint32)(int64)((reference_getuid(data) >> 32) & 0xFFFFFFFF) ) /// Returns the name of the reference #define reference_getname(data) ( script->str_buf + script->str_data[reference_getid(data)].str ) /// Returns the linked list of uid-value pairs of the reference (can be NULL) @@ -132,18 +142,22 @@ struct eri; #define reference_getparamtype(data) ( script->str_data[reference_getid(data)].val ) /// Composes the uid of a reference from the id and the index -#define reference_uid(id,idx) ( (int32)((((uint32)(id)) & 0x00ffffff) | (((uint32)(idx)) << 24)) ) +#define reference_uid(id,idx) ( (int64) ((uint64)(id) & 0xFFFFFFFF) | ((uint64)(idx) << 32) ) + +#define script_getvarid(var) ( (int32)(int64)(var & 0xFFFFFFFF) ) +#define script_getvaridx(var) ( (uint32)(int64)((var >> 32) & 0xFFFFFFFF) ) #define not_server_variable(prefix) ( (prefix) != '$' && (prefix) != '.' && (prefix) != '\'') -#define not_array_variable(prefix) ( (prefix) != '$' && (prefix) != '@' && (prefix) != '.' && (prefix) != '\'' ) #define is_string_variable(name) ( (name)[strlen(name) - 1] == '$' ) #define BUILDIN(x) bool buildin_ ## x (struct script_state* st) -#define BUILDIN_A(x) buildin_ ## x -#define script_fetch(st, n, t) \ - if( script_hasdata(st,n) ) \ - (t)=script_getnum(st,n); +#define script_fetch(st, n, t) do { \ + if( script_hasdata((st),(n)) ) \ + (t)=script_getnum((st),(n)); \ + else \ + (t) = 0; \ +} while(0) /** @@ -188,8 +202,10 @@ typedef enum c_op { C_NOT, // ~ a C_R_SHIFT, // a >> b C_L_SHIFT, // a << b - C_ADD_PP, // ++a - C_SUB_PP, // --a + C_ADD_POST, // a++ + C_SUB_POST, // a-- + C_ADD_PRE, // ++a + C_SUB_PRE, // --a } c_op; enum hQueueOpt { @@ -287,7 +303,8 @@ enum { MF_PVP_NOCALCRANK, //50 MF_BATTLEGROUND, MF_RESET, - MF_NOTOMB + MF_NOTOMB, + MF_NOCASHSHOP }; /** @@ -326,7 +343,7 @@ struct script_retinfo { struct script_data { enum c_op type; union script_data_val { - int num; + int64 num; char *str; struct script_retinfo* ri; } u; @@ -337,8 +354,9 @@ struct script_data { // it must be saved when script state is RERUNLINE. [Eoe / jA 1094] struct script_code { int script_size; - unsigned char* script_buf; - struct DBMap* script_vars; + unsigned char *script_buf; + struct DBMap *script_vars; + struct DBMap *script_arrays_db; }; struct script_stack { @@ -346,7 +364,8 @@ struct script_stack { int sp_max;// capacity of the stack int defsp; struct script_data *stack_data;// stack - struct DBMap* var_function;// scope variables + struct DBMap *var_function;// scope variables + struct DBMap *array_function_db; }; /* [Ind/Hercules] */ @@ -388,13 +407,14 @@ struct script_state { unsigned int id; }; +/* TODO: HELLO DUCK THIS */ struct script_reg { - int index; + int64 index; int data; }; - +/* TODO: HELLO DUCK THIS */ struct script_regstr { - int index; + int64 index; char* data; }; @@ -432,6 +452,25 @@ struct script_syntax_data { int index; // Number of the syntax used in the script }; +struct casecheck_data { + struct str_data_struct *str_data; + int str_data_size; // size of the data + int str_num; // next id to be assigned + // str_buf holds the strings themselves + char *str_buf; + int str_size; // size of the buffer + int str_pos; // next position to be assigned + int str_hash[SCRIPT_HASH_SIZE]; + const char *(*add_str) (const char* p); + void (*clear) (void); +}; + +struct script_array { + unsigned int id;/* the first 32b of the 64b uid, aka the id */ + unsigned int size;/* how many members */ + unsigned int *members;/* member list */ +}; + /** * Interface **/ @@ -446,22 +485,25 @@ struct script_interface { struct hQueue *hq; struct hQueueIterator *hqi; int hqs, hqis; - int hqe[HQO_MAX]; /* */ char **buildin; unsigned int buildin_count; + /** + * used to generate quick script_array entries + **/ + struct eri *array_ers; /* */ struct str_data_struct *str_data; int str_data_size; // size of the data int str_num; // next id to be assigned // str_buf holds the strings themselves char *str_buf; - int str_size; // size of the buffer + size_t str_size; // size of the buffer int str_pos; // next position to be assigned int str_hash[SCRIPT_HASH_SIZE]; /* */ char *word_buf; - int word_size; + size_t word_size; /* */ unsigned short current_item_id; /* */ @@ -505,12 +547,16 @@ struct script_interface { int potion_flag; //For use on Alchemist improved potions/Potion Pitcher. [Skotlex] int potion_hp, potion_per_hp, potion_sp, potion_per_sp; int potion_target; + /* */ + unsigned int *generic_ui_array; + unsigned int generic_ui_array_size; /* */ - void (*init) (void); + void (*init) (bool minimal); void (*final) (void); int (*reload) (void); /* parse */ struct script_code* (*parse) (const char* src,const char* file,int line,int options); + bool (*add_builtin) (const struct script_function *buildin, bool override); void (*parse_builtin) (void); const char* (*parse_subexpr) (const char* p,int limit); const char* (*skip_space) (const char* p); @@ -522,20 +568,19 @@ struct script_interface { const char* (*conv_str) (struct script_state *st,struct script_data *data); TBL_PC *(*rid2sd) (struct script_state *st); void (*detach_rid) (struct script_state* st); - struct script_data* (*push_val)(struct script_stack* stack, enum c_op type, int val, struct DBMap** ref); - void (*get_val) (struct script_state* st, struct script_data* data); - void* (*get_val2) (struct script_state* st, int uid, struct DBMap** ref); + struct script_data* (*push_val)(struct script_stack* stack, enum c_op type, int64 val, struct DBMap** ref); + struct script_data *(*get_val) (struct script_state* st, struct script_data* data); + void* (*get_val2) (struct script_state* st, int64 uid, struct DBMap** ref); struct script_data* (*push_str) (struct script_stack* stack, enum c_op type, char* str); struct script_data* (*push_copy) (struct script_stack* stack, int pos); void (*pop_stack) (struct script_state* st, int start, int end); void (*set_constant) (const char* name, int value, bool isparameter); void (*set_constant2) (const char *name, int value, bool isparameter); - void (*set_constant_force) (const char *name, int value, bool isparameter); bool (*get_constant) (const char* name, int* value); void (*label_add)(int key, int pos); void (*run) (struct script_code *rootscript,int pos,int rid,int oid); void (*run_main) (struct script_state *st); - int (*run_timer) (int tid, unsigned int tick, int id, intptr_t data); + int (*run_timer) (int tid, int64 tick, int id, intptr_t data); int (*set_var) (struct map_session_data *sd, char *name, void *val); void (*stop_instances) (struct script_code *code); void (*free_code) (struct script_code* code); @@ -544,7 +589,7 @@ struct script_interface { void (*free_state) (struct script_state* st); void (*run_autobonus) (const char *autobonus,int id, int pos); void (*cleararray_pc) (struct map_session_data* sd, const char* varname, void* value); - void (*setarray_pc) (struct map_session_data* sd, const char* varname, uint8 idx, void* value, int* refcache); + void (*setarray_pc) (struct map_session_data* sd, const char* varname, uint32 idx, void* value, int* refcache); int (*config_read) (char *cfgName); int (*add_str) (const char* p); const char* (*get_str) (int id); @@ -569,7 +614,6 @@ struct script_interface { void (*reportsrc) (struct script_state *st); void (*reportdata) (struct script_data *data); void (*reportfunc) (struct script_state *st); - void (*disp_error_message2) (const char *mes, const char *pos, int report); void (*disp_warning_message) (const char *mes, const char *pos); void (*check_event) (struct script_state *st, const char *evt); unsigned int (*calc_hash) (const char *p); @@ -589,10 +633,9 @@ struct script_interface { void (*read_constdb) (void); const char* (*print_line) (StringBuf *buf, const char *p, const char *mark, int line); void (*errorwarning_sub) (StringBuf *buf, const char *src, const char *file, int start_line, const char *error_msg, const char *error_pos); - int (*set_reg) (struct script_state *st, TBL_PC *sd, int num, const char *name, const void *value, struct DBMap **ref); + int (*set_reg) (struct script_state *st, TBL_PC *sd, int64 num, const char *name, const void *value, struct DBMap **ref); void (*stack_expand) (struct script_stack *stack); struct script_data* (*push_retinfo) (struct script_stack *stack, struct script_retinfo *ri, DBMap **ref); - int (*pop_val) (struct script_state *st); void (*op_3) (struct script_state *st, int op); void (*op_2str) (struct script_state *st, int op, const char *s1, const char *s2); void (*op_2num) (struct script_state *st, int op, int i1, int i2); @@ -605,7 +648,6 @@ struct script_interface { int (*menu_countoptions) (const char *str, int max_count, int *total); int (*buildin_areawarp_sub) (struct block_list *bl, va_list ap); int (*buildin_areapercentheal_sub) (struct block_list *bl, va_list ap); - int32 (*getarraysize) (struct script_state *st, int32 id, int32 idx, int isstring, struct DBMap **ref); void (*buildin_delitem_delete) (struct map_session_data *sd, int idx, int *amount, bool delete_items); bool (*buildin_delitem_search) (struct map_session_data *sd, struct item *it, bool exact_match); int (*buildin_killmonster_sub_strip) (struct block_list *bl, va_list ap); @@ -620,19 +662,42 @@ struct script_interface { int (*buildin_maprespawnguildid_sub_pc) (struct map_session_data *sd, va_list ap); int (*buildin_maprespawnguildid_sub_mob) (struct block_list *bl, va_list ap); int (*buildin_mobcount_sub) (struct block_list *bl, va_list ap); - int (*playBGM_sub) (struct block_list *bl, va_list ap); - int (*playBGM_foreachpc_sub) (struct map_session_data *sd, va_list args); + int (*playbgm_sub) (struct block_list *bl, va_list ap); + int (*playbgm_foreachpc_sub) (struct map_session_data *sd, va_list args); int (*soundeffect_sub) (struct block_list *bl, va_list ap); int (*buildin_query_sql_sub) (struct script_state *st, Sql *handle); - int (*axtoi) (const char *hexStg); int (*buildin_instance_warpall_sub) (struct block_list *bl, va_list ap); int (*buildin_mobuseskill_sub) (struct block_list *bl, va_list ap); int (*cleanfloor_sub) (struct block_list *bl, va_list ap); int (*run_func) (struct script_state *st); + const char *(*getfuncname) (struct script_state *st); + // for ENABLE_CASE_CHECK + unsigned int (*calc_hash_ci) (const char *p); + struct casecheck_data local_casecheck; + struct casecheck_data global_casecheck; + // end ENABLE_CASE_CHECK + /** + * Array Handling + **/ + struct DBMap *(*array_src) (struct script_state *st, struct map_session_data *sd, const char *name, struct DBMap **ref); + void (*array_update) (struct DBMap **src, int64 num, bool empty); + void (*array_delete) (struct DBMap *src, struct script_array *sa); + void (*array_remove_member) (struct DBMap *src, struct script_array *sa, unsigned int idx); + void (*array_add_member) (struct script_array *sa, unsigned int idx); + unsigned int (*array_size) (struct script_state *st, struct map_session_data *sd, const char *name, struct DBMap** ref); + unsigned int (*array_highest_key) (struct script_state *st, struct map_session_data *sd, const char *name, struct DBMap** ref); + int (*array_free_db) (DBKey key, DBData *data, va_list ap); + void (*array_ensure_zero) (struct script_state *st, struct map_session_data *sd, int64 uid, struct DBMap** ref); + /* */ + void (*reg_destroy_single) (struct map_session_data *sd, int64 reg, struct script_reg_state *data); + int (*reg_destroy) (DBKey key, DBData *data, va_list ap); + /* */ + void (*generic_ui_array_expand) (unsigned int plus); + unsigned int *(*array_cpy_list) (struct script_array *sa); }; struct script_interface *script; void script_defaults(void); -#endif /* _SCRIPT_H_ */ +#endif /* _MAP_SCRIPT_H_ */ diff --git a/src/map/searchstore.h b/src/map/searchstore.h index d7a327181..827e39053 100644 --- a/src/map/searchstore.h +++ b/src/map/searchstore.h @@ -2,8 +2,8 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _SEARCHSTORE_H_ -#define _SEARCHSTORE_H_ +#ifndef _MAP_SEARCHSTORE_H_ +#define _MAP_SEARCHSTORE_H_ /** * Defines @@ -93,4 +93,4 @@ struct searchstore_interface *searchstore; void searchstore_defaults (void); -#endif // _SEARCHSTORE_H_ +#endif /* _MAP_SEARCHSTORE_H_ */ diff --git a/src/map/skill.c b/src/map/skill.c index ab937fadd..37ee297ca 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -47,13 +47,13 @@ // ranges reserved for mapping skill ids to skilldb offsets #define HM_SKILLRANGEMIN 750 -#define HM_SKILLRANGEMAX HM_SKILLRANGEMIN + MAX_HOMUNSKILL -#define MC_SKILLRANGEMIN HM_SKILLRANGEMAX + 1 -#define MC_SKILLRANGEMAX MC_SKILLRANGEMIN + MAX_MERCSKILL -#define EL_SKILLRANGEMIN MC_SKILLRANGEMAX + 1 -#define EL_SKILLRANGEMAX EL_SKILLRANGEMIN + MAX_ELEMENTALSKILL -#define GD_SKILLRANGEMIN EL_SKILLRANGEMAX + 1 -#define GD_SKILLRANGEMAX GD_SKILLRANGEMIN + MAX_GUILDSKILL +#define HM_SKILLRANGEMAX (HM_SKILLRANGEMIN + MAX_HOMUNSKILL) +#define MC_SKILLRANGEMIN (HM_SKILLRANGEMAX + 1) +#define MC_SKILLRANGEMAX (MC_SKILLRANGEMIN + MAX_MERCSKILL) +#define EL_SKILLRANGEMIN (MC_SKILLRANGEMAX + 1) +#define EL_SKILLRANGEMAX (EL_SKILLRANGEMIN + MAX_ELEMENTALSKILL) +#define GD_SKILLRANGEMIN (EL_SKILLRANGEMAX + 1) +#define GD_SKILLRANGEMAX (GD_SKILLRANGEMIN + MAX_GUILDSKILL) #if GD_SKILLRANGEMAX > 999 #error GD_SKILLRANGEMAX is greater than 999 @@ -131,17 +131,17 @@ void skill_chk(uint16* skill_id) { *skill_id = skill->get_index(*skill_id); // checks/adjusts id } -#define skill_get(var,id) { skill->chk(&id); if(!id) return 0; return var; } -#define skill_get2(var,id,lv) { \ - skill->chk(&id); \ - if(!id) return 0; \ - if( lv > MAX_SKILL_LEVEL && var > 1 ) { \ - int lv2 = lv; lv = skill->db[id].max; \ - return (var) + ((lv2-lv)/2);\ +#define skill_get(var,id) do { skill->chk(&(id)); if(!(id)) return 0; return (var); } while(0) +#define skill_get2(var,id,lv) do { \ + skill->chk(&(id)); \ + if(!(id)) return 0; \ + if( (lv) > MAX_SKILL_LEVEL && (var) > 1 ) { \ + int lv2__ = (lv); (lv) = skill->db[(id)].max; \ + return (var) + ((lv2__-(lv))/2);\ } \ - return var;\ -} -#define skill_glv(lv) min(lv,MAX_SKILL_LEVEL-1) + return (var);\ +} while(0) +#define skill_glv(lv) min((lv),MAX_SKILL_LEVEL-1) // Skill DB int skill_get_hit( uint16 skill_id ) { skill_get (skill->db[skill_id].hit, skill_id); } int skill_get_inf( uint16 skill_id ) { skill_get (skill->db[skill_id].inf, skill_id); } @@ -328,6 +328,8 @@ int skill_calc_heal(struct block_list *src, struct block_list *target, uint16 sk struct map_session_data *tsd = BL_CAST(BL_PC, target); struct status_change* sc; + nullpo_ret(src); + switch( skill_id ) { case BA_APPLEIDUN: #ifdef RENEWAL @@ -372,6 +374,11 @@ int skill_calc_heal(struct block_list *src, struct block_list *target, uint16 sk if( tsd && (skill2_lv = pc->skillheal2_bonus(tsd, skill_id)) ) hp += hp*skill2_lv/100; + sc = status->get_sc(src); + if( sc && sc->count && sc->data[SC_OFFERTORIUM] ) { + if( skill_id == AB_HIGHNESSHEAL || skill_id == AB_CHEAL || skill_id == PR_SANCTUARY || skill_id == AL_HEAL ) + hp += hp * sc->data[SC_OFFERTORIUM]->val2 / 100; + } sc = status->get_sc(target); if( sc && sc->count ) { if( sc->data[SC_CRITICALWOUND] && heal ) // Critical Wound has no effect on offensive heal. [Inkfish] @@ -382,8 +389,8 @@ int skill_calc_heal(struct block_list *src, struct block_list *target, uint16 sk hp += hp * sc->data[SC_HEALPLUS]->val1/100; // Only affects Heal, Sanctuary and PotionPitcher.(like bHealPower) [Inkfish] if( sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 2) hp += hp / 10; - if( sc->data[SC_OFFERTORIUM] && (skill_id == AB_HIGHNESSHEAL || skill_id == AB_CHEAL || skill_id == PR_SANCTUARY || skill_id == AL_HEAL) ) - hp += hp * sc->data[SC_OFFERTORIUM]->val2 / 100; + if ( sc && sc->data[SC_VITALITYACTIVATION] ) + hp = hp * 150 / 100; } #ifdef RENEWAL @@ -424,7 +431,7 @@ int can_copy (struct map_session_data *sd, uint16 skill_id, struct block_list* b return 0; // Couldn't preserve 3rd Class skills except only when using Reproduce skill. [Jobbie] - if( !(sd->sc.data[SC__REPRODUCE]) && (skill_id >= RK_ENCHANTBLADE && skill_id <= SR_RIDEINLIGHTNING) ) + if( !(sd->sc.data[SC__REPRODUCE]) && ((skill_id >= RK_ENCHANTBLADE && skill_id <= SR_RIDEINLIGHTNING) || (skill_id >= KO_YAMIKUMO && skill_id <= OB_AKAITSUKI))) return 0; // Reproduce will only copy skills according on the list. [Jobbie] else if( sd->sc.data[SC__REPRODUCE] && !skill->reproduce_db[skill->get_index(skill_id)] ) @@ -444,7 +451,7 @@ int skillnotok (uint16 skill_id, struct map_session_data *sd) if (idx == 0) return 1; // invalid skill id - if (pc->has_permission(sd, PC_PERM_SKILL_UNCONDITIONAL)) + if (pc_has_permission(sd, PC_PERM_SKILL_UNCONDITIONAL)) return 0; // can do any damn thing they want if( skill_id == AL_TELEPORT && sd->skillitem == skill_id && sd->skillitemlv > 2 ) @@ -460,7 +467,7 @@ int skillnotok (uint16 skill_id, struct map_session_data *sd) return 1; } - if (sd->blockskill[idx] > 0) { + if (sd->blockskill[idx]) { clif->skill_fail(sd, skill_id, USESKILL_FAIL_SKILLINTERVAL, 0); return 1; } @@ -552,11 +559,10 @@ int skillnotok (uint16 skill_id, struct map_session_data *sd) } break; - case WM_SIRCLEOFNATURE: - case WM_SOUND_OF_DESTRUCTION: case SC_MANHOLE: - case WM_LULLABY_DEEPSLEEP: + case WM_SOUND_OF_DESTRUCTION: case WM_SATURDAY_NIGHT_FEVER: + case WM_LULLABY_DEEPSLEEP: if( !map_flag_vs(m) ) { clif->skill_mapinfomessage(sd,2); // This skill uses this msg instead of skill fails. return 1; @@ -639,7 +645,7 @@ struct s_skill_unit_layout* skill_get_unit_layout (uint16 skill_id, uint16 skill /*========================================== * *------------------------------------------*/ -int skill_additional_effect(struct block_list* src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int attack_type, int dmg_lv, unsigned int tick) { +int skill_additional_effect(struct block_list* src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int attack_type, int dmg_lv, int64 tick) { struct map_session_data *sd, *dstsd; struct mob_data *md, *dstmd; struct status_data *sstatus, *tstatus; @@ -700,10 +706,10 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 temp = skill->get_time2(status->sc2skill(type),7); if (sd->addeff[i].flag&ATF_TARGET) - status->change_start(bl,type,rate,7,0,(type == SC_BURNING)?src->id:0,0,temp,0); + status->change_start(src,bl,type,rate,7,0,(type == SC_BURNING)?src->id:0,0,temp,0); if (sd->addeff[i].flag&ATF_SELF) - status->change_start(src,type,rate,7,0,(type == SC_BURNING)?src->id:0,0,temp,0); + status->change_start(src,src,type,rate,7,0,(type == SC_BURNING)?src->id:0,0,temp,0); } } @@ -718,9 +724,9 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 temp = skill->get_time2(status->sc2skill(type),7); if( sd->addeff3[i].target&ATF_TARGET ) - status->change_start(bl,type,sd->addeff3[i].rate,7,0,0,0,temp,0); + status->change_start(src,bl,type,sd->addeff3[i].rate,7,0,0,0,temp,0); if( sd->addeff3[i].target&ATF_SELF ) - status->change_start(src,type,sd->addeff3[i].rate,7,0,0,0,temp,0); + status->change_start(src,src,type,sd->addeff3[i].rate,7,0,0,0,temp,0); } } } @@ -754,15 +760,15 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 // Chance to trigger Taekwon kicks [Dralnu] if(sc && !sc->data[SC_COMBOATTACK]) { if(sc->data[SC_STORMKICK_READY] && - sc_start(src,SC_COMBOATTACK, 15, TK_STORMKICK, + sc_start(NULL,src,SC_COMBOATTACK, 15, TK_STORMKICK, (2000 - 4*sstatus->agi - 2*sstatus->dex))) ; //Stance triggered else if(sc->data[SC_DOWNKICK_READY] && - sc_start(src,SC_COMBOATTACK, 15, TK_DOWNKICK, + sc_start(NULL,src,SC_COMBOATTACK, 15, TK_DOWNKICK, (2000 - 4*sstatus->agi - 2*sstatus->dex))) ; //Stance triggered else if(sc->data[SC_TURNKICK_READY] && - sc_start(src,SC_COMBOATTACK, 15, TK_TURNKICK, + sc_start(NULL,src,SC_COMBOATTACK, 15, TK_TURNKICK, (2000 - 4*sstatus->agi - 2*sstatus->dex))) ; //Stance triggered else if (sc->data[SC_COUNTERKICK_READY]) { //additional chance from SG_FRIEND [Komurka] @@ -771,7 +777,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 rate += rate*sc->data[SC_SKILLRATE_UP]->val2/100; status_change_end(src, SC_SKILLRATE_UP, INVALID_TIMER); } - sc_start2(src, SC_COMBOATTACK, rate, TK_COUNTER, bl->id, + sc_start2(NULL, src, SC_COMBOATTACK, rate, TK_COUNTER, bl->id, (2000 - 4*sstatus->agi - 2*sstatus->dex)); } } @@ -783,11 +789,11 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 struct status_change_entry *sce; // Enchant Poison gives a chance to poison attacked enemies if((sce=sc->data[SC_ENCHANTPOISON])) //Don't use sc_start since chance comes in 1/10000 rate. - status->change_start(bl,SC_POISON,sce->val2, sce->val1,src->id,0,0, + status->change_start(src,bl,SC_POISON,sce->val2, sce->val1,src->id,0,0, skill->get_time2(AS_ENCHANTPOISON,sce->val1),0); // Enchant Deadly Poison gives a chance to deadly poison attacked enemies if((sce=sc->data[SC_EDP])) - sc_start4(bl,SC_DPOISON,sce->val2, sce->val1,src->id,0,0, + sc_start4(src,bl,SC_DPOISON,sce->val2, sce->val1,src->id,0,0, skill->get_time2(ASC_EDP,sce->val1)); } } @@ -795,12 +801,12 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 case SM_BASH: if( sd && skill_lv > 5 && pc->checkskill(sd,SM_FATALBLOW)>0 ) - status->change_start(bl,SC_STUN,500*(skill_lv-5)*sd->status.base_level/50, + status->change_start(src,bl,SC_STUN,500*(skill_lv-5)*sd->status.base_level/50, skill_lv,0,0,0,skill->get_time2(SM_FATALBLOW,skill_lv),0); break; case MER_CRASH: - sc_start(bl,SC_STUN,(6*skill_lv),skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_STUN,(6*skill_lv),skill_lv,skill->get_time2(skill_id,skill_lv)); break; case AS_VENOMKNIFE: @@ -808,14 +814,14 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 skill_lv = pc->checkskill(sd, TF_POISON); case TF_POISON: case AS_SPLASHER: - if(!sc_start2(bl,SC_POISON,(4*skill_lv+10),skill_lv,src->id,skill->get_time2(skill_id,skill_lv)) + if(!sc_start2(src,bl,SC_POISON,(4*skill_lv+10),skill_lv,src->id,skill->get_time2(skill_id,skill_lv)) && sd && skill_id==TF_POISON ) clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); break; case AS_SONICBLOW: - sc_start(bl,SC_STUN,(2*skill_lv+10),skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_STUN,(2*skill_lv+10),skill_lv,skill->get_time2(skill_id,skill_lv)); break; case WZ_FIREPILLAR: @@ -826,14 +832,14 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 #ifndef RENEWAL case WZ_FROSTNOVA: #endif - if( !sc_start(bl,SC_FREEZE,skill_lv*3+35,skill_lv,skill->get_time2(skill_id,skill_lv)) + if( !sc_start(src,bl,SC_FREEZE,skill_lv*3+35,skill_lv,skill->get_time2(skill_id,skill_lv)) && sd && skill_id == MG_FROSTDIVER ) clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); break; #ifdef RENEWAL case WZ_FROSTNOVA: - sc_start(bl,SC_FREEZE,skill_lv*5+33,skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_FREEZE,skill_lv*5+33,skill_lv,skill->get_time2(skill_id,skill_lv)); break; #endif @@ -842,11 +848,11 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 * Storm Gust counter was dropped in renewal **/ #ifdef RENEWAL - sc_start(bl,SC_FREEZE,65-(5*skill_lv),skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_FREEZE,65-(5*skill_lv),skill_lv,skill->get_time2(skill_id,skill_lv)); #else //Tharis pointed out that this is normal freeze chance with a base of 300% if(tsc->sg_counter >= 3 && - sc_start(bl,SC_FREEZE,300,skill_lv,skill->get_time2(skill_id,skill_lv))) + sc_start(src,bl,SC_FREEZE,300,skill_lv,skill->get_time2(skill_id,skill_lv))) tsc->sg_counter = 0; /** * being it only resets on success it'd keep stacking and eventually overflowing on mvps, so we reset at a high value @@ -857,25 +863,25 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 break; case WZ_METEOR: - sc_start(bl,SC_STUN,3*skill_lv,skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_STUN,3*skill_lv,skill_lv,skill->get_time2(skill_id,skill_lv)); break; case WZ_VERMILION: - sc_start(bl,SC_BLIND,4*skill_lv,skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_BLIND,4*skill_lv,skill_lv,skill->get_time2(skill_id,skill_lv)); break; case HT_FREEZINGTRAP: case MA_FREEZINGTRAP: - sc_start(bl,SC_FREEZE,(3*skill_lv+35),skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_FREEZE,(3*skill_lv+35),skill_lv,skill->get_time2(skill_id,skill_lv)); break; case HT_FLASHER: - sc_start(bl,SC_BLIND,(10*skill_lv+30),skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_BLIND,(10*skill_lv+30),skill_lv,skill->get_time2(skill_id,skill_lv)); break; case HT_LANDMINE: case MA_LANDMINE: - sc_start(bl,SC_STUN,(5*skill_lv+30),skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_STUN,(5*skill_lv+30),skill_lv,skill->get_time2(skill_id,skill_lv)); break; case HT_SHOCKWAVE: @@ -884,33 +890,32 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 case HT_SANDMAN: case MA_SANDMAN: - sc_start(bl,SC_SLEEP,(10*skill_lv+40),skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_SLEEP,(10*skill_lv+40),skill_lv,skill->get_time2(skill_id,skill_lv)); break; case TF_SPRINKLESAND: - sc_start(bl,SC_BLIND,20,skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_BLIND,20,skill_lv,skill->get_time2(skill_id,skill_lv)); break; case TF_THROWSTONE: - if( !sc_start(bl,SC_STUN,3,skill_lv,skill->get_time(skill_id,skill_lv)) ) - sc_start(bl,SC_BLIND,3,skill_lv,skill->get_time2(skill_id,skill_lv)); + if( !sc_start(src,bl,SC_STUN,3,skill_lv,skill->get_time(skill_id,skill_lv)) ) + sc_start(src,bl,SC_BLIND,3,skill_lv,skill->get_time2(skill_id,skill_lv)); break; case NPC_DARKCROSS: case CR_HOLYCROSS: - sc_start(bl,SC_BLIND,3*skill_lv,skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_BLIND,3*skill_lv,skill_lv,skill->get_time2(skill_id,skill_lv)); break; case CR_GRANDCROSS: case NPC_GRANDDARKNESS: //Chance to cause blind status vs demon and undead element, but not against players if(!dstsd && (battle->check_undead(tstatus->race,tstatus->def_ele) || tstatus->race == RC_DEMON)) - sc_start(bl,SC_BLIND,100,skill_lv,skill->get_time2(skill_id,skill_lv)); - attack_type |= BF_WEAPON; + sc_start(src,bl,SC_BLIND,100,skill_lv,skill->get_time2(skill_id,skill_lv)); break; case AM_ACIDTERROR: - sc_start2(bl,SC_BLOODING,(skill_lv*3),skill_lv,src->id,skill->get_time2(skill_id,skill_lv)); + sc_start2(src,bl,SC_BLOODING,(skill_lv*3),skill_lv,src->id,skill->get_time2(skill_id,skill_lv)); if (skill->break_equip(bl, EQP_ARMOR, 100*skill->get_time(skill_id,skill_lv), BCT_ENEMY)) clif->emotion(bl,E_OMG); break; @@ -920,7 +925,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 break; case CR_SHIELDCHARGE: - sc_start(bl,SC_STUN,(15+skill_lv*5),skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_STUN,(15+skill_lv*5),skill_lv,skill->get_time2(skill_id,skill_lv)); break; case PA_PRESSURE: @@ -928,28 +933,28 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 break; case RG_RAID: - sc_start(bl,SC_STUN,(10+3*skill_lv),skill_lv,skill->get_time(skill_id,skill_lv)); - sc_start(bl,SC_BLIND,(10+3*skill_lv),skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_STUN,(10+3*skill_lv),skill_lv,skill->get_time(skill_id,skill_lv)); + sc_start(src,bl,SC_BLIND,(10+3*skill_lv),skill_lv,skill->get_time2(skill_id,skill_lv)); #ifdef RENEWAL - sc_start(bl,SC_RAID,100,7,5000); + sc_start(src,bl,SC_RAID,100,7,5000); break; case RG_BACKSTAP: - sc_start(bl,SC_STUN,(5+2*skill_lv),skill_lv,skill->get_time(skill_id,skill_lv)); + sc_start(src,bl,SC_STUN,(5+2*skill_lv),skill_lv,skill->get_time(skill_id,skill_lv)); #endif break; case BA_FROSTJOKER: - sc_start(bl,SC_FREEZE,(15+5*skill_lv),skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_FREEZE,(15+5*skill_lv),skill_lv,skill->get_time2(skill_id,skill_lv)); break; case DC_SCREAM: - sc_start(bl,SC_STUN,(25+5*skill_lv),skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_STUN,(25+5*skill_lv),skill_lv,skill->get_time2(skill_id,skill_lv)); break; case BD_LULLABY: - sc_start(bl,SC_SLEEP,15,skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_SLEEP,15,skill_lv,skill->get_time2(skill_id,skill_lv)); break; case DC_UGLYDANCE: @@ -960,11 +965,11 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 break; case SL_STUN: if (tstatus->size==SZ_MEDIUM) //Only stuns mid-sized mobs. - sc_start(bl,SC_STUN,(30+10*skill_lv),skill_lv,skill->get_time(skill_id,skill_lv)); + sc_start(src,bl,SC_STUN,(30+10*skill_lv),skill_lv,skill->get_time(skill_id,skill_lv)); break; case NPC_PETRIFYATTACK: - sc_start4(bl,status->skill2sc(skill_id),50+10*skill_lv, + sc_start4(src,bl,status->skill2sc(skill_id),50+10*skill_lv, skill_lv,0,0,skill->get_time(skill_id,skill_lv), skill->get_time2(skill_id,skill_lv)); break; @@ -975,14 +980,14 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 case NPC_SILENCEATTACK: case NPC_STUNATTACK: case NPC_HELLPOWER: - sc_start(bl,status->skill2sc(skill_id),50+10*skill_lv,skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,status->skill2sc(skill_id),50+10*skill_lv,skill_lv,skill->get_time2(skill_id,skill_lv)); break; case NPC_ACIDBREATH: case NPC_ICEBREATH: - sc_start(bl,status->skill2sc(skill_id),70,skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,status->skill2sc(skill_id),70,skill_lv,skill->get_time2(skill_id,skill_lv)); break; case NPC_BLEEDING: - sc_start2(bl,SC_BLOODING,(20*skill_lv),skill_lv,src->id,skill->get_time2(skill_id,skill_lv)); + sc_start2(src,bl,SC_BLOODING,(20*skill_lv),skill_lv,src->id,skill->get_time2(skill_id,skill_lv)); break; case NPC_MENTALBREAKER: { @@ -1008,32 +1013,32 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 break; case CH_TIGERFIST: - sc_start(bl,SC_STOP,(10+skill_lv*10),0,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_STOP,(10+skill_lv*10),0,skill->get_time2(skill_id,skill_lv)); break; case LK_SPIRALPIERCE: case ML_SPIRALPIERCE: - sc_start(bl,SC_ANKLESNARE,100,0,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_ANKLESNARE,100,0,skill->get_time2(skill_id,skill_lv)); break; case ST_REJECTSWORD: - sc_start(bl,SC_AUTOCOUNTER,(skill_lv*15),skill_lv,skill->get_time(skill_id,skill_lv)); + sc_start(src,bl,SC_AUTOCOUNTER,(skill_lv*15),skill_lv,skill->get_time(skill_id,skill_lv)); break; case PF_FOGWALL: if (src != bl && !tsc->data[SC_DELUGE]) - sc_start(bl,SC_BLIND,100,skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_BLIND,100,skill_lv,skill->get_time2(skill_id,skill_lv)); break; case LK_HEADCRUSH: //Headcrush has chance of causing Bleeding status, except on demon and undead element if (!(battle->check_undead(tstatus->race, tstatus->def_ele) || tstatus->race == RC_DEMON)) - sc_start2(bl, SC_BLOODING,50, skill_lv, src->id, skill->get_time2(skill_id,skill_lv)); + sc_start2(src, bl, SC_BLOODING,50, skill_lv, src->id, skill->get_time2(skill_id,skill_lv)); break; case LK_JOINTBEAT: if (tsc->jb_flag) { enum sc_type type = status->skill2sc(skill_id); - sc_start4(bl,type,(5*skill_lv+5),skill_lv,tsc->jb_flag&BREAK_FLAGS,src->id,0,skill->get_time2(skill_id,skill_lv)); + sc_start4(src,bl,type,(5*skill_lv+5),skill_lv,tsc->jb_flag&BREAK_FLAGS,src->id,0,skill->get_time2(skill_id,skill_lv)); tsc->jb_flag = 0; } break; @@ -1041,22 +1046,22 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 //Any enemies hit by this skill will receive Stun, Darkness, or external bleeding status ailment with a 5%+5*skill_lv% chance. switch(rnd()%3) { case 0: - sc_start(bl,SC_BLIND,(5+skill_lv*5),skill_lv,skill->get_time2(skill_id,1)); + sc_start(src,bl,SC_BLIND,(5+skill_lv*5),skill_lv,skill->get_time2(skill_id,1)); break; case 1: - sc_start(bl,SC_STUN,(5+skill_lv*5),skill_lv,skill->get_time2(skill_id,2)); + sc_start(src,bl,SC_STUN,(5+skill_lv*5),skill_lv,skill->get_time2(skill_id,2)); break; default: - sc_start2(bl,SC_BLOODING,(5+skill_lv*5),skill_lv,src->id,skill->get_time2(skill_id,3)); + sc_start2(src,bl,SC_BLOODING,(5+skill_lv*5),skill_lv,src->id,skill->get_time2(skill_id,3)); } break; case HW_NAPALMVULCAN: - sc_start(bl,SC_CURSE,5*skill_lv,skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_CURSE,5*skill_lv,skill_lv,skill->get_time2(skill_id,skill_lv)); break; case WS_CARTTERMINATION: // Cart termination - sc_start(bl,SC_STUN,5*skill_lv,skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_STUN,5*skill_lv,skill_lv,skill->get_time2(skill_id,skill_lv)); break; case CR_ACIDDEMONSTRATION: @@ -1064,7 +1069,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 break; case TK_DOWNKICK: - sc_start(bl,SC_STUN,100,skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_STUN,100,skill_lv,skill->get_time2(skill_id,skill_lv)); break; case TK_JUMPKICK: @@ -1081,20 +1086,20 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 case TK_TURNKICK: case MO_BALKYOUNG: //Note: attack_type is passed as BF_WEAPON for the actual target, BF_MISC for the splash-affected mobs. if(attack_type&BF_MISC) //70% base stun chance... - sc_start(bl,SC_STUN,70,skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_STUN,70,skill_lv,skill->get_time2(skill_id,skill_lv)); break; case GS_BULLSEYE: //0.1% coma rate. if(tstatus->race == RC_BRUTE || tstatus->race == RC_DEMIHUMAN) - status->change_start(bl,SC_COMA,10,skill_lv,0,src->id,0,0,0); + status->change_start(src,bl,SC_COMA,10,skill_lv,0,src->id,0,0,0); break; case GS_PIERCINGSHOT: - sc_start2(bl,SC_BLOODING,(skill_lv*3),skill_lv,src->id,skill->get_time2(skill_id,skill_lv)); + sc_start2(src,bl,SC_BLOODING,(skill_lv*3),skill_lv,src->id,skill->get_time2(skill_id,skill_lv)); break; case NJ_HYOUSYOURAKU: - sc_start(bl,SC_FREEZE,(10+10*skill_lv),skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_FREEZE,(10+10*skill_lv),skill_lv,skill->get_time2(skill_id,skill_lv)); break; case GS_FLING: - sc_start(bl,SC_FLING,100, sd?sd->spiritball_old:5,skill->get_time(skill_id,skill_lv)); + sc_start(src,bl,SC_FLING,100, sd?sd->spiritball_old:5,skill->get_time(skill_id,skill_lv)); break; case GS_DISARM: rate = 3*skill_lv; @@ -1104,112 +1109,132 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 clif->skill_nodamage(src,bl,skill_id,skill_lv,1); break; case NPC_EVILLAND: - sc_start(bl,SC_BLIND,5*skill_lv,skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_BLIND,5*skill_lv,skill_lv,skill->get_time2(skill_id,skill_lv)); break; case NPC_HELLJUDGEMENT: - sc_start(bl,SC_CURSE,100,skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_CURSE,100,skill_lv,skill->get_time2(skill_id,skill_lv)); break; case NPC_CRITICALWOUND: - sc_start(bl,SC_CRITICALWOUND,100,skill_lv,skill->get_time2(skill_id,skill_lv)); - break; - case RK_HUNDREDSPEAR: - if( !sd || pc->checkskill(sd,KN_SPEARBOOMERANG) == 0 ) - break; // Spear Boomerang auto cast chance only works if you have mastered Spear Boomerang. - rate = 10 + 3 * skill_lv; - if( rnd()%100 < rate ) - skill->castend_damage_id(src,bl,KN_SPEARBOOMERANG,1,tick,0); + sc_start(src,bl,SC_CRITICALWOUND,100,skill_lv,skill->get_time2(skill_id,skill_lv)); break; case RK_WINDCUTTER: - sc_start(bl,SC_FEAR,3+2*skill_lv,skill_lv,skill->get_time(skill_id,skill_lv)); + sc_start(src,bl,SC_FEAR,3+2*skill_lv,skill_lv,skill->get_time(skill_id,skill_lv)); break; case RK_DRAGONBREATH: - sc_start4(bl,SC_BURNING,5+5*skill_lv,skill_lv,0,src->id,0,skill->get_time(skill_id,skill_lv)); + sc_start4(src,bl,SC_BURNING,15,skill_lv,1000,src->id,0,skill->get_time(skill_id,skill_lv)); break; case RK_DRAGONBREATH_WATER: - sc_start(bl,SC_FROSTMISTY,5+5*skill_lv,skill_lv,skill->get_time(skill_id,skill_lv)); + sc_start4(src,bl,SC_FROSTMISTY,15,skill_lv,1000,src->id,0,skill->get_time(skill_id,skill_lv)); break; case AB_ADORAMUS: if( tsc && !tsc->data[SC_DEC_AGI] ) //Prevent duplicate agi-down effect. - sc_start(bl, SC_ADORAMUS, 100, skill_lv, skill->get_time(skill_id, skill_lv)); + sc_start(src, bl, SC_ADORAMUS, skill_lv * 4 + (sd? sd->status.job_level:50)/2, skill_lv, skill->get_time(skill_id, skill_lv)); break; case WL_CRIMSONROCK: - sc_start(bl, SC_STUN, 40, skill_lv, skill->get_time(skill_id, skill_lv)); + sc_start(src, bl, SC_STUN, 40, skill_lv, skill->get_time(skill_id, skill_lv)); break; case WL_COMET: - sc_start4(bl,SC_BURNING,100,skill_lv,0,src->id,0,skill->get_time2(skill_id,skill_lv)); + sc_start4(src,bl,SC_BURNING,100,skill_lv,0,src->id,0,skill->get_time2(skill_id,skill_lv)); break; case WL_EARTHSTRAIN: - { - // lv 1 & 2 = Strip Helm, lv 3 = Strip Armor, lv 4 = Strip Weapon and lv 5 = Strip Accessory. [malufett] - const int pos[5] = { EQP_HELM, EQP_HELM, EQP_ARMOR, EQP_WEAPON, EQP_ACC }; - skill->strip_equip(bl, pos[skill_lv], 6 * skill_lv + status->get_lv(src) / 4 + status_get_dex(src) / 10, - skill_lv, skill->get_time2(skill_id,skill_lv)); - } + { + int i; + const int pos[5] = { EQP_WEAPON, EQP_HELM, EQP_SHIELD, EQP_ARMOR, EQP_ACC }; + + for( i = 0; i < skill_lv; i++ ) + skill->strip_equip(bl,pos[i], 6 * skill_lv + status->get_lv(src) / 4 + status_get_dex(src) / 10, + skill_lv,skill->get_time2(skill_id,skill_lv)); + } break; case WL_JACKFROST: - sc_start(bl,SC_FREEZE,100,skill_lv,skill->get_time(skill_id,skill_lv)); + sc_start(src,bl,SC_FREEZE,100,skill_lv,skill->get_time(skill_id,skill_lv)); break; case WL_FROSTMISTY: - sc_start(bl,SC_FROSTMISTY,25 + 5 * skill_lv,skill_lv,skill->get_time(skill_id,skill_lv)); + sc_start(src,bl,SC_FROSTMISTY,25 + 5 * skill_lv,skill_lv,skill->get_time(skill_id,skill_lv)); break; case RA_WUGBITE: - sc_start(bl, SC_WUGBITE, (sd ? pc->checkskill(sd,RA_TOOTHOFWUG)*2 : 0), skill_lv, (skill->get_time(skill_id,skill_lv) + (sd ? pc->checkskill(sd,RA_TOOTHOFWUG)*500 : 0)) ); + rate = 50 + 10 * skill_lv + 2 * (sd ? pc->checkskill(sd,RA_TOOTHOFWUG) : 0) - tstatus->agi / 4; + if ( rate < 50 ) + rate = 50; + sc_start(src,bl,SC_WUGBITE, rate, skill_lv, skill->get_time(skill_id, skill_lv) + (sd ? pc->checkskill(sd,RA_TOOTHOFWUG) * 500 : 0)); break; case RA_SENSITIVEKEEN: if( rnd()%100 < 8 * skill_lv ) skill->castend_damage_id(src, bl, RA_WUGBITE, sd ? pc->checkskill(sd, RA_WUGBITE):skill_lv, tick, SD_ANIMATION); break; + case RA_MAGENTATRAP: + case RA_COBALTTRAP: + case RA_MAIZETRAP: + case RA_VERDURETRAP: + if( dstmd && !(dstmd->status.mode&MD_BOSS) ) + sc_start2(src,bl,SC_ARMOR_PROPERTY,100,skill_lv,skill->get_ele(skill_id,skill_lv),skill->get_time2(skill_id,skill_lv)); + break; case RA_FIRINGTRAP: case RA_ICEBOUNDTRAP: - sc_start4(bl, (skill_id == RA_FIRINGTRAP) ? SC_BURNING:SC_FROSTMISTY, 40 + 10 * skill_lv, skill_lv, 0, src->id, 0, skill->get_time2(skill_id, skill_lv)); + sc_start4(src, bl, (skill_id == RA_FIRINGTRAP) ? SC_BURNING:SC_FROSTMISTY, 50 + 10 * skill_lv, skill_lv, 0, src->id, 0, skill->get_time2(skill_id, skill_lv)); break; case NC_PILEBUNKER: - if( rnd()%100 < 5 + 15*skill_lv ) - { //Deactivatable Statuses: Kyrie Eleison, Auto Guard, Steel Body, Assumptio, and Millennium Shield + if( rnd()%100 < 25 + 15 *skill_lv ) { + //Deactivatable Statuses: Kyrie Eleison, Auto Guard, Steel Body, Assumptio, and Millennium Shield status_change_end(bl, SC_KYRIE, INVALID_TIMER); - status_change_end(bl, SC_AUTOGUARD, INVALID_TIMER); - status_change_end(bl, SC_STEELBODY, INVALID_TIMER); status_change_end(bl, SC_ASSUMPTIO, INVALID_TIMER); + status_change_end(bl, SC_STEELBODY, INVALID_TIMER); + status_change_end(bl, SC_GENTLETOUCH_CHANGE, INVALID_TIMER); + status_change_end(bl, SC_GENTLETOUCH_REVITALIZE, INVALID_TIMER); + status_change_end(bl, SC_AUTOGUARD, INVALID_TIMER); + status_change_end(bl, SC_REFLECTSHIELD, INVALID_TIMER); + status_change_end(bl, SC_DEFENDER, INVALID_TIMER); + status_change_end(bl, SC_LG_REFLECTDAMAGE, INVALID_TIMER); + status_change_end(bl, SC_PRESTIGE, INVALID_TIMER); + status_change_end(bl, SC_BANDING, INVALID_TIMER); status_change_end(bl, SC_MILLENNIUMSHIELD, INVALID_TIMER); } break; case NC_FLAMELAUNCHER: - sc_start4(bl, SC_BURNING, 50 + 10 * skill_lv, skill_lv, 0, src->id, 0, skill->get_time2(skill_id, skill_lv)); + sc_start4(src, bl, SC_BURNING, 20 + 10 * skill_lv, skill_lv, 0, src->id, 0, skill->get_time2(skill_id, skill_lv)); break; case NC_COLDSLOWER: - sc_start(bl, SC_FREEZE, 10 * skill_lv, skill_lv, skill->get_time(skill_id, skill_lv)); - sc_start(bl, SC_FROSTMISTY, 20 + 10 * skill_lv, skill_lv, skill->get_time(skill_id, skill_lv)); + sc_start(src, bl, SC_FREEZE, 10 * skill_lv, skill_lv, skill->get_time(skill_id, skill_lv)); + if ( tsc && !tsc->data[SC_FREEZE] ) + sc_start(src, bl, SC_FROSTMISTY, 20 + 10 * skill_lv, skill_lv, skill->get_time2(skill_id, skill_lv)); break; case NC_POWERSWING: - sc_start(bl, SC_STUN, 5*skill_lv, skill_lv, skill->get_time(skill_id, skill_lv)); + // Use flag=2, the stun duration is not vit-reduced. + status->change_start(src, bl, SC_STUN, 5*skill_lv*100, skill_lv, 0, 0, 0, skill->get_time(skill_id, skill_lv), 2); if( rnd()%100 < 5*skill_lv ) skill->castend_damage_id(src, bl, NC_AXEBOOMERANG, pc->checkskill(sd, NC_AXEBOOMERANG), tick, 1); break; case NC_MAGMA_ERUPTION: - sc_start4(bl, SC_BURNING, 10 * skill_lv, skill_lv, 0, src->id, 0, skill->get_time2(skill_id, skill_lv)); - sc_start(bl, SC_STUN, 10 * skill_lv, skill_lv, skill->get_time(skill_id, skill_lv)); + sc_start4(src, bl, SC_BURNING, 10 * skill_lv, skill_lv, 0, src->id, 0, skill->get_time2(skill_id, skill_lv)); + sc_start(src, bl, SC_STUN, 10 * skill_lv, skill_lv, skill->get_time(skill_id, skill_lv)); break; case GC_WEAPONCRUSH: skill->castend_nodamage_id(src,bl,skill_id,skill_lv,tick,BCT_ENEMY); break; case GC_DARKCROW: - sc_start(bl, SC_DARKCROW, 10 * skill_lv, skill_lv, skill->get_time(skill_id, skill_lv)); + sc_start(src, bl, SC_DARKCROW, 100, skill_lv, skill->get_time(skill_id, skill_lv)); break; case LG_SHIELDPRESS: - sc_start(bl, SC_STUN, 30 + 8 * skill_lv, skill_lv, skill->get_time(skill_id,skill_lv)); + rate = 30 + 8 * skill_lv + sstatus->dex / 10 + (sd? sd->status.job_level:0) / 4; + sc_start(src, bl, SC_STUN, rate, skill_lv, skill->get_time(skill_id,skill_lv)); break; case LG_PINPOINTATTACK: - rate = 30 + (((5 * (sd?pc->checkskill(sd,LG_PINPOINTATTACK):skill_lv)) + (sstatus->agi + status->get_lv(src))) / 10); + rate = 30 + 5 * (sd ? pc->checkskill(sd,LG_PINPOINTATTACK) : 1) + (sstatus->agi + status->get_lv(src)) / 10; switch( skill_lv ) { case 1: - sc_start2(bl,SC_BLOODING,rate,skill_lv,src->id,skill->get_time(skill_id,skill_lv)); + sc_start(src, bl,SC_BLOODING,rate,skill_lv,skill->get_time(skill_id,skill_lv)); break; case 2: - if( dstsd && dstsd->spiritball && rnd()%100 < rate ) - pc->delspiritball(dstsd, dstsd->spiritball, 0); + skill->break_equip(bl, EQP_HELM, rate*100, BCT_ENEMY); break; - default: - skill->break_equip(bl,(skill_lv == 3) ? EQP_SHIELD : (skill_lv == 4) ? EQP_ARMOR : EQP_WEAPON,rate * 100,BCT_ENEMY); + case 3: + skill->break_equip(bl, EQP_SHIELD, rate*100, BCT_ENEMY); + break; + case 4: + skill->break_equip(bl, EQP_ARMOR, rate*100, BCT_ENEMY); + break; + case 5: + skill->break_equip(bl, EQP_WEAPON, rate*100, BCT_ENEMY); break; } break; @@ -1218,135 +1243,103 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 if( rnd()%100 < rate && dstsd ) // Uses skill->addtimerskill to avoid damage and setsit packet overlaping. Officially clif->setsit is received about 500 ms after damage packet. skill->addtimerskill(src,tick+500,bl->id,0,0,skill_id,skill_lv,BF_WEAPON,0); else if( dstmd && !is_boss(bl) ) - sc_start(bl,SC_STOP,100,skill_lv,skill->get_time(skill_id,skill_lv)); + sc_start(src, bl,SC_STOP,100,skill_lv,skill->get_time(skill_id,skill_lv)); break; case LG_RAYOFGENESIS: // 50% chance to cause Blind on Undead and Demon monsters. if ( battle->check_undead(tstatus->race, tstatus->def_ele) || tstatus->race == RC_DEMON ) - sc_start(bl, SC_BLIND,50, skill_lv, skill->get_time(skill_id,skill_lv)); + sc_start(src, bl, SC_BLIND,50, skill_lv, skill->get_time(skill_id,skill_lv)); break; case LG_EARTHDRIVE: - skill->break_equip(src, EQP_SHIELD, 500, BCT_SELF); - sc_start(bl, SC_EARTHDRIVE, 100, skill_lv, skill->get_time(skill_id, skill_lv)); + skill->break_equip(src, EQP_SHIELD, 100 * skill_lv, BCT_SELF); + sc_start(src, bl, SC_EARTHDRIVE, 100, skill_lv, skill->get_time(skill_id, skill_lv)); break; case SR_DRAGONCOMBO: - sc_start(bl, SC_STUN, 1 + skill_lv, skill_lv, skill->get_time(skill_id, skill_lv)); + sc_start(src, bl, SC_STUN, 1 + skill_lv, skill_lv, skill->get_time(skill_id, skill_lv)); break; case SR_FALLENEMPIRE: - sc_start(bl, SC_STOP, 100, skill_lv, skill->get_time(skill_id, skill_lv)); + sc_start(src, bl, SC_STOP, 100, skill_lv, skill->get_time(skill_id, skill_lv)); break; case SR_WINDMILL: if( dstsd ) skill->addtimerskill(src,tick+status_get_amotion(src),bl->id,0,0,skill_id,skill_lv,BF_WEAPON,0); else if( dstmd && !is_boss(bl) ) - sc_start(bl, SC_STUN, 100, skill_lv, 1000 + 1000 * (rnd() %3)); + sc_start(src, bl, SC_STUN, 100, skill_lv, 1000 + 1000 * (rnd() %3)); break; case SR_GENTLETOUCH_QUIET: // [(Skill Level x 5) + (Caster?s DEX + Caster?s Base Level) / 10] - sc_start(bl, SC_SILENCE, 5 * skill_lv + (sstatus->dex + status->get_lv(src)) / 10, skill_lv, skill->get_time(skill_id, skill_lv)); + sc_start(src, bl, SC_SILENCE, 5 * skill_lv + (sstatus->dex + status->get_lv(src)) / 10, skill_lv, skill->get_time(skill_id, skill_lv)); break; case SR_EARTHSHAKER: - sc_start(bl,SC_STUN, 25 + 5 * skill_lv,skill_lv,skill->get_time(skill_id,skill_lv)); + sc_start(src, bl,SC_STUN, 25 + 5 * skill_lv,skill_lv,skill->get_time(skill_id,skill_lv)); break; case SR_HOWLINGOFLION: - sc_start(bl, SC_FEAR, 5 + 5 * skill_lv, skill_lv, skill->get_time(skill_id, skill_lv)); - break; - case WM_SOUND_OF_DESTRUCTION: - if( rnd()%100 < 5 + 5 * skill_lv ) { // Temporarly Check Until We Get the Official Formula - status_change_end(bl, SC_DANCING, INVALID_TIMER); - status_change_end(bl, SC_RICHMANKIM, INVALID_TIMER); - status_change_end(bl, SC_ETERNALCHAOS, INVALID_TIMER); - status_change_end(bl, SC_DRUMBATTLE, INVALID_TIMER); - status_change_end(bl, SC_NIBELUNGEN, INVALID_TIMER); - status_change_end(bl, SC_INTOABYSS, INVALID_TIMER); - status_change_end(bl, SC_SIEGFRIED, INVALID_TIMER); - status_change_end(bl, SC_WHISTLE, INVALID_TIMER); - status_change_end(bl, SC_ASSNCROS, INVALID_TIMER); - status_change_end(bl, SC_POEMBRAGI, INVALID_TIMER); - status_change_end(bl, SC_APPLEIDUN, INVALID_TIMER); - status_change_end(bl, SC_HUMMING, INVALID_TIMER); - status_change_end(bl, SC_FORTUNE, INVALID_TIMER); - status_change_end(bl, SC_SERVICEFORYOU, INVALID_TIMER); - status_change_end(bl, SC_LONGING, INVALID_TIMER); - status_change_end(bl, SC_SWING, INVALID_TIMER); - status_change_end(bl, SC_SYMPHONY_LOVE, INVALID_TIMER); - status_change_end(bl, SC_MOONLIT_SERENADE, INVALID_TIMER); - status_change_end(bl, SC_RUSH_WINDMILL, INVALID_TIMER); - status_change_end(bl, SC_ECHOSONG, INVALID_TIMER); - status_change_end(bl, SC_HARMONIZE, INVALID_TIMER); - status_change_end(bl, SC_DC_WINKCHARM, INVALID_TIMER); - status_change_end(bl, SC_SONG_OF_MANA, INVALID_TIMER); - status_change_end(bl, SC_DANCE_WITH_WUG, INVALID_TIMER); - status_change_end(bl, SC_LERADS_DEW, INVALID_TIMER); - status_change_end(bl, SC_MELODYOFSINK, INVALID_TIMER); - status_change_end(bl, SC_BEYOND_OF_WARCRY, INVALID_TIMER); - status_change_end(bl, SC_UNLIMITED_HUMMING_VOICE, INVALID_TIMER); - } + sc_start(src, bl, SC_FEAR, 5 + 5 * skill_lv, skill_lv, skill->get_time(skill_id, skill_lv)); break; case SO_EARTHGRAVE: - sc_start2(bl, SC_BLOODING, 5 * skill_lv, skill_lv, src->id, skill->get_time2(skill_id, skill_lv)); // Need official rate. [LimitLine] + sc_start2(src, bl, SC_BLOODING, 5 * skill_lv, skill_lv, src->id, skill->get_time2(skill_id, skill_lv)); // Need official rate. [LimitLine] break; case SO_DIAMONDDUST: rate = 5 + 5 * skill_lv; if( sc && sc->data[SC_COOLER_OPTION] ) - rate += rate * sc->data[SC_COOLER_OPTION]->val2 / 100; - sc_start(bl, SC_COLD, rate, skill_lv, skill->get_time2(skill_id, skill_lv)); + rate += sc->data[SC_COOLER_OPTION]->val3 / 5; + sc_start(src, bl, SC_COLD, rate, skill_lv, skill->get_time2(skill_id, skill_lv)); break; case SO_VARETYR_SPEAR: - sc_start(bl, SC_STUN, 5 + 5 * skill_lv, skill_lv, skill->get_time2(skill_id, skill_lv)); + sc_start(src, bl, SC_STUN, 5 + 5 * skill_lv, skill_lv, skill->get_time(skill_id, skill_lv)); break; case GN_SLINGITEM_RANGEMELEEATK: if( sd ) { switch( sd->itemid ) { // Starting SCs here instead of do it in skill->additional_effect to simplify the code. - case 13261: - sc_start(bl, SC_STUN, 100, skill_lv, skill->get_time2(GN_SLINGITEM, skill_lv)); - sc_start2(bl, SC_BLOODING, 100, skill_lv, src->id, skill->get_time2(GN_SLINGITEM, skill_lv)); + case ITEMID_COCONUT_BOMB: + sc_start(src, bl, SC_STUN, 100, skill_lv, 5000); // 5 seconds until I get official + sc_start(src, bl, SC_BLOODING, 100, skill_lv, 10000); break; - case 13262: - sc_start(bl, SC_MELON_BOMB, 100, skill_lv, skill->get_time(GN_SLINGITEM, skill_lv)); // Reduces ASPD and moviment speed + case ITEMID_MELON_BOMB: + sc_start(src, bl, SC_MELON_BOMB, 100, skill_lv, 60000); // Reduces ASPD and moviment speed break; - case 13264: - sc_start(bl, SC_BANANA_BOMB, 100, skill_lv, skill->get_time(GN_SLINGITEM, skill_lv)); // Reduces LUK ??Needed confirm it, may be it's bugged in kRORE? - sc_start(bl, SC_BANANA_BOMB_SITDOWN_POSTDELAY, 75, skill_lv, skill->get_time(GN_SLINGITEM_RANGEMELEEATK,skill_lv)); // Sitdown for 3 seconds. + case ITEMID_BANANA_BOMB: + sc_start(src, bl, SC_BANANA_BOMB, 100, skill_lv, 60000); // Reduces LUK? Needed confirm it, may be it's bugged in kRORE? + sc_start(src, bl, SC_BANANA_BOMB_SITDOWN_POSTDELAY, (sd? sd->status.job_level:0) + sstatus->dex / 6 + tstatus->agi / 4 - tstatus->luk / 5 - status->get_lv(bl) + status->get_lv(src), skill_lv, 1000); // Sitdown for 3 seconds. break; } sd->itemid = -1; } break; case GN_HELLS_PLANT_ATK: - sc_start(bl, SC_STUN, 5 + 5 * skill_lv, skill_lv, skill->get_time2(skill_id, skill_lv)); - sc_start2(bl, SC_BLOODING, 20 + 10 * skill_lv, skill_lv, src->id,skill->get_time2(skill_id, skill_lv)); + sc_start(src, bl, SC_STUN, 20 + 10 * skill_lv, skill_lv, skill->get_time2(skill_id, skill_lv)); + sc_start2(src, bl, SC_BLOODING, 5 + 5 * skill_lv, skill_lv, src->id,skill->get_time2(skill_id, skill_lv)); break; case EL_WIND_SLASH: // Non confirmed rate. - sc_start2(bl, SC_BLOODING, 25, skill_lv, src->id, skill->get_time(skill_id,skill_lv)); + sc_start2(src, bl, SC_BLOODING, 25, skill_lv, src->id, skill->get_time(skill_id,skill_lv)); break; case EL_STONE_HAMMER: rate = 10 * skill_lv; - sc_start(bl, SC_STUN, rate, skill_lv, skill->get_time(skill_id,skill_lv)); + sc_start(src, bl, SC_STUN, rate, skill_lv, skill->get_time(skill_id,skill_lv)); break; case EL_ROCK_CRUSHER: case EL_ROCK_CRUSHER_ATK: - sc_start(bl,status->skill2sc(skill_id),50,skill_lv,skill->get_time(EL_ROCK_CRUSHER,skill_lv)); + sc_start(src, bl,status->skill2sc(skill_id),50,skill_lv,skill->get_time(EL_ROCK_CRUSHER,skill_lv)); break; case EL_TYPOON_MIS: - sc_start(bl,SC_SILENCE,10*skill_lv,skill_lv,skill->get_time(skill_id,skill_lv)); + sc_start(src, bl,SC_SILENCE,10*skill_lv,skill_lv,skill->get_time(skill_id,skill_lv)); break; case KO_JYUMONJIKIRI: - sc_start(bl,SC_KO_JYUMONJIKIRI,90,skill_lv,skill->get_time(skill_id,skill_lv)); + sc_start(src, bl,SC_KO_JYUMONJIKIRI,90,skill_lv,skill->get_time(skill_id,skill_lv)); break; case KO_MAKIBISHI: - sc_start(bl, SC_STUN, 10 * skill_lv, skill_lv, 1000 * (skill_lv / 2 + 2)); + sc_start(src, bl, SC_STUN, 10 * skill_lv, skill_lv, 1000 * (skill_lv / 2 + 2)); break; case MH_LAVA_SLIDE: - if (tsc && !tsc->data[SC_BURNING]) sc_start4(bl, SC_BURNING, 10 * skill_lv, skill_lv, 0, src->id, 0, skill->get_time(skill_id, skill_lv)); + if (tsc && !tsc->data[SC_BURNING]) sc_start4(src, bl, SC_BURNING, 10 * skill_lv, skill_lv, 0, src->id, 0, skill->get_time(skill_id, skill_lv)); break; case MH_STAHL_HORN: - sc_start(bl, SC_STUN, (20 + 4 * (skill_lv-1)), skill_lv, skill->get_time(skill_id, skill_lv)); + sc_start(src, bl, SC_STUN, (20 + 4 * (skill_lv-1)), skill_lv, skill->get_time(skill_id, skill_lv)); break; case MH_NEEDLE_OF_PARALYZE: - sc_start(bl, SC_NEEDLE_OF_PARALYZE, 40 + (5*skill_lv), skill_lv, skill->get_time(skill_id, skill_lv)); + sc_start(src, bl, SC_NEEDLE_OF_PARALYZE, 40 + (5*skill_lv), skill_lv, skill->get_time(skill_id, skill_lv)); break; case GN_ILLUSIONDOPING: - if( sc_start(bl, SC_ILLUSIONDOPING, 10 * skill_lv, skill_lv, skill->get_time(skill_id, skill_lv)) ) //custom rate. - sc_start(bl, SC_ILLUSION, 100, skill_lv, skill->get_time(skill_id, skill_lv)); + if( sc_start(src, bl, SC_ILLUSIONDOPING, 10 * skill_lv, skill_lv, skill->get_time(skill_id, skill_lv)) ) //custom rate. + sc_start(src, bl, SC_ILLUSION, 100, skill_lv, skill->get_time(skill_id, skill_lv)); break; } @@ -1356,14 +1349,14 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 src = sd?&sd->bl:src; } - if( attack_type&BF_WEAPON ) { + if( attack_type&BF_WEAPON && skill_id != CR_REFLECTSHIELD ) { // Coma, Breaking Equipment if( sd && sd->special_state.bonus_coma ) { rate = sd->weapon_coma_ele[tstatus->def_ele]; rate += sd->weapon_coma_race[tstatus->race]; rate += sd->weapon_coma_race[tstatus->mode&MD_BOSS?RC_BOSS:RC_NONBOSS]; if (rate) - status->change_start(bl, SC_COMA, rate, 0, 0, src->id, 0, 0, 0); + status->change_start(src, bl, SC_COMA, rate, 0, 0, src->id, 0, 0, 0); } if( sd && battle_config.equip_self_break_rate ) { // Self weapon breaking @@ -1434,7 +1427,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 if( sd && !status->isdead(bl) && sd->autospell[0].id ) { struct block_list *tbl; struct unit_data *ud; - int i, skill_lv, type, notok; + int i, auto_skill_lv, type, notok; for (i = 0; i < ARRAYLENGTH(sd->autospell) && sd->autospell[i].id; i++) { @@ -1452,8 +1445,8 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 if ( notok ) continue; - skill_lv = sd->autospell[i].lv?sd->autospell[i].lv:1; - if (skill_lv < 0) skill_lv = 1+rnd()%(-skill_lv); + auto_skill_lv = sd->autospell[i].lv?sd->autospell[i].lv:1; + if (auto_skill_lv < 0) auto_skill_lv = 1+rnd()%(-auto_skill_lv); rate = (!sd->state.arrow_atk) ? sd->autospell[i].rate : sd->autospell[i].rate / 2; @@ -1466,18 +1459,18 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 int maxcount = 0; if( !(BL_PC&battle_config.skill_reiteration) && skill->get_unit_flag(temp)&UF_NOREITERATION && - skill->check_unit_range(src,tbl->x,tbl->y,temp,skill_lv) + skill->check_unit_range(src,tbl->x,tbl->y,temp,auto_skill_lv) ) { continue; } if( BL_PC&battle_config.skill_nofootset && skill->get_unit_flag(temp)&UF_NOFOOTSET && - skill->check_unit_range2(src,tbl->x,tbl->y,temp,skill_lv) + skill->check_unit_range2(src,tbl->x,tbl->y,temp,auto_skill_lv) ) { continue; } if( BL_PC&battle_config.land_skill_limit && - (maxcount = skill->get_maxcount(temp, skill_lv)) > 0 + (maxcount = skill->get_maxcount(temp, auto_skill_lv)) > 0 ) { int v; for(v=0;v<MAX_SKILLUNITGROUP && sd->ud.skillunit[v] && maxcount;v++) { @@ -1490,7 +1483,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 } } if( battle_config.autospell_check_range && - !battle->check_range(src, tbl, skill->get_range2(src, temp,skill_lv) + (temp == RG_CLOSECONFINE?0:1)) ) + !battle->check_range(src, tbl, skill->get_range2(src, temp,auto_skill_lv) + (temp == RG_CLOSECONFINE?0:1)) ) continue; if (temp == AS_SONICBLOW) @@ -1499,24 +1492,24 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 type = CAST_GROUND; sd->state.autocast = 1; - skill->consume_requirement(sd,temp,skill_lv,1); + skill->consume_requirement(sd,temp,auto_skill_lv,1); skill->toggle_magicpower(src, temp); switch (type) { case CAST_GROUND: - skill->castend_pos2(src, tbl->x, tbl->y, temp, skill_lv, tick, 0); + skill->castend_pos2(src, tbl->x, tbl->y, temp, auto_skill_lv, tick, 0); break; case CAST_NODAMAGE: - skill->castend_nodamage_id(src, tbl, temp, skill_lv, tick, 0); + skill->castend_nodamage_id(src, tbl, temp, auto_skill_lv, tick, 0); break; case CAST_DAMAGE: - skill->castend_damage_id(src, tbl, temp, skill_lv, tick, 0); + skill->castend_damage_id(src, tbl, temp, auto_skill_lv, tick, 0); break; } sd->state.autocast = 0; //Set canact delay. [Skotlex] ud = unit->bl2ud(src); if (ud) { - rate = skill->delay_fix(src, temp, skill_lv); + rate = skill->delay_fix(src, temp, auto_skill_lv); if (DIFF_TICK(ud->canact_tick, tick + rate) < 0){ ud->canact_tick = tick+rate; if ( battle_config.display_status_timers && sd ) @@ -1569,7 +1562,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 return 0; } -int skill_onskillusage(struct map_session_data *sd, struct block_list *bl, uint16 skill_id, unsigned int tick) { +int skill_onskillusage(struct map_session_data *sd, struct block_list *bl, uint16 skill_id, int64 tick) { int temp, skill_lv, i, type, notok; struct block_list *tbl; @@ -1667,7 +1660,7 @@ int skill_onskillusage(struct map_session_data *sd, struct block_list *bl, uint1 * type of skills, so not every instance of skill->additional_effect needs a call * to this one. */ -int skill_counter_additional_effect(struct block_list* src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int attack_type, unsigned int tick) { +int skill_counter_additional_effect(struct block_list* src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int attack_type, int64 tick) { int rate; struct map_session_data *sd=NULL; struct map_session_data *dstsd=NULL; @@ -1700,19 +1693,19 @@ int skill_counter_additional_effect(struct block_list* src, struct block_list *b time = skill->get_time2(status->sc2skill(type),7); if (dstsd->addeff2[i].flag&ATF_TARGET) - status->change_start(src,type,rate,7,0,0,0,time,0); + status->change_start(bl,src,type,rate,7,0,0,0,time,0); if (dstsd->addeff2[i].flag&ATF_SELF && !status->isdead(bl)) - status->change_start(bl,type,rate,7,0,0,0,time,0); + status->change_start(bl,bl,type,rate,7,0,0,0,time,0); } } switch(skill_id){ case MO_EXTREMITYFIST: - sc_start(src,SC_EXTREMITYFIST,100,skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,src,SC_EXTREMITYFIST,100,skill_lv,skill->get_time2(skill_id,skill_lv)); break; case GS_FULLBUSTER: - sc_start(src,SC_BLIND,2*skill_lv,skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,src,SC_BLIND,2*skill_lv,skill_lv,skill->get_time2(skill_id,skill_lv)); break; case HFLI_SBR44: //[orn] case HVAN_EXPLOSION: @@ -1731,7 +1724,7 @@ int skill_counter_additional_effect(struct block_list* src, struct block_list *b if( sd && (sd->class_&MAPID_UPPERMASK) == MAPID_STAR_GLADIATOR && rnd()%10000 < battle_config.sg_miracle_skill_ratio) //SG_MIRACLE [Komurka] - sc_start(src,SC_MIRACLE,100,1,battle_config.sg_miracle_skill_duration); + sc_start(src,src,SC_MIRACLE,100,1,battle_config.sg_miracle_skill_duration); if( sd && skill_id && attack_type&BF_MAGIC && status->isdead(bl) && !(skill->get_inf(skill_id)&(INF_GROUND_SKILL|INF_SELF_SKILL)) @@ -1779,7 +1772,7 @@ int skill_counter_additional_effect(struct block_list* src, struct block_list *b if(dstsd && !status->isdead(bl) && dstsd->autospell2[0].id && !(skill_id && skill->get_nk(skill_id)&NK_NO_DAMAGE)) { struct block_list *tbl; struct unit_data *ud; - int i, skill_id, skill_lv, rate, type, notok; + int i, auto_skill_id, auto_skill_lv, type, notok; for (i = 0; i < ARRAYLENGTH(dstsd->autospell2) && dstsd->autospell2[i].id; i++) { @@ -1788,16 +1781,16 @@ int skill_counter_additional_effect(struct block_list* src, struct block_list *b dstsd->autospell2[i].flag&attack_type&BF_SKILLMASK)) continue; // one or more trigger conditions were not fulfilled - skill_id = (dstsd->autospell2[i].id > 0) ? dstsd->autospell2[i].id : -dstsd->autospell2[i].id; - skill_lv = dstsd->autospell2[i].lv?dstsd->autospell2[i].lv:1; - if (skill_lv < 0) skill_lv = 1+rnd()%(-skill_lv); + auto_skill_id = (dstsd->autospell2[i].id > 0) ? dstsd->autospell2[i].id : -dstsd->autospell2[i].id; + auto_skill_lv = dstsd->autospell2[i].lv?dstsd->autospell2[i].lv:1; + if (auto_skill_lv < 0) auto_skill_lv = 1+rnd()%(-auto_skill_lv); rate = dstsd->autospell2[i].rate; if (attack_type&BF_LONG) rate>>=1; dstsd->state.autocast = 1; - notok = skill->not_ok(skill_id, dstsd); + notok = skill->not_ok(auto_skill_id, dstsd); dstsd->state.autocast = 0; if ( notok ) @@ -1808,26 +1801,26 @@ int skill_counter_additional_effect(struct block_list* src, struct block_list *b tbl = (dstsd->autospell2[i].id < 0) ? bl : src; - if( (type = skill->get_casttype(skill_id)) == CAST_GROUND ) { + if( (type = skill->get_casttype(auto_skill_id)) == CAST_GROUND ) { int maxcount = 0; if( !(BL_PC&battle_config.skill_reiteration) && - skill->get_unit_flag(skill_id)&UF_NOREITERATION && - skill->check_unit_range(bl,tbl->x,tbl->y,skill_id,skill_lv) + skill->get_unit_flag(auto_skill_id)&UF_NOREITERATION && + skill->check_unit_range(bl,tbl->x,tbl->y,auto_skill_id,auto_skill_lv) ) { continue; } if( BL_PC&battle_config.skill_nofootset && - skill->get_unit_flag(skill_id)&UF_NOFOOTSET && - skill->check_unit_range2(bl,tbl->x,tbl->y,skill_id,skill_lv) + skill->get_unit_flag(auto_skill_id)&UF_NOFOOTSET && + skill->check_unit_range2(bl,tbl->x,tbl->y,auto_skill_id,auto_skill_lv) ) { continue; } if( BL_PC&battle_config.land_skill_limit && - (maxcount = skill->get_maxcount(skill_id, skill_lv)) > 0 + (maxcount = skill->get_maxcount(auto_skill_id, auto_skill_lv)) > 0 ) { int v; for(v=0;v<MAX_SKILLUNITGROUP && dstsd->ud.skillunit[v] && maxcount;v++) { - if(dstsd->ud.skillunit[v]->skill_id == skill_id) + if(dstsd->ud.skillunit[v]->skill_id == auto_skill_id) maxcount--; } if( maxcount == 0 ) { @@ -1836,27 +1829,27 @@ int skill_counter_additional_effect(struct block_list* src, struct block_list *b } } - if( !battle->check_range(src, tbl, skill->get_range2(src, skill_id,skill_lv) + (skill_id == RG_CLOSECONFINE?0:1)) && battle_config.autospell_check_range ) + if( !battle->check_range(src, tbl, skill->get_range2(src, auto_skill_id,auto_skill_lv) + (auto_skill_id == RG_CLOSECONFINE?0:1)) && battle_config.autospell_check_range ) continue; dstsd->state.autocast = 1; - skill->consume_requirement(dstsd,skill_id,skill_lv,1); + skill->consume_requirement(dstsd,auto_skill_id,auto_skill_lv,1); switch (type) { case CAST_GROUND: - skill->castend_pos2(bl, tbl->x, tbl->y, skill_id, skill_lv, tick, 0); + skill->castend_pos2(bl, tbl->x, tbl->y, auto_skill_id, auto_skill_lv, tick, 0); break; case CAST_NODAMAGE: - skill->castend_nodamage_id(bl, tbl, skill_id, skill_lv, tick, 0); + skill->castend_nodamage_id(bl, tbl, auto_skill_id, auto_skill_lv, tick, 0); break; case CAST_DAMAGE: - skill->castend_damage_id(bl, tbl, skill_id, skill_lv, tick, 0); + skill->castend_damage_id(bl, tbl, auto_skill_id, auto_skill_lv, tick, 0); break; } dstsd->state.autocast = 0; //Set canact delay. [Skotlex] ud = unit->bl2ud(bl); if (ud) { - rate = skill->delay_fix(bl, skill_id, skill_lv); + rate = skill->delay_fix(bl, auto_skill_id, auto_skill_lv); if (DIFF_TICK(ud->canact_tick, tick + rate) < 0){ ud->canact_tick = tick+rate; if ( battle_config.display_status_timers && dstsd ) @@ -1936,7 +1929,7 @@ int skill_break_equip (struct block_list *bl, unsigned short where, int rate, in else if (rnd()%10000 >= rate) where&=~where_list[i]; else if (!sd && !(status_get_mode(bl)&MD_BOSS)) //Cause Strip effect. - sc_start(bl,scatk[i],100,0,skill->get_time(status->sc2skill(scatk[i]),1)); + sc_start(bl,bl,scatk[i],100,0,skill->get_time(status->sc2skill(scatk[i]),1)); } } if (!where) //Nothing to break. @@ -2001,7 +1994,7 @@ int skill_strip_equip(struct block_list *bl, unsigned short where, int rate, int if (!where) return 0; for (i = 0; i < ARRAYLENGTH(pos); i++) { - if (where&pos[i] && !sc_start(bl, sc_atk[i], 100, lv, time)) + if (where&pos[i] && !sc_start(bl, bl, sc_atk[i], 100, lv, time)) where&=~pos[i]; } return where?1:0; @@ -2043,7 +2036,7 @@ int skill_blown(struct block_list* src, struct block_list* target, int count, in break; case BL_SKILL: su = (struct skill_unit *)target; - if( su && su->group && su->group->unit_id == UNT_ANKLESNARE ) + if( su && su->group && (su->group->unit_id == UNT_ANKLESNARE || su->group->unit_id == UNT_REVERBERATION)) return 0; // ankle snare cannot be knocked back break; } @@ -2109,15 +2102,15 @@ int skill_magic_reflect(struct block_list* src, struct block_list* bl, int type) * flag&0x2000 is used to signal that the skill_lv should be passed as -1 to the * client (causes player characters to not scream skill name) *-------------------------------------------------------------------------*/ -int skill_attack (int attack_type, struct block_list* src, struct block_list *dsrc, struct block_list *bl, uint16 skill_id, uint16 skill_lv, unsigned int tick, int flag) { +int skill_attack(int attack_type, struct block_list* src, struct block_list *dsrc, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag) { struct Damage dmg; struct status_data *sstatus, *tstatus; struct status_change *sc; struct map_session_data *sd, *tsd; int type; int64 damage; - int8 rmdamage=0;//magic reflected - bool additional_effects = true; + bool rmdamage = false;//magic reflected + bool additional_effects = true, shadow_flag = false; if(skill_id > 0 && !skill_lv) return 0; @@ -2173,7 +2166,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds if( (dmg.damage || dmg.damage2) && (type = skill->magic_reflect(src, bl, src==dsrc)) ) { //Magic reflection, switch caster/target struct block_list *tbl = bl; - rmdamage = 1; + rmdamage = true; bl = src; src = tbl; dsrc = tbl; @@ -2184,11 +2177,12 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds sc = NULL; //Don't need it. /* bugreport:2564 flag&2 disables double casting trigger */ flag |= 2; - + /* bugreport:7859 magical reflect'd zeroes blewcount */ + dmg.blewcount = 0; //Spirit of Wizard blocks Kaite's reflection if( type == 2 && sc && sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_WIZARD ) { //Consume one Fragment per hit of the casted skill? [Skotlex] - type = tsd?pc->search_inventory (tsd, 7321):0; + type = tsd?pc->search_inventory(tsd, ITEMID_FRAGMENT_OF_CRYSTAL):0; if (type >= 0) { if ( tsd ) pc->delitem(tsd, type, 1, 0, 1, LOG_TYPE_CONSUME); dmg.damage = dmg.damage2 = 0; @@ -2275,7 +2269,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds } if(sd) { - int flag = 0; //Used to signal if this skill can be combo'ed later on. + int combo = 0; //Used to signal if this skill can be combo'ed later on. struct status_change_entry *sce; if ((sce = sd->sc.data[SC_COMBOATTACK])) {//End combo state after skill is invoked. [Skotlex] switch (skill_id) { @@ -2301,29 +2295,29 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds switch(skill_id) { case MO_TRIPLEATTACK: if (pc->checkskill(sd, MO_CHAINCOMBO) > 0 || pc->checkskill(sd, SR_DRAGONCOMBO) > 0) - flag=1; + combo=1; break; case MO_CHAINCOMBO: if(pc->checkskill(sd, MO_COMBOFINISH) > 0 && sd->spiritball > 0) - flag=1; + combo=1; break; case MO_COMBOFINISH: if (sd->status.party_id>0) //bonus from SG_FRIEND [Komurka] party->skill_check(sd, sd->status.party_id, MO_COMBOFINISH, skill_lv); if (pc->checkskill(sd, CH_TIGERFIST) > 0 && sd->spiritball > 0) - flag=1; + combo=1; case CH_TIGERFIST: - if (!flag && pc->checkskill(sd, CH_CHAINCRUSH) > 0 && sd->spiritball > 1) - flag=1; + if (!combo && pc->checkskill(sd, CH_CHAINCRUSH) > 0 && sd->spiritball > 1) + combo=1; case CH_CHAINCRUSH: - if (!flag && pc->checkskill(sd, MO_EXTREMITYFIST) > 0 && sd->spiritball > 0 && sd->sc.data[SC_EXPLOSIONSPIRITS]) - flag=1; + if (!combo && pc->checkskill(sd, MO_EXTREMITYFIST) > 0 && sd->spiritball > 0 && sd->sc.data[SC_EXPLOSIONSPIRITS]) + combo=1; break; case AC_DOUBLE: if( (tstatus->race == RC_BRUTE || tstatus->race == RC_INSECT) && pc->checkskill(sd, HT_POWER)) { //TODO: This code was taken from Triple Blows, is this even how it should be? [Skotlex] - sc_start2(src,SC_COMBOATTACK,100,HT_POWER,bl->id,2000); + sc_start2(NULL,src,SC_COMBOATTACK,100,HT_POWER,bl->id,2000); clif->combo_delay(src,2000); } break; @@ -2337,7 +2331,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds case SL_STIN: case SL_STUN: if (skill_lv >= 7 && !sd->sc.data[SC_SMA_READY]) - sc_start(src,SC_SMA_READY,100,skill_lv,skill->get_time(SL_SMA, skill_lv)); + sc_start(src, src,SC_SMA_READY,100,skill_lv,skill->get_time(SL_SMA, skill_lv)); break; case GS_FULLBUSTER: //Can't attack nor use items until skill's delay expires. [Skotlex] @@ -2345,21 +2339,21 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds break; case TK_DODGE: if( pc->checkskill(sd, TK_JUMPKICK) > 0 ) - flag = 1; + combo = 1; break; case SR_DRAGONCOMBO: if( pc->checkskill(sd, SR_FALLENEMPIRE) > 0 ) - flag = 1; + combo = 1; break; case SR_FALLENEMPIRE: if( pc->checkskill(sd, SR_TIGERCANNON) > 0 || pc->checkskill(sd, SR_GATEOFHELL) > 0 ) - flag = 1; + combo = 1; break; } //Switch End - if (flag) { //Possible to chain - if ( (flag = DIFF_TICK(sd->ud.canact_tick, tick)) < 50 ) flag = 50;/* less is a waste. */ - sc_start2(src,SC_COMBOATTACK,100,skill_id,bl->id,flag); - clif->combo_delay(src, flag); + if (combo) { //Possible to chain + if ( (combo = DIFF_TICK32(sd->ud.canact_tick, tick)) < 50 ) combo = 50;/* less is a waste. */ + sc_start2(NULL,src,SC_COMBOATTACK,100,skill_id,bl->id,combo); + clif->combo_delay(src, combo); } } @@ -2379,7 +2373,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds case NPC_CRITICALSLASH: case TF_DOUBLE: case GS_CHAINACTION: - dmg.dmotion = clif->damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,dmg.type,dmg.damage2); + dmg.dmotion = clif->damage(src,bl,dmg.amotion,dmg.dmotion,damage,dmg.div_,dmg.type,dmg.damage2); break; case AS_SPLASHER: @@ -2404,7 +2398,11 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,1,WL_CHAINLIGHTNING,-2,6); break; case LG_OVERBRAND_BRANDISH: + case LG_OVERBRAND: + dmg.amotion = status_get_amotion(src) * 2; case LG_OVERBRAND_PLUSATK: + dmg.dmotion = clif->skill_damage(dsrc,bl,tick,status_get_amotion(src),dmg.dmotion,damage,dmg.div_,skill_id,-1,5); + break; case EL_FIRE_BOMB: case EL_FIRE_BOMB_ATK: case EL_FIRE_WAVE: @@ -2422,18 +2420,23 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds case EL_HURRICANE: case EL_HURRICANE_ATK: case KO_BAKURETSU: - case GN_CRAZYWEED_ATK: case NC_MAGMA_ERUPTION: dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skill_id,-1,5); break; case GN_SLINGITEM_RANGEMELEEATK: dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,GN_SLINGITEM,-2,6); break; + case SC_FEINTBOMB: + dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,1,skill_id,skill_lv,5); + break; + case GN_CRAZYWEED_ATK: + dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skill_id, -2, 6); + break; case EL_STONE_RAIN: dmg.dmotion = clif->skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skill_id,-1,(flag&1)?8:5); break; case WM_SEVERE_RAINSTORM_MELEE: - dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,WM_SEVERE_RAINSTORM,skill_lv,5); + dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,WM_SEVERE_RAINSTORM,-2,6); break; case WM_REVERBERATION_MELEE: case WM_REVERBERATION_MAGIC: @@ -2508,6 +2511,9 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds case GN_HELLS_PLANT_ATK: copy_skill = GN_HELLS_PLANT; break; + case GN_SLINGITEM_RANGEMELEEATK: + copy_skill = GN_SLINGITEM; + break; case LG_OVERBRAND_BRANDISH: case LG_OVERBRAND_PLUSATK: copy_skill = LG_OVERBRAND; @@ -2533,8 +2539,8 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds } tsd->reproduceskill_id = copy_skill; - pc_setglobalreg(tsd, "REPRODUCE_SKILL", copy_skill); - pc_setglobalreg(tsd, "REPRODUCE_SKILL_LV", lv); + pc_setglobalreg(tsd, script->add_str("REPRODUCE_SKILL"), copy_skill); + pc_setglobalreg(tsd, script->add_str("REPRODUCE_SKILL_LV"), lv); tsd->status.skill[cidx].id = copy_skill; tsd->status.skill[cidx].lv = lv; @@ -2556,8 +2562,8 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds lv = type; tsd->cloneskill_id = copy_skill; - pc_setglobalreg(tsd, "CLONE_SKILL", copy_skill); - pc_setglobalreg(tsd, "CLONE_SKILL_LV", lv); + pc_setglobalreg(tsd, script->add_str("CLONE_SKILL"), copy_skill); + pc_setglobalreg(tsd, script->add_str("CLONE_SKILL_LV"), lv); tsd->status.skill[cidx].id = copy_skill; tsd->status.skill[cidx].lv = lv; @@ -2574,10 +2580,12 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds if (ud && DIFF_TICK(ud->attackabletime, tick + type) < 0) ud->attackabletime = tick + type; } + + shadow_flag = skill->check_shadowform(bl, damage, dmg.div_); if( !dmg.amotion ) { //Instant damage - if( !sc || (!sc->data[SC_DEVOTION] && skill_id != CR_REFLECTSHIELD) ) + if( (!sc || (!sc->data[SC_DEVOTION] && skill_id != CR_REFLECTSHIELD)) && !shadow_flag) status_fix_damage(src,bl,damage,dmg.dmotion); //Deal damage before knockback to allow stuff like firewall+storm gust combo. if( !status->isdead(bl) && additional_effects ) skill->additional_effect(src,bl,skill_id,skill_lv,dmg.flag,dmg.dmg_lv,tick); @@ -2586,7 +2594,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds } // Hell Inferno burning status only starts if Fire part hits. if( skill_id == WL_HELLINFERNO && dmg.damage > 0 && !(flag&ELE_DARK) ) - sc_start4(bl,SC_BURNING,55+5*skill_lv,skill_lv,0,src->id,0,skill->get_time(skill_id,skill_lv)); + sc_start4(src,bl,SC_BURNING,55+5*skill_lv,skill_lv,0,src->id,0,skill->get_time(skill_id,skill_lv)); // Apply knock back chance in SC_TRIANGLESHOT skill. else if( skill_id == SC_TRIANGLESHOT && rnd()%100 > (1 + skill_lv) ) dmg.blewcount = 0; @@ -2599,7 +2607,6 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds case MG_FIREWALL: case PR_SANCTUARY: case SC_TRIANGLESHOT: - case LG_OVERBRAND: case SR_KNUCKLEARROW: case GN_WALLOFTHORN: case EL_FIRE_MANTLE: @@ -2607,7 +2614,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds break; // This ensures the storm randomly pushes instead of exactly a cell backwards per official mechanics. case WZ_STORMGUST: - dir = rand()%8; + dir = rnd()%8; break; case WL_CRIMSONROCK: dir = map->calc_dir(bl,skill->area_temp[4],skill->area_temp[5]); @@ -2621,15 +2628,9 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds //blown-specific handling switch( skill_id ) { - case LG_OVERBRAND: - if( skill->blown(dsrc,bl,dmg.blewcount,dir,0) ) { - short dir_x, dir_y; - dir_x = dirx[(dir+4)%8]; - dir_y = diry[(dir+4)%8]; - if( map->getcell(bl->m, bl->x+dir_x, bl->y+dir_y, CELL_CHKNOPASS) != 0 ) - skill->addtimerskill(src, tick + status_get_amotion(src), bl->id, 0, 0, LG_OVERBRAND_PLUSATK, skill_lv, BF_WEAPON, flag ); - } else - skill->addtimerskill(src, tick + status_get_amotion(src), bl->id, 0, 0, LG_OVERBRAND_PLUSATK, skill_lv, BF_WEAPON, flag ); + case LG_OVERBRAND_BRANDISH: + if( skill->blown(dsrc,bl,dmg.blewcount,dir,0) < dmg.blewcount ) + skill->addtimerskill(src, tick + status_get_amotion(src), bl->id, 0, 0, LG_OVERBRAND_PLUSATK, skill_lv, BF_WEAPON, flag|SD_ANIMATION); break; case SR_KNUCKLEARROW: if( skill->blown(dsrc,bl,dmg.blewcount,dir,0) && !(flag&4) ) { @@ -2640,11 +2641,6 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds skill->addtimerskill(src, tick + 300 * ((flag&2) ? 1 : 2), bl->id, 0, 0, skill_id, skill_lv, BF_WEAPON, flag|4); } break; - case GN_WALLOFTHORN: - unit->stop_walking(bl,1); - skill->blown(dsrc,bl,dmg.blewcount,dir, 0x2 ); - clif->fixpos(bl); - break; default: skill->blown(dsrc,bl,dmg.blewcount,dir, 0x0 ); if ( !dmg.blewcount && bl->type == BL_SKILL && damage > 0 ){ @@ -2657,8 +2653,15 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds } //Delayed damage must be dealt after the knockback (it needs to know actual position of target) - if (dmg.amotion) - battle->delay_damage(tick, dmg.amotion,src,bl,dmg.flag,skill_id,skill_lv,damage,dmg.dmg_lv,dmg.dmotion, additional_effects); + if (dmg.amotion){ + if( shadow_flag ){ + if( !status->isdead(bl) && additional_effects ) + skill->additional_effect(src,bl,skill_id,skill_lv,dmg.flag,dmg.dmg_lv,tick); + if( dmg.flag > ATK_BLOCK ) + skill->counter_additional_effect(src,bl,skill_id,skill_lv,dmg.flag,tick); + }else + battle->delay_damage(tick, dmg.amotion,src,bl,dmg.flag,skill_id,skill_lv,damage,dmg.dmg_lv,dmg.dmotion, additional_effects); + } if( sc && sc->data[SC_DEVOTION] && skill_id != PA_PRESSURE ) { struct status_change_entry *sce = sc->data[SC_DEVOTION]; @@ -2670,12 +2673,12 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds ) && check_distance_bl(bl, d_bl, sce->val3) ) { if(!rmdamage){ - clif->damage(d_bl,d_bl, timer->gettick(), 0, 0, damage, 0, 0, 0); + clif->damage(d_bl,d_bl, 0, 0, damage, 0, 0, 0); status_fix_damage(NULL,d_bl, damage, 0); } else{ //Reflected magics are done directly on the target not on paladin //This check is only for magical skill. //For BF_WEAPON skills types track var rdamage and function battle_calc_return_damage - clif->damage(bl,bl, timer->gettick(), 0, 0, damage, 0, 0, 0); + clif->damage(bl,bl, 0, 0, damage, 0, 0, 0); status_fix_damage(bl,bl, damage, 0); } } @@ -2721,8 +2724,11 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds { struct status_change *ssc = status->get_sc(src); if( ssc && ssc->data[SC_POISONINGWEAPON] && rnd()%100 < 70 + 5*skill_lv ) { - sc_start(bl,ssc->data[SC_POISONINGWEAPON]->val2,100,ssc->data[SC_POISONINGWEAPON]->val1,skill->get_time2(GC_POISONINGWEAPON, 1)); - status_change_end(src,SC_POISONINGWEAPON,INVALID_TIMER); + short rate = 100; + if ( ssc->data[SC_POISONINGWEAPON]->val1 == 9 )//Oblivion Curse gives a 2nd success chance after the 1st one passes which is reduceable. [Rytech] + rate = 100 - tstatus->int_ * 4 / 5; + sc_start(src, bl,ssc->data[SC_POISONINGWEAPON]->val2,rate,ssc->data[SC_POISONINGWEAPON]->val1,skill->get_time2(GC_POISONINGWEAPON,1) - (tstatus->vit + tstatus->luk) / 2 * 1000); + status_change_end(src,SC_POISONINGWEAPON,-1); clif->skill_nodamage(src,bl,skill_id,skill_lv,1); } } @@ -2758,21 +2764,21 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds * Checking bl battle flag and display dammage * then call func with source,target,skill_id,skill_lv,tick,flag *------------------------------------------*/ -int skill_area_sub (struct block_list *bl, va_list ap) { +int skill_area_sub(struct block_list *bl, va_list ap) { struct block_list *src; uint16 skill_id,skill_lv; int flag; - unsigned int tick; + int64 tick; SkillFunc func; nullpo_ret(bl); - src=va_arg(ap,struct block_list *); - skill_id=va_arg(ap,int); - skill_lv=va_arg(ap,int); - tick=va_arg(ap,unsigned int); - flag=va_arg(ap,int); - func=va_arg(ap,SkillFunc); + src = va_arg(ap,struct block_list *); + skill_id = va_arg(ap,int); + skill_lv = va_arg(ap,int); + tick = va_arg(ap,int64); + flag = va_arg(ap,int); + func = va_arg(ap,SkillFunc); if(battle->check_target(src,bl,flag) > 0) { // several splash skills need this initial dummy packet to display correctly @@ -2807,7 +2813,8 @@ int skill_check_unit_range_sub (struct block_list *bl, va_list ap) { case MG_SAFETYWALL: case AL_PNEUMA: case SC_MAELSTROM: - if(g_skill_id != MH_STEINWAND && g_skill_id != MG_SAFETYWALL && g_skill_id != AL_PNEUMA && g_skill_id != SC_MAELSTROM) + case SO_ELEMENTAL_SHIELD: + if(g_skill_id != MH_STEINWAND && g_skill_id != MG_SAFETYWALL && g_skill_id != AL_PNEUMA && g_skill_id != SC_MAELSTROM && g_skill_id != SO_ELEMENTAL_SHIELD) return 0; break; case AL_WARP: @@ -2836,6 +2843,8 @@ int skill_check_unit_range_sub (struct block_list *bl, va_list ap) { case RA_ICEBOUNDTRAP: case SC_DIMENSIONDOOR: case SC_BLOODYLUST: + case SC_CHAOSPANIC: + case GN_HELLS_PLANT: //Non stackable on themselves and traps (including venom dust which does not has the trap inf2 set) if (skill_id != g_skill_id && !(skill->get_inf2(g_skill_id)&INF2_TRAP) && g_skill_id != AS_VENOMDUST && g_skill_id != MH_POISON_MIST) return 0; @@ -2888,6 +2897,12 @@ int skill_check_unit_range2 (struct block_list *bl, int x, int y, uint16 skill_i case WZ_ICEWALL: range = 2; break; + case SC_MANHOLE: + range = 0; + break; + case GN_HELLS_PLANT: + range = 0; + break; default: { int layout_type = skill->get_unit_layout_type(skill_id,skill_lv); if (layout_type==-1 || layout_type>MAX_SQUARE_LAYOUT) { @@ -3027,14 +3042,14 @@ int skill_check_condition_mercenary(struct block_list *bl, int skill_id, int lv, /*========================================== * what the hell it doesn't need to receive this many params, it doesn't do anything ~_~ *------------------------------------------*/ -int skill_area_sub_count (struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, unsigned int tick, int flag) { +int skill_area_sub_count(struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int64 tick, int flag) { return 1; } /*========================================== * *------------------------------------------*/ -int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data) { +int skill_timerskill(int tid, int64 tick, int id, intptr_t data) { struct block_list *src = map->id2bl(id),*target; struct unit_data *ud = unit->bl2ud(src); struct skill_timerskill *skl; @@ -3059,8 +3074,23 @@ int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data) { break; // Target not on Map if(src->m != target->m) break; // Different Maps - if(status->isdead(src)) - break; // Caster is Dead + if(status->isdead(src)){ + // Exceptions + switch(skl->skill_id){ + case WL_CHAINLIGHTNING_ATK: + case WL_TETRAVORTEX_FIRE: + case WL_TETRAVORTEX_WATER: + case WL_TETRAVORTEX_WIND: + case WL_TETRAVORTEX_GROUND: + case SR_FLASHCOMBO_ATK_STEP1: + case SR_FLASHCOMBO_ATK_STEP2: + case SR_FLASHCOMBO_ATK_STEP3: + case SR_FLASHCOMBO_ATK_STEP4: + break; + default: + continue; // Caster is Dead + } + } if(status->isdead(target) && skl->skill_id != RG_INTIMIDATE && skl->skill_id != WZ_WATERBALL) break; @@ -3129,25 +3159,25 @@ int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data) { case WL_TETRAVORTEX_WIND: case WL_TETRAVORTEX_GROUND: clif->skill_nodamage(src, target, skl->skill_id, skl->skill_lv, 1); - skill_attack(BF_MAGIC, src, src, target, skl->skill_id, skl->skill_lv, tick, skl->flag); + skill->attack(BF_MAGIC, src, src, target, skl->skill_id, skl->skill_lv, tick, skl->flag); skill->toggle_magicpower(src, skl->skill_id); // only the first hit will be amplify if( skl->type == 4 ){ const enum sc_type scs[] = { SC_BURNING, SC_BLOODING, SC_FROSTMISTY, SC_STUN }; // status inflicts are depend on what summoned element is used. int rate = skl->y, index = skl->x-1; - sc_start2(target, scs[index], rate, skl->skill_lv, src->id, skill->get_time(WL_TETRAVORTEX,index)); + sc_start2(src,target, scs[index], rate, skl->skill_lv, src->id, skill->get_time(WL_TETRAVORTEX,index+1)); } break; case WM_REVERBERATION_MELEE: case WM_REVERBERATION_MAGIC: - skill->castend_damage_id(src, target, skl->skill_id, skl->skill_lv, tick, skl->flag|SD_LEVEL); // damage should split among targets + skill->attack(skill->get_type(skl->skill_id),src, src, target, skl->skill_id, skl->skill_lv, 0, SD_LEVEL); break; case SC_FATALMENACE: if( src == target ) // Casters Part - unit->warp(src, -1, skl->x, skl->y, 3); + unit->warp(src, -1, skl->x, skl->y, CLR_TELEPORT); else { // Target's Part short x = skl->x, y = skl->y; map->search_freecell(NULL, target->m, &x, &y, 2, 2, 1); - unit->warp(target,-1,x,y,3); + unit->warp(target,-1,x,y,CLR_TELEPORT); } break; case LG_MOONSLASHER: @@ -3161,19 +3191,12 @@ int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data) { } } break; - case LG_OVERBRAND_BRANDISH: - case LG_OVERBRAND_PLUSATK: - if( status->check_skilluse(src, target, skl->skill_id, 1) ) - skill->attack(BF_WEAPON, src, src, target, skl->skill_id, skl->skill_lv, tick, skl->flag|SD_LEVEL); - else - clif->skill_damage(src, target, tick, status_get_amotion(src), status_get_dmotion(target), 0, 1, skl->skill_id, skl->skill_lv, skill->get_hit(skl->skill_id)); - break; case SR_KNUCKLEARROW: skill->attack(BF_WEAPON, src, src, target, skl->skill_id, skl->skill_lv, tick, skl->flag|SD_LEVEL); break; case GN_SPORE_EXPLOSION: map->foreachinrange(skill->area_sub, target, skill->get_splash(skl->skill_id, skl->skill_lv), BL_CHAR, - src, skl->skill_id, skl->skill_lv, 0, skl->flag|1|BCT_ENEMY, skill->castend_damage_id); + src, skl->skill_id, skl->skill_lv, (int64)0, skl->flag|1|BCT_ENEMY, skill->castend_damage_id); break; case SR_FLASHCOMBO_ATK_STEP1: case SR_FLASHCOMBO_ATK_STEP2: @@ -3184,6 +3207,9 @@ int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data) { const enum e_skill combos[] = {SR_DRAGONCOMBO, SR_FALLENEMPIRE, SR_TIGERCANNON, SR_SKYNETBLOW}; if( (sd = ((TBL_PC*)src)) ){ uint16 cid = combos[skl->skill_id-SR_FLASHCOMBO_ATK_STEP1]; + if( distance_xy(src->x, src->y, target->x, target->y) >= 3 ) + break; + skill->consume_requirement(sd,cid,pc->checkskill(sd, cid),1); skill->castend_damage_id(src, target, cid, pc->checkskill(sd, cid), tick, 0); } } @@ -3195,6 +3221,14 @@ int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data) { skill->addtimerskill(src,tick+80,src->id,0,0,skl->skill_id,skl->skill_lv,skl->type+1,0); } break; + case RK_HUNDREDSPEAR: + if(src->type == BL_PC) { + int skill_lv = pc->checkskill((TBL_PC *)src, KN_SPEARBOOMERANG); + if(skill_lv > 0) + skill->attack(BF_WEAPON, src, src, target, KN_SPEARBOOMERANG, skill_lv, tick, skl->flag); + } else + skill->attack(BF_WEAPON, src, src, target, KN_SPEARBOOMERANG, 1, tick, skl->flag); + break; case CH_PALMSTRIKE: { struct status_change* tsc = status->get_sc(target); @@ -3225,15 +3259,30 @@ int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data) { else if( path->search_long(NULL, src->m, src->x, src->y, skl->x, skl->y, CELL_CHKWALL) ) skill->unitsetting(src,skl->skill_id,skl->skill_lv,skl->x,skl->y,skl->flag); break; - case GN_CRAZYWEED_ATK: - { - int dummy = 1, i = skill->get_unit_range(skl->skill_id,skl->skill_lv); - map->foreachinarea(skill->cell_overlap, src->m, skl->x-i, skl->y-i, skl->x+i, skl->y+i, BL_SKILL, skl->skill_id, &dummy, src); - } - // FIXME: there's no 'break' here. If it was intended, please consider adding a comment (issue #160) + // fall through ... case WL_EARTHSTRAIN: skill->unitsetting(src,skl->skill_id,skl->skill_lv,skl->x,skl->y,(skl->type<<16)|skl->flag); break; + case LG_OVERBRAND_BRANDISH: + { + short x2 = src->x, y2 = src->y, x = x2, y = y2; + switch( skl->type ){ + case 0: case 1: case 7: x2 += 4; x -= 4; y2 += 4; break; + case 3: case 4: case 5: x2 += 4; x -= 4; y -= 4; break; + case 2: y2 += 4; y -= 4; x -= 4; break; + case 6: y2 += 4; y -= 4; x2 += 4; break; + } + map->foreachinarea(skill->area_sub, src->m, x, y, x2, y2, BL_CHAR, src, skl->skill_id, skl->skill_lv, tick, skl->flag|BCT_ENEMY|SD_ANIMATION|1,skill->castend_damage_id); + } + break; + case GN_CRAZYWEED: + if( skl->type >= 0 ) { + int x = skl->type>>16, y = skl->type&0xFFFF; + if( path->search_long(NULL, src->m, src->x, src->y, skl->x, skl->y, CELL_CHKWALL) ) + skill->castend_pos2(src, x, y, GN_CRAZYWEED_ATK, skl->skill_lv, tick, skl->flag); + } else if( path->search_long(NULL, src->m, src->x, src->y, skl->x, skl->y, CELL_CHKWALL) ) + skill->castend_pos2(src, skl->x, skl->y, GN_CRAZYWEED_ATK, skl->skill_lv, tick, skl->flag); + break; } } } while (0); @@ -3245,8 +3294,7 @@ int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data) { /*========================================== * *------------------------------------------*/ -int skill_addtimerskill (struct block_list *src, unsigned int tick, int target, int x,int y, uint16 skill_id, uint16 skill_lv, int type, int flag) -{ +int skill_addtimerskill(struct block_list *src, int64 tick, int target, int x,int y, uint16 skill_id, uint16 skill_lv, int type, int flag) { int i; struct unit_data *ud; nullpo_retr(1, src); @@ -3285,6 +3333,17 @@ int skill_cleartimerskill (struct block_list *src) for(i=0;i<MAX_SKILLTIMERSKILL;i++) { if(ud->skilltimerskill[i]) { + switch(ud->skilltimerskill[i]->skill_id){ + case WL_TETRAVORTEX_FIRE: + case WL_TETRAVORTEX_WATER: + case WL_TETRAVORTEX_WIND: + case WL_TETRAVORTEX_GROUND: + case SR_FLASHCOMBO_ATK_STEP1: + case SR_FLASHCOMBO_ATK_STEP2: + case SR_FLASHCOMBO_ATK_STEP3: + case SR_FLASHCOMBO_ATK_STEP4: + continue; + } timer->delete(ud->skilltimerskill[i]->timer, skill->timerskill); ers_free(skill->timer_ers, ud->skilltimerskill[i]); ud->skilltimerskill[i]=NULL; @@ -3292,14 +3351,16 @@ int skill_cleartimerskill (struct block_list *src) } return 1; } -int skill_activate_reverbetion( struct block_list *bl, va_list ap) { +int skill_activate_reverberation(struct block_list *bl, va_list ap) { struct skill_unit *su = (TBL_SKILL*)bl; struct skill_unit_group *sg; if( bl->type != BL_SKILL ) return 0; - if( su->alive && (sg = su->group) && sg->skill_id == WM_REVERBERATION ) { - map->foreachinrange(skill->trap_splash, bl, skill->get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, bl, timer->gettick()); - su->limit=DIFF_TICK(timer->gettick(),sg->tick); + if( su->alive && (sg = su->group) && sg->skill_id == WM_REVERBERATION && sg->unit_id == UNT_REVERBERATION ) { + int64 tick = timer->gettick(); + clif->changetraplook(bl,UNT_USED_TRAPS); + map->foreachinrange(skill->trap_splash, bl, skill->get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, bl, tick); + su->limit = DIFF_TICK32(tick,sg->tick)+1500; sg->unit_id = UNT_USED_TRAPS; } return 0; @@ -3310,7 +3371,7 @@ int skill_reveal_trap (struct block_list *bl, va_list ap) { if (su->alive && su->group && skill->get_inf2(su->group->skill_id)&INF2_TRAP) { //Reveal trap. //Change look is not good enough, the client ignores it as an actual trap still. [Skotlex] //clif->changetraplook(bl, su->group->unit_id); - clif->skill_setunit(su); + clif->getareachar_skillunit(&su->bl,su,AREA); return 1; } return 0; @@ -3320,7 +3381,7 @@ int skill_reveal_trap (struct block_list *bl, va_list ap) { * * *------------------------------------------*/ -int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, unsigned int tick, int flag) { +int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag) { struct map_session_data *sd = NULL; struct status_data *tstatus; struct status_change *sc; @@ -3448,7 +3509,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint case NPC_CRITICALWOUND: case NPC_HELLPOWER: case RK_SONICWAVE: - case RK_HUNDREDSPEAR: case RK_STORMBLAST: case RK_CRUSHSTRIKE: case AB_DUPLELIGHT_MELEE: @@ -3470,10 +3530,13 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint case SR_GENTLETOUCH_QUIET: case WM_SEVERE_RAINSTORM_MELEE: case WM_GREAT_ECHO: + case GN_CRAZYWEED_ATK: case GN_SLINGITEM_RANGEMELEEATK: case KO_JYUMONJIKIRI: case KO_SETSUDAN: case GC_DARKCROW: + case LG_OVERBRAND_BRANDISH: + case LG_OVERBRAND: skill->attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag); break; @@ -3482,9 +3545,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint **/ case NC_BOOSTKNUCKLE: case NC_PILEBUNKER: - case NC_VULCANARM: case NC_COLDSLOWER: - case NC_ARMSCANNON: if (sd) pc->overheat(sd,1); case RK_WINDCUTTER: skill->attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag|SD_ANIMATION); @@ -3620,7 +3681,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint status_change_end(src, SC_EXPLOSIONSPIRITS, INVALID_TIMER); status_change_end(src, SC_BLADESTOP, INVALID_TIMER); #ifdef RENEWAL - sc_start(src,SC_EXTREMITYFIST2,100,skill_lv,skill->get_time(skill_id,skill_lv)); + sc_start(src, src,SC_EXTREMITYFIST2,100,skill_lv,skill->get_time(skill_id,skill_lv)); #endif // RENEWAL } else { status_change_end(src, SC_NJ_NEN, INVALID_TIMER); @@ -3680,6 +3741,8 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint case WL_JACKFROST: case RA_ARROWSTORM: case RA_WUGDASH: + case NC_VULCANARM: + case NC_ARMSCANNON: case NC_SELFDESTRUCTION: case NC_AXETORNADO: case GC_ROLLINGCUTTER: @@ -3691,9 +3754,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint case SR_SKYNETBLOW: case SR_WINDMILL: case SR_RIDEINLIGHTNING: - case WM_SOUND_OF_DESTRUCTION: - case WM_REVERBERATION_MELEE: - case WM_REVERBERATION_MAGIC: + case WM_REVERBERATION: case SO_VARETYR_SPEAR: case GN_CART_TORNADO: case GN_CARTCANNON: @@ -3744,8 +3805,10 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint skill->area_temp[4] = bl->x; skill->area_temp[5] = bl->y; } - if( skill_id == WM_REVERBERATION_MELEE || skill_id == WM_REVERBERATION_MAGIC ) - skill->area_temp[1] = 0; + + if( skill_id == NC_VULCANARM ) + if (sd) pc->overheat(sd,1); + // if skill damage should be split among targets, count them //SD_LEVEL -> Forced splash damage for Auto Blitz-Beat -> count targets //special case: Venom Splasher uses a different range for searching than for splashing @@ -3753,7 +3816,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint skill->area_temp[0] = map->foreachinrange(skill->area_sub, bl, (skill_id == AS_SPLASHER)?1:skill->get_splash(skill_id, skill_lv), BL_CHAR, src, skill_id, skill_lv, tick, BCT_ENEMY, skill->area_sub_count); // recursive invocation of skill->castend_damage_id() with flag|1 - map->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id, skill_lv), ( skill_id == WM_REVERBERATION_MELEE || skill_id == WM_REVERBERATION_MAGIC )?BL_CHAR:splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill->castend_damage_id); + map->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id, skill_lv), splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill->castend_damage_id); } break; @@ -3831,7 +3894,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint break; case CH_PALMSTRIKE: // Palm Strike takes effect 1sec after casting. [Skotlex] // clif->skill_nodamage(src,bl,skill_id,skill_lv,0); //Can't make this one display the correct attack animation delay :/ - clif->damage(src,bl,tick,status_get_amotion(src),0,-1,1,4,0); //Display an absorbed damage attack. + clif->damage(src,bl,status_get_amotion(src),0,-1,1,4,0); //Display an absorbed damage attack. skill->addtimerskill(src, tick + (1000+status_get_amotion(src)), bl->id, 0, 0, skill_id, skill_lv, BF_WEAPON, flag); break; @@ -3871,7 +3934,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint case NPC_MAGICALATTACK: skill->attack(BF_MAGIC,src,src,bl,skill_id,skill_lv,tick,flag); - sc_start(src,status->skill2sc(skill_id),100,skill_lv,skill->get_time(skill_id,skill_lv)); + sc_start(src, src,status->skill2sc(skill_id),100,skill_lv,skill->get_time(skill_id,skill_lv)); break; case HVAN_CAPRICE: //[blackhole89] @@ -3933,7 +3996,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint case SL_STIN: case SL_STUN: if (sd && !battle_config.allow_es_magic_pc && bl->type != BL_MOB) { - status->change_start(src,SC_STUN,10000,skill_lv,0,0,0,500,10); + status->change_start(src,src,SC_STUN,10000,skill_lv,0,0,0,500,10); clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); break; } @@ -3966,7 +4029,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint if( (tsc = status->get_sc(bl)) && (tsc->data[SC_HIDING] )) { clif->skill_nodamage(src,src,skill_id,skill_lv,1); } else - skill->attack(BF_MISC,src,src,bl,skill_id,skill_lv,tick,flag); + skill->attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag); } break; case NPC_SELFDESTRUCTION: { @@ -4012,7 +4075,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint case NJ_KASUMIKIRI: if (skill->attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag) > 0) - sc_start(src,SC_HIDING,100,skill_lv,skill->get_time(skill_id,skill_lv)); + sc_start(src,src,SC_HIDING,100,skill_lv,skill->get_time(skill_id,skill_lv)); break; case NJ_KIRIKAGE: if( !map_flag_gvg2(src->m) && !map->list[src->m].flag.battleground ) { @@ -4025,13 +4088,28 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint status_change_end(src, SC_HIDING, INVALID_TIMER); skill->attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag); break; + case RK_HUNDREDSPEAR: + skill->attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag); + if(rnd()%100 < (10 + 3*skill_lv)) { + if( !sd || pc->checkskill(sd,KN_SPEARBOOMERANG) == 0 ) + break; // Spear Boomerang auto cast chance only works if you have mastered Spear Boomerang. + skill->blown(src,bl,6,-1,0); + skill->addtimerskill(src,tick+800,bl->id,0,0,skill_id,skill_lv,BF_WEAPON,flag); + skill->castend_damage_id(src,bl,KN_SPEARBOOMERANG,1,tick,0); + } + break; case RK_PHANTOMTHRUST: + { + struct map_session_data *tsd = BL_CAST(BL_PC, bl); unit->setdir(src,map->calc_dir(src, bl->x, bl->y)); clif->skill_nodamage(src,bl,skill_id,skill_lv,1); skill->blown(src,bl,distance_bl(src,bl)-1,unit->getdir(src),0); - if( battle->check_target(src,bl,BCT_ENEMY) > 0 ) + if( sd && tsd && sd->status.party_id && sd->status.party_id && sd->status.party_id == tsd->status.party_id ) // Don't damage party members. + ; // No damage to Members + else skill->attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag); + } break; case GC_DARKILLUSION: @@ -4115,7 +4193,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint types[x][1] = 25; // 25% each for equal sharing if( x == 3 ){ x = 0; - sc_index = types[rand()%4][0]; + sc_index = types[rnd()%4][0]; for(; x < 4; x++) if(types[x][0] == sc_index) rate += types[x][1]; @@ -4136,7 +4214,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint skill->toggle_magicpower(src, skill_id); // Priority is to release SpellBook if( sc && sc->data[SC_READING_SB] ) { // SpellBook - uint16 skill_id, skill_lv, point, s = 0; + uint16 spell_skill_id, spell_skill_lv, point, s = 0; int spell[SC_SPELLBOOK7-SC_SPELLBOOK1 + 1]; for(i = SC_SPELLBOOK7; i >= SC_SPELLBOOK1; i--) // List all available spell to be released @@ -4145,10 +4223,10 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint if ( s == 0 ) break; - i = spell[s==1?0:rand()%s];// Random select of spell to be released. + i = spell[s==1?0:rnd()%s];// Random select of spell to be released. if( s && sc->data[i] ){// Now extract the data from the preserved spell - skill_id = sc->data[i]->val1; - skill_lv = sc->data[i]->val2; + spell_skill_id = sc->data[i]->val1; + spell_skill_lv = sc->data[i]->val2; point = sc->data[i]->val3; status_change_end(src, (sc_type)i, INVALID_TIMER); }else //something went wrong :( @@ -4159,36 +4237,35 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint else // Last spell to be released status_change_end(src, SC_READING_SB, INVALID_TIMER); - if( !skill->check_condition_castbegin(sd, skill_id, skill_lv) ) + if( !skill->check_condition_castbegin(sd, spell_skill_id, spell_skill_lv) ) break; - switch( skill->get_casttype(skill_id) ) { + switch( skill->get_casttype(spell_skill_id) ) { case CAST_GROUND: - skill->castend_pos2(src, bl->x, bl->y, skill_id, skill_lv, tick, 0); + skill->castend_pos2(src, bl->x, bl->y, spell_skill_id, spell_skill_lv, tick, 0); break; case CAST_NODAMAGE: - skill->castend_nodamage_id(src, bl, skill_id, skill_lv, tick, 0); + skill->castend_nodamage_id(src, bl, spell_skill_id, spell_skill_lv, tick, 0); break; case CAST_DAMAGE: - skill->castend_damage_id(src, bl, skill_id, skill_lv, tick, 0); + skill->castend_damage_id(src, bl, spell_skill_id, spell_skill_lv, tick, 0); break; } - sd->ud.canact_tick = tick + skill->delay_fix(src, skill_id, skill_lv); - clif->status_change(src, SI_POSTDELAY, 1, skill->delay_fix(src, skill_id, skill_lv), 0, 0, 0); + sd->ud.canact_tick = tick + skill->delay_fix(src, spell_skill_id, spell_skill_lv); + clif->status_change(src, SI_POSTDELAY, 1, skill->delay_fix(src, spell_skill_id, spell_skill_lv), 0, 0, 0); - cooldown = skill_get_cooldown(skill_id, skill_lv); + cooldown = skill->get_cooldown(spell_skill_id, spell_skill_lv); for (i = 0; i < ARRAYLENGTH(sd->skillcooldown) && sd->skillcooldown[i].id; i++) { - if (sd->skillcooldown[i].id == skill_id){ + if (sd->skillcooldown[i].id == spell_skill_id){ cooldown += sd->skillcooldown[i].val; break; } } if(cooldown) - skill->blockpc_start(sd, skill_id, cooldown, false); + skill->blockpc_start(sd, spell_skill_id, cooldown); }else if( sc ){ // Summon Balls - int i = SC_SUMMON5; - for(; i >= SC_SUMMON1; i--){ + for(i = SC_SUMMON5; i >= SC_SUMMON1; i--){ if( sc->data[i] ){ int skillid = WL_SUMMON_ATK_FIRE + (sc->data[i]->val1 - WLS_FIRE); skill->addtimerskill(src, tick + status_get_adelay(src) * (SC_SUMMON5 - i), bl->id, 0, 0, skillid, skill_lv, BF_MAGIC, flag); @@ -4258,8 +4335,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint case NC_INFRAREDSCAN: if( flag&1 ) { //TODO: Need a confirmation if the other type of hidden status is included to be scanned. [Jobbie] - if( rnd()%100 < 50 ) - sc_start(bl, SC_INFRAREDSCAN, 10000, skill_lv, skill->get_time(skill_id, skill_lv)); + sc_start(src, bl, SC_INFRAREDSCAN, 10000, skill_lv, skill->get_time(skill_id, skill_lv)); status_change_end(bl, SC_HIDING, INVALID_TIMER); status_change_end(bl, SC_CLOAKING, INVALID_TIMER); status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER); // Need confirm it. @@ -4271,7 +4347,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint break; case NC_MAGNETICFIELD: - sc_start2(bl,SC_MAGNETICFIELD,100,skill_lv,src->id,skill->get_time(skill_id,skill_lv)); + sc_start2(src,bl,SC_MAGNETICFIELD,100,skill_lv,src->id,skill->get_time(skill_id,skill_lv)); break; case SC_FATALMENACE: if( flag&1 ) @@ -4294,20 +4370,12 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint break; case LG_SHIELDSPELL: - // flag&1: Phisycal Attack, flag&2: Magic Attack. - skill->attack((flag&1)?BF_WEAPON:BF_MAGIC,src,src,bl,skill_id,skill_lv,tick,flag); - break; - - case LG_OVERBRAND: - if( status->check_skilluse(src, bl, skill_id, 1) ) - skill->attack(BF_WEAPON, src, src, bl, skill_id, skill_lv, tick, flag|SD_LEVEL); - else - clif->skill_damage(src, bl, tick, status_get_amotion(src), status_get_dmotion(bl), 0, 1, skill_id, skill_lv, skill->get_hit(skill_id)); + if ( skill_lv == 1 ) + skill->attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag); + else if ( skill_lv == 2 ) + skill->attack(BF_MAGIC,src,src,bl,skill_id,skill_lv,tick,flag); break; - case LG_OVERBRAND_BRANDISH: - skill->addtimerskill(src, tick + status_get_amotion(src)*8/10, bl->id, 0, 0, skill_id, skill_lv, BF_WEAPON, flag|SD_LEVEL); - break; case SR_DRAGONCOMBO: skill->attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag); break; @@ -4331,9 +4399,13 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint status_change_end(bl, SC_RUSH_WINDMILL, INVALID_TIMER); status_change_end(bl, SC_ECHOSONG, INVALID_TIMER); status_change_end(bl, SC_HARMONIZE, INVALID_TIMER); + status_change_end(bl, SC_SIREN, INVALID_TIMER); + status_change_end(bl, SC_DEEP_SLEEP, INVALID_TIMER); status_change_end(bl, SC_SIRCLEOFNATURE, INVALID_TIMER); - status_change_end(bl, SC_SATURDAY_NIGHT_FEVER, INVALID_TIMER); + status_change_end(bl, SC_GLOOMYDAY, INVALID_TIMER); + status_change_end(bl, SC_SONG_OF_MANA, INVALID_TIMER); status_change_end(bl, SC_DANCE_WITH_WUG, INVALID_TIMER); + status_change_end(bl, SC_SATURDAY_NIGHT_FEVER, INVALID_TIMER); status_change_end(bl, SC_LERADS_DEW, INVALID_TIMER); status_change_end(bl, SC_MELODYOFSINK, INVALID_TIMER); status_change_end(bl, SC_BEYOND_OF_WARCRY, INVALID_TIMER); @@ -4352,6 +4424,39 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint } break; + case WM_SOUND_OF_DESTRUCTION: + { + struct status_change *tsc = status->get_sc(bl); + if( tsc && tsc->count && ( tsc->data[SC_SWING] || tsc->data[SC_SYMPHONY_LOVE] || tsc->data[SC_MOONLIT_SERENADE] || + tsc->data[SC_RUSH_WINDMILL] || tsc->data[SC_ECHOSONG] || tsc->data[SC_HARMONIZE] || + tsc->data[SC_SIREN] || tsc->data[SC_DEEP_SLEEP] || tsc->data[SC_SIRCLEOFNATURE] || + tsc->data[SC_GLOOMYDAY] || tsc->data[SC_SONG_OF_MANA] || + tsc->data[SC_DANCE_WITH_WUG] || tsc->data[SC_SATURDAY_NIGHT_FEVER] || tsc->data[SC_LERADS_DEW] || + tsc->data[SC_MELODYOFSINK] || tsc->data[SC_BEYOND_OF_WARCRY] || tsc->data[SC_UNLIMITED_HUMMING_VOICE] ) && + rnd()%100 < 4 * skill_lv + 2 * (sd ? pc->checkskill(sd,WM_LESSON) : 10) + 10 * battle->calc_chorusbonus(sd)) { + skill->attack(BF_MISC,src,src,bl,skill_id,skill_lv,tick,flag); + status->change_start(src,bl,SC_STUN,10000,skill_lv,0,0,0,skill->get_time(skill_id,skill_lv),8); + status_change_end(bl, SC_SWING, INVALID_TIMER); + status_change_end(bl, SC_SYMPHONY_LOVE, INVALID_TIMER); + status_change_end(bl, SC_MOONLIT_SERENADE, INVALID_TIMER); + status_change_end(bl, SC_RUSH_WINDMILL, INVALID_TIMER); + status_change_end(bl, SC_ECHOSONG, INVALID_TIMER); + status_change_end(bl, SC_HARMONIZE, INVALID_TIMER); + status_change_end(bl, SC_SIREN, INVALID_TIMER); + status_change_end(bl, SC_DEEP_SLEEP, INVALID_TIMER); + status_change_end(bl, SC_SIRCLEOFNATURE, INVALID_TIMER); + status_change_end(bl, SC_GLOOMYDAY, INVALID_TIMER); + status_change_end(bl, SC_SONG_OF_MANA, INVALID_TIMER); + status_change_end(bl, SC_DANCE_WITH_WUG, INVALID_TIMER); + status_change_end(bl, SC_SATURDAY_NIGHT_FEVER, INVALID_TIMER); + status_change_end(bl, SC_LERADS_DEW, INVALID_TIMER); + status_change_end(bl, SC_MELODYOFSINK, INVALID_TIMER); + status_change_end(bl, SC_BEYOND_OF_WARCRY, INVALID_TIMER); + status_change_end(bl, SC_UNLIMITED_HUMMING_VOICE, INVALID_TIMER); + } + } + break; + case SO_POISON_BUSTER: { struct status_change *tsc = status->get_sc(bl); @@ -4365,10 +4470,10 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint case GN_SPORE_EXPLOSION: if( flag&1 ) - skill->attack(skill->get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, flag); + skill->attack(BF_WEAPON, src, src, bl, skill_id, skill_lv, tick, flag); else { clif->skill_nodamage(src, bl, skill_id, 0, 1); - skill->addtimerskill(src, timer->gettick() + skill->get_time(skill_id, skill_lv) - 1000, bl->id, 0, 0, skill_id, skill_lv, 0, 0); + skill->addtimerskill(src, timer->gettick() + skill->get_time(skill_id, skill_lv), bl->id, 0, 0, skill_id, skill_lv, 0, 0); } break; @@ -4425,21 +4530,21 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint case EL_TIDAL_WEAPON: if( src->type == BL_ELEM ) { struct elemental_data *ele = BL_CAST(BL_ELEM,src); - struct status_change *sc = status->get_sc(&ele->bl); + struct status_change *esc = status->get_sc(&ele->bl); struct status_change *tsc = status->get_sc(bl); sc_type type = status->skill2sc(skill_id), type2; type2 = type-1; clif->skill_nodamage(src,battle->get_master(src),skill_id,skill_lv,1); clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); - if( (sc && sc->data[type2]) || (tsc && tsc->data[type]) ) { + if( (esc && esc->data[type2]) || (tsc && tsc->data[type]) ) { elemental->clean_single_effect(ele, skill_id); } if( rnd()%100 < 50 ) skill->attack(skill->get_type(skill_id),src,src,bl,skill_id,skill_lv,tick,flag); else { - sc_start(src,type2,100,skill_lv,skill->get_time(skill_id,skill_lv)); - sc_start(battle->get_master(src),type,100,ele->bl.id,skill->get_time(skill_id,skill_lv)); + sc_start(src, src,type2,100,skill_lv,skill->get_time(skill_id,skill_lv)); + sc_start(src, battle->get_master(src),type,100,ele->bl.id,skill->get_time(skill_id,skill_lv)); } clif->skill_nodamage(src,src,skill_id,skill_lv,1); } @@ -4469,7 +4574,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint #endif } clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start4(bl,SC_RG_CCONFINE_S,100,skill_lv,src->id,0,0,skill->get_time(skill_id,skill_lv))); + sc_start4(src,bl,SC_RG_CCONFINE_S,100,skill_lv,src->id,0,0,skill->get_time(skill_id,skill_lv))); skill->attack(BF_WEAPON, src, src, bl, skill_id, skill_lv, tick, flag); break; @@ -4522,8 +4627,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint /*========================================== * *------------------------------------------*/ -int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data) -{ +int skill_castend_id(int tid, int64 tick, int id, intptr_t data) { struct block_list *target, *src; struct map_session_data *sd; struct mob_data *md; @@ -4667,6 +4771,9 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data) else if (inf && battle->check_target(src, target, inf) <= 0){ if (sd) clif->skill_fail(sd,ud->skill_id,USESKILL_FAIL_LEVEL,0); break; + } else if( ud->skill_id == RK_PHANTOMTHRUST && target->type != BL_MOB ) { + if( !map_flag_vs(src->m) && battle->check_target(src,target,BCT_PARTY) <= 0 ) + break; // You can use Phantom Thurst on party members in normal maps too. [pakpil] } if( inf&BCT_ENEMY @@ -4734,7 +4841,7 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data) } } if(cooldown) - skill->blockpc_start(sd, ud->skill_id, cooldown, false); + skill->blockpc_start(sd, ud->skill_id, cooldown); } if( battle_config.display_status_timers && sd ) clif->status_change(src, SI_POSTDELAY, 1, skill->delay_fix(src, ud->skill_id, ud->skill_lv), 0, 0, 0); @@ -4752,7 +4859,7 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data) if( td && td->func == status->change_timer && DIFF_TICK(td->tick,timer->gettick()+skill->get_time(ud->skill_id, ud->skill_lv)) > 0 ) break; } - sc_start2(src, SC_NOEQUIPSHIELD, 100, 0, 1, skill->get_time(ud->skill_id, ud->skill_lv)); + sc_start2(src,src, SC_NOEQUIPSHIELD, 100, 0, 1, skill->get_time(ud->skill_id, ud->skill_lv)); break; } } @@ -4767,8 +4874,11 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data) // SC_MAGICPOWER needs to switch states before any damage is actually dealt skill->toggle_magicpower(src, ud->skill_id); + + /* On aegis damage skills are also increase by camouflage. Need confirmation on kRo. if( ud->skill_id != RA_CAMOUFLAGE ) // only normal attack and auto cast skills benefit from its bonuses status_change_end(src,SC_CAMOUFLAGE, INVALID_TIMER); + */ if (skill->get_casttype(ud->skill_id) == CAST_NODAMAGE) skill->castend_nodamage_id(src,target,ud->skill_id,ud->skill_lv,tick,flag); @@ -4785,7 +4895,7 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data) sc->data[SC_SOULLINK]->val3 = 0; //Clear bounced spell check. if( sc->data[SC_DANCING] && skill->get_inf2(ud->skill_id)&INF2_SONG_DANCE && sd ) - skill->blockpc_start(sd,BD_ADAPTATION,3000, false); + skill->blockpc_start(sd,BD_ADAPTATION,3000); } if( sd && ud->skill_id != SA_ABRACADABRA && ud->skill_id != WM_RANDOMIZESPELL ) // they just set the data so leave it as it is.[Inkfish] @@ -4812,7 +4922,7 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data) status_change_end(src, SC_EXPLOSIONSPIRITS, INVALID_TIMER); status_change_end(src, SC_BLADESTOP, INVALID_TIMER); #ifdef RENEWAL - sc_start(src, SC_EXTREMITYFIST2, 100, ud->skill_lv, skill->get_time(ud->skill_id, ud->skill_lv)); + sc_start(src, src, SC_EXTREMITYFIST2, 100, ud->skill_lv, skill->get_time(ud->skill_id, ud->skill_lv)); #endif } if (target && target->m == src->m) { @@ -4850,8 +4960,7 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data) /*========================================== * *------------------------------------------*/ -int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, unsigned int tick, int flag) -{ +int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag) { struct map_session_data *sd, *dstsd; struct mob_data *md, *dstmd; struct homun_data *hd; @@ -4860,7 +4969,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui struct status_change *tsc; struct status_change_entry *tsce; - int i = 0; + int element = 0; enum sc_type type; if(skill_id > 0 && !skill_lv) return 0; // celest @@ -4930,11 +5039,47 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); return 0; } - return skill->castend_damage_id (src, bl, skill_id, skill_lv, tick, flag); + return skill->castend_damage_id(src, bl, skill_id, skill_lv, tick, flag); + } + break; + case SO_ELEMENTAL_SHIELD: + { + struct party_data *p; + short ret = 0; + int x0, y0, x1, y1, range, i; + + if(sd == NULL || !sd->ed) + break; + if((p = party->search(sd->status.party_id)) == NULL) + break; + + range = skill_get_splash(skill_id,skill_lv); + x0 = sd->bl.x - range; + y0 = sd->bl.y - range; + x1 = sd->bl.x + range; + y1 = sd->bl.y + range; + + elemental->delete(sd->ed,0); + + if(!skill->check_unit_range(src,src->x,src->y,skill_id,skill_lv)) + ret = skill->castend_pos2(src,src->x,src->y,skill_id,skill_lv,tick,flag); + for(i = 0; i < MAX_PARTY; i++) { + struct map_session_data *psd = p->data[i].sd; + if(!psd) + continue; + if(psd->bl.m != sd->bl.m || !psd->bl.prev) + continue; + if(range && (psd->bl.x < x0 || psd->bl.y < y0 || + psd->bl.x > x1 || psd->bl.y > y1)) + continue; + if(!skill->check_unit_range(bl,psd->bl.x,psd->bl.y,skill_id,skill_lv)) + ret |= skill->castend_pos2(bl,psd->bl.x,psd->bl.y,skill_id,skill_lv,tick,flag); + } + return ret; } break; case NPC_SMOKING: //Since it is a self skill, this one ends here rather than in damage_id. [Skotlex] - return skill->castend_damage_id (src, bl, skill_id, skill_lv, tick, flag); + return skill->castend_damage_id(src, bl, skill_id, skill_lv, tick, flag); case MH_STEINWAND: { struct block_list *s_src = battle->get_master(src); short ret = 0; @@ -4957,7 +5102,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case RK_FIGHTINGSPIRIT: case RK_ABUNDANCE: if( sd && !pc->checkskill(sd, RK_RUNEMASTERY) ){ - if( status->change_start(&sd->bl, (sc_type)(rnd()%SC_CONFUSION), 1000, 1, 0, 0, 0, skill->get_time2(skill_id,skill_lv),8) ){ + if( status->change_start(src,&sd->bl, (sc_type)(rnd()%SC_CONFUSION), 1000, 1, 0, 0, 0, skill->get_time2(skill_id,skill_lv),8) ){ skill->consume_requirement(sd,skill_id,skill_lv,2); map->freeblock_unlock(); return 0; @@ -4975,9 +5120,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui tsce = (tsc && type != -1)?tsc->data[type]:NULL; if (src!=bl && type > -1 && - (i = skill->get_ele(skill_id, skill_lv)) > ELE_NEUTRAL && + (element = skill->get_ele(skill_id, skill_lv)) > ELE_NEUTRAL && skill->get_inf(skill_id) != INF_SUPPORT_SKILL && - battle->attr_fix(NULL, NULL, 100, i, tstatus->def_ele, tstatus->ele_lv) <= 0) + battle->attr_fix(NULL, NULL, 100, element, tstatus->def_ele, tstatus->ele_lv) <= 0) return 1; //Skills that cause an status should be blocked if the target element blocks its element. map->freeblock_lock(); @@ -4991,9 +5136,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui { int heal = skill->calc_heal(src, bl, (skill_id == AB_HIGHNESSHEAL)?AL_HEAL:skill_id, (skill_id == AB_HIGHNESSHEAL)?10:skill_lv, true); int heal_get_jobexp; - //Highness Heal: starts at 1.5 boost + 0.5 for each level + //Highness Heal: starts at 1.7 boost + 0.3 for each level if( skill_id == AB_HIGHNESSHEAL ) { - heal = heal * ( 15 + 5 * skill_lv ) / 10; + heal = heal * ( 17 + 3 * skill_lv ) / 10; } if( status->isimmune(bl) || (dstmd && (dstmd->class_ == MOBID_EMPERIUM || mob_is_battleground(dstmd))) ) @@ -5015,7 +5160,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui dstsd = sd; } } - else if (tsc->data[SC_BERSERK] || tsc->data[SC_SATURDAY_NIGHT_FEVER]) + else if (tsc->data[SC_BERSERK]) heal = 0; //Needed so that it actually displays 0 when healing. } clif->skill_nodamage (src, bl, skill_id, heal, 1); @@ -5111,19 +5256,20 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case AL_DECAGI: clif->skill_nodamage (src, bl, skill_id, skill_lv, - sc_start(bl, type, (40 + skill_lv * 2 + (status->get_lv(src) + sstatus->int_)/5), skill_lv, + sc_start(src, bl, type, (40 + skill_lv * 2 + (status->get_lv(src) + sstatus->int_)/5), skill_lv, /* monsters using lvl 48 get the rate benefit but the duration of lvl 10 */ ( src->type == BL_MOB && skill_lv == 48 ) ? skill->get_time(skill_id,10) : skill->get_time(skill_id,skill_lv))); break; case MER_DECAGI: - clif->skill_nodamage (src, bl, skill_id, skill_lv, - sc_start(bl, type, (40 + skill_lv * 2 + (status->get_lv(src) + sstatus->int_)/5), skill_lv, skill->get_time(skill_id,skill_lv))); + if( tsc && !tsc->data[SC_ADORAMUS] ) //Prevent duplicate agi-down effect. + clif->skill_nodamage(src, bl, skill_id, skill_lv, + sc_start(src, bl, type, (40 + skill_lv * 2 + (status->get_lv(src) + sstatus->int_)/5), skill_lv, skill->get_time(skill_id,skill_lv))); break; case AL_CRUCIS: if (flag&1) - sc_start(bl,type, 23+skill_lv*4 +status->get_lv(src) -status->get_lv(bl), skill_lv,skill->get_time(skill_id,skill_lv)); + sc_start(src, bl,type, 23+skill_lv*4 +status->get_lv(src) -status->get_lv(bl), skill_lv,skill->get_time(skill_id,skill_lv)); else { map->foreachinrange(skill->area_sub, src, skill->get_splash(skill_id, skill_lv), BL_CHAR, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill->castend_nodamage_id); @@ -5136,19 +5282,19 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui if( tsce ) status_change_end(bl,type, INVALID_TIMER); else - sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)); + sc_start(src, bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)); clif->skill_nodamage (src, bl, skill_id, skill_lv, 1); break; case SA_ABRACADABRA: { - int abra_skill_id = 0, abra_skill_lv; + int abra_skill_id = 0, abra_skill_lv, abra_idx; do { - i = rnd() % MAX_SKILL_ABRA_DB; - abra_skill_id = skill->abra_db[i].skill_id; + abra_idx = rnd() % MAX_SKILL_ABRA_DB; + abra_skill_id = skill->abra_db[abra_idx].skill_id; } while (abra_skill_id == 0 || - skill->abra_db[i].req_lv > skill_lv || //Required lv for it to appear - rnd()%10000 >= skill->abra_db[i].per + skill->abra_db[abra_idx].req_lv > skill_lv || //Required lv for it to appear + rnd()%10000 >= skill->abra_db[abra_idx].per ); abra_skill_lv = min(skill_lv, skill->get_max(abra_skill_id)); clif->skill_nodamage (src, bl, skill_id, skill_lv, 1); @@ -5193,7 +5339,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case SA_COMA: clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start(bl,type,100,skill_lv,skill->get_time2(skill_id,skill_lv))); + sc_start(src, bl,type,100,skill_lv,skill->get_time2(skill_id,skill_lv))); break; case SA_FULLRECOVERY: clif->skill_nodamage(src,bl,skill_id,skill_lv,1); @@ -5217,7 +5363,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui break; case SA_SUMMONMONSTER: clif->skill_nodamage(src,bl,skill_id,skill_lv,1); - if (sd) mob->once_spawn(sd, src->m, src->x, src->y," --ja--", -1, 1, "", SZ_SMALL, AI_NONE); + if (sd) mob->once_spawn(sd, src->m, src->x, src->y," --ja--", -1, 1, "", SZ_MEDIUM, AI_NONE); break; case SA_LEVELUP: clif->skill_nodamage(src,bl,skill_id,skill_lv,1); @@ -5246,6 +5392,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui mob->class_change(dstmd,class_); if( tsc && dstmd->status.mode&MD_BOSS ) { + int i; const enum sc_type scs[] = { SC_QUAGMIRE, SC_PROVOKE, SC_ROKISWEIL, SC_GRAVITATION, SC_NJ_SUITON, SC_NOEQUIPWEAPON, SC_NOEQUIPSHIELD, SC_NOEQUIPARMOR, SC_NOEQUIPHELM, SC_BLADESTOP }; for (i = SC_COMMON_MIN; i <= SC_COMMON_MAX; i++) if (tsc->data[i]) status_change_end(bl, (sc_type)i, INVALID_TIMER); @@ -5266,7 +5413,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case SA_REVERSEORCISH: case ALL_REVERSEORCISH: clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start(bl,type,100,skill_lv,skill->get_time(skill_id, skill_lv))); + sc_start(src, bl,type,100,skill_lv,skill->get_time(skill_id, skill_lv))); break; case SA_FORTUNE: clif->skill_nodamage(src,bl,skill_id,skill_lv,1); @@ -5275,6 +5422,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case SA_TAMINGMONSTER: clif->skill_nodamage(src,bl,skill_id,skill_lv,1); if (sd && dstmd) { + int i; ARR_FIND( 0, MAX_PET_DB, i, dstmd->class_ == pet->db[i].class_ ); if( i < MAX_PET_DB ) pet->catch_process1(sd, dstmd->class_); @@ -5290,7 +5438,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui } } clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); + sc_start(src, bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); break; case CG_MARIONETTE: @@ -5306,8 +5454,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui if( sc && tsc ) { if( !sc->data[SC_MARIONETTE_MASTER] && !tsc->data[SC_MARIONETTE] ) { - sc_start(src,SC_MARIONETTE_MASTER,100,bl->id,skill->get_time(skill_id,skill_lv)); - sc_start(bl,SC_MARIONETTE,100,src->id,skill->get_time(skill_id,skill_lv)); + sc_start(src,src,SC_MARIONETTE_MASTER,100,bl->id,skill->get_time(skill_id,skill_lv)); + sc_start(src,bl,SC_MARIONETTE,100,src->id,skill->get_time(skill_id,skill_lv)); clif->skill_nodamage(src,bl,skill_id,skill_lv,1); } else if( sc->data[SC_MARIONETTE_MASTER ] && sc->data[SC_MARIONETTE_MASTER ]->val1 == bl->id && tsc->data[SC_MARIONETTE] && tsc->data[SC_MARIONETTE]->val1 == src->id @@ -5326,7 +5474,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case RG_CLOSECONFINE: clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start4(bl,type,100,skill_lv,src->id,0,0,skill->get_time(skill_id,skill_lv))); + sc_start4(src,bl,type,100,skill_lv,src->id,0,0,skill->get_time(skill_id,skill_lv))); break; case SA_FLAMELAUNCHER: // added failure chance and chance to break weapon if turned on [Valaris] case SA_FROSTWEAPON: @@ -5351,7 +5499,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui } } // 100% success rate at lv4 & 5, but lasts longer at lv5 - if(!clif->skill_nodamage(src,bl,skill_id,skill_lv, sc_start(bl,type,(60+skill_lv*10),skill_lv, skill->get_time(skill_id,skill_lv)))) { + if(!clif->skill_nodamage(src,bl,skill_id,skill_lv, sc_start(src,bl,type,(60+skill_lv*10),skill_lv, skill->get_time(skill_id,skill_lv)))) { if (sd) clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); if (skill->break_equip(bl, EQP_WEAPON, 10000, BCT_PARTY) && sd && sd != dstsd) @@ -5365,12 +5513,12 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui break; } clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); + sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); break; case ITEM_ENCHANTARMS: clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start2(bl,type,100,skill_lv, + sc_start2(src,bl,type,100,skill_lv, skill->get_ele(skill_id,skill_lv), skill->get_time(skill_id,skill_lv))); break; @@ -5385,16 +5533,16 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case ELE_HOLY : type = SC_ASPERSIO; break; } clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); + sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); - sc_start2(bl,SC_TK_SEVENWIND,100,skill_lv,skill->get_ele(skill_id,skill_lv),skill->get_time(skill_id,skill_lv)); + sc_start2(src,bl,SC_TK_SEVENWIND,100,skill_lv,skill->get_ele(skill_id,skill_lv),skill->get_time(skill_id,skill_lv)); break; case PR_KYRIE: case MER_KYRIE: clif->skill_nodamage(bl,bl,skill_id,skill_lv, - sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); + sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); break; //Passive Magnum, should had been casted on yourself. case SM_MAGNUM: @@ -5404,9 +5552,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui src,skill_id,skill_lv,tick, flag|BCT_ENEMY|1, skill->castend_damage_id); clif->skill_nodamage (src,src,skill_id,skill_lv,1); // Initiate 10% of your damage becomes fire element. - sc_start4(src,SC_SUB_WEAPONPROPERTY,100,3,20,0,0,skill->get_time2(skill_id, skill_lv)); + sc_start4(src,src,SC_SUB_WEAPONPROPERTY,100,3,20,0,0,skill->get_time2(skill_id, skill_lv)); if( sd ) - skill->blockpc_start(sd, skill_id, skill->get_time(skill_id, skill_lv), false); + skill->blockpc_start(sd, skill_id, skill->get_time(skill_id, skill_lv)); else if( bl->type == BL_MER ) skill->blockmerc_start((TBL_MER*)bl, skill_id, skill->get_time(skill_id, skill_lv)); break; @@ -5492,6 +5640,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case NC_SHAPESHIFT: case WL_RECOGNIZEDSPELL: case GC_VENOMIMPRESS: + case SC_INVISIBILITY: case SC_DEADLYINFECT: case LG_EXEEDBREAK: case LG_PRESTIGE: @@ -5510,7 +5659,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case RK_CRUSHSTRIKE: case ALL_ODINS_POWER: clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); + sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); break; case SO_STRIKING: @@ -5519,7 +5668,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui bonus += (pc->checkskill(sd, SA_FLAMELAUNCHER)+pc->checkskill(sd, SA_FROSTWEAPON)+pc->checkskill(sd, SA_LIGHTNINGLOADER)+pc->checkskill(sd, SA_SEISMICWEAPON))*5; clif->skill_nodamage( src, bl, skill_id, skill_lv, battle->check_target(src,bl,BCT_PARTY) > 0 ? - sc_start2(bl, type, 100, skill_lv, bonus, skill->get_time(skill_id,skill_lv)) : + sc_start2(src, bl, type, 100, skill_lv, bonus, skill->get_time(skill_id,skill_lv)) : 0 ); } @@ -5527,15 +5676,15 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case NPC_STOP: if( clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start2(bl,type,100,skill_lv,src->id,skill->get_time(skill_id,skill_lv)) ) ) - sc_start2(src,type,100,skill_lv,bl->id,skill->get_time(skill_id,skill_lv)); + sc_start2(src,bl,type,100,skill_lv,src->id,skill->get_time(skill_id,skill_lv)) ) ) + sc_start2(src,src,type,100,skill_lv,bl->id,skill->get_time(skill_id,skill_lv)); break; case HP_ASSUMPTIO: if( sd && dstmd ) clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); else clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); + sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); break; case MG_SIGHT: case MER_SIGHT: @@ -5545,23 +5694,25 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case NPC_STONESKIN: case NPC_ANTIMAGIC: clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start2(bl,type,100,skill_lv,skill_id,skill->get_time(skill_id,skill_lv))); + sc_start2(src,bl,type,100,skill_lv,skill_id,skill->get_time(skill_id,skill_lv))); break; case HLIF_AVOID: case HAMI_DEFENCE: - i = skill->get_time(skill_id,skill_lv); - clif->skill_nodamage(bl,bl,skill_id,skill_lv,sc_start(bl,type,100,skill_lv,i)); // Master - clif->skill_nodamage(src,src,skill_id,skill_lv,sc_start(src,type,100,skill_lv,i)); // Homunc + { + int duration = skill->get_time(skill_id,skill_lv); + clif->skill_nodamage(bl,bl,skill_id,skill_lv,sc_start(src,bl,type,100,skill_lv,duration)); // Master + clif->skill_nodamage(src,src,skill_id,skill_lv,sc_start(src,src,type,100,skill_lv,duration)); // Homunc + } break; case NJ_BUNSINJYUTSU: clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); + sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); status_change_end(bl, SC_NJ_NEN, INVALID_TIMER); break; #if 0 /* Was modified to only affect targetted char. [Skotlex] */ case HP_ASSUMPTIO: if (flag&1) - sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)); + sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)); else { map->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id, skill_lv), BL_PC, @@ -5573,15 +5724,15 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui #endif // 0 case SM_ENDURE: clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); + sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); if (sd) - skill->blockpc_start (sd, skill_id, skill->get_time2(skill_id,skill_lv), false); + skill->blockpc_start (sd, skill_id, skill->get_time2(skill_id,skill_lv)); break; case ALL_ANGEL_PROTECT: if( dstsd ) clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); + sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); else if( sd ) clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); break; @@ -5601,12 +5752,12 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui } } clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); + sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); break; case LK_TENSIONRELAX: clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start4(bl,type,100,skill_lv,0,0,skill->get_time2(skill_id,skill_lv), + sc_start4(src,bl,type,100,skill_lv,0,0,skill->get_time2(skill_id,skill_lv), skill->get_time(skill_id,skill_lv))); break; @@ -5629,7 +5780,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui } sd->mission_mobid = id; sd->mission_count = 0; - pc_setglobalreg(sd,"TK_MISSION_ID", id); + pc_setglobalreg(sd,script->add_str("TK_MISSION_ID"), id); clif->mission_info(sd, id, 0); clif->skill_nodamage(src,bl,skill_id,skill_lv,1); } @@ -5638,7 +5789,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case AC_CONCENTRATION: { clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); + sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); map->foreachinrange(status->change_timer_sub, src, skill->get_splash(skill_id, skill_lv), BL_CHAR, src,NULL,type,tick); @@ -5648,14 +5799,16 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case SM_PROVOKE: case SM_SELFPROVOKE: case MER_PROVOKE: + { + int failure; if( (tstatus->mode&MD_BOSS) || battle->check_undead(tstatus->race,tstatus->def_ele) ) { map->freeblock_unlock(); return 1; } //TODO: How much does base level affects? Dummy value of 1% per level difference used. [Skotlex] clif->skill_nodamage(src,bl,skill_id == SM_SELFPROVOKE ? SM_PROVOKE : skill_id,skill_lv, - (i = sc_start(bl,type, skill_id == SM_SELFPROVOKE ? 100:( 50 + 3*skill_lv + status->get_lv(src) - status->get_lv(bl)), skill_lv, skill->get_time(skill_id,skill_lv)))); - if( !i ) { + (failure = sc_start(src,bl,type, skill_id == SM_SELFPROVOKE ? 100:( 50 + 3*skill_lv + status->get_lv(src) - status->get_lv(bl)), skill_lv, skill->get_time(skill_id,skill_lv)))); + if( !failure ) { if( sd ) clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); map->freeblock_unlock(); @@ -5677,12 +5830,13 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui dstmd->state.provoke_flag = src->id; mob->target(dstmd, src, skill->get_range2(src,skill_id,skill_lv)); } + } break; case ML_DEVOTION: case CR_DEVOTION: { - int count, lv; + int count, lv, i; if( !dstsd || (!sd && !mer) ) { // Only players can be devoted if( sd ) @@ -5726,7 +5880,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui mer->devotion_flag = 1; // Mercenary Devoting Owner clif->skill_nodamage(src, bl, skill_id, skill_lv, - sc_start4(bl, type, 100, src->id, i, skill->get_range2(src,skill_id,skill_lv),0, skill->get_time2(skill_id, skill_lv))); + sc_start4(src, bl, type, 100, src->id, i, skill->get_range2(src,skill_id,skill_lv),0, skill->get_time2(skill_id, skill_lv))); clif->devotion(src, NULL); } break; @@ -5743,7 +5897,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case CH_SOULCOLLECT: if(sd) { - int limit = 5; + int limit = 5, i; if( sd->sc.data[SC_RAISINGDRAGON] ) limit += sd->sc.data[SC_RAISINGDRAGON]->val1; clif->skill_nodamage(src,bl,skill_id,skill_lv,1); @@ -5767,18 +5921,20 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui break; case MO_ABSORBSPIRITS: - i = 0; + { + int sp = 0; if (dstsd && dstsd->spiritball && (sd == dstsd || map_flag_vs(src->m)) && ((dstsd->class_&MAPID_BASEMASK)!=MAPID_GUNSLINGER || (dstsd->class_&MAPID_UPPERMASK)!=MAPID_REBELLION)) { // split the if for readability, and included gunslingers in the check so that their coins cannot be removed [Reddozen] - i = dstsd->spiritball * 7; + sp = dstsd->spiritball * 7; pc->delspiritball(dstsd,dstsd->spiritball,0); } else if (dstmd && !(tstatus->mode&MD_BOSS) && rnd() % 100 < 20) { // check if target is a monster and not a Boss, for the 20% chance to absorb 2 SP per monster's level [Reddozen] - i = 2 * dstmd->level; + sp = 2 * dstmd->level; mob->target(dstmd,src,0); } - if (i) status->heal(src, 0, i, 3); - clif->skill_nodamage(src,bl,skill_id,skill_lv,i?1:0); + if (sp) status->heal(src, 0, sp, 3); + clif->skill_nodamage(src,bl,skill_id,skill_lv,sp?1:0); + } break; case AC_MAKINGARROW: @@ -5804,7 +5960,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case BS_HAMMERFALL: clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start(bl,SC_STUN,(20 + 10 * skill_lv),skill_lv,skill->get_time2(skill_id,skill_lv))); + sc_start(src,bl,SC_STUN,(20 + 10 * skill_lv),skill_lv,skill->get_time2(skill_id,skill_lv))); break; case RG_RAID: skill->area_temp[1] = 0; @@ -5825,12 +5981,15 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case SR_RAMPAGEBLASTER: case SR_HOWLINGOFLION: case KO_HAPPOKUNAI: + { + int count = 0; skill->area_temp[1] = 0; clif->skill_nodamage(src,bl,skill_id,skill_lv,1); - i = map->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id, skill_lv), splash_target(src), + count = map->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id, skill_lv), splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill->castend_damage_id); - if( !i && ( skill_id == NC_AXETORNADO || skill_id == SR_SKYNETBLOW || skill_id == KO_HAPPOKUNAI ) ) + if( !count && ( skill_id == NC_AXETORNADO || skill_id == SR_SKYNETBLOW || skill_id == KO_HAPPOKUNAI ) ) clif->skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + } break; case NC_EMERGENCYCOOL: @@ -5878,18 +6037,20 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case HVAN_EXPLOSION: //[orn] case NPC_SELFDESTRUCTION: + { //Self Destruction hits everyone in range (allies+enemies) //Except for Summoned Marine spheres on non-versus maps, where it's just enemy. - i = ((!md || md->special_state.ai == 2) && !map_flag_vs(src->m))? + int targetmask = ((!md || md->special_state.ai == 2) && !map_flag_vs(src->m))? BCT_ENEMY:BCT_ALL; clif->skill_nodamage(src, src, skill_id, -1, 1); map->delblock(src); //Required to prevent chain-self-destructions hitting back. map->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id, skill_lv), splash_target(src), - src, skill_id, skill_lv, tick, flag|i, + src, skill_id, skill_lv, tick, flag|targetmask, skill->castend_damage_id); map->addblock(src); status->damage(src, src, sstatus->max_hp,0,0,1); + } break; case AL_ANGELUS: @@ -5901,18 +6062,18 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case CASH_ASSUMPTIO: case WM_FRIGG_SONG: if( sd == NULL || sd->status.party_id == 0 || (flag & 1) ) - clif->skill_nodamage(bl, bl, skill_id, skill_lv, sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); + clif->skill_nodamage(bl, bl, skill_id, skill_lv, sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); else if( sd ) party->foreachsamemap(skill->area_sub, sd, skill->get_splash(skill_id, skill_lv), src, skill_id, skill_lv, tick, flag|BCT_PARTY|1, skill->castend_nodamage_id); break; case MER_MAGNIFICAT: if( mer != NULL ) { - clif->skill_nodamage(bl, bl, skill_id, skill_lv, sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); + clif->skill_nodamage(bl, bl, skill_id, skill_lv, sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); if( mer->master && mer->master->status.party_id != 0 && !(flag&1) ) party->foreachsamemap(skill->area_sub, mer->master, skill->get_splash(skill_id, skill_lv), src, skill_id, skill_lv, tick, flag|BCT_PARTY|1, skill->castend_nodamage_id); else if( mer->master && !(flag&1) ) - clif->skill_nodamage(src, &mer->master->bl, skill_id, skill_lv, sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); + clif->skill_nodamage(src, &mer->master->bl, skill_id, skill_lv, sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); } break; @@ -5922,7 +6083,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case BS_OVERTHRUST: if (sd == NULL || sd->status.party_id == 0 || (flag & 1)) { clif->skill_nodamage(bl,bl,skill_id,skill_lv, - sc_start2(bl,type,100,skill_lv,(src == bl)? 1:0,skill->get_time(skill_id,skill_lv))); + sc_start2(src,bl,type,100,skill_lv,(src == bl)? 1:0,skill->get_time(skill_id,skill_lv))); } else if (sd) { party->foreachsamemap(skill->area_sub, sd,skill->get_splash(skill_id, skill_lv), @@ -5951,7 +6112,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui map->freeblock_unlock(); return 0; } - clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); + clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); break; case SL_KAITE: case SL_KAAHI: @@ -5966,21 +6127,24 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui || dstsd->status.char_id == sd->status.child ) ) { - status->change_start(src,SC_STUN,10000,skill_lv,0,0,0,500,8); + status->change_start(src,src,SC_STUN,10000,skill_lv,0,0,0,500,8); clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); break; } } clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start(bl,type,100,skill_lv,skill->get_time(skill_id, skill_lv))); + sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id, skill_lv))); break; case SM_AUTOBERSERK: case MER_AUTOBERSERK: + { + int failure; if( tsce ) - i = status_change_end(bl, type, INVALID_TIMER); + failure = status_change_end(bl, type, INVALID_TIMER); else - i = sc_start(bl,type,100,skill_lv,60000); - clif->skill_nodamage(src,bl,skill_id,skill_lv,i); + failure = sc_start(src,bl,type,100,skill_lv,60000); + clif->skill_nodamage(src,bl,skill_id,skill_lv,failure); + } break; case TF_HIDING: case ST_CHASEWALK: @@ -5995,7 +6159,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui map->freeblock_unlock(); return 0; } - clif->skill_nodamage(src,bl,skill_id,-1,sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); + clif->skill_nodamage(src,bl,skill_id,-1,sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); break; case TK_RUN: if (tsce) { @@ -6003,7 +6167,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui map->freeblock_unlock(); return 0; } - clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start4(bl,type,100,skill_lv,unit->getdir(bl),0,0,0)); + clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start4(src,bl,type,100,skill_lv,unit->getdir(bl),0,0,0)); if (sd) // If the client receives a skill-use packet inmediately before a walkok packet, it will discard the walk packet! [Skotlex] clif->walkok(sd); // So aegis has to resend the walk ok. break; @@ -6011,22 +6175,25 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case GC_CLOAKINGEXCEED: case LG_FORCEOFVANGUARD: case SC_REPRODUCE: - case SC_INVISIBILITY: if (tsce) { - i = status_change_end(bl, type, INVALID_TIMER); - if( i ) - clif->skill_nodamage(src,bl,skill_id,( skill_id == LG_FORCEOFVANGUARD ) ? skill_lv : -1,i); + int failure = status_change_end(bl, type, INVALID_TIMER); + if( failure ) + clif->skill_nodamage(src,bl,skill_id,( skill_id == LG_FORCEOFVANGUARD ) ? skill_lv : -1,failure); else if( sd ) clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); + if ( skill_id == LG_FORCEOFVANGUARD ) + break; map->freeblock_unlock(); return 0; } case RA_CAMOUFLAGE: - i = sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)); - if( i ) - clif->skill_nodamage(src,bl,skill_id,( skill_id == LG_FORCEOFVANGUARD ) ? skill_lv : -1,i); + { + int failure = sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)); + if( failure ) + clif->skill_nodamage(src,bl,skill_id,( skill_id == LG_FORCEOFVANGUARD ) ? skill_lv : -1,failure); else if( sd ) clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); + } break; case BD_ADAPTATION: @@ -6051,18 +6218,18 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui break; case BA_PANGVOICE: - clif->skill_nodamage(src,bl,skill_id,skill_lv, sc_start(bl,SC_CONFUSION,50,7,skill->get_time(skill_id,skill_lv))); + clif->skill_nodamage(src,bl,skill_id,skill_lv, sc_start(src,bl,SC_CONFUSION,50,7,skill->get_time(skill_id,skill_lv))); break; case DC_WINKCHARM: if( dstsd ) - clif->skill_nodamage(src,bl,skill_id,skill_lv, sc_start(bl,SC_CONFUSION,30,7,skill->get_time2(skill_id,skill_lv))); + clif->skill_nodamage(src,bl,skill_id,skill_lv, sc_start(src,bl,SC_CONFUSION,30,7,skill->get_time2(skill_id,skill_lv))); else if( dstmd ) { if( status->get_lv(src) > status->get_lv(bl) && (tstatus->race == RC_DEMON || tstatus->race == RC_DEMIHUMAN || tstatus->race == RC_ANGEL) && !(tstatus->mode&MD_BOSS) ) { - clif->skill_nodamage(src,bl,skill_id,skill_lv, sc_start2(bl,type,70,skill_lv,src->id,skill->get_time(skill_id,skill_lv))); + clif->skill_nodamage(src,bl,skill_id,skill_lv, sc_start2(src,bl,type,70,skill_lv,src->id,skill->get_time(skill_id,skill_lv))); } else { clif->skill_nodamage(src,bl,skill_id,skill_lv,0); if(sd) clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); @@ -6081,15 +6248,14 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case RG_STEALCOIN: if(sd) { - if(pc->steal_coin(sd,bl)) - { + int amount = pc->steal_coin(sd, bl); + if( amount > 0 ) { dstmd->state.provoke_flag = src->id; - mob->target(dstmd, src, skill->get_range2(src,skill_id,skill_lv)); - clif->skill_nodamage(src,bl,skill_id,skill_lv,1); + mob->target(dstmd, src, skill->get_range2(src, skill_id, skill_lv)); + clif->skill_nodamage(src, bl, skill_id, amount, 1); - } - else - clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); + } else + clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0); } break; @@ -6111,7 +6277,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui if (sd) clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); break; } - if (sc_start4(bl,SC_STONE,(skill_lv*4+20)+brate, + if (sc_start4(src,bl,SC_STONE,(skill_lv*4+20)+brate, skill_lv, 0, 0, skill->get_time(skill_id, skill_lv), skill->get_time2(skill_id,skill_lv))) clif->skill_nodamage(src,bl,skill_id,skill_lv,1); @@ -6163,7 +6329,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui } //Is this equation really right? It looks so... special. if( battle->check_undead(tstatus->race,tstatus->def_ele) ) { - status->change_start(bl, SC_BLIND, + status->change_start(src, bl, SC_BLIND, 100*(100-(tstatus->int_/2+tstatus->vit/3+tstatus->luk/10)), 1,0,0,0, skill->get_time2(skill_id, skill_lv) * (100-(tstatus->int_+tstatus->vit)/2)/100,0); } @@ -6257,7 +6423,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case MC_VENDING: if(sd) { //Prevent vending of GMs with unnecessary Level to trade/drop. [Skotlex] - if ( !pc->can_give_items(sd) ) + if ( !pc_can_give_items(sd) ) clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); else { sd->state.prevend = sd->state.workinprogress = 3; @@ -6344,18 +6510,18 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case GC_WEAPONCRUSH: case SC_STRIPACCESSARY: { unsigned short location = 0; - int d = 0; + int d = 0, rate; //Rate in percent if ( skill_id == ST_FULLSTRIP ) { - i = 5 + 2*skill_lv + (sstatus->dex - tstatus->dex)/5; + rate = 5 + 2*skill_lv + (sstatus->dex - tstatus->dex)/5; } else if( skill_id == SC_STRIPACCESSARY ) { - i = 12 + 2 * skill_lv + (sstatus->dex - tstatus->dex)/5; + rate = 12 + 2 * skill_lv + (sstatus->dex - tstatus->dex)/5; } else { - i = 5 + 5*skill_lv + (sstatus->dex - tstatus->dex)/5; + rate = 5 + 5*skill_lv + (sstatus->dex - tstatus->dex)/5; } - if (i < 5) i = 5; //Minimum rate 5% + if (rate < 5) rate = 5; //Minimum rate 5% //Duration in ms if( skill_id == GC_WEAPONCRUSH){ @@ -6399,11 +6565,11 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui } //Attempts to strip at rate i and duration d - if( (i = skill->strip_equip(bl, location, i, skill_lv, d)) || (skill_id != ST_FULLSTRIP && skill_id != GC_WEAPONCRUSH ) ) - clif->skill_nodamage(src,bl,skill_id,skill_lv,i); + if( (rate = skill->strip_equip(bl, location, rate, skill_lv, d)) || (skill_id != ST_FULLSTRIP && skill_id != GC_WEAPONCRUSH ) ) + clif->skill_nodamage(src,bl,skill_id,skill_lv,rate); //Nothing stripped. - if( sd && !i ) + if( sd && !rate ) clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); break; } @@ -6529,14 +6695,14 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui } clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); + sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); } break; case AM_TWILIGHT1: if (sd) { clif->skill_nodamage(src,bl,skill_id,skill_lv,1); //Prepare 200 White Potions. - if (!skill->produce_mix(sd, skill_id, 504, 0, 0, 0, 200)) + if (!skill->produce_mix(sd, skill_id, ITEMID_WHITE_POTION, 0, 0, 0, 200)) clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); } break; @@ -6544,36 +6710,44 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui if (sd) { clif->skill_nodamage(src,bl,skill_id,skill_lv,1); //Prepare 200 Slim White Potions. - if (!skill->produce_mix(sd, skill_id, 547, 0, 0, 0, 200)) + if (!skill->produce_mix(sd, skill_id, ITEMID_WHITE_SLIM_POTION, 0, 0, 0, 200)) clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); } break; case AM_TWILIGHT3: if (sd) { - int ebottle = pc->search_inventory(sd,713); + int ebottle = pc->search_inventory(sd,ITEMID_EMPTY_BOTTLE); if( ebottle >= 0 ) ebottle = sd->status.inventory[ebottle].amount; //check if you can produce all three, if not, then fail: - if (!skill->can_produce_mix(sd,970,-1, 100) //100 Alcohol - || !skill->can_produce_mix(sd,7136,-1, 50) //50 Acid Bottle - || !skill->can_produce_mix(sd,7135,-1, 50) //50 Flame Bottle + if (!skill->can_produce_mix(sd,ITEMID_ALCHOL,-1, 100) //100 Alcohol + || !skill->can_produce_mix(sd,ITEMID_ACID_BOTTLE,-1, 50) //50 Acid Bottle + || !skill->can_produce_mix(sd,ITEMID_FIRE_BOTTLE,-1, 50) //50 Flame Bottle || ebottle < 200 //200 empty bottle are required at total. ) { clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); break; } clif->skill_nodamage(src,bl,skill_id,skill_lv,1); - skill->produce_mix(sd, skill_id, 970, 0, 0, 0, 100); - skill->produce_mix(sd, skill_id, 7136, 0, 0, 0, 50); - skill->produce_mix(sd, skill_id, 7135, 0, 0, 0, 50); + skill->produce_mix(sd, skill_id, ITEMID_ALCHOL, 0, 0, 0, 100); + skill->produce_mix(sd, skill_id, ITEMID_ACID_BOTTLE, 0, 0, 0, 50); + skill->produce_mix(sd, skill_id, ITEMID_FIRE_BOTTLE, 0, 0, 0, 50); } break; case SA_DISPELL: - if (flag&1 || (i = skill->get_splash(skill_id, skill_lv)) < 1) - { + { + int splash; + if (flag&1 || (splash = skill->get_splash(skill_id, skill_lv)) < 1) { + int i; + if( sd && dstsd && !map_flag_vs(sd->bl.m) + && (sd->status.party_id == 0 || sd->status.party_id != dstsd->status.party_id) ) { + // Outside PvP it should only affect party members and no skill fail message. + break; + } clif->skill_nodamage(src,bl,skill_id,skill_lv,1); if((dstsd && (dstsd->class_&MAPID_UPPERMASK) == MAPID_SOUL_LINKER) || (tsc && tsc->data[SC_SOULLINK] && tsc->data[SC_SOULLINK]->val2 == SL_ROGUE) //Rogue's spirit defends againt dispel. + || (dstsd && pc_ismadogear(dstsd)) || rnd()%100 >= 50+10*skill_lv ) { if (sd) @@ -6582,14 +6756,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui } if(status->isimmune(bl) || !tsc || !tsc->count) break; - - if( sd && dstsd && !map_flag_vs(sd->bl.m) - && (sd->status.party_id == 0 || sd->status.party_id != dstsd->status.party_id) ) { - // Outside PvP it should only affect party members - clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); - break; - } - for(i = 0; i < SC_MAX; i++) { if ( !tsc->data[i] ) continue; @@ -6624,11 +6790,13 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui status_change_end(bl, (sc_type)i, INVALID_TIMER); } break; + } else { + //Affect all targets on splash area. + map->foreachinrange(skill->area_sub, bl, splash, BL_CHAR, + src, skill_id, skill_lv, tick, flag|1, + skill->castend_damage_id); } - //Affect all targets on splash area. - map->foreachinrange(skill->area_sub, bl, i, BL_CHAR, - src, skill_id, skill_lv, tick, flag|1, - skill->castend_damage_id); + } break; case TF_BACKSLIDING: //This is the correct implementation as per packet logging information. [Skotlex] @@ -6666,7 +6834,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui if(sd) { int sp = skill->get_sp(sd->skill_id_old,sd->skill_lv_old); if( skill_id == SO_SPELLFIST ){ - sc_start4(src,type,100,skill_lv+1,skill_lv,sd->skill_id_old,sd->skill_lv_old,skill->get_time(skill_id,skill_lv)); + sc_start4(src,src,type,100,skill_lv+1,skill_lv,sd->skill_id_old,sd->skill_lv_old,skill->get_time(skill_id,skill_lv)); sd->skill_id_old = sd->skill_lv_old = 0; break; } @@ -6721,7 +6889,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui break; case SA_MAGICROD: clif->skill_nodamage(src,src,SA_MAGICROD,skill_lv,1); - sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)); + sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)); break; case SA_AUTOSPELL: clif->skill_nodamage(src,bl,skill_id,skill_lv,1); @@ -6756,7 +6924,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui maxlv = 3; } if(spellid > 0) - sc_start4(src,SC_AUTOSPELL,100,skill_lv,spellid,maxlv,0, + sc_start4(src,src,SC_AUTOSPELL,100,skill_lv,spellid,maxlv,0, skill->get_time(SA_AUTOSPELL,skill_lv)); } break; @@ -6787,7 +6955,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case NPC_CHANGEDARKNESS: case NPC_CHANGETELEKINESIS: clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start2(bl, type, 100, skill_lv, skill->get_ele(skill_id,skill_lv), + sc_start2(src, bl, type, 100, skill_lv, skill->get_ele(skill_id,skill_lv), skill->get_time(skill_id, skill_lv))); break; case NPC_CHANGEUNDEAD: @@ -6795,7 +6963,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui //TO-DO This is ugly, fix it if(tstatus->def_ele==ELE_UNDEAD || tstatus->def_ele==ELE_DARK) break; clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start2(bl, type, 100, skill_lv, skill->get_ele(skill_id,skill_lv), + sc_start2(src, bl, type, 100, skill_lv, skill->get_ele(skill_id,skill_lv), skill->get_time(skill_id, skill_lv))); break; @@ -6810,7 +6978,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui int skill_time = skill->get_time(skill_id,skill_lv); struct unit_data *ud = unit->bl2ud(bl); if (clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start(bl,type,100,skill_lv,skill_time)) + sc_start(src,bl,type,100,skill_lv,skill_time)) && ud) { //Disable attacking/acting/moving for skill's duration. ud->attackabletime = ud->canact_tick = @@ -6822,18 +6990,18 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case NPC_REBIRTH: if( md && md->state.rebirth ) break; // only works once - sc_start(bl,type,100,skill_lv,-1); + sc_start(src,bl,type,100,skill_lv,-1); break; case NPC_DARKBLESSING: clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start2(bl,type,(50+skill_lv*5),skill_lv,skill_lv,skill->get_time2(skill_id,skill_lv))); + sc_start2(src,bl,type,(50+skill_lv*5),skill_lv,skill_lv,skill->get_time2(skill_id,skill_lv))); break; case NPC_LICK: status_zap(bl, 0, 100); clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start(bl,type,(skill_lv*5),skill_lv,skill->get_time2(skill_id,skill_lv))); + sc_start(src,bl,type,(skill_lv*5),skill_lv,skill->get_time2(skill_id,skill_lv))); break; case NPC_SUICIDE: @@ -6865,7 +7033,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui if (i > SC_ATTHASTE_INFINITY) i = SC_ATTHASTE_INFINITY; clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start(bl,(sc_type)i,100,skill_lv,skill_lv * 60000)); + sc_start(src,bl,(sc_type)i,100,skill_lv,skill_lv * 60000)); } break; @@ -6920,7 +7088,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui mob->unlocktarget(md,tick); if(md->db->skill[md->skill_idx].val[1] || md->db->skill[md->skill_idx].val[2]) - sc_start4(src, type, 100, skill_lv, + sc_start4(src, src, type, 100, skill_lv, md->db->skill[md->skill_idx].val[1], md->db->skill[md->skill_idx].val[2], md->db->skill[md->skill_idx].val[3], @@ -6929,21 +7097,21 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui break; case NPC_POWERUP: - sc_start(bl,SC_INCATKRATE,100,200,skill->get_time(skill_id, skill_lv)); + sc_start(src,bl,SC_INCATKRATE,100,200,skill->get_time(skill_id, skill_lv)); clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start(bl,type,100,100,skill->get_time(skill_id, skill_lv))); + sc_start(src,bl,type,100,100,skill->get_time(skill_id, skill_lv))); break; case NPC_AGIUP: - sc_start(bl,SC_MOVHASTE_INFINITY,100,skill_lv,skill->get_time(skill_id, skill_lv)); + sc_start(src,bl,SC_MOVHASTE_INFINITY,100,skill_lv,skill->get_time(skill_id, skill_lv)); clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start(bl,type,100,100,skill->get_time(skill_id, skill_lv))); + sc_start(src,bl,type,100,100,skill->get_time(skill_id, skill_lv))); break; case NPC_INVISIBLE: //Have val4 passed as 6 is for "infinite cloak" (do not end on attack/skill use). clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start4(bl,type,100,skill_lv,0,0,6,skill->get_time(skill_id,skill_lv))); + sc_start4(src,bl,type,100,skill_lv,0,0,6,skill->get_time(skill_id,skill_lv))); break; case NPC_SIEGEMODE: @@ -6973,12 +7141,12 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui struct map_session_data *m_sd = pc->get_mother(sd); bool we_baby_parents = false; if(m_sd && check_distance_bl(bl,&m_sd->bl,AREA_SIZE)) { - sc_start(&m_sd->bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)); + sc_start(src,&m_sd->bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)); clif->specialeffect(&m_sd->bl,408,AREA); we_baby_parents = true; } if(f_sd && check_distance_bl(bl,&f_sd->bl,AREA_SIZE)) { - sc_start(&f_sd->bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)); + sc_start(src,&f_sd->bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)); clif->specialeffect(&f_sd->bl,408,AREA); we_baby_parents = true; } @@ -6987,7 +7155,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui map->freeblock_unlock(); return 0; } - else status->change_start(bl,SC_STUN,10000,skill_lv,0,0,0,skill->get_time2(skill_id,skill_lv),8); + else + status->change_start(src,bl,SC_STUN,10000,skill_lv,0,0,0,skill->get_time2(skill_id,skill_lv),8); } break; @@ -7017,19 +7186,20 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui if( su && (sg = su->group) && (src->type == BL_MER || sg->src_id == src->id || map_flag_vs(bl->m)) && (skill->get_inf2(sg->skill_id)&INF2_TRAP) ) { clif->skill_nodamage(src, bl, skill_id, skill_lv, 1); - if( sd && !(sg->unit_id == UNT_USED_TRAPS || (sg->unit_id == UNT_ANKLESNARE && sg->val2 != 0 )) ) { + if( sd && !(sg->unit_id == UNT_USED_TRAPS || (sg->unit_id == UNT_ANKLESNARE && sg->val2 != 0 )) && sg->unit_id != UNT_THORNS_TRAP ) { // prevent picking up expired traps if( battle_config.skill_removetrap_type ) { + int i; // get back all items used to deploy the trap for( i = 0; i < 10; i++ ) { if( skill->db[su->group->skill_id].itemid[i] > 0 ) { - int flag; + int success; struct item item_tmp; memset(&item_tmp,0,sizeof(item_tmp)); item_tmp.nameid = skill->db[su->group->skill_id].itemid[i]; item_tmp.identify = 1; - if( item_tmp.nameid && (flag=pc->additem(sd,&item_tmp,skill->db[su->group->skill_id].amount[i],LOG_TYPE_OTHER)) ) { - clif->additem(sd,0,0,flag); + if( item_tmp.nameid && (success=pc->additem(sd,&item_tmp,skill->db[su->group->skill_id].amount[i],LOG_TYPE_OTHER)) ) { + clif->additem(sd,0,0,success); map->addflooritem(&item_tmp,skill->db[su->group->skill_id].amount[i],sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0); } } @@ -7075,8 +7245,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case UNT_TALKIEBOX: su->group->unit_id = UNT_USED_TRAPS; clif->changetraplook(bl, UNT_USED_TRAPS); - su->group->limit=DIFF_TICK(tick+1500,su->group->tick); - su->limit=DIFF_TICK(tick+1500,su->group->tick); + su->group->limit=DIFF_TICK32(tick+1500,su->group->tick); + su->limit=DIFF_TICK32(tick+1500,su->group->tick); } } } @@ -7099,9 +7269,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui return 1; } clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start4(bl,type,100,skill_lv,skill_id,src->id,skill->get_time(skill_id,skill_lv),1000)); + sc_start4(src,bl,type,100,skill_lv,skill_id,src->id,skill->get_time(skill_id,skill_lv),1000)); #ifndef RENEWAL - if (sd) skill->blockpc_start (sd, skill_id, skill->get_time(skill_id, skill_lv)+3000, false); + if (sd) skill->blockpc_start (sd, skill_id, skill->get_time(skill_id, skill_lv)+3000); #endif break; @@ -7121,7 +7291,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui //Has a 55% + skill_lv*5% success chance. if (!clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start(bl,type,55+5*skill_lv,skill_lv,skill->get_time(skill_id,skill_lv))) + sc_start(src,bl,type,55+5*skill_lv,skill_lv,skill->get_time(skill_id,skill_lv))) ) { if (sd) clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); map->freeblock_unlock(); @@ -7215,7 +7385,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui for (i=0 ; i<4; i++) { if( bl->type != BL_PC || ( dstsd && pc->checkequip(dstsd,equip[i]) < 0 ) ) continue; - sc_start(bl,(sc_type)(SC_PROTECTWEAPON + i),100,skill_lv,skilltime); + sc_start(src,bl,(sc_type)(SC_PROTECTWEAPON + i),100,skill_lv,skilltime); s++; } if( sd && !s ){ @@ -7237,7 +7407,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui && (tsce->val1&0xFFFF) != CG_MOONLIT) //Can't use Longing for Freedom while under Moonlight Petals. [Skotlex] { clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); + sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); } } break; @@ -7269,7 +7439,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui status_percent_damage(src, bl, 0, 100, false); break; case 1: // matk halved - sc_start(bl,SC_INCMATKRATE,100,-50,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_INCMATKRATE,100,-50,skill->get_time2(skill_id,skill_lv)); break; case 2: // all buffs removed status->change_clear_buffs(bl,1); @@ -7277,7 +7447,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case 3: // 1000 damage, random armor destroyed { status_fix_damage(src, bl, 1000, 0); - clif->damage(src,bl,tick,0,0,1000,0,0,0); + clif->damage(src,bl,0,0,1000,0,0,0); if( !status->isdead(bl) ) { int where[] = { EQP_ARMOR, EQP_SHIELD, EQP_HELM, EQP_SHOES, EQP_GARMENT }; skill->break_equip(bl, where[rnd()%5], 10000, BCT_ENEMY); @@ -7285,7 +7455,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui } break; case 4: // atk halved - sc_start(bl,SC_INCATKRATE,100,-50,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_INCATKRATE,100,-50,skill->get_time2(skill_id,skill_lv)); break; case 5: // 2000HP heal, random teleported status->heal(src, 2000, 0, 0); @@ -7301,38 +7471,38 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case 7: // stop freeze or stoned { enum sc_type sc[] = { SC_STOP, SC_FREEZE, SC_STONE }; - sc_start(bl,sc[rnd()%3],100,skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,sc[rnd()%3],100,skill_lv,skill->get_time2(skill_id,skill_lv)); } break; case 8: // curse coma and poison - sc_start(bl,SC_COMA,100,skill_lv,skill->get_time2(skill_id,skill_lv)); - sc_start(bl,SC_CURSE,100,skill_lv,skill->get_time2(skill_id,skill_lv)); - sc_start(bl,SC_POISON,100,skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_COMA,100,skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_CURSE,100,skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_POISON,100,skill_lv,skill->get_time2(skill_id,skill_lv)); break; case 9: // confusion - sc_start(bl,SC_CONFUSION,100,skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_CONFUSION,100,skill_lv,skill->get_time2(skill_id,skill_lv)); break; case 10: // 6666 damage, atk matk halved, cursed status_fix_damage(src, bl, 6666, 0); - clif->damage(src,bl,tick,0,0,6666,0,0,0); - sc_start(bl,SC_INCATKRATE,100,-50,skill->get_time2(skill_id,skill_lv)); - sc_start(bl,SC_INCMATKRATE,100,-50,skill->get_time2(skill_id,skill_lv)); - sc_start(bl,SC_CURSE,skill_lv,100,skill->get_time2(skill_id,skill_lv)); + clif->damage(src,bl,0,0,6666,0,0,0); + sc_start(src,bl,SC_INCATKRATE,100,-50,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_INCMATKRATE,100,-50,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_CURSE,skill_lv,100,skill->get_time2(skill_id,skill_lv)); break; case 11: // 4444 damage status_fix_damage(src, bl, 4444, 0); - clif->damage(src,bl,tick,0,0,4444,0,0,0); + clif->damage(src,bl,0,0,4444,0,0,0); break; case 12: // stun - sc_start(bl,SC_STUN,100,skill_lv,5000); + sc_start(src,bl,SC_STUN,100,skill_lv,5000); break; case 13: // atk,matk,hit,flee,def reduced - sc_start(bl,SC_INCATKRATE,100,-20,skill->get_time2(skill_id,skill_lv)); - sc_start(bl,SC_INCMATKRATE,100,-20,skill->get_time2(skill_id,skill_lv)); - sc_start(bl,SC_INCHITRATE,100,-20,skill->get_time2(skill_id,skill_lv)); - sc_start(bl,SC_INCFLEERATE,100,-20,skill->get_time2(skill_id,skill_lv)); - sc_start(bl,SC_INCDEFRATE,100,-20,skill->get_time2(skill_id,skill_lv)); - sc_start(bl,type,100,skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_INCATKRATE,100,-20,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_INCMATKRATE,100,-20,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_INCHITRATE,100,-20,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_INCFLEERATE,100,-20,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_INCDEFRATE,100,-20,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,type,100,skill_lv,skill->get_time2(skill_id,skill_lv)); break; default: break; @@ -7365,13 +7535,13 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui if (skill_id == SL_SUPERNOVICE && dstsd && dstsd->die_counter && !(rnd()%100)) { //Erase death count 1% of the casts dstsd->die_counter = 0; - pc_setglobalreg(dstsd,"PC_DIE_COUNTER", 0); + pc_setglobalreg(dstsd,script->add_str("PC_DIE_COUNTER"), 0); clif->specialeffect(bl, 0x152, AREA); //SC_SOULLINK invokes status_calc_pc for us. } clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start4(bl,SC_SOULLINK,100,skill_lv,skill_id,0,0,skill->get_time(skill_id,skill_lv))); - sc_start(src,SC_SMA_READY,100,skill_lv,skill->get_time(SL_SMA,skill_lv)); + sc_start4(src,bl,SC_SOULLINK,100,skill_lv,skill_id,0,0,skill->get_time(skill_id,skill_lv))); + sc_start(src,src,SC_SMA_READY,100,skill_lv,skill->get_time(SL_SMA,skill_lv)); break; case SL_HIGH: if (sd && !(dstsd && (dstsd->class_&JOBL_UPPER) && !(dstsd->class_&JOBL_2) && dstsd->status.base_level < 70)) { @@ -7379,15 +7549,15 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui break; } clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start4(bl,type,100,skill_lv,skill_id,0,0,skill->get_time(skill_id,skill_lv))); - sc_start(src,SC_SMA_READY,100,skill_lv,skill->get_time(SL_SMA,skill_lv)); + sc_start4(src,bl,type,100,skill_lv,skill_id,0,0,skill->get_time(skill_id,skill_lv))); + sc_start(src,src,SC_SMA_READY,100,skill_lv,skill->get_time(SL_SMA,skill_lv)); break; case SL_SWOO: if (tsce) { if(sd) clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); - status->change_start(src,SC_STUN,10000,skill_lv,0,0,0,10000,8); + status->change_start(src,src,SC_STUN,10000,skill_lv,0,0,0,10000,8); status_change_end(bl, SC_SWOO, INVALID_TIMER); break; } @@ -7395,19 +7565,19 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case SL_SKE: if (sd && !battle_config.allow_es_magic_pc && bl->type != BL_MOB) { clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); - status->change_start(src,SC_STUN,10000,skill_lv,0,0,0,500,10); + status->change_start(src,src,SC_STUN,10000,skill_lv,0,0,0,500,10); break; } - clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); + clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); if (skill_id == SL_SKE) - sc_start(src,SC_SMA_READY,100,skill_lv,skill->get_time(SL_SMA,skill_lv)); + sc_start(src,src,SC_SMA_READY,100,skill_lv,skill->get_time(SL_SMA,skill_lv)); break; // New guild skills [Celest] case GD_BATTLEORDER: if(flag&1) { if (status->get_guild_id(src) == status->get_guild_id(bl)) - sc_start(bl,type,100,skill_lv,skill->get_time(skill_id, skill_lv)); + sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id, skill_lv)); } else if (status->get_guild_id(src)) { clif->skill_nodamage(src,bl,skill_id,skill_lv,1); map->foreachinrange(skill->area_sub, src, @@ -7421,7 +7591,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case GD_REGENERATION: if(flag&1) { if (status->get_guild_id(src) == status->get_guild_id(bl)) - sc_start(bl,type,100,skill_lv,skill->get_time(skill_id, skill_lv)); + sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id, skill_lv)); } else if (status->get_guild_id(src)) { clif->skill_nodamage(src,bl,skill_id,skill_lv,1); map->foreachinrange(skill->area_sub, src, @@ -7450,7 +7620,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui { int dx[9]={-1, 1, 0, 0,-1, 1,-1, 1, 0}; int dy[9]={ 0, 0, 1,-1, 1,-1,-1, 1, 0}; - int j = 0; + int i, j = 0; struct guild *g; // i don't know if it actually summons in a circle, but oh well. ;P g = sd ? sd->guild : guild->search(status->get_guild_id(src)); @@ -7504,21 +7674,25 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui /* per official standards, this skill works on players and mobs. */ if (sd && (dstsd || dstmd)) { - i =65 -5*distance_bl(src,bl); //Base rate - if (i < 30) i = 30; + int rate = 65 -5*distance_bl(src,bl); //Base rate + if (rate < 30) rate = 30; clif->skill_nodamage(src,bl,skill_id,skill_lv,1); - sc_start(bl,SC_STUN, i,skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,bl,SC_STUN, rate,skill_lv,skill->get_time2(skill_id,skill_lv)); } break; case AM_CALLHOMUN: //[orn] - if (sd && homun->call(sd)) - clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); + if( sd ) { + if (homun->call(sd)) + clif->skill_nodamage(src, bl, skill_id, skill_lv, 1); + else + clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); + } break; case AM_REST: if (sd) { - if (homun->vaporize(sd,1)) + if (homun->vaporize(sd,HOM_ST_REST)) clif->skill_nodamage(src, bl, skill_id, skill_lv, 1); else clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); @@ -7558,20 +7732,21 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui { static const int per[5][2]={{20,50},{50,60},{25,75},{60,64},{34,67}}; int r = rnd()%100; - i = (skill_lv-1)%5; - if(r<per[i][0]) //Self + int target = (skill_lv-1)%5; + int hp; + if(r<per[target][0]) //Self bl = src; - else if(r<per[i][1]) //Master + else if(r<per[target][1]) //Master bl = battle->get_master(src); else //Enemy bl = map->id2bl(battle->get_target(src)); if (!bl) bl = src; - i = skill->calc_heal(src, bl, skill_id, 1+rnd()%skill_lv, true); + hp = skill->calc_heal(src, bl, skill_id, 1+rnd()%skill_lv, true); //Eh? why double skill packet? - clif->skill_nodamage(src,bl,AL_HEAL,i,1); - clif->skill_nodamage(src,bl,skill_id,i,1); - status->heal(bl, i, 0, 0); + clif->skill_nodamage(src,bl,AL_HEAL,hp,1); + clif->skill_nodamage(src,bl,skill_id,hp,1); + status->heal(bl, hp, 0, 0); } break; //Homun single-target support skills [orn] @@ -7582,7 +7757,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case MH_ANGRIFFS_MODUS: case MH_GOLDENE_FERSE: clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); + sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); if (hd) skill->blockhomun_start(hd, skill_id, skill->get_time2(skill_id,skill_lv)); break; @@ -7590,9 +7765,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case NPC_DRAGONFEAR: if (flag&1) { const enum sc_type sc[] = { SC_STUN, SC_SILENCE, SC_CONFUSION, SC_BLOODING }; - int j; + int i, j; j = i = rnd()%ARRAYLENGTH(sc); - while ( !sc_start2(bl,sc[i],100,skill_lv,src->id,skill->get_time2(skill_id,i+1)) ) { + while ( !sc_start2(src,bl,sc[i],100,skill_lv,src->id,skill->get_time2(skill_id,i+1)) ) { i++; if ( i == ARRAYLENGTH(sc) ) i = 0; @@ -7620,13 +7795,13 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui if (flag&1){ switch( type ){ case SC_BURNING: - sc_start4(bl,type,100,skill_lv,0,src->id,0,skill->get_time2(skill_id,skill_lv)); + sc_start4(src,bl,type,100,skill_lv,0,src->id,0,skill->get_time2(skill_id,skill_lv)); break; case SC_SIREN: - sc_start2(bl,type,100,skill_lv,src->id,skill->get_time2(skill_id,skill_lv)); + sc_start2(src,bl,type,100,skill_lv,src->id,skill->get_time2(skill_id,skill_lv)); break; default: - sc_start2(bl,type,100,skill_lv,src->id,skill->get_time2(skill_id,skill_lv)); + sc_start2(src,bl,type,100,skill_lv,src->id,skill->get_time2(skill_id,skill_lv)); } } else { skill->area_temp[2] = 0; //For SD_PREAMBLE @@ -7660,7 +7835,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui party->foreachsamemap(skill->area_sub, sd, skill->get_splash(skill_id, skill_lv), src, skill_id, skill_lv, tick, flag|BCT_PARTY|1, skill->castend_nodamage_id); } else - clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); + clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); break; case NPC_TALK: case ALL_WEWISH: @@ -7676,11 +7851,11 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui break; case RK_ENCHANTBLADE: clif->skill_nodamage(src,bl,skill_id,skill_lv,// formula not confirmed - sc_start2(bl,type,100,skill_lv,100+20*skill_lv/*+sstatus->int_/2+status->get_lv(bl)/10*/,skill->get_time(skill_id,skill_lv))); + sc_start2(src,bl,type,100,skill_lv,(100+20*skill_lv)*status->get_lv(src)/150+sstatus->int_,skill->get_time(skill_id,skill_lv))); break; case RK_DRAGONHOWLING: if( flag&1) - sc_start(bl,type,50 + 6 * skill_lv,skill_lv,skill->get_time(skill_id,skill_lv)); + sc_start(src,bl,type,50 + 6 * skill_lv,skill_lv,skill->get_time(skill_id,skill_lv)); else { skill->area_temp[2] = 0; clif->skill_nodamage(src,bl,skill_id,skill_lv,1); @@ -7692,20 +7867,23 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui break; case RK_IGNITIONBREAK: case LG_EARTHDRIVE: + { + int splash; clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); - i = skill->get_splash(skill_id,skill_lv); + splash = skill->get_splash(skill_id,skill_lv); if( skill_id == LG_EARTHDRIVE ) { int dummy = 1; - map->foreachinarea(skill->cell_overlap, src->m, src->x-i, src->y-i, src->x+i, src->y+i, BL_SKILL, LG_EARTHDRIVE, &dummy, src); + map->foreachinarea(skill->cell_overlap, src->m, src->x-splash, src->y-splash, src->x+splash, src->y+splash, BL_SKILL, LG_EARTHDRIVE, &dummy, src); } - map->foreachinrange(skill->area_sub, bl,i,BL_CHAR, + map->foreachinrange(skill->area_sub, bl,splash,BL_CHAR, src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id); + } break; case RK_STONEHARDSKIN: if( sd ) { - int heal = sstatus->hp / 4; // 25% HP + int heal = sstatus->hp / 5; // 20% HP if( status->charge(bl,heal,0) ) - clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start2(bl,type,100,skill_lv,heal,skill->get_time(skill_id,skill_lv))); + clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start2(src,bl,type,100,skill_lv,heal,skill->get_time(skill_id,skill_lv))); else clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); } @@ -7714,36 +7892,43 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui { int heal = status_get_max_hp(bl) * 25 / 100; clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); + sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); status->heal(bl,heal,0,1); status->change_clear_buffs(bl,4); } break; case RK_MILLENNIUMSHIELD: - if( sd ){ - short shields = (rnd()%100<50) ? 4 : ((rnd()%100<80) ? 3 : 2); - sc_start4(bl,type,100,skill_lv,shields,1000,0,skill->get_time(skill_id,skill_lv)); - clif->millenniumshield(sd,shields); + if( sd && pc->checkskill(sd,RK_RUNEMASTERY) >= 9 ) { + short chance = 0; + short num_shields = 0; + chance = rnd()%100 + 1;//Generates a random number between 1 - 100 which is then used to determine how many shields will generate. + if ( chance >= 1 && chance <= 20 )//20% chance for 4 shields. + num_shields = 4; + else if ( chance >= 21 && chance <= 50 )//30% chance for 3 shields. + num_shields = 3; + else if ( chance >= 51 && chance <= 100 )//50% chance for 2 shields. + num_shields = 2; + sc_start4(src,bl,type,100,skill_lv,num_shields,1000,0,skill->get_time(skill_id,skill_lv)); + clif->millenniumshield(src,num_shields); clif->skill_nodamage(src,bl,skill_id,1,1); } break; case RK_FIGHTINGSPIRIT: if( flag&1 ) { + int atkbonus = 7 * party->foreachsamemap(skill->area_sub,sd,skill->get_splash(skill_id,skill_lv),src,skill_id,skill_lv,tick,BCT_PARTY,skill->area_sub_count); if( src == bl ) - sc_start2(bl,type,100,skill->area_temp[5],10*(sd?pc->checkskill(sd,RK_RUNEMASTERY):10),skill->get_time(skill_id,skill_lv)); + sc_start2(src,bl,type,100,atkbonus,10*(sd?pc->checkskill(sd,RK_RUNEMASTERY):10),skill->get_time(skill_id,skill_lv)); else - sc_start(bl,type,100,skill->area_temp[5]/4,skill->get_time(skill_id,skill_lv)); - } else if( sd ) { - if( sd->status.party_id ) { - i = party->foreachsamemap(skill->area_sub,sd,skill->get_splash(skill_id,skill_lv),src,skill_id,skill_lv,tick,BCT_PARTY,skill->area_sub_count); - skill->area_temp[5] = 7 * i; // ATK + sc_start(src,bl,type,100,atkbonus / 4,skill->get_time(skill_id,skill_lv)); + } else if( sd && pc->checkskill(sd,RK_RUNEMASTERY) >= 5 ) { + if( sd->status.party_id ) party->foreachsamemap(skill->area_sub,sd,skill->get_splash(skill_id,skill_lv),src,skill_id,skill_lv,tick,flag|BCT_PARTY|1,skill->castend_nodamage_id); - } else - sc_start2(bl,type,100,7,5,skill->get_time(skill_id,skill_lv)); + else + sc_start2(src,bl,type,100,7,10*(sd?pc->checkskill(sd,RK_RUNEMASTERY):10),skill->get_time(skill_id,skill_lv)); + clif->skill_nodamage(src,bl,skill_id,1,1); } - clif->skill_nodamage(src,bl,skill_id,1,1); break; case RK_LUXANIMA: @@ -7751,28 +7936,26 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui if( src == bl ) break; while( skill->area_temp[5] >= 0x10 ){ + int value = 0; type = SC_NONE; - i = 0; if( skill->area_temp[5]&0x10 ){ - if( dstsd ){ - i = (rnd()%100<50) ? 4 : ((rnd()%100<80) ? 3 : 2); - clif->millenniumshield(dstsd,i); - skill->area_temp[5] &= ~0x10; - type = SC_MILLENNIUMSHIELD; - } + value = (rnd()%100<50) ? 4 : ((rnd()%100<80) ? 3 : 2); + clif->millenniumshield(bl,value); + skill->area_temp[5] &= ~0x10; + type = SC_MILLENNIUMSHIELD; }else if( skill->area_temp[5]&0x20 ){ - i = status_get_max_hp(bl) * 25 / 100; + value = status_get_max_hp(bl) * 25 / 100; status->change_clear_buffs(bl,4); skill->area_temp[5] &= ~0x20; - status->heal(bl,i,0,1); + status->heal(bl,value,0,1); type = SC_REFRESH; }else if( skill->area_temp[5]&0x40 ){ skill->area_temp[5] &= ~0x40; type = SC_GIANTGROWTH; }else if( skill->area_temp[5]&0x80 ){ if( dstsd ){ - i = sstatus->hp / 4; - if( status->charge(bl,i,0) ) + value = sstatus->hp / 4; + if( status->charge(bl,value,0) ) type = SC_STONEHARDSKIN; skill->area_temp[5] &= ~0x80; } @@ -7785,7 +7968,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui } if( type > SC_NONE ) clif->skill_nodamage(bl, bl, skill_id, skill_lv, - sc_start4(bl, type, 100, skill_lv, i, 0, 1, skill->get_time(skill_id, skill_lv))); + sc_start4(src,bl, type, 100, skill_lv, value, 0, 1, skill->get_time(skill_id, skill_lv))); } }else if( sd ){ if( tsc && tsc->count ){ @@ -7821,7 +8004,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui count = 10; // Max coounter status_change_end(bl, SC_ROLLINGCUTTER, INVALID_TIMER); } - sc_start(bl,SC_ROLLINGCUTTER,100,count,skill->get_time(skill_id,skill_lv)); + sc_start(src,bl,SC_ROLLINGCUTTER,100,count,skill->get_time(skill_id,skill_lv)); clif->skill_nodamage(src,src,skill_id,skill_lv,1); } break; @@ -7830,7 +8013,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui if( tsc && tsc->data[SC_WEAPONBLOCKING] ) status_change_end(bl, SC_WEAPONBLOCKING, INVALID_TIMER); else - sc_start(bl,SC_WEAPONBLOCKING,100,skill_lv,skill->get_time(skill_id,skill_lv)); + sc_start(src,bl,SC_WEAPONBLOCKING,100,skill_lv,skill->get_time(skill_id,skill_lv)); clif->skill_nodamage(src,bl,skill_id,skill_lv,1); break; @@ -7865,15 +8048,20 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui break; case GC_PHANTOMMENACE: + { + int r; clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); clif->skill_nodamage(src,bl,skill_id,skill_lv,1); + r = skill->get_splash(skill_id, skill_lv); map->foreachinrange(skill->area_sub,src,skill->get_splash(skill_id,skill_lv),BL_CHAR, - src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id); + src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id); + map->foreachinarea( status->change_timer_sub, + src->m, src->x-r, src->y-r, src->x+r, src->y+r, BL_CHAR, src, NULL, SC_SIGHT, tick); + } break; - case GC_HALLUCINATIONWALK: { - int heal = status_get_max_hp(bl) / 10; + int heal = status_get_max_hp(bl) * ( 18 - 2 * skill_lv ) / 100; if( status_get_hp(bl) < heal ) { // if you haven't enough HP skill fails. if( sd ) clif->skill_fail(sd,skill_id,USESKILL_FAIL_HP_INSUFFICIENT,0); break; @@ -7882,7 +8070,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui if( sd ) clif->skill_fail(sd,skill_id,USESKILL_FAIL_HP_INSUFFICIENT,0); break; } - clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); + clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); } break; /** @@ -7897,46 +8085,64 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case AB_CLEMENTIA: case AB_CANTO: + { + int level = 0; if( sd ) - i = skill_id == AB_CLEMENTIA ? pc->checkskill(sd,AL_BLESSING) : pc->checkskill(sd,AL_INCAGI); + level = skill_id == AB_CLEMENTIA ? pc->checkskill(sd,AL_BLESSING) : pc->checkskill(sd,AL_INCAGI); if( sd == NULL || sd->status.party_id == 0 || flag&1 ) - clif->skill_nodamage(bl, bl, skill_id, skill_lv, sc_start(bl, type, 100, i + (sd?(sd->status.job_level / 10):0), skill->get_time(skill_id,skill_lv))); + clif->skill_nodamage(bl, bl, skill_id, skill_lv, sc_start(src, bl, type, 100, level + (sd?(sd->status.job_level / 10):0), skill->get_time(skill_id,skill_lv))); else if( sd ) { - if( !i ) + if( !level ) clif->skill_fail(sd,skill_id,USESKILL_FAIL,0); else party->foreachsamemap(skill->area_sub, sd, skill->get_splash(skill_id, skill_lv), src, skill_id, skill_lv, tick, flag|BCT_PARTY|1, skill->castend_nodamage_id); } + } break; case AB_PRAEFATIO: - if( sd == NULL || sd->status.party_id == 0 || flag&1 ) - clif->skill_nodamage(bl, bl, skill_id, skill_lv, sc_start4(bl, type, 100, skill_lv, 0, 0, 1, skill->get_time(skill_id, skill_lv))); - else if( sd ) + if( (flag&1) || sd == NULL || sd->status.party_id == 0 ) { + int count = 1; + + if( dstsd && dstsd->special_state.no_magic_damage ) + break; + + if ( sd && sd->status.party_id == 0 ) + count = 1; + else + count = party->foreachsamemap(party->sub_count, sd, 0); + + if (count > 0) + clif->skill_nodamage(bl, bl, skill_id, skill_lv, + sc_start4(src, bl, type, 100, skill_lv, 0, 0, count, skill->get_time(skill_id, skill_lv))); + } else party->foreachsamemap(skill->area_sub, sd, skill->get_splash(skill_id, skill_lv), src, skill_id, skill_lv, tick, flag|BCT_PARTY|1, skill->castend_nodamage_id); break; - case AB_CHEAL: if( sd == NULL || sd->status.party_id == 0 || flag&1 ) { - if( sd && tstatus && !battle->check_undead(tstatus->race, tstatus->def_ele) ) { - i = skill->calc_heal(src, bl, AL_HEAL, pc->checkskill(sd, AL_HEAL), true); - - if( (dstsd && pc_ismadogear(dstsd)) || status->isimmune(bl)) - i = 0; // Should heal by 0 or won't do anything?? in iRO it breaks the healing to members.. [malufett] + if( sd && tstatus && !battle->check_undead(tstatus->race, tstatus->def_ele) && !tsc->data[SC_BERSERK] ) { + int lv = pc->checkskill(sd, AL_HEAL); + int heal = skill_calc_heal(src, bl, AL_HEAL, lv, true); + + if( sd->status.party_id ) { + int partycount = party->foreachsamemap(party->sub_count, sd, 0); + if (partycount > 1) + heal += ((heal / 100) * (partycount * 10) / 4); + } + if( status->isimmune(bl) || (dstsd && pc_ismadogear(dstsd)) ) + heal = 0; - clif->skill_nodamage(bl, bl, skill_id, i, 1); - if( tsc && tsc->data[SC_AKAITSUKI] && i ) - i = ~i + 1; - status->heal(bl, i, 0, 0); + clif->skill_nodamage(bl, bl, skill_id, heal, 1); + if( tsc && tsc->data[SC_AKAITSUKI] && heal ) + heal = ~heal + 1; + status->heal(bl, heal, 0, 1); } - } - else if( sd ) + } else if( sd ) party->foreachsamemap(skill->area_sub, sd, skill->get_splash(skill_id, skill_lv), src, skill_id, skill_lv, tick, flag|BCT_PARTY|1, skill->castend_nodamage_id); break; - case AB_ORATIO: if( flag&1 ) - sc_start(bl, type, 40 + 5 * skill_lv, skill_lv, skill->get_time(skill_id, skill_lv)); + sc_start(src, bl, type, 40 + 5 * skill_lv, skill_lv, skill->get_time(skill_id, skill_lv)); else { map->foreachinrange(skill->area_sub, src, skill->get_splash(skill_id, skill_lv), BL_CHAR, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill->castend_nodamage_id); @@ -7958,7 +8164,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui status_change_end(bl, SC_COLD, INVALID_TIMER); }else //Success rate only applies to the curing effect and not stat bonus. Bonus status only applies to non infected targets clif->skill_nodamage(bl, bl, skill_id, skill_lv, - sc_start(bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv))); + sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv))); } else if( sd ) party->foreachsamemap(skill->area_sub, sd, skill->get_splash(skill_id, skill_lv), src, skill_id, skill_lv, tick, flag|BCT_PARTY|1, skill->castend_nodamage_id); @@ -7966,23 +8172,27 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case AB_LAUDARAMUS: if( flag&1 || sd == NULL ) { - if( tsc && (tsc->data[SC_SLEEP] || tsc->data[SC_STUN] || tsc->data[SC_MANDRAGORA] || tsc->data[SC_SILENCE]) ){ + if( tsc && (tsc->data[SC_SLEEP] || tsc->data[SC_STUN] || tsc->data[SC_MANDRAGORA] || tsc->data[SC_SILENCE] || tsc->data[SC_DEEP_SLEEP]) ){ // Success Chance: (40 + 10 * Skill Level) % if( rnd()%100 > 40+10*skill_lv ) break; status_change_end(bl, SC_SLEEP, INVALID_TIMER); status_change_end(bl, SC_STUN, INVALID_TIMER); status_change_end(bl, SC_MANDRAGORA, INVALID_TIMER); status_change_end(bl, SC_SILENCE, INVALID_TIMER); + status_change_end(bl, SC_DEEP_SLEEP, INVALID_TIMER); }else // Success rate only applies to the curing effect and not stat bonus. Bonus status only applies to non infected targets clif->skill_nodamage(bl, bl, skill_id, skill_lv, - sc_start(bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv))); + sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv))); } else if( sd ) party->foreachsamemap(skill->area_sub, sd, skill->get_splash(skill_id, skill_lv), src, skill_id, skill_lv, tick, flag|BCT_PARTY|1, skill->castend_nodamage_id); break; case AB_CLEARANCE: - if( flag&1 || (i = skill->get_splash(skill_id, skill_lv)) < 1 ) { + { + int splash; + if( flag&1 || (splash = skill->get_splash(skill_id, skill_lv)) < 1 ) { + int i; //As of the behavior in official server Clearance is just a super version of Dispell skill. [Jobbie] if( bl->type != BL_MOB && battle->check_target(src,bl,BCT_PARTY) <= 0 ) // Only affect mob or party. break; @@ -8015,8 +8225,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui status_change_end(bl,(sc_type)i,INVALID_TIMER); } break; + } else { + map->foreachinrange(skill->area_sub, bl, splash, BL_CHAR, src, skill_id, skill_lv, tick, flag|1, skill->castend_damage_id); } - map->foreachinrange(skill->area_sub, bl, i, BL_CHAR, src, skill_id, skill_lv, tick, flag|1, skill->castend_damage_id); + } break; case AB_SILENTIUM: @@ -8030,7 +8242,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui **/ case WL_STASIS: if( flag&1 ) - sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)); + sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)); else { map->foreachinrange(skill->area_sub,src,skill->get_splash(skill_id, skill_lv),BL_CHAR,src,skill_id,skill_lv,tick,(map_flag_vs(src->m)?BCT_ALL:BCT_ENEMY|BCT_SELF)|flag|1,skill->castend_nodamage_id); clif->skill_nodamage(src, bl, skill_id, skill_lv, 1); @@ -8046,10 +8258,13 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui else if(bl->type == BL_PC) rate += 20 + 10 * skill_lv; // On Players, (20 + 10 * Skill Level) % else rate += 40 + 10 * skill_lv; // On Monsters, (40 + 10 * Skill Level) % + if( sd ) + skill->blockpc_start(sd,skill_id,4000); + if( !(tsc && tsc->data[type]) ){ - i = sc_start2(bl,type,rate,skill_lv,src->id,(src == bl)?5000:(bl->type == BL_PC)?skill->get_time(skill_id,skill_lv):skill->get_time2(skill_id, skill_lv)); - clif->skill_nodamage(src,bl,skill_id,skill_lv,i); - if( sd && !i ) + int failure = sc_start2(src,bl,type,rate,skill_lv,src->id,(src == bl)?5000:(bl->type == BL_PC)?skill->get_time(skill_id,skill_lv):skill->get_time2(skill_id, skill_lv)); + clif->skill_nodamage(src,bl,skill_id,skill_lv,failure); + if( sd && !failure ) clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); } }else @@ -8058,18 +8273,22 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui break; case WL_FROSTMISTY: + if( tsc && (tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK))) + break; // Doesn't hit/cause Freezing to invisible enemy // Really? [Rytech] clif->skill_nodamage(src,bl,skill_id,skill_lv,1); map->foreachinrange(skill->area_sub,bl,skill->get_splash(skill_id,skill_lv),BL_CHAR|BL_SKILL,src,skill_id,skill_lv,tick,flag|BCT_ENEMY,skill->castend_damage_id); break; case WL_JACKFROST: + if( tsc && (tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK))) + break; // Do not hit invisible enemy clif->skill_nodamage(src,bl,skill_id,skill_lv,1); map->foreachinshootrange(skill->area_sub,bl,skill->get_splash(skill_id,skill_lv),BL_CHAR|BL_SKILL,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id); break; case WL_MARSHOFABYSS: clif->skill_nodamage(src, bl, skill_id, skill_lv, - sc_start(bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv))); + sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv))); break; case WL_SIENNAEXECRATE: @@ -8079,7 +8298,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui if( tsc && tsc->data[SC_STONE] ) status_change_end(bl,SC_STONE,INVALID_TIMER); else - status->change_start(bl,SC_STONE,10000,skill_lv,0,0,500,skill->get_time(skill_id, skill_lv),2); + status->change_start(src,bl,SC_STONE,10000,skill_lv,0,0,500,skill->get_time(skill_id, skill_lv),2); } else { int rate = 45 + 5 * skill_lv; if( rnd()%100 < rate ){ @@ -8094,19 +8313,23 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case WL_SUMMONBL: case WL_SUMMONWB: case WL_SUMMONSTONE: + { + int i; for( i = SC_SUMMON1; i <= SC_SUMMON5; i++ ){ if( tsc && !tsc->data[i] ){ // officially it doesn't work like a stack int ele = WLS_FIRE + (skill_id - WL_SUMMONFB) - (skill_id == WL_SUMMONSTONE ? 4 : 0); clif->skill_nodamage(src, bl, skill_id, skill_lv, - sc_start(bl, (sc_type)i, 100, ele, skill->get_time(skill_id, skill_lv))); + sc_start(src, bl, (sc_type)i, 100, ele, skill->get_time(skill_id, skill_lv))); break; } } + } break; case WL_READING_SB: if( sd ) { struct status_change *sc = status->get_sc(bl); + int i; for( i = SC_SPELLBOOK1; i <= SC_SPELLBOOK7; i++) if( sc && !sc->data[i] ) @@ -8116,7 +8339,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui break; } - sc_start(bl, SC_STOP, 100, skill_lv, INVALID_TIMER); //Can't move while selecting a spellbook. + sc_start(src, bl, SC_STOP, 100, skill_lv, INVALID_TIMER); //Can't move while selecting a spellbook. clif->spellbook_list(sd); clif->skill_nodamage(src, bl, skill_id, skill_lv, 1); } @@ -8126,7 +8349,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui **/ case RA_FEARBREEZE: clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); - clif->skill_nodamage(src, bl, skill_id, skill_lv, sc_start(bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv))); + clif->skill_nodamage(src, bl, skill_id, skill_lv, sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv))); break; case RA_WUGMASTERY: @@ -8159,7 +8382,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui return 0; } if( sd && pc_isridingwug(sd) ) { - clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start4(bl,type,100,skill_lv,unit->getdir(bl),0,0,1)); + clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start4(src,bl,type,100,skill_lv,unit->getdir(bl),0,0,1)); clif->walkok(sd); } break; @@ -8195,34 +8418,39 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case NC_ANALYZE: clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); clif->skill_nodamage(src, bl, skill_id, skill_lv, - sc_start(bl,type, 30 + 12 * skill_lv,skill_lv,skill->get_time(skill_id,skill_lv))); + sc_start(src,bl,type, 30 + 12 * skill_lv,skill_lv,skill->get_time(skill_id,skill_lv))); if( sd ) pc->overheat(sd,1); break; case NC_MAGNETICFIELD: - if( (i = sc_start2(bl,type,100,skill_lv,src->id,skill->get_time(skill_id,skill_lv))) ) + { + int failure; + if( (failure = sc_start2(src,bl,type,100,skill_lv,src->id,skill->get_time(skill_id,skill_lv))) ) { map->foreachinrange(skill->area_sub,src,skill->get_splash(skill_id,skill_lv),splash_target(src),src,skill_id,skill_lv,tick,flag|BCT_ENEMY|SD_SPLASH|1,skill->castend_damage_id);; clif->skill_damage(src,src,tick,status_get_amotion(src),0,-30000,1,skill_id,skill_lv,6); if (sd) pc->overheat(sd,1); } - clif->skill_nodamage(src,src,skill_id,skill_lv,i); + clif->skill_nodamage(src,src,skill_id,skill_lv,failure); + } break; case NC_REPAIR: - if( sd ) - { - int heal; - if( dstsd && pc_ismadogear(dstsd) ) - { - heal = dstsd->status.max_hp * (3+3*skill_lv) / 100; - status->heal(bl,heal,0,2); - } else { - heal = sd->status.max_hp * (3+3*skill_lv) / 100; - status->heal(src,heal,0,2); + if( sd ) { + int heal, hp = 0; // % of max hp regen + if( !dstsd || !pc_ismadogear(dstsd) ) { + clif->skill_fail(sd, skill_id,USESKILL_FAIL_TOTARGET,0); + break; } - - clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); + switch (cap_value(skill_lv, 1, 5)) { + case 1: hp = 4; break; + case 2: hp = 7; break; + case 3: hp = 13; break; + case 4: hp = 17; break; + case 5: hp = 23; break; + } + heal = tstatus->max_hp * hp / 100; + status->heal(bl,heal,0,2); clif->skill_nodamage(src, bl, skill_id, skill_lv, heal); } break; @@ -8240,7 +8468,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui if( sd ) { int idx1 = skill->get_index(sd->reproduceskill_id), idx2 = skill->get_index(sd->cloneskill_id); if( sd->status.skill[idx1].id || sd->status.skill[idx2].id ) { - sc_start(src,SC_STOP,100,skill_lv,-1);// The skill_lv is stored in val1 used in skill_select_menu to determine the used skill lvl [Xazax] + sc_start(src,src,SC_STOP,100,skill_lv,-1);// The skill_lv is stored in val1 used in skill_select_menu to determine the used skill lvl [Xazax] clif->autoshadowspell_list(sd); clif->skill_nodamage(src,bl,skill_id,1,1); } @@ -8251,7 +8479,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case SC_SHADOWFORM: if( sd && dstsd && src != bl && !dstsd->shadowform_id ) { - if( clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start4(src,type,100,skill_lv,bl->id,4+skill_lv,0,skill->get_time(skill_id, skill_lv))) ) + if( clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start4(src,src,type,100,skill_lv,bl->id,4+skill_lv,0,skill->get_time(skill_id, skill_lv))) ) dstsd->shadowform_id = src->id; } else if( sd ) @@ -8261,16 +8489,14 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case SC_BODYPAINT: if( flag&1 ) { if( tsc && (tsc->data[SC_HIDING] || tsc->data[SC_CLOAKING] || - tsc->data[SC_CHASEWALK] || tsc->data[SC_CLOAKINGEXCEED] || - tsc->data[SC__INVISIBILITY]) ) { + tsc->data[SC_CHASEWALK] || tsc->data[SC_CLOAKINGEXCEED] ) ) { status_change_end(bl, SC_HIDING, INVALID_TIMER); status_change_end(bl, SC_CLOAKING, INVALID_TIMER); status_change_end(bl, SC_CHASEWALK, INVALID_TIMER); status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER); - status_change_end(bl, SC__INVISIBILITY, INVALID_TIMER); - sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)); - sc_start(bl,SC_BLIND,53 + 2 * skill_lv,skill_lv,skill->get_time(skill_id,skill_lv)); + sc_start(src,bl,type,20 + 5 * skill_lv,skill_lv,skill->get_time(skill_id,skill_lv)); + sc_start(src,bl,SC_BLIND,53 + 2 * skill_lv,skill_lv,skill->get_time(skill_id,skill_lv)); } } else { clif->skill_nodamage(src, bl, skill_id, 0, 1); @@ -8281,34 +8507,44 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case SC_ENERVATION: case SC_GROOMY: + case SC_IGNORANCE: case SC_LAZINESS: case SC_UNLUCKY: case SC_WEAKNESS: if( !(tsc && tsc->data[type]) ) { - //((rand(myDEX / 12, myDEX / 4) + myJobLevel + 10 * skLevel) + myLevel / 10) - (targetLevel / 10 + targetLUK / 10 + (targetMaxWeight - targetWeight) / 1000 + rand(targetAGI / 6, targetAGI / 3)) - int rate = rnd_value(sstatus->dex/12,sstatus->dex/4) + 10*skill_lv + (sd?sd->status.job_level:0) + status->get_lv(src)/10 - - status->get_lv(bl)/10 - tstatus->luk/10 - (dstsd?(dstsd->max_weight-dstsd->weight)/10000:0) - rnd_value(tstatus->agi/6,tstatus->agi/3); - rate = cap_value(rate, skill_lv+sstatus->dex/20, 100); - clif->skill_nodamage(src,bl,skill_id,0,sc_start(bl,type,rate,skill_lv,skill->get_time(skill_id,skill_lv))); - } else if( sd ) - clif->skill_fail(sd,skill_id,0,0); - break; - - case SC_IGNORANCE: - if( !(tsc && tsc->data[type]) ) { - int rate = rnd_value(sstatus->dex/12,sstatus->dex/4) + 10*skill_lv + (sd?sd->status.job_level:0) - + status->get_lv(src)/10 - status->get_lv(bl)/10 - tstatus->luk/10 - - (dstsd?(dstsd->max_weight-dstsd->weight)/10000:0) - rnd_value(tstatus->agi/6,tstatus->agi/3); - rate = cap_value(rate, skill_lv+sstatus->dex/20, 100); - if (clif->skill_nodamage(src,bl,skill_id,0,sc_start(bl,type,rate,skill_lv,skill->get_time(skill_id,skill_lv)))) { - int sp = 200 * skill_lv; + int joblvbonus = 0; + int rate = 0; + if (is_boss(bl)) break; + joblvbonus = ( sd ? sd->status.job_level : 50 ); + //First we set the success chance based on the caster's build which increases the chance. + rate = 10 * skill_lv + rnd_value( sstatus->dex / 12, sstatus->dex / 4 ) + joblvbonus + status->get_lv(src) / 10; + // We then reduce the success chance based on the target's build. + rate -= rnd_value( tstatus->agi / 6, tstatus->agi / 3 ) - tstatus->luk / 10 - ( dstsd ? (dstsd->max_weight / 10 - dstsd->weight / 10 ) / 100 : 0 ) - status->get_lv(bl) / 10; + //Finally we set the minimum success chance cap based on the caster's skill level and DEX. + rate = cap_value( rate, skill_lv + sstatus->dex / 20, 100); + clif->skill_nodamage(src,bl,skill_id,0,sc_start(src,bl,type,rate,skill_lv,skill->get_time(skill_id,skill_lv))); + if ( tsc && tsc->data[SC__IGNORANCE] && skill_id == SC_IGNORANCE) { + //If the target was successfully inflected with the Ignorance status, drain some of the targets SP. + int sp = 100 * skill_lv; if( dstmd ) sp = dstmd->level * 2; if( status_zap(bl,0,sp) ) - status->heal(src,0,sp/2,3); - } else if( sd ) - clif->skill_fail(sd,skill_id,0,0); + status->heal(src,0,sp/2,3);//What does flag 3 do? [Rytech] + } + if ( tsc && tsc->data[SC__UNLUCKY] && skill_id == SC_UNLUCKY) { + //If the target was successfully inflected with the Unlucky status, give 1 of 3 random status's. + switch(rnd()%3) {//Targets in the Unlucky status will be affected by one of the 3 random status's reguardless of resistance. + case 0: + status->change_start(src,bl,SC_POISON,10000,skill_lv,0,0,0,skill->get_time(skill_id,skill_lv),10); + break; + case 1: + status->change_start(src,bl,SC_SILENCE,10000,skill_lv,0,0,0,skill->get_time(skill_id,skill_lv),10); + break; + case 2: + status->change_start(src,bl,SC_BLIND,10000,skill_lv,0,0,0,skill->get_time(skill_id,skill_lv),10); + } + } } else if( sd ) - clif->skill_fail(sd,skill_id,0,0); + clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0); break; case LG_TRAMPLE: @@ -8320,114 +8556,96 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui if( tsc && tsc->data[type] ) status_change_end(bl,type,INVALID_TIMER); else - sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)); + sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)); clif->skill_nodamage(src,bl,skill_id,skill_lv,1); break; case LG_SHIELDSPELL: if( flag&1 ) { - int duration = (sd) ? sd->bonus.shieldmdef * 2000 : 10000; - sc_start(bl,SC_SILENCE,100,skill_lv,duration); + sc_start(src,bl,SC_SILENCE,100,skill_lv,sd->bonus.shieldmdef * 30000); } else if( sd ) { - int opt = skill_lv; - int rate = rnd()%100; - int val, brate; + int opt = 0, val = 0, splashrange = 0; + struct item_data *shield_data = sd->inventory_data[sd->equip_index[EQI_HAND_L]]; + if( !shield_data || shield_data->type != IT_ARMOR ) { + //Skill will first check if a shield is equipped. If none is found on the caster the skill will fail. + clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); + break; + } + //Generates a number between 1 - 3. The number generated will determine which effect will be triggered. + opt = rnd()%3 + 1; switch( skill_lv ) { case 1: - { - struct item_data *shield_data = sd->inventory_data[sd->equip_index[EQI_HAND_L]]; - if( !shield_data || shield_data->type != IT_ARMOR ) { // No shield? - clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0); - break; - } - brate = shield_data->def * 10; - if( rate < 50 ) - opt = 1; - else if( rate < 75 ) - opt = 2; + if ( shield_data->def >= 0 && shield_data->def <= 40) + splashrange = 1; + else if ( shield_data->def >= 41 && shield_data->def <= 80) + splashrange = 2; else - opt = 3; - + splashrange = 3; switch( opt ) { case 1: - sc_start(bl,SC_SHIELDSPELL_DEF,100,opt,-1); + sc_start(src,bl,SC_SHIELDSPELL_DEF,100,opt,INVALID_TIMER); //Splash AoE ATK clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); - if( rate < brate ) - map->foreachinrange(skill->area_sub,src,skill->get_splash(skill_id,skill_lv),BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id); + map->foreachinrange(skill->area_sub,src,splashrange,BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id); status_change_end(bl,SC_SHIELDSPELL_DEF,INVALID_TIMER); break; case 2: - val = shield_data->def / 10; // % Reflected damage. - sc_start2(bl,SC_SHIELDSPELL_DEF,brate,opt,val,shield_data->def * 1000); + val = shield_data->def/10; //Damage Reflecting Increase. + sc_start2(src,bl,SC_SHIELDSPELL_DEF,100,opt,val,shield_data->def * 1000); break; case 3: - val = shield_data->def; // Attack increase. - sc_start2(bl,SC_SHIELDSPELL_DEF,brate,opt,val,shield_data->def * 3000); + //Weapon Attack Increase. + val = shield_data->def; + sc_start2(src,bl,SC_SHIELDSPELL_DEF,100,opt,val,shield_data->def * 3000); break; } - } break; case 2: - brate = sd->bonus.shieldmdef * 20; - if( rate < 30 ) - opt = 1; - else if( rate < 60 ) - opt = 2; + if ( sd->bonus.shieldmdef >= 1 && sd->bonus.shieldmdef <= 3 ) + splashrange = 1; + else if ( sd->bonus.shieldmdef >= 4 && sd->bonus.shieldmdef <= 5 ) + splashrange = 2; else - opt = 3; + splashrange = 3; switch( opt ) { case 1: - sc_start(bl,SC_SHIELDSPELL_MDEF,100,opt,-1); + sc_start(src,bl,SC_SHIELDSPELL_MDEF,100,opt,INVALID_TIMER); //Splash AoE MATK clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); - if( rate < brate ) - map->foreachinrange(skill->area_sub,src,skill->get_splash(skill_id,skill_lv),BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|2,skill->castend_damage_id); + map->foreachinrange(skill->area_sub,src,splashrange,BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id); status_change_end(bl,SC_SHIELDSPELL_MDEF,INVALID_TIMER); break; case 2: - sc_start(bl,SC_SHIELDSPELL_MDEF,100,opt,-1); - clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); - if( rate < brate ) - map->foreachinrange(skill->area_sub,src,skill->get_splash(skill_id,skill_lv),BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_nodamage_id); + sc_start(src,bl,SC_SHIELDSPELL_MDEF,100,opt,sd->bonus.shieldmdef * 2000); //Splash AoE Lex Divina + clif->skill_damage(src,bl,tick,status_get_amotion(src),0,-30000,1,skill_id,skill_lv,6); + map->foreachinrange(skill->area_sub,src,splashrange,BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_nodamage_id); break; case 3: - if( sc_start(bl,SC_SHIELDSPELL_MDEF,brate,opt,sd->bonus.shieldmdef * 30000) ) + if( sc_start(src,bl,SC_SHIELDSPELL_MDEF,100,opt,sd->bonus.shieldmdef * 30000) ) //Magnificat clif->skill_nodamage(src,bl,PR_MAGNIFICAT,skill_lv, - sc_start(bl,SC_MAGNIFICAT,100,1,sd->bonus.shieldmdef * 30000)); + sc_start(src,bl,SC_MAGNIFICAT,100,1,sd->bonus.shieldmdef * 30000)); break; } break; - case 3: { - struct item *it = &sd->status.inventory[sd->equip_index[EQI_HAND_L]]; - if( !it ) { // No shield? - clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); - break; - } - brate = it->refine * 5; - if( rate < 25 ) - opt = 1; - else if( rate < 50 ) - opt = 2; - else - opt = 3; + struct item *shield = &sd->status.inventory[sd->equip_index[EQI_HAND_L]]; + int rate = 0; switch( opt ) { case 1: - val = 105 * it->refine / 10; - sc_start2(bl,SC_SHIELDSPELL_REF,brate,opt,val,skill->get_time(skill_id,skill_lv)); + sc_start(src,bl,SC_SHIELDSPELL_REF,100,opt,shield->refine * 30000); //Now breaks Armor at 100% rate break; case 2: - case 3: - if( rate < brate ) { - val = sstatus->max_hp * (11 + it->refine) / 100; - status->heal(bl, val, 0, 3); - } + val = shield->refine * 10 * status->get_lv(src) / 100; //DEF Increase + rate = (shield->refine * 2) + (status_get_luk(src) / 10); //Status Resistance Rate + if( sc_start2(src,bl,SC_SHIELDSPELL_REF,100,opt,val,shield->refine * 20000)) + clif->skill_nodamage(src,bl,SC_SCRESIST,skill_lv, + sc_start(src,bl,SC_SCRESIST,100,rate,shield->refine * 30000)); break; -#if 0 // TODO: I need confirm what effect should be here. Moved to case 2 to until we got it. case 3: - // Full protection. + sc_start(src,bl,SC_SHIELDSPELL_REF,100,opt,INVALID_TIMER); //HP Recovery + val = sstatus->max_hp * ((status->get_lv(src) / 10) + (shield->refine + 1)) / 100; + status->heal(bl, val, 0, 2); + status_change_end(bl,SC_SHIELDSPELL_REF,INVALID_TIMER); break; -#endif // 0 } } break; @@ -8438,7 +8656,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case LG_PIETY: if( flag&1 ) - sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)); + sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)); else { skill->area_temp[2] = 0; map->foreachinrange(skill->area_sub,bl,skill->get_splash(skill_id,skill_lv),BL_PC,src,skill_id,skill_lv,tick,flag|SD_PREAMBLE|BCT_PARTY|BCT_SELF|1,skill->castend_nodamage_id); @@ -8447,7 +8665,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui break; case LG_KINGS_GRACE: if( flag&1 ){ - sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)); + int i; + sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)); for(i=0; i<SC_MAX; i++) { if (!tsc->data[i]) @@ -8459,9 +8678,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case SC_BLOODING: case SC_CURSE: case SC_CONFUSION: case SC_ILLUSION: case SC_SILENCE: case SC_BURNING: - case SC_COLD: case SC_FROSTMISTY: + case SC_COLD: case SC_FROSTMISTY: case SC_DEEP_SLEEP: case SC_FEAR: - case SC_MANDRAGORA: + case SC_MANDRAGORA: case SC__CHAOS: status_change_end(bl, (sc_type)i, INVALID_TIMER); } } @@ -8481,12 +8700,12 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui clif->updatestatus(sd,SP_JOBEXP); } clif->skill_nodamage(bl,src,skill_id,skill_lv, - sc_start(bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv))); + sc_start(src,bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv))); break; case SR_CURSEDCIRCLE: if( flag&1 ) { if( is_boss(bl) ) break; - if( sc_start2(bl, type, 100, skill_lv, src->id, skill->get_time(skill_id, skill_lv))) { + if( sc_start2(src,bl, type, 100, skill_lv, src->id, skill->get_time(skill_id, skill_lv))) { if( bl->type == BL_MOB ) mob->unlocktarget((TBL_MOB*)bl,timer->gettick()); unit->stop_attack(bl); @@ -8501,30 +8720,31 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui BL_CHAR, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill->castend_nodamage_id); if( sd ) pc->delspiritball(sd, count, 0); clif->skill_nodamage(src, src, skill_id, skill_lv, - sc_start2(src, SC_CURSEDCIRCLE_ATKER, 100, skill_lv, count, skill->get_time(skill_id,skill_lv))); + sc_start2(src, src, SC_CURSEDCIRCLE_ATKER, 100, skill_lv, count, skill->get_time(skill_id,skill_lv))); } break; case SR_RAISINGDRAGON: if( sd ) { short max = 5 + skill_lv; - sc_start(bl, SC_EXPLOSIONSPIRITS, 100, skill_lv, skill->get_time(skill_id, skill_lv)); + int i; + sc_start(src, bl, SC_EXPLOSIONSPIRITS, 100, skill_lv, skill->get_time(skill_id, skill_lv)); for( i = 0; i < max; i++ ) // Don't call more than max available spheres. pc->addspiritball(sd, skill->get_time(skill_id, skill_lv), max); - clif->skill_nodamage(src, bl, skill_id, skill_lv, sc_start(bl, type, 100, skill_lv,skill->get_time(skill_id, skill_lv))); + clif->skill_nodamage(src, bl, skill_id, skill_lv, sc_start(src, bl, type, 100, skill_lv,skill->get_time(skill_id, skill_lv))); } break; case SR_ASSIMILATEPOWER: if( flag&1 ) { - i = 0; + int sp = 0; if( dstsd && dstsd->spiritball && (sd == dstsd || map_flag_vs(src->m)) && (dstsd->class_&MAPID_BASEMASK)!=MAPID_GUNSLINGER ) { - i = dstsd->spiritball; //1%sp per spiritball. + sp = dstsd->spiritball; //1%sp per spiritball. pc->delspiritball(dstsd, dstsd->spiritball, 0); } - if( i ) status_percent_heal(src, 0, i); - clif->skill_nodamage(src, bl, skill_id, skill_lv, i ? 1:0); + if( sp ) status_percent_heal(src, 0, sp); + clif->skill_nodamage(src, bl, skill_id, skill_lv, sp ? 1:0); } else { clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); map->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id, skill_lv), splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY|BCT_SELF|SD_SPLASH|1, skill->castend_nodamage_id); @@ -8535,6 +8755,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui if( !dstsd ) break; if( sd && dstsd->spiritball <= 5 ) { + int i; for(i = 0; i <= 5; i++) { pc->addspiritball(dstsd, skill->get_time(MO_CALLSPIRITS, pc->checkskill(sd,MO_CALLSPIRITS)), i); pc->delspiritball(sd, sd->spiritball, 0); @@ -8573,38 +8794,32 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case SR_GENTLETOUCH_CHANGE: case SR_GENTLETOUCH_REVITALIZE: clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start2(bl,type,100,skill_lv,src->id,skill->get_time(skill_id,skill_lv))); + sc_start2(src,bl,type,100,skill_lv,src->id,skill->get_time(skill_id,skill_lv))); break; case SR_FLASHCOMBO: + { + int i; clif->skill_nodamage(src,bl,skill_id,skill_lv,1); for(i = SR_FLASHCOMBO_ATK_STEP1; i <= SR_FLASHCOMBO_ATK_STEP4; i++) - skill->addtimerskill(src, tick + 500 * (i - SR_FLASHCOMBO_ATK_STEP1), bl->id, 0, 0, i, skill_lv, BF_WEAPON, flag|SD_LEVEL); + skill->addtimerskill(src, tick + 400 * (i - SR_FLASHCOMBO_ATK_STEP1), bl->id, 0, 0, i, skill_lv, BF_WEAPON, flag|SD_LEVEL); + } break; case WA_SWING_DANCE: - case WA_MOONLIT_SERENADE: - if( sd == NULL || sd->status.party_id == 0 || (flag & 1) ) - sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)); - else if( sd ) { // Only shows effects on caster. - clif->skill_nodamage(src,bl,skill_id,skill_lv,1); - party->foreachsamemap(skill->area_sub, sd, skill->get_splash(skill_id, skill_lv), src, skill_id, skill_lv, tick, flag|BCT_PARTY|1, skill->castend_nodamage_id); - } - break; - case WA_SYMPHONY_OF_LOVER: + case WA_MOONLIT_SERENADE: case MI_RUSH_WINDMILL: case MI_ECHOSONG: - if( sd == NULL || sd->status.party_id == 0 || (flag & 1) ) - sc_start4(bl,type,100,skill_lv,6*skill_lv,(sd?pc->checkskill(sd,WM_LESSON):0),(sd?sd->status.job_level:0),skill->get_time(skill_id,skill_lv)); - else if( sd ) { // Only shows effects on caster. + if( flag&1 ) + sc_start2(src,bl,type,100,skill_lv,(sd?pc->checkskill(sd,WM_LESSON):0),skill->get_time(skill_id,skill_lv)); + else if( sd ) { + party->foreachsamemap(skill->area_sub,sd,skill->get_splash(skill_id,skill_lv),src,skill_id,skill_lv,tick,flag|BCT_PARTY|1,skill->castend_nodamage_id); + sc_start2(src,bl,type,100,skill_lv,pc->checkskill(sd,WM_LESSON),skill->get_time(skill_id,skill_lv)); clif->skill_nodamage(src,bl,skill_id,skill_lv,1); - party->foreachsamemap(skill->area_sub, sd, skill->get_splash(skill_id, skill_lv), src, skill_id, skill_lv, tick, flag|BCT_PARTY|1, skill->castend_nodamage_id); } break; case MI_HARMONIZE: - if( src != bl ) - clif->skill_nodamage(src, src, skill_id, skill_lv, sc_start(src, type, 100, skill_lv, skill->get_time(skill_id,skill_lv))); - clif->skill_nodamage(src, bl, skill_id, skill_lv, sc_start(bl, type, 100, skill_lv, skill->get_time(skill_id,skill_lv))); + clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start2(src,bl,type,100,skill_lv,(sd?pc->checkskill(sd,WM_LESSON):1),skill->get_time(skill_id,skill_lv))); break; case WM_DEADHILLHERE: @@ -8613,107 +8828,115 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui break; if( rnd()%100 < 88 + 2 * skill_lv ) { - int heal = tstatus->sp; - if( heal <= 0 ) + int heal = 0; + status_zap(bl, 0, tstatus->sp * (60 - 10 * skill_lv) / 100); + heal = tstatus->sp; + if ( heal <= 0 ) heal = 1; - tstatus->hp = heal; - tstatus->sp -= tstatus->sp * ( 120 - 20 * skill_lv ) / 100; + status->fixed_revive(bl, heal, 0); clif->skill_nodamage(src,bl,skill_id,skill_lv,1); - pc->revive((TBL_PC*)bl,heal,0); - clif->resurrection(bl,1); + status->set_sp(bl, 0, 0); } } break; + case WM_LULLABY_DEEPSLEEP: + if ( flag&1 ) + sc_start2(src,bl,type,100,skill_lv,src->id,skill->get_time(skill_id,skill_lv)); + else if ( sd ) { + int rate = 4 * skill_lv + 2 * (sd ? pc->checkskill(sd,WM_LESSON) : 1) + status->get_lv(src) / 15 + (sd? sd->status.job_level:0) / 5; + if ( rnd()%100 < rate ) { + flag |= BCT_PARTY|BCT_GUILD; + map->foreachinrange(skill->area_sub, src, skill->get_splash(skill_id,skill_lv),BL_CHAR|BL_NPC|BL_SKILL, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill->castend_nodamage_id); + clif->skill_nodamage(src,bl,skill_id,skill_lv,1); + status_change_end(bl, SC_DEEP_SLEEP, INVALID_TIMER); + } + } + break; case WM_SIRCLEOFNATURE: flag |= BCT_SELF|BCT_PARTY|BCT_GUILD; case WM_VOICEOFSIREN: if( skill_id != WM_SIRCLEOFNATURE ) flag &= ~BCT_SELF; if( flag&1 ) { - sc_start2(bl,type,(skill_id==WM_VOICEOFSIREN)?20+10*skill_lv:100,skill_lv,(skill_id==WM_VOICEOFSIREN)?src->id:0,skill->get_time(skill_id,skill_lv)); - } else { - map->foreachinrange(skill->area_sub, src, skill->get_splash(skill_id,skill_lv),(skill_id==WM_VOICEOFSIREN)?BL_CHAR|BL_SKILL:BL_PC, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill->castend_nodamage_id); - clif->skill_nodamage(src,bl,skill_id,skill_lv,1); + sc_start2(src,bl,type,100,skill_lv,(skill_id==WM_VOICEOFSIREN)?src->id:0,skill->get_time(skill_id,skill_lv)); + } else if( sd ) { + int rate = 6 * skill_lv + (sd ? pc->checkskill(sd,WM_LESSON) : 1) + (sd? sd->status.job_level:0) / 2; + if ( rnd()%100 < rate ) { + flag |= BCT_PARTY|BCT_GUILD; + map->foreachinrange(skill->area_sub, src, skill->get_splash(skill_id,skill_lv),(skill_id==WM_VOICEOFSIREN)?BL_CHAR|BL_NPC|BL_SKILL:BL_PC, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill->castend_nodamage_id); + clif->skill_nodamage(src,bl,skill_id,skill_lv,1); + status_change_end(bl, SC_SIREN, INVALID_TIMER); + } } break; case WM_GLOOMYDAY: - clif->skill_nodamage(src,bl,skill_id,skill_lv,1); - if( dstsd && ( pc->checkskill(dstsd,KN_BRANDISHSPEAR) || pc->checkskill(dstsd,LK_SPIRALPIERCE) || - pc->checkskill(dstsd,CR_SHIELDCHARGE) || pc->checkskill(dstsd,CR_SHIELDBOOMERANG) || - pc->checkskill(dstsd,PA_SHIELDCHAIN) || pc->checkskill(dstsd,LG_SHIELDPRESS) ) ) - { - sc_start(bl,SC_GLOOMYDAY_SK,100,skill_lv,skill->get_time(skill_id,skill_lv)); - break; - } - sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)); - break; - - case WM_SATURDAY_NIGHT_FEVER: - if( flag&1 ) { // Affect to all targets arround the caster and caster too. - if( !(tsc && tsc->data[type]) ) - sc_start(bl, type, 100, skill_lv,skill->get_time(skill_id, skill_lv)); - } else if( flag&2 ) { - if( src->id != bl->id && battle->check_target(src,bl,BCT_ENEMY) > 0 ) - status_fix_damage(src,bl,9999,clif->damage(src,bl,tick,0,0,9999,0,0,0)); - } else if( sd ) { - short chance = sstatus->int_/6 + sd->status.job_level/5 + skill_lv*4; - if( !sd->status.party_id || (rnd()%100 > chance)) { - clif->skill_fail(sd,skill_id,USESKILL_FAIL_NEED_HELPER,0); - break; - } - if( map->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id,skill_lv), - BL_PC, src, skill_id, skill_lv, tick, BCT_ENEMY, skill->area_sub_count) > 7 ) - flag |= 2; - else - flag |= 1; - map->foreachinrange(skill->area_sub, src, skill->get_splash(skill_id,skill_lv),BL_PC, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|BCT_SELF, skill->castend_nodamage_id); - clif->skill_nodamage(src, bl, skill_id, skill_lv, - sc_start(src,SC_STOP,100,skill_lv,skill->get_time2(skill_id,skill_lv))); - if( flag&2 ) // Dealed here to prevent conflicts - status_fix_damage(src,bl,9999,clif->damage(src,bl,tick,0,0,9999,0,0,0)); + if ( tsc && tsc->data[type] ) { + clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0); + break; } + // val4 indicates caster's voice lesson level + sc_start4(src,bl,type,100,skill_lv, 0, 0, sd?pc->checkskill(sd,WM_LESSON):10, skill->get_time(skill_id,skill_lv)); + clif->skill_nodamage(src,bl,skill_id,skill_lv,1); break; case WM_SONG_OF_MANA: case WM_DANCE_WITH_WUG: case WM_LERADS_DEW: + case WM_UNLIMITED_HUMMING_VOICE: + { + int chorusbonus = battle->calc_chorusbonus(sd); + if( flag&1 ) + sc_start2(src,bl,type,100,skill_lv,chorusbonus,skill->get_time(skill_id,skill_lv)); + else if( sd ) { + party->foreachsamemap(skill->area_sub,sd,skill->get_splash(skill_id,skill_lv),src,skill_id,skill_lv,tick,flag|BCT_PARTY|1,skill->castend_nodamage_id); + sc_start2(src,bl,type,100,skill_lv,chorusbonus,skill->get_time(skill_id,skill_lv)); + clif->skill_nodamage(src,bl,skill_id,skill_lv,1); + } + } + break; + case WM_SATURDAY_NIGHT_FEVER: + { if( flag&1 ) { - // These affect to to all party members near the caster. - struct status_change *sc = status->get_sc(src); - if( sc && sc->data[type] ) { - sc_start2(bl,type,100,skill_lv,sc->data[type]->val2,skill->get_time(skill_id,skill_lv)); - } + int madnesscheck = 0; + if ( sd )//Required to check if the lord of madness effect will be applied. + madnesscheck = map->foreachinrange(skill->area_sub, src, skill->get_splash(skill_id,skill_lv),BL_PC, src, skill_id, skill_lv, tick, flag|BCT_ENEMY, skill->area_sub_count); + sc_start(src, bl, type, 100, skill_lv,skill->get_time(skill_id, skill_lv)); + if ( madnesscheck >= 8 )//The god of madness deals 9999 fixed unreduceable damage when 8 or more enemy players are affected. + status_fix_damage(src, bl, 9999, clif->damage(src, bl, 0, 0, 9999, 0, 0, 0)); + //skill->attack(BF_MISC,src,src,bl,skillid,skilllv,tick,flag);//To renable when I can confirm it deals damage like this. Data shows its dealed as reflected damage which I dont have it coded like that yet. [Rytech] } else if( sd ) { - uint16 lv = skill_lv; - int count = skill->check_pc_partner(sd,skill_id,&lv,skill->get_splash(skill_id,skill_lv),1); - if( sc_start2(bl,type,100,skill_lv,count,skill->get_time(skill_id,skill_lv)) ) - party->foreachsamemap(skill->area_sub,sd,skill->get_splash(skill_id,skill_lv),src,skill_id,skill_lv,tick,flag|BCT_PARTY|1,skill->castend_nodamage_id); - clif->skill_nodamage(src,bl,skill_id,skill_lv,1); - + int rate = sstatus->int_ / 6 + (sd? sd->status.job_level:0) / 5 + skill_lv * 4; + if ( rnd()%100 < rate ) { + map->foreachinrange(skill->area_sub, src, skill->get_splash(skill_id,skill_lv),BL_PC, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill->castend_nodamage_id); + clif->skill_nodamage(src, bl, skill_id, skill_lv, 1); + } } + } break; case WM_MELODYOFSINK: case WM_BEYOND_OF_WARCRY: - case WM_UNLIMITED_HUMMING_VOICE: - if( flag&1 ) { - sc_start2(bl,type,100,skill_lv,skill->area_temp[0],skill->get_time(skill_id,skill_lv)); - } else { // These affect to all targets arround the caster. - uint16 lv = skill_lv; - skill->area_temp[0] = (sd) ? skill->check_pc_partner(sd,skill_id,&lv,skill->get_splash(skill_id,skill_lv),1) : 50; // 50% chance in non BL_PC (clones). - map->foreachinrange(skill->area_sub, src, skill->get_splash(skill_id,skill_lv),BL_PC, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill->castend_nodamage_id); - clif->skill_nodamage(src,bl,skill_id,skill_lv,1); + { + int chorusbonus = battle->calc_chorusbonus(sd); + if( flag&1 ) + sc_start2(src,bl,type,100,skill_lv,chorusbonus,skill->get_time(skill_id,skill_lv)); + else if( sd ) { + if ( rnd()%100 < 15 + 5 * skill_lv + 5 * chorusbonus ) { + map->foreachinrange(skill->area_sub, src, skill->get_splash(skill_id,skill_lv),BL_PC, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill->castend_nodamage_id); + clif->skill_nodamage(src,bl,skill_id,skill_lv,1); + } } + } break; case WM_RANDOMIZESPELL: { - int improv_skill_id = 0, improv_skill_lv; + int improv_skill_id = 0, improv_skill_lv, improv_idx; do { - i = rnd() % MAX_SKILL_IMPROVISE_DB; - improv_skill_id = skill->improvise_db[i].skill_id; - } while( improv_skill_id == 0 || rnd()%10000 >= skill->improvise_db[i].per ); + improv_idx = rnd() % MAX_SKILL_IMPROVISE_DB; + improv_skill_id = skill->improvise_db[improv_idx].skill_id; + } while( improv_skill_id == 0 || rnd()%10000 >= skill->improvise_db[improv_idx].per ); improv_skill_lv = 4 + skill_lv; clif->skill_nodamage (src, bl, skill_id, skill_lv, 1); @@ -8758,28 +8981,25 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui if( sd ) { short x, y; // Destiny position. - unsigned short mapindex; + unsigned short map_index; - if( skill_id == RETURN_TO_ELDICASTES) - { + if( skill_id == RETURN_TO_ELDICASTES) { x = 198; y = 187; - mapindex = mapindex_name2id(MAP_DICASTES); - } - else - { + map_index = mapindex->name2id(MAP_DICASTES); + } else { x = 44; y = 151; - mapindex = mapindex_name2id(MAP_MORA); + map_index = mapindex->name2id(MAP_MORA); } - if(!mapindex) { + if(!map_index) { //Given map not found? clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); map->freeblock_unlock(); return 0; } - pc->setpos(sd, mapindex, x, y, CLR_TELEPORT); + pc->setpos(sd, map_index, x, y, CLR_TELEPORT); } break; @@ -8797,23 +9017,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case SO_ARRULLO: { // [(15 + 5 * Skill Level) + ( Caster?s INT / 5 ) + ( Caster?s Job Level / 5 ) - ( Target?s INT / 6 ) - ( Target?s LUK / 10 )] % - int rate = (15 + 5 * skill_lv) + status_get_int(src)/5 + (sd ? sd->status.job_level : 0); + int rate = (15 + 5 * skill_lv) + status_get_int(src)/5 + (sd? sd->status.job_level:0)/5; rate -= status_get_int(bl)/6 - status_get_luk(bl)/10; clif->skill_nodamage(src, bl, skill_id, skill_lv, 1); - sc_start2(bl, type, rate, skill_lv, 1, skill->get_time(skill_id, skill_lv)); - } - break; - - case WM_LULLABY_DEEPSLEEP: - if( flag&1 ){ - //[(Skill Level x 4) + (Voice Lessons Skill Level x 2) + (Caster?s Base Level / 15) + (Caster?s Job Level / 5)] % - int rate = (4 * skill_lv) + ( (sd) ? pc->checkskill(sd,WM_LESSON)*2 + sd->status.job_level/5 : 0 ) + status->get_lv(src) / 15; - if( bl != src ) - sc_start(bl,type,rate,skill_lv,skill->get_time(skill_id,skill_lv)); - }else { - clif->skill_nodamage(src, bl, skill_id, skill_lv, 1); - map->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id, skill_lv), BL_CHAR, - src, skill_id, skill_lv, tick, flag|BCT_ALL|1, skill->castend_nodamage_id); + sc_start2(src,bl, type, rate, skill_lv, 1, skill->get_time(skill_id, skill_lv)); } break; @@ -8830,7 +9037,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui // Summoning the new one. if( !elemental->create(sd,elemental_class,skill->get_time(skill_id,skill_lv)) ) { - clif->skill_fail(sd,skill_id,0,0); + clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); break; } clif->skill_nodamage(src,bl,skill_id,skill_lv,1); @@ -8876,7 +9083,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui duration = 9000; break; } - skill->blockpc_start(sd, skill_id, duration, false); + skill->blockpc_start(sd, skill_id, duration); } break; @@ -8898,16 +9105,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui } break; - case SO_ELEMENTAL_SHIELD: - if( sd == NULL || !sd->ed ) - break; - elemental->delete(sd->ed, 0); - if( sd->status.party_id == 0 || flag&1 ) - skill->unitsetting(src,MG_SAFETYWALL,skill_lv,bl->x,bl->y,0); - else - party->foreachsamemap(skill->area_sub, sd, skill->get_splash(skill_id, skill_lv), src, skill_id, skill_lv, tick, flag|BCT_PARTY|1, skill->castend_nodamage_id); - break; - case GN_CHANGEMATERIAL: case SO_EL_ANALYSIS: if( sd ) { @@ -8926,7 +9123,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui status_change_end(src, type, INVALID_TIMER); // the first one cancels and the last one will take effect resetting the timer } clif->skill_nodamage(src, bl, skill_id, skill_lv, 1); - sc_start2(bl, type, 100, skill_lv, src->id, skill->get_time(skill_id,skill_lv)); + sc_start2(src,bl, type, 100, skill_lv, src->id, skill->get_time(skill_id,skill_lv)); (sc->bs_counter)++; } else if( sd ) { clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0); @@ -8940,8 +9137,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui int chance = 25 + 10 * skill_lv - (status_get_vit(bl) + status_get_luk(bl)) / 5; if ( chance < 10 ) chance = 10;//Minimal chance is 10%. - if ( rand()%100 < chance ) {//Coded to both inflect the status and drain the target's SP only when successful. [Rytech] - sc_start(bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)); + if ( rnd()%100 < chance ) {//Coded to both inflect the status and drain the target's SP only when successful. [Rytech] + sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)); status_zap(bl, 0, status_get_max_sp(bl) * (25 + 5 * skill_lv) / 100); } } else if ( sd ) { @@ -8953,23 +9150,23 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case GN_SLINGITEM: if( sd ) { short ammo_id; - i = sd->equip_index[EQI_AMMO]; - if( i <= 0 ) + int equip_idx = sd->equip_index[EQI_AMMO]; + if( equip_idx <= 0 ) break; // No ammo. - ammo_id = sd->inventory_data[i]->nameid; + ammo_id = sd->inventory_data[equip_idx]->nameid; if( ammo_id <= 0 ) break; sd->itemid = ammo_id; if( itemdb_is_GNbomb(ammo_id) ) { if(battle->check_target(src,bl,BCT_ENEMY) > 0) {// Only attack if the target is an enemy. - if( ammo_id == 13263 ) + if( ammo_id == ITEMID_PINEAPPLE_BOMB ) map->foreachincell(skill->area_sub,bl->m,bl->x,bl->y,BL_CHAR,src,GN_SLINGITEM_RANGEMELEEATK,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id); else skill->attack(BF_WEAPON,src,src,bl,GN_SLINGITEM_RANGEMELEEATK,skill_lv,tick,flag); } else //Otherwise, it fails, shows animation and removes items. clif->skill_fail(sd,GN_SLINGITEM_RANGEMELEEATK,0xa,0); } else if( itemdb_is_GNthrowable(ammo_id) ) { - struct script_code *scriptroot = sd->inventory_data[i]->script; + struct script_code *scriptroot = sd->inventory_data[equip_idx]->script; if( !scriptroot ) break; if( dstsd ) @@ -9026,9 +9223,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui clif->skill_nodamage(src,src,skill_id,skill_lv,1); clif->skill_damage(src, ( skill_id == EL_GUST || skill_id == EL_BLAST || skill_id == EL_WILD_STORM )?src:bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); if( skill_id == EL_WIND_STEP ) // There aren't teleport, just push the master away. - skill->blown(src,bl,(rnd()%skill->get_blewcount(skill_id,skill_lv))+1,rand()%8,0); - sc_start(src,type2,100,skill_lv,skill->get_time(skill_id,skill_lv)); - sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)); + skill->blown(src,bl,(rnd()%skill->get_blewcount(skill_id,skill_lv))+1,rnd()%8,0); + sc_start(src, src,type2,100,skill_lv,skill->get_time(skill_id,skill_lv)); + sc_start(src, bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)); } } } @@ -9056,8 +9253,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui } else { // This not heals at the end. clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); - sc_start(src,type2,100,skill_lv,skill->get_time(skill_id,skill_lv)); - sc_start(bl,type,100,src->id,skill->get_time(skill_id,skill_lv)); + sc_start(src, src,type2,100,skill_lv,skill->get_time(skill_id,skill_lv)); + sc_start(src, bl,type,100,src->id,skill->get_time(skill_id,skill_lv)); } } } @@ -9068,6 +9265,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case KO_KAZEHU_SEIRAN: case KO_DOHU_KOUKAI: if(sd) { + int i; int ttype = skill->get_ele(skill_id, skill_lv); clif->skill_nodamage(src, bl, skill_id, skill_lv, 1); ARR_FIND(1, 6, i, sd->charm[i] > 0 && ttype != i); @@ -9079,16 +9277,16 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case KO_ZANZOU: if(sd) { - struct mob_data *md; - - md = mob->once_spawn_sub(src, src->m, src->x, src->y, status->get_name(src), 2308, "", SZ_SMALL, AI_NONE); - if( md ) { - md->master_id = src->id; - md->special_state.ai = AI_ZANZOU; - if( md->deletetimer != INVALID_TIMER ) - timer->delete(md->deletetimer, mob->timer_delete); - md->deletetimer = timer->add (timer->gettick() + skill->get_time(skill_id, skill_lv), mob->timer_delete, md->bl.id, 0); - mob->spawn( md ); + struct mob_data *summon_md; + + summon_md = mob->once_spawn_sub(src, src->m, src->x, src->y, status->get_name(src), 2308, "", SZ_MEDIUM, AI_NONE); + if( summon_md ) { + summon_md->master_id = src->id; + summon_md->special_state.ai = AI_ZANZOU; + if( summon_md->deletetimer != INVALID_TIMER ) + timer->delete(summon_md->deletetimer, mob->timer_delete); + summon_md->deletetimer = timer->add(timer->gettick() + skill->get_time(skill_id, skill_lv), mob->timer_delete, summon_md->bl.id, 0); + mob->spawn( summon_md ); pc->setinvincibletimer(sd,500);// unlock target lock clif->skill_nodamage(src,bl,skill_id,skill_lv,1); skill->blown(src,bl,skill->get_blewcount(skill_id,skill_lv),unit->getdir(bl),0); @@ -9105,7 +9303,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui } if( dstsd && tsc && !tsc->data[type] && rand()%100 < rate ){ clif->skill_nodamage(src, bl, skill_id, skill_lv, - sc_start(bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv))); + sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv))); }else if( sd ) clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0); } @@ -9116,10 +9314,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui && rand()%100 < (10 * (5 * skill_lv - status_get_int(bl) / 2 + 45 + 5 * skill_lv)) ) { clif->skill_nodamage(src, bl, skill_id, skill_lv, - status->change_start(bl, type, 10000, skill_lv, 0, 0, 0, skill->get_time(skill_id, skill_lv), 1)); + status->change_start(src, bl, type, 10000, skill_lv, 0, 0, 0, skill->get_time(skill_id, skill_lv), 1)); status_zap(bl, tstatus->max_hp * skill_lv * 5 / 100 , 0); if( status->get_lv(bl) <= status->get_lv(src) ) - status->change_start(bl, SC_COMA, skill_lv, skill_lv, 0, src->id, 0, 0, 0); + status->change_start(src, bl, SC_COMA, skill_lv, skill_lv, 0, src->id, 0, 0, 0); } else if( sd ) clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0); break; @@ -9135,13 +9333,13 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui if (unit->movepos(src, bl->x, bl->y, 0, 0)) { clif->skill_nodamage(src, src, skill_id, skill_lv, 1); clif->slide(src, bl->x, bl->y) ; - sc_start(src, SC_CONFUSION, 25, skill_lv, skill->get_time(skill_id, skill_lv)); + sc_start(src, src, SC_CONFUSION, 25, skill_lv, skill->get_time(skill_id, skill_lv)); if ( !is_boss(bl) && unit->stop_walking(&sd->bl, 1) && unit->movepos(bl, x, y, 0, 0) ) { if( dstsd && pc_issit(dstsd) ) pc->setstand(dstsd); clif->slide(bl, x, y) ; - sc_start(bl, SC_CONFUSION, 75, skill_lv, skill->get_time(skill_id, skill_lv)); + sc_start(src, bl, SC_CONFUSION, 75, skill_lv, skill->get_time(skill_id, skill_lv)); } } } @@ -9159,7 +9357,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case KG_KYOMU: case KG_KAGEMUSYA: clif->skill_nodamage(src,bl,skill_id,skill_lv, - sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); + sc_start(src, bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv))); clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); break; @@ -9168,8 +9366,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui if(tsc && ( tsc->option&(OPTION_CLOAK|OPTION_HIDE) || tsc->data[SC_CAMOUFLAGE] || tsc->data[SC__SHADOWFORM] || tsc->data[SC_MARIONETTE_MASTER] || tsc->data[SC_HARMONIZE])){ - sc_start(src, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)); - sc_start(bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)); + sc_start(src, src, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)); + sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)); status_change_end(bl, SC_HIDING, INVALID_TIMER); status_change_end(bl, SC_CLOAKING, INVALID_TIMER); status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER); @@ -9180,7 +9378,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui } if( skill->area_temp[2] == 1 ){ clif->skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); - sc_start(src, SC_STOP, 100, skill_lv, skill->get_time(skill_id, skill_lv)); + sc_start(src, src, SC_STOP, 100, skill_lv, skill->get_time(skill_id, skill_lv)); } } else { skill->area_temp[2] = 0; @@ -9197,22 +9395,23 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui }; int heal; if(tsc){ + int i; for (i = 0; i < ARRAYLENGTH(scs); i++) { if (tsc->data[scs[i]]) status_change_end(bl, scs[i], INVALID_TIMER); } if (!tsc->data[SC_SILENCE]) //put inavoidable silence on target - status->change_start(bl, SC_SILENCE, 100, skill_lv, 0,0,0, skill->get_time(skill_id, skill_lv),1|2|8); + status->change_start(src, bl, SC_SILENCE, 100, skill_lv, 0,0,0, skill->get_time(skill_id, skill_lv),1|2|8); } heal = status_get_matk_min(src)*4; status->heal(bl, heal, 0, 7); //now inflict silence on everyone if(ssc && !ssc->data[SC_SILENCE]) //put inavoidable silence on homun - status->change_start(src, SC_SILENCE, 100, skill_lv, 0,0,0, skill->get_time(skill_id, skill_lv),1|2|8); + status->change_start(src, src, SC_SILENCE, 100, skill_lv, 0,0,0, skill->get_time(skill_id, skill_lv),1|2|8); if(m_bl){ struct status_change *msc = status->get_sc(m_bl); if(msc && !msc->data[SC_SILENCE]) //put inavoidable silence on master - status->change_start(m_bl, SC_SILENCE, 100, skill_lv, 0,0,0, skill->get_time(skill_id, skill_lv),1|2|8); + status->change_start(src, m_bl, SC_SILENCE, 100, skill_lv, 0,0,0, skill->get_time(skill_id, skill_lv),1|2|8); } if (hd) skill->blockhomun_start(hd, skill_id, skill->get_cooldown(skill_id, skill_lv)); @@ -9228,22 +9427,24 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui if(s_bl && s_bl->type==BL_PC) { status->set_sp(s_bl,status_get_max_sp(s_bl)/2,0); //master drain 50% sp clif->send_homdata(((TBL_PC *)s_bl), SP_HUNGRY, hd->homunculus.hunger); //refresh hunger info - sc_start(s_bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)); //gene bonus + sc_start(src, s_bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)); //gene bonus } - sc_start(bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)); + sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)); skill->blockhomun_start(hd, skill_id, skill->get_cooldown(skill_id, skill_lv)); } break; case MH_GRANITIC_ARMOR: case MH_PYROCLASTIC: - { - struct block_list *s_bl = battle->get_master(src); - if(s_bl) - sc_start2(s_bl, type, 100, skill_lv, hd->homunculus.level, skill->get_time(skill_id, skill_lv)); //start on master - sc_start2(bl, type, 100, skill_lv, hd->homunculus.level, skill->get_time(skill_id, skill_lv)); - if (hd) + if( hd ){ + struct block_list *s_bl = battle->get_master(src); + + if(s_bl) + sc_start2(src, s_bl, type, 100, skill_lv, hd->homunculus.level, skill->get_time(skill_id, skill_lv)); //start on master + + sc_start2(src, bl, type, 100, skill_lv, hd->homunculus.level, skill->get_time(skill_id, skill_lv)); + skill->blockhomun_start(hd, skill_id, skill->get_cooldown(skill_id, skill_lv)); - } + } break; case MH_LIGHT_OF_REGENE: @@ -9254,7 +9455,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui //don't break need to start status and start block timer case MH_MAGMA_FLOW: case MH_PAIN_KILLER: - sc_start(bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)); + sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)); if (hd) skill->blockhomun_start(hd, skill_id, skill->get_cooldown(skill_id, skill_lv)); break; @@ -9262,22 +9463,22 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui { int summons[5] = {1004, 1303, 1303, 1994, 1994}; int qty[5] = {3 , 3 , 4 , 4 , 5}; - struct mob_data *md; + struct mob_data *summon_md; int i, dummy = 0; - i = map->foreachinmap(skill->check_condition_mob_master_sub ,hd->bl.m, BL_MOB, hd->bl.id, summons[skill_lv-1], skill_id, &dummy); + i = map->foreachinmap(skill->check_condition_mob_master_sub, src->m, BL_MOB, src->id, summons[skill_lv-1], skill_id, &dummy); if(i >= qty[skill_lv-1]) break; for(i=0; i<qty[skill_lv - 1]; i++){ //easy way - md = mob->once_spawn_sub(src, src->m, src->x, src->y, status->get_name(src), summons[skill_lv - 1], "", SZ_SMALL, AI_ATTACK); - if (md) { - md->master_id = src->id; - if (md->deletetimer != INVALID_TIMER) - timer->delete(md->deletetimer, mob->timer_delete); - md->deletetimer = timer->add(timer->gettick() + skill->get_time(skill_id, skill_lv), mob->timer_delete, md->bl.id, 0); - mob->spawn(md); //Now it is ready for spawning. - sc_start4(&md->bl, SC_MODECHANGE, 100, 1, 0, MD_CANATTACK|MD_AGGRESSIVE, 0, 60000); + summon_md = mob->once_spawn_sub(src, src->m, src->x, src->y, status->get_name(src), summons[skill_lv - 1], "", SZ_MEDIUM, AI_ATTACK); + if (summon_md) { + summon_md->master_id = src->id; + if (summon_md->deletetimer != INVALID_TIMER) + timer->delete(summon_md->deletetimer, mob->timer_delete); + summon_md->deletetimer = timer->add(timer->gettick() + skill->get_time(skill_id, skill_lv), mob->timer_delete, summon_md->bl.id, 0); + mob->spawn(summon_md); //Now it is ready for spawning. + sc_start4(src,&summon_md->bl, SC_MODECHANGE, 100, 1, 0, MD_CANATTACK|MD_AGGRESSIVE, 0, 60000); } } if (hd) @@ -9310,7 +9511,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui } skill->onskillusage(sd, bl, skill_id, tick); // perform skill requirement consumption - skill->consume_requirement(sd,skill_id,skill_lv,2); + if( skill_id != NC_SELFDESTRUCTION ) + skill->consume_requirement(sd,skill_id,skill_lv,2); } map->freeblock_unlock(); @@ -9320,7 +9522,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui /*========================================== * *------------------------------------------*/ -int skill_castend_pos(int tid, unsigned int tick, int id, intptr_t data) { +int skill_castend_pos(int tid, int64 tick, int id, intptr_t data) { struct block_list* src = map->id2bl(id); int maxcount; struct map_session_data *sd; @@ -9433,7 +9635,7 @@ int skill_castend_pos(int tid, unsigned int tick, int id, intptr_t data) { } } if(cooldown) - skill->blockpc_start(sd, ud->skill_id, cooldown, false); + skill->blockpc_start(sd, ud->skill_id, cooldown); } if( battle_config.display_status_timers && sd ) clif->status_change(src, SI_POSTDELAY, 1, skill->delay_fix(src, ud->skill_id, ud->skill_lv), 0, 0, 0); @@ -9474,6 +9676,14 @@ int skill_castend_pos(int tid, unsigned int tick, int id, intptr_t data) { return 0; } +static int check_npc_chaospanic(struct block_list* bl, va_list args) { + TBL_NPC* nd = (TBL_NPC*)bl; + + if( nd->option&(OPTION_HIDE|OPTION_INVISIBLE) || nd->class_ != 45 ) + return 0; + + return 1; +} /* skill count without self */ static int skill_count_wos(struct block_list *bl,va_list ap) { struct block_list* src = va_arg(ap, struct block_list*); @@ -9490,7 +9700,7 @@ int skill_castend_map (struct map_session_data *sd, uint16 skill_id, const char nullpo_ret(sd); //Simplify skill_failed code. -#define skill_failed(sd) { sd->menuskill_id = sd->menuskill_val = 0; } +#define skill_failed(sd) ( (sd)->menuskill_id = (sd)->menuskill_val = 0 ) if(skill_id != sd->menuskill_id) return 0; @@ -9549,10 +9759,10 @@ int skill_castend_map (struct map_session_data *sd, uint16 skill_id, const char int i, lv, wx, wy; int maxcount=0; int x,y; - unsigned short mapindex; + unsigned short map_index; - mapindex = mapindex_name2id(mapname); - if(!mapindex) { //Given map not found? + map_index = mapindex->name2id(mapname); + if(!map_index) { //Given map not found? clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); skill_failed(sd); return 0; @@ -9582,7 +9792,7 @@ int skill_castend_map (struct map_session_data *sd, uint16 skill_id, const char if( lv > 4 ) lv = 4; // crash prevention // check if the chosen map exists in the memo list - ARR_FIND( 0, lv, i, mapindex == p[i]->map ); + ARR_FIND( 0, lv, i, map_index == p[i]->map ); if( i < lv ) { x=p[i]->x; y=p[i]->y; @@ -9607,7 +9817,7 @@ int skill_castend_map (struct map_session_data *sd, uint16 skill_id, const char group->val1 = (group->val1<<16)|(short)0; // record the destination coordinates group->val2 = (x<<16)|y; - group->val3 = mapindex; + group->val3 = map_index; } break; } @@ -9620,14 +9830,13 @@ int skill_castend_map (struct map_session_data *sd, uint16 skill_id, const char /*========================================== * *------------------------------------------*/ -int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, uint16 skill_lv, unsigned int tick, int flag) -{ +int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, uint16 skill_lv, int64 tick, int flag) { struct map_session_data* sd; struct status_change* sc; struct status_change_entry *sce; struct skill_unit_group* sg; enum sc_type type; - int i; + int r; //if(skill_lv <= 0) return 0; if(skill_id > 0 && !skill_lv) return 0; // celest @@ -9663,47 +9872,46 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui switch(skill_id) { case PR_BENEDICTIO: + r = skill->get_splash(skill_id, skill_lv); skill->area_temp[1] = src->id; - i = skill->get_splash(skill_id, skill_lv); map->foreachinarea(skill->area_sub, - src->m, x-i, y-i, x+i, y+i, BL_PC, + src->m, x-r, y-r, x+r, y+r, BL_PC, src, skill_id, skill_lv, tick, flag|BCT_ALL|1, skill->castend_nodamage_id); map->foreachinarea(skill->area_sub, - src->m, x-i, y-i, x+i, y+i, BL_CHAR, + src->m, x-r, y-r, x+r, y+r, BL_CHAR, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill->castend_damage_id); break; case BS_HAMMERFALL: - i = skill->get_splash(skill_id, skill_lv); + r = skill->get_splash(skill_id, skill_lv); map->foreachinarea(skill->area_sub, - src->m, x-i, y-i, x+i, y+i, BL_CHAR, + src->m, x-r, y-r, x+r, y+r, BL_CHAR, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|2, skill->castend_nodamage_id); break; case HT_DETECTING: - i = skill->get_splash(skill_id, skill_lv); + r = skill->get_splash(skill_id, skill_lv); map->foreachinarea(status->change_timer_sub, - src->m, x-i, y-i, x+i,y+i,BL_CHAR, + src->m, x-r, y-r, x+r,y+r,BL_CHAR, src,NULL,SC_SIGHT,tick); if(battle_config.traps_setting&1) map->foreachinarea(skill_reveal_trap, - src->m, x-i, y-i, x+i,y+i,BL_SKILL); + src->m, x-r, y-r, x+r, y+r, BL_SKILL); break; case SR_RIDEINLIGHTNING: - i = skill->get_splash(skill_id, skill_lv); - map->foreachinarea(skill->area_sub, src->m, x-i, y-i, x+i, y+i, BL_CHAR, + r = skill->get_splash(skill_id, skill_lv); + map->foreachinarea(skill->area_sub, src->m, x-r, y-r, x+r, y+r, BL_CHAR, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill->castend_damage_id); break; case SA_VOLCANO: case SA_DELUGE: case SA_VIOLENTGALE: - { //Does not consumes if the skill is already active. [Skotlex] - struct skill_unit_group *sg; + //Does not consumes if the skill is already active. [Skotlex] if ((sg= skill->locate_element_field(src)) != NULL && ( sg->skill_id == SA_VOLCANO || sg->skill_id == SA_DELUGE || sg->skill_id == SA_VIOLENTGALE )) { if (sg->limit - DIFF_TICK(timer->gettick(), sg->tick) > 0) { @@ -9714,7 +9922,14 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui } skill->unitsetting(src,skill_id,skill_lv,x,y,0); break; - } + + case SC_CHAOSPANIC: + case SC_MAELSTROM: + if (sd && map->foreachinarea(&check_npc_chaospanic,src->m, x-3, y-3, x+3, y+3, BL_NPC) > 0 ) { + clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); + break; + } + case MG_SAFETYWALL: case MG_FIREWALL: case MG_THUNDERSTORM: @@ -9795,8 +10010,6 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui case RA_ICEBOUNDTRAP: case SC_MANHOLE: case SC_DIMENSIONDOOR: - case SC_CHAOSPANIC: - case SC_MAELSTROM: case SC_BLOODYLUST: case WM_REVERBERATION: case WM_SEVERE_RAINSTORM: @@ -9823,6 +10036,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui case MH_STEINWAND: case MH_XENO_SLASHER: case NC_MAGMA_ERUPTION: + case SO_ELEMENTAL_SHIELD: case RL_B_TRAP: flag|=1;//Set flag to 1 to prevent deleting ammo (it will be deleted on group-delete). case GS_GROUNDDRIFT: //Ammo should be deleted right away. @@ -9845,20 +10059,20 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui skill->clear_unitgroup(src); if( skill->unitsetting(src,skill_id,skill_lv,x,y,0) ) - sc_start4(src,type,100,skill_lv,0,0,src->id,skill->get_time(skill_id,skill_lv)); + sc_start4(src,src,type,100,skill_lv,0,0,src->id,skill->get_time(skill_id,skill_lv)); flag|=1; } break; case CG_HERMODE: skill->clear_unitgroup(src); if ((sg = skill->unitsetting(src,skill_id,skill_lv,x,y,0))) - sc_start4(src,SC_DANCING,100, + sc_start4(src,src,SC_DANCING,100, skill_id,0,skill_lv,sg->group_id,skill->get_time(skill_id,skill_lv)); flag|=1; break; case RG_CLEANER: // [Valaris] - i = skill->get_splash(skill_id, skill_lv); - map->foreachinarea(skill->graffitiremover,src->m,x-i,y-i,x+i,y+i,BL_SKILL); + r = skill->get_splash(skill_id, skill_lv); + map->foreachinarea(skill->graffitiremover,src->m,x-r,y-r,x+r,y+r,BL_SKILL); break; case SO_WARMER: @@ -9867,9 +10081,11 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui skill->unitsetting(src,skill_id,skill_lv,x,y,0); break; - case WZ_METEOR: { + case WZ_METEOR: + { int area = skill->get_splash(skill_id, skill_lv); short tmpx = 0, tmpy = 0, x1 = 0, y1 = 0; + int i; for( i = 0; i < 2 + (skill_lv>>1); i++ ) { // Creates a random Cell in the Splash Area @@ -9911,7 +10127,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui clif->skill_poseffect(src,skill_id,skill_lv,src->x,src->y,tick); #endif if (sd) - skill->blockpc_start (sd, MO_EXTREMITYFIST, 2000, false); + skill->blockpc_start (sd, MO_EXTREMITYFIST, 2000); } break; case NJ_SHADOWJUMP: @@ -9930,13 +10146,13 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui struct mob_data *md; // Correct info, don't change any of this! [celest] - md = mob->once_spawn_sub(src, src->m, x, y, status->get_name(src), class_, "", SZ_SMALL, AI_NONE); + md = mob->once_spawn_sub(src, src->m, x, y, status->get_name(src), class_, "", SZ_MEDIUM, AI_NONE); if (md) { md->master_id = src->id; md->special_state.ai = (skill_id == AM_SPHEREMINE) ? AI_SPHERE : AI_FLORA; if( md->deletetimer != INVALID_TIMER ) timer->delete(md->deletetimer, mob->timer_delete); - md->deletetimer = timer->add (timer->gettick() + skill->get_time(skill_id,skill_lv), mob->timer_delete, md->bl.id, 0); + md->deletetimer = timer->add(timer->gettick() + skill->get_time(skill_id,skill_lv), mob->timer_delete, md->bl.id, 0); mob->spawn (md); //Now it is ready for spawning. } } @@ -10002,8 +10218,8 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui if (rnd()%100 < 80) { int dummy = 1; clif->skill_poseffect(src,skill_id,skill_lv,x,y,tick); - i = skill->get_splash(skill_id, skill_lv); - map->foreachinarea(skill->cell_overlap, src->m, x-i, y-i, x+i, y+i, BL_SKILL, HW_GANBANTEIN, &dummy, src); + r = skill->get_splash(skill_id, skill_lv); + map->foreachinarea(skill->cell_overlap, src->m, x-r, y-r, x+r, y+r, BL_SKILL, HW_GANBANTEIN, &dummy, src); } else { if (sd) clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); return 1; @@ -10012,7 +10228,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui case HW_GRAVITATION: if ((sg = skill->unitsetting(src,skill_id,skill_lv,x,y,0))) - sc_start4(src,type,100,skill_lv,0,BCT_SELF,sg->group_id,skill->get_time(skill_id,skill_lv)); + sc_start4(src,src,type,100,skill_lv,0,BCT_SELF,sg->group_id,skill->get_time(skill_id,skill_lv)); flag|=1; break; @@ -10027,14 +10243,14 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui if (rnd()%100 < 50) { clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); } else { - TBL_MOB* md = mob->once_spawn_sub(src, src->m, x, y, "--ja--",(skill_lv < 2 ? 1084+rnd()%2 : 1078+rnd()%6),"", SZ_SMALL, AI_NONE); + TBL_MOB* md = mob->once_spawn_sub(src, src->m, x, y, "--ja--",(skill_lv < 2 ? 1084+rnd()%2 : 1078+rnd()%6),"", SZ_MEDIUM, AI_NONE); int i; if (!md) break; if ((i = skill->get_time(skill_id, skill_lv)) > 0) { if( md->deletetimer != INVALID_TIMER ) timer->delete(md->deletetimer, mob->timer_delete); - md->deletetimer = timer->add (tick + i, mob->timer_delete, md->bl.id, 0); + md->deletetimer = timer->add(tick + i, mob->timer_delete, md->bl.id, 0); } mob->spawn (md); } @@ -10046,7 +10262,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui case SG_STAR_WARM: skill->clear_unitgroup(src); if ((sg = skill->unitsetting(src,skill_id,skill_lv,src->x,src->y,0))) - sc_start4(src,type,100,skill_lv,0,0,sg->group_id,skill->get_time(skill_id,skill_lv)); + sc_start4(src,src,type,100,skill_lv,0,0,sg->group_id,skill->get_time(skill_id,skill_lv)); flag|=1; break; @@ -10060,13 +10276,13 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui if (sce) status_change_end(src, type, INVALID_TIMER); //Was under someone else's Gospel. [Skotlex] status->change_clear_buffs(src,3); - sc_start4(src,type,100,skill_lv,0,sg->group_id,BCT_SELF,skill->get_time(skill_id,skill_lv)); + sc_start4(src,src,type,100,skill_lv,0,sg->group_id,BCT_SELF,skill->get_time(skill_id,skill_lv)); clif->skill_poseffect(src, skill_id, skill_lv, 0, 0, tick); // PA_GOSPEL music packet } break; case NJ_TATAMIGAESHI: if (skill->unitsetting(src,skill_id,skill_lv,src->x,src->y,0)) - sc_start(src,type,100,skill_lv,skill->get_time2(skill_id,skill_lv)); + sc_start(src,src,type,100,skill_lv,skill->get_time2(skill_id,skill_lv)); break; case AM_RESURRECTHOMUN: //[orn] @@ -10081,17 +10297,32 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui case RK_WINDCUTTER: clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); case NC_COLDSLOWER: - case NC_ARMSCANNON: case RK_DRAGONBREATH: case RK_DRAGONBREATH_WATER: - i = skill->get_splash(skill_id,skill_lv); - map->foreachinarea(skill->area_sub,src->m,x-i,y-i,x+i,y+i,splash_target(src), + r = skill->get_splash(skill_id,skill_lv); + map->foreachinarea(skill->area_sub,src->m,x-r,y-r,x+r,y+r,splash_target(src), src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id); break; + case WM_GREAT_ECHO: + case WM_SOUND_OF_DESTRUCTION: + r = skill->get_splash(skill_id,skill_lv); + map->foreachinarea(skill->area_sub,src->m,x-r,y-r,x+r,y+r,BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id); + break; + case WM_LULLABY_DEEPSLEEP: + r = skill->get_splash(skill_id,skill_lv); + map->foreachinarea(skill->area_sub,src->m,x-r,y-r,x+r,y+r,BL_CHAR, + src,skill_id,skill_lv,tick,flag|BCT_ALL|1,skill->castend_damage_id); + break; + + case WM_VOICEOFSIREN: + r = skill->get_splash(skill_id,skill_lv); + map->foreachinarea(skill->area_sub,src->m,x-r,y-r,x+r,y+r,BL_CHAR, + src,skill_id,skill_lv,tick,flag|BCT_ALL|1,skill->castend_damage_id); + break; case SO_ARRULLO: - i = skill->get_splash(skill_id,skill_lv); - map->foreachinarea(skill->area_sub,src->m,x-i,y-i,x+i,y+i,splash_target(src), + r = skill->get_splash(skill_id,skill_lv); + map->foreachinarea(skill->area_sub,src->m,x-r,y-r,x+r,y+r,splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill->castend_nodamage_id); break; /** @@ -10112,8 +10343,8 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui **/ case AB_EPICLESIS: if( (sg = skill->unitsetting(src, skill_id, skill_lv, x, y, 0)) ) { - i = sg->unit->range; - map->foreachinarea(skill->area_sub, src->m, x - i, y - i, x + i, y + i, BL_CHAR, src, ALL_RESURRECTION, 1, tick, flag|BCT_NOENEMY|1,skill->castend_nodamage_id); + r = sg->unit->range; + map->foreachinarea(skill->area_sub, src->m, x - r, y - r, x + r, y + r, BL_CHAR, src, ALL_RESURRECTION, 1, tick, flag|BCT_NOENEMY|1,skill->castend_nodamage_id); } break; @@ -10138,8 +10369,8 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui * Ranger **/ case RA_DETONATOR: - i = skill->get_splash(skill_id, skill_lv); - map->foreachinarea(skill->detonator, src->m, x-i, y-i, x+i, y+i, BL_SKILL, src); + r = skill->get_splash(skill_id, skill_lv); + map->foreachinarea(skill->detonator, src->m, x-r, y-r, x+r, y+r, BL_SKILL, src); clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6); break; /** @@ -10149,7 +10380,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui case NC_STEALTHFIELD: skill->clear_unitgroup(src); // To remove previous skills - cannot used combined if( (sg = skill->unitsetting(src,skill_id,skill_lv,src->x,src->y,0)) != NULL ) { - sc_start2(src,skill_id == NC_NEUTRALBARRIER ? SC_NEUTRALBARRIER_MASTER : SC_STEALTHFIELD_MASTER,100,skill_lv,sg->group_id,skill->get_time(skill_id,skill_lv)); + sc_start2(src,src,skill_id == NC_NEUTRALBARRIER ? SC_NEUTRALBARRIER_MASTER : SC_STEALTHFIELD_MASTER,100,skill_lv,sg->group_id,skill->get_time(skill_id,skill_lv)); if( sd ) pc->overheat(sd,1); } break; @@ -10159,13 +10390,13 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui int class_ = 2042; struct mob_data *md; - md = mob->once_spawn_sub(src, src->m, x, y, status->get_name(src), class_, "", SZ_SMALL, AI_NONE); + md = mob->once_spawn_sub(src, src->m, x, y, status->get_name(src), class_, "", SZ_MEDIUM, AI_NONE); if( md ) { md->master_id = src->id; md->special_state.ai = AI_FLORA; if( md->deletetimer != INVALID_TIMER ) timer->delete(md->deletetimer, mob->timer_delete); - md->deletetimer = timer->add (timer->gettick() + skill->get_time(skill_id, skill_lv), mob->timer_delete, md->bl.id, 0); + md->deletetimer = timer->add(timer->gettick() + skill->get_time(skill_id, skill_lv), mob->timer_delete, md->bl.id, 0); mob->spawn( md ); } } @@ -10178,8 +10409,9 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui case SC_FEINTBOMB: skill->unitsetting(src,skill_id,skill_lv,x,y,0); // Set bomb on current Position clif->skill_nodamage(src,src,skill_id,skill_lv,1); - if( skill->blown(src,src,6,unit->getdir(src),0) ) - skill->castend_nodamage_id(src,src,TF_HIDING,1,tick,0x2); + skill->blown(src,src,3*skill_lv,unit->getdir(src),0); + //After back sliding, the player goes into hiding. Hiding level used is throught to be the learned level. + sc_start(src,src,SC_HIDING,100,(sd?pc->checkskill(sd,TF_HIDING):10),skill->get_time(TF_HIDING,(sd?pc->checkskill(sd,TF_HIDING):10))); break; case SC_ESCAPE: @@ -10190,13 +10422,16 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui case LG_OVERBRAND: { - int width;//according to data from irowiki it actually is a square - for( width = 0; width < 7; width++ ) - for( i = 0; i < 7; i++ ) - map->foreachincell(skill->area_sub, src->m, x-2+i, y-2+width, splash_target(src), src, LG_OVERBRAND_BRANDISH, skill_lv, tick, flag|BCT_ENEMY,skill->castend_damage_id); - for( width = 0; width < 7; width++ ) - for( i = 0; i < 7; i++ ) - map->foreachincell(skill->area_sub, src->m, x-2+i, y-2+width, splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY,skill->castend_damage_id); + uint8 dir = map->calc_dir(src, x, y); + uint8 x2 = x = src->x, y2 = y = src->y; + switch( dir ){ + case 0: case 1: case 7: x2++; x--; y2 += 7; break; + case 3: case 4: case 5: x2++; x--; y -= 7; break; + case 2: y2++; y--; x -= 7;break; + case 6: y2++; y--; x2 += 7;break; + } + map->foreachinarea(skill->area_sub, src->m, x, y, x2, y2, BL_CHAR, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|SD_ANIMATION|1,skill->castend_damage_id); + skill->addtimerskill(src,timer->gettick() + status_get_amotion(src), 0, 0, 0, LG_OVERBRAND_BRANDISH, skill_lv, dir, flag); } break; @@ -10204,7 +10439,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui if( sc && sc->data[SC_BANDING] ) status_change_end(src,SC_BANDING,INVALID_TIMER); else if( (sg = skill->unitsetting(src,skill_id,skill_lv,src->x,src->y,0)) != NULL ) { - sc_start4(src,SC_BANDING,100,skill_lv,0,0,sg->group_id,skill->get_time(skill_id,skill_lv)); + sc_start4(src,src,SC_BANDING,100,skill_lv,0,0,sg->group_id,skill->get_time(skill_id,skill_lv)); if( sd ) pc->banding(sd,skill_lv); } clif->skill_nodamage(src,src,skill_id,skill_lv,1); @@ -10212,32 +10447,46 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui case LG_RAYOFGENESIS: if( status->charge(src,status_get_max_hp(src)*3*skill_lv / 100,0) ) { - i = skill->get_splash(skill_id,skill_lv); - map->foreachinarea(skill->area_sub,src->m,x-i,y-i,x+i,y+i,splash_target(src), + r = skill->get_splash(skill_id,skill_lv); + map->foreachinarea(skill->area_sub,src->m,x-r,y-r,x+r,y+r,splash_target(src), src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id); } else if( sd ) clif->skill_fail(sd,skill_id,USESKILL_FAIL,0); break; case WM_DOMINION_IMPULSE: - i = skill->get_splash(skill_id, skill_lv); - map->foreachinarea( skill->activate_reverberation, - src->m, x-i, y-i, x+i,y+i,BL_SKILL); + r = skill->get_splash(skill_id, skill_lv); + map->foreachinarea( skill->activate_reverberation,src->m, x-r, y-r, x+r,y+r,BL_SKILL); break; - case WM_GREAT_ECHO: - flag|=1; // Should counsume 1 item per skill usage. - map->foreachinrange(skill->area_sub, src, skill->get_splash(skill_id,skill_lv),splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY, skill->castend_damage_id); - break; - case GN_CRAZYWEED: { - int area = skill->get_splash(GN_CRAZYWEED_ATK, skill_lv); - short x1 = 0, y1 = 0; + case GN_CRAZYWEED: + { + int area = skill->get_splash(skill_id, skill_lv); + short tmpx = 0, tmpy = 0, x1 = 0, y1 = 0; + + for( r = 0; r < 3 + (skill_lv>>1); r++ ) { + // Creates a random Cell in the Splash Area + tmpx = x - area + rnd()%(area * 2 + 1); + tmpy = y - area + rnd()%(area * 2 + 1); - for( i = 0; i < 3 + (skill_lv/2); i++ ) { - x1 = x - area + rnd()%(area * 2 + 1); - y1 = y - area + rnd()%(area * 2 + 1); - skill->addtimerskill(src,tick+i*150,0,x1,y1,GN_CRAZYWEED_ATK,skill_lv,-1,0); + if( r > 0 ) + skill->addtimerskill(src,tick+r*250,0,tmpx,tmpy,GN_CRAZYWEED,skill_lv,(x1<<16)|y1,flag); + + x1 = tmpx; + y1 = tmpy; } + + skill->addtimerskill(src,tick+r*250,0,tmpx,tmpy,GN_CRAZYWEED,skill_lv,-1,flag); + } + break; + + case GN_CRAZYWEED_ATK: { + int dummy = 1; + //Enable if any unique animation gets added to this skill ID in the future. [Rytech] + //clif_skill_poseffect(src,skillid,skilllv,x,y,tick); + r = skill->get_splash(skill_id, skill_lv); + map->foreachinarea(skill->cell_overlap, src->m, x-r, y-r, x+r, y+r, BL_SKILL, skill_id, &dummy, src); + map->foreachinarea(skill->area_sub, src->m, x-r, y-r, x+r, y+r, BL_CHAR, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill->castend_damage_id); } break; case GN_FIRE_EXPANSION: { @@ -10280,15 +10529,18 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui if( sc && sc->data[type] ) status_change_end(src,type,INVALID_TIMER); clif->skill_nodamage(src, src ,skill_id, skill_lv, - sc_start2(src, type, 100, skill_id, skill_lv, skill->get_time(skill_id, skill_lv))); + sc_start2(src,src, type, 100, skill_id, skill_lv, skill->get_time(skill_id, skill_lv))); break; case KO_MAKIBISHI: + { + int i; for( i = 0; i < (skill_lv+2); i++ ) { x = src->x - 1 + rnd()%3; y = src->y - 1 + rnd()%3; skill->unitsetting(src,skill_id,skill_lv,x,y,0); } + } break; default: @@ -10332,7 +10584,7 @@ int skill_dance_overlap_sub(struct block_list* bl, va_list ap) { else //Remove dissonance target->val2 &= ~UF_ENSEMBLE; - clif->skill_setunit(target); //Update look of affected cell. + clif->getareachar_skillunit(&target->bl,target,AREA); //Update look of affected cell. return 1; } @@ -10463,6 +10715,9 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_ sc = status->get_sc(src); // for traps, firewall and fogwall - celest switch( skill_id ) { + case SO_ELEMENTAL_SHIELD: + val2 = 300 * skill_lv + 65 * (st->int_ + status->get_lv(src)) + st->max_sp; + break; case MH_STEINWAND: val2 = 4 + skill_lv; //nb of attack blocked break; @@ -10515,6 +10770,8 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_ case WZ_QUAGMIRE: //The target changes to "all" if used in a gvg map. [Skotlex] case AM_DEMONSTRATION: case GN_HELLS_PLANT: + if( skill_id == GN_HELLS_PLANT && map->getcell(src->m, x, y, CELL_CHKLANDPROTECTOR) ) + return NULL; if (map_flag_vs(src->m) && battle_config.vs_traps_bctall && (src->type&battle_config.vs_traps_bctall)) target = BCT_ALL; @@ -10549,7 +10806,7 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_ { struct skill_condition req = skill->get_requirement(sd,skill_id,skill_lv); ARR_FIND(0, MAX_SKILL_ITEM_REQUIRE, i, req.itemid[i] && (req.itemid[i] == ITEMID_TRAP || req.itemid[i] == ITEMID_TRAP_ALLOY)); - if( req.itemid[i] ) + if( i != MAX_SKILL_ITEM_REQUIRE && req.itemid[i] ) req_item = req.itemid[i]; if( map_flag_gvg2(src->m) || map->list[src->m].flag.battleground ) limit *= 4; // longer trap times in WOE [celest] @@ -10573,7 +10830,7 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_ old_sg->skill_id == SA_VIOLENTGALE ) && old_sg->limit > 0) { //Use the previous limit (minus the elapsed time) [Skotlex] - limit = old_sg->limit - DIFF_TICK(timer->gettick(), old_sg->tick); + limit = old_sg->limit - DIFF_TICK32(timer->gettick(), old_sg->tick); if (limit < 0) //This can happen... limit = skill->get_time(skill_id,skill_lv); } @@ -10743,7 +11000,9 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_ limit = -1; break; case WM_REVERBERATION: - interval = limit; + if( battle_config.vs_traps_bctall && map_flag_vs(src->m) && (src->type&battle_config.vs_traps_bctall) ) + target = BCT_ALL; + val1 = skill_lv + 1; val2 = 1; case WM_POEMOFNETHERWORLD: // Can't be placed on top of Land Protector. if( map->getcell(src->m, x, y, CELL_CHKLANDPROTECTOR) ) @@ -10755,9 +11014,6 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_ case SO_WARMER: skill->clear_group(src, 8); break; - case SO_VACUUM_EXTREME: - range++; - break; case GN_WALLOFTHORN: if( flag&1 ) limit = 3000; @@ -10805,7 +11061,7 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_ sd->skill_lv_dance = skill_lv; } if ( - sc_start4(src, SC_DANCING, 100, skill_id, group->group_id, skill_lv, + sc_start4(src,src, SC_DANCING, 100, skill_id, group->group_id, skill_lv, (group->state.song_dance&2?BCT_SELF:0), limit+1000) && sd && group->state.song_dance&2 && skill_id != CG_HERMODE //Hermod is a encore with a warp! ) @@ -10817,9 +11073,9 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_ struct skill_unit *su; int ux = x + layout->dx[i]; int uy = y + layout->dy[i]; - int val1 = skill_lv; - int val2 = 0; int alive = 1; + val1 = skill_lv; + val2 = 0; if( !group->state.song_dance && !map->getcell(src->m,ux,uy,CELL_CHKREACH) ) continue; // don't place skill units on walls (except for songs/dances/encores) @@ -10871,11 +11127,9 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_ if (val1 < 1) val1 = 1; val2 = 0; break; - case WM_REVERBERATION: - val1 = 1 + skill_lv; - break; case GN_WALLOFTHORN: - val1 = 1000 * skill_lv; // Need official value. [LimitLine] + val1 = 2000 + 2000 * skill_lv; + val2 = src->id; break; default: if (group->state.song_dance&0x1) @@ -10885,9 +11139,6 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_ if (skill->get_unit_flag(skill_id) & UF_RANGEDSINGLEUNIT && i == (layout->count / 2)) val2 |= UF_RANGEDSINGLEUNIT; // center. - if( sd && map->getcell(src->m, ux, uy, CELL_CHKMAELSTROM) ) //Does not recover SP from monster skills - map->foreachincell(skill->maelstrom_suction,src->m,ux,uy,BL_SKILL,skill_id,skill_lv); - if( range <= 0 ) map->foreachincell(skill->cell_overlap,src->m,ux,uy,BL_SKILL,skill_id, &alive, src); if( !alive ) @@ -10930,7 +11181,7 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_ /*========================================== * *------------------------------------------*/ -int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned int tick) { +int skill_unit_onplace(struct skill_unit *src, struct block_list *bl, int64 tick) { struct skill_unit_group *sg; struct block_list *ss; struct status_change *sc; @@ -10949,13 +11200,14 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned if( skill->get_type(sg->skill_id) == BF_MAGIC && map->getcell(bl->m, bl->x, bl->y, CELL_CHKLANDPROTECTOR) && sg->skill_id != SA_LANDPROTECTOR ) return 0; //AoE skills are ineffective. [Skotlex] - if( map->getcell(bl->m, bl->x, bl->y, CELL_CHKMAELSTROM) ) - return 0; sc = status->get_sc(bl); if (sc && sc->option&OPTION_HIDE && sg->skill_id != WZ_HEAVENDRIVE && sg->skill_id != WL_EARTHSTRAIN ) return 0; //Hidden characters are immune to AoE skills except to these. [Skotlex] + if (sc && sc->data[SC_VACUUM_EXTREME] && map->getcell(bl->m, bl->x, bl->y, CELL_CHKLANDPROTECTOR)) + status_change_end(bl, SC_VACUUM_EXTREME, INVALID_TIMER); + type = status->skill2sc(sg->skill_id); sce = (sc && type != -1)?sc->data[type]:NULL; skill_id = sg->skill_id; //In case the group is deleted, we need to return the correct skill id, still. @@ -10967,34 +11219,36 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned break; } else if( sc && battle->check_target(&sg->unit->bl,bl,sg->target_flag) > 0 ) { int sec = skill->get_time2(sg->skill_id,sg->skill_lv); - if( status->change_start(bl,type,10000,sg->skill_lv,1,sg->group_id,0,sec,8) ) { + if( status->change_start(ss, bl,type,10000,sg->skill_lv,1,sg->group_id,0,sec,8) ) { const struct TimerData* td = sc->data[type]?timer->get(sc->data[type]->timer):NULL; if( td ) - sec = DIFF_TICK(td->tick, tick); + sec = DIFF_TICK32(td->tick, tick); map->moveblock(bl, src->bl.x, src->bl.y, tick); clif->fixpos(bl); sg->val2 = bl->id; } else sec = 3000; //Couldn't trap it? - sg->limit = DIFF_TICK(tick,sg->tick)+sec; + sg->limit = DIFF_TICK32(tick,sg->tick)+sec; } break; case UNT_SAFETYWALL: if (!sce) - sc_start4(bl,type,100,sg->skill_lv,sg->skill_id,sg->group_id,0,sg->limit); + sc_start4(ss,bl,type,100,sg->skill_lv,sg->skill_id,sg->group_id,0,sg->limit); break; - case UNT_BLOODYLUST: if (sg->src_id == bl->id) break; //Does not affect the caster. - if( !sce && sc_start4(bl,type,100,sg->skill_lv,0,SC__BLOODYLUST,0,sg->limit) ) - sc_start(bl,SC__BLOODYLUST,100,sg->skill_lv,sg->limit); + if (bl->type == BL_MOB) + break; //Does not affect the caster. + if( !sce && sc_start4(ss,bl,type,100,sg->skill_lv,0,SC__BLOODYLUST,0,sg->limit) ) + sc_start(ss,bl,SC__BLOODYLUST,100,sg->skill_lv,sg->limit); break; case UNT_PNEUMA: case UNT_CHAOSPANIC: + case UNT_MAELSTROM: if (!sce) - sc_start4(bl,type,100,sg->skill_lv,sg->group_id,0,0,sg->limit); + sc_start4(ss,bl,type,100,sg->skill_lv,sg->group_id,0,0,sg->limit); break; case UNT_WARP_WAITING: { @@ -11030,19 +11284,19 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned case UNT_QUAGMIRE: if( !sce && battle->check_target(&sg->unit->bl,bl,sg->target_flag) > 0 ) - sc_start4(bl,type,100,sg->skill_lv,sg->group_id,0,0,sg->limit); + sc_start4(ss,bl,type,100,sg->skill_lv,sg->group_id,0,0,sg->limit); break; case UNT_VOLCANO: case UNT_DELUGE: case UNT_VIOLENTGALE: if(!sce) - sc_start(bl,type,100,sg->skill_lv,sg->limit); + sc_start(ss,bl,type,100,sg->skill_lv,sg->limit); break; case UNT_SUITON: if(!sce) - sc_start4(bl,type,100,sg->skill_lv, + sc_start4(ss,bl,type,100,sg->skill_lv, map_flag_vs(bl->m) || battle->check_target(&src->bl,bl,BCT_ENEMY)>0?1:0, //Send val3 =1 to reduce agi. 0,0,sg->limit); break; @@ -11061,7 +11315,7 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned if (sg->src_id==bl->id && !(sc && sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_BARDDANCER)) return skill_id; if (!sce) - sc_start4(bl,type,100,sg->skill_lv,sg->val1,sg->val2,0,sg->limit); + sc_start4(ss,bl,type,100,sg->skill_lv,sg->val1,sg->val2,0,sg->limit); break; case UNT_WHISTLE: case UNT_ASSASSINCROSS: @@ -11076,7 +11330,7 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned if (!sc) return 0; if (!sce) - sc_start4(bl,type,100,sg->skill_lv,sg->val1,sg->val2,0,sg->limit); + sc_start4(ss,bl,type,100,sg->skill_lv,sg->val1,sg->val2,0,sg->limit); else if (sce->val4 == 1) { //Readjust timers since the effect will not last long. sce->val4 = 0; @@ -11088,7 +11342,7 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned case UNT_FOGWALL: if (!sce) { - sc_start4(bl, type, 100, sg->skill_lv, sg->val1, sg->val2, sg->group_id, sg->limit); + sc_start4(ss, bl, type, 100, sg->skill_lv, sg->val1, sg->val2, sg->group_id, sg->limit); if (battle->check_target(&src->bl,bl,BCT_ENEMY)>0) skill->additional_effect (ss, bl, sg->skill_id, sg->skill_lv, BF_MISC, ATK_DEF, tick); } @@ -11096,14 +11350,14 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned case UNT_GRAVITATION: if (!sce) - sc_start4(bl,type,100,sg->skill_lv,0,BCT_ENEMY,sg->group_id,sg->limit); + sc_start4(ss,bl,type,100,sg->skill_lv,0,BCT_ENEMY,sg->group_id,sg->limit); break; // officially, icewall has no problems existing on occupied cells [ultramage] // case UNT_ICEWALL: //Destroy the cell. [Skotlex] // src->val1 = 0; // if(src->limit + sg->tick > tick + 700) - // src->limit = DIFF_TICK(tick+700,sg->tick); + // src->limit = DIFF_TICK32(tick+700,sg->tick); // break; case UNT_MOONLIT: @@ -11122,9 +11376,16 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned skill->attack(skill->get_type(sg->skill_id), ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0); break; + case UNT_REVERBERATION: + clif->changetraplook(&src->bl,UNT_USED_TRAPS); + map->foreachinrange(skill->trap_splash,&src->bl, skill->get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, &src->bl,tick); + sg->unit_id = UNT_USED_TRAPS; + sg->limit = DIFF_TICK32(tick,sg->tick) + 1500; + break; + case UNT_VOLCANIC_ASH: if (!sce) - sc_start(bl, SC_VOLCANIC_ASH, 100, sg->skill_lv, skill->get_time(MH_VOLCANIC_ASH, sg->skill_lv)); + sc_start(ss, bl, SC_VOLCANIC_ASH, 100, sg->skill_lv, skill->get_time(MH_VOLCANIC_ASH, sg->skill_lv)); break; case UNT_GD_LEADERSHIP: @@ -11132,7 +11393,7 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned case UNT_GD_SOULCOLD: case UNT_GD_HAWKEYES: if ( !sce && battle->check_target(&sg->unit->bl,bl,sg->target_flag) > 0 ) - sc_start4(bl,type,100,sg->skill_lv,0,0,0,1000); + sc_start4(ss,bl,type,100,sg->skill_lv,0,0,0,1000); break; } return skill_id; @@ -11141,12 +11402,12 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned /*========================================== * *------------------------------------------*/ -int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, unsigned int tick) { +int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int64 tick) { struct skill_unit_group *sg; struct block_list *ss; TBL_PC* tsd; struct status_data *tstatus; - struct status_change *tsc; + struct status_change *tsc, *ssc; struct skill_unit_group_tickset *ts; enum sc_type type; uint16 skill_id; @@ -11162,10 +11423,15 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns nullpo_ret(ss=map->id2bl(sg->src_id)); tsd = BL_CAST(BL_PC, bl); tsc = status->get_sc(bl); + ssc = status->get_sc(ss); // Status Effects for Unit caster. if ( tsc && tsc->data[SC_HOVERING] ) return 0; //Under hovering characters are immune to trap and ground target skills. + // Maestro or Wanderer is unaffected by traps of trappers he or she charmed [SuperHulk] + if ( ssc && ssc->data[SC_SIREN] && ssc->data[SC_SIREN]->val2 == bl->id && (skill->get_inf2(sg->skill_id)&INF2_TRAP) ) + return 0; + tstatus = status->get_status_data(bl); type = status->skill2sc(sg->skill_id); skill_id = sg->skill_id; @@ -11185,7 +11451,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns if ((ts = skill->unitgrouptickset_search(bl,sg,tick))) { //Not all have it, eg: Traps don't have it even though they can be hit by Heaven's Drive [Skotlex] - diff = DIFF_TICK(tick,ts->tick); + diff = DIFF_TICK32(tick,ts->tick); if (diff < 0) return 0; ts->tick = tick+sg->interval; @@ -11275,6 +11541,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns int count = 0; const int x = bl->x, y = bl->y; + map->freeblock_lock(); //If target isn't knocked back it should hit every "interval" ms [Playtester] do { if( bl->type == BL_PC ) @@ -11285,11 +11552,12 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns status->charge(ss, 0, 8); //costs additional 8 SP if miss } else { // mobs //should end when out of sp. - sg->limit = DIFF_TICK(tick,sg->tick); + sg->limit = DIFF_TICK32(tick,sg->tick); break; } - } while( x == bl->x && y == bl->y + } while( x == bl->x && y == bl->y && sg->alive_count && ++count < SKILLUNITTIMER_INTERVAL/sg->interval && !status->isdead(bl) ); + map->freeblock_unlock(); } break; /** @@ -11307,12 +11575,6 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns if (rnd()%100 < src->val1) skill->attack(BF_WEAPON,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0); break; - case GN_CRAZYWEED_ATK: - if( bl->type == BL_SKILL ){ - struct skill_unit *su = (struct skill_unit *)bl; - if( su && !(skill->get_inf2(su->group->skill_id)&INF2_TRAP) ) - break; - } default: skill->attack(skill->get_type(sg->skill_id),ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0); } @@ -11328,7 +11590,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns skill->blown(&src->bl,bl,skill->get_blewcount(sg->skill_id,sg->skill_lv),unit->getdir(bl),0); sg->unit_id = UNT_USED_TRAPS; clif->changetraplook(&src->bl, UNT_USED_TRAPS); - sg->limit=DIFF_TICK(tick,sg->tick)+1500; + sg->limit=DIFF_TICK32(tick,sg->tick)+1500; } break; @@ -11336,10 +11598,10 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns case UNT_MANHOLE: if( sg->val2 == 0 && tsc && (sg->unit_id == UNT_ANKLESNARE || bl->id != sg->src_id) ) { int sec = skill->get_time2(sg->skill_id,sg->skill_lv); - if( status->change_start(bl,type,10000,sg->skill_lv,sg->group_id,0,0,sec, 8) ) { + if( status->change_start(ss,bl,type,10000,sg->skill_lv,sg->group_id,0,0,sec, 8) ) { const struct TimerData* td = tsc->data[type]?timer->get(tsc->data[type]->timer):NULL; if( td ) - sec = DIFF_TICK(td->tick, tick); + sec = DIFF_TICK32(td->tick, tick); if( sg->unit_id == UNT_MANHOLE || battle_config.skill_trap_type || !map_flag_gvg2(src->bl.m) ) { unit->movepos(bl, src->bl.x, src->bl.y, 0, 0); clif->fixpos(bl); @@ -11356,7 +11618,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns **/ clif->changetraplook(&src->bl, UNT_ANKLESNARE); } - sg->limit = DIFF_TICK(tick,sg->tick)+sec; + sg->limit = DIFF_TICK32(tick,sg->tick)+sec; sg->interval = -1; src->range = 0; } @@ -11366,7 +11628,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns if( bl->id != ss->id ) { if( status_get_mode(bl)&MD_BOSS ) break; - if( status->change_start(bl,type,10000,sg->skill_lv,sg->group_id,0,0,skill->get_time2(sg->skill_id, sg->skill_lv), 8) ) { + if( status->change_start(ss,bl,type,10000,sg->skill_lv,sg->group_id,0,0,skill->get_time2(sg->skill_id, sg->skill_lv), 8) ) { map->moveblock(bl, src->bl.x, src->bl.y, tick); clif->fixpos(bl); @@ -11379,7 +11641,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns case UNT_VENOMDUST: if(tsc && !tsc->data[type]) - status->change_start(bl,type,10000,sg->skill_lv,sg->group_id,0,0,skill->get_time2(sg->skill_id,sg->skill_lv),0); + status->change_start(ss,bl,type,10000,sg->skill_lv,sg->group_id,0,0,skill->get_time2(sg->skill_id,sg->skill_lv),0); break; @@ -11408,7 +11670,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns map->foreachinrange(skill->trap_splash,&src->bl, skill->get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, &src->bl,tick); if (sg->unit_id != UNT_FIREPILLAR_ACTIVE) clif->changetraplook(&src->bl, sg->unit_id==UNT_LANDMINE?UNT_FIREPILLAR_ACTIVE:UNT_USED_TRAPS); - sg->limit=DIFF_TICK(tick,sg->tick)+1500 + + sg->limit=DIFF_TICK32(tick,sg->tick)+1500 + (sg->unit_id== UNT_CLUSTERBOMB || sg->unit_id== UNT_ICEBOUNDTRAP?1000:0);// Cluster Bomb/Icebound has 1s to disappear once activated. sg->unit_id = UNT_USED_TRAPS; //Changed ID so it does not invoke a for each in area again. break; @@ -11420,7 +11682,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns clif->talkiebox(&src->bl, sg->valstr); sg->unit_id = UNT_USED_TRAPS; clif->changetraplook(&src->bl, UNT_USED_TRAPS); - sg->limit = DIFF_TICK(tick, sg->tick) + 5000; + sg->limit = DIFF_TICK32(tick, sg->tick) + 5000; sg->val2 = -1; } break; @@ -11482,46 +11744,46 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns if (tsd) clif->gospel_info(tsd, 0x15); break; case 2: // Immunity to all status - sc_start(bl,SC_SCRESIST,100,100,time); + sc_start(ss,bl,SC_SCRESIST,100,100,time); if (tsd) clif->gospel_info(tsd, 0x16); break; case 3: // MaxHP +100% - sc_start(bl,SC_INCMHPRATE,100,100,time); + sc_start(ss,bl,SC_INCMHPRATE,100,100,time); if (tsd) clif->gospel_info(tsd, 0x17); break; case 4: // MaxSP +100% - sc_start(bl,SC_INCMSPRATE,100,100,time); + sc_start(ss,bl,SC_INCMSPRATE,100,100,time); if (tsd) clif->gospel_info(tsd, 0x18); break; case 5: // All stats +20 - sc_start(bl,SC_INCALLSTATUS,100,20,time); + sc_start(ss,bl,SC_INCALLSTATUS,100,20,time); if (tsd) clif->gospel_info(tsd, 0x19); break; case 6: // Level 10 Blessing - sc_start(bl,SC_BLESSING,100,10,time); + sc_start(ss,bl,SC_BLESSING,100,10,time); break; case 7: // Level 10 Increase AGI - sc_start(bl,SC_INC_AGI,100,10,time); + sc_start(ss,bl,SC_INC_AGI,100,10,time); break; case 8: // Enchant weapon with Holy element - sc_start(bl,SC_ASPERSIO,100,1,time); + sc_start(ss,bl,SC_ASPERSIO,100,1,time); if (tsd) clif->gospel_info(tsd, 0x1c); break; case 9: // Enchant armor with Holy element - sc_start(bl,SC_BENEDICTIO,100,1,time); + sc_start(ss,bl,SC_BENEDICTIO,100,1,time); if (tsd) clif->gospel_info(tsd, 0x1d); break; case 10: // DEF +25% - sc_start(bl,SC_INCDEFRATE,100,25,time); + sc_start(ss,bl,SC_INCDEFRATE,100,25,time); if (tsd) clif->gospel_info(tsd, 0x1e); break; case 11: // ATK +100% - sc_start(bl,SC_INCATKRATE,100,100,time); + sc_start(ss,bl,SC_INCATKRATE,100,100,time); if (tsd) clif->gospel_info(tsd, 0x1f); break; case 12: // HIT/Flee +50 - sc_start(bl,SC_INCHIT,100,50,time); - sc_start(bl,SC_INCFLEE,100,50,time); + sc_start(ss,bl,SC_INCHIT,100,50,time); + sc_start(ss,bl,SC_INCFLEE,100,50,time); if (tsd) clif->gospel_info(tsd, 0x20); break; } @@ -11536,28 +11798,28 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns skill->attack(BF_MISC,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0); break; case 1: // Curse - sc_start(bl,SC_CURSE,100,1,time); + sc_start(ss,bl,SC_CURSE,100,1,time); break; case 2: // Blind - sc_start(bl,SC_BLIND,100,1,time); + sc_start(ss,bl,SC_BLIND,100,1,time); break; case 3: // Poison - sc_start(bl,SC_POISON,100,1,time); + sc_start(ss,bl,SC_POISON,100,1,time); break; case 4: // Level 10 Provoke - sc_start(bl,SC_PROVOKE,100,10,time); + sc_start(ss,bl,SC_PROVOKE,100,10,time); break; case 5: // DEF -100% - sc_start(bl,SC_INCDEFRATE,100,-100,time); + sc_start(ss,bl,SC_INCDEFRATE,100,-100,time); break; case 6: // ATK -100% - sc_start(bl,SC_INCATKRATE,100,-100,time); + sc_start(ss,bl,SC_INCATKRATE,100,-100,time); break; case 7: // Flee -100% - sc_start(bl,SC_INCFLEERATE,100,-100,time); + sc_start(ss,bl,SC_INCFLEERATE,100,-100,time); break; case 8: // Speed/ASPD -25% - sc_start4(bl,SC_GOSPEL,100,1,0,0,BCT_ENEMY,time); + sc_start4(ss,bl,SC_GOSPEL,100,1,0,0,BCT_ENEMY,time); break; } } @@ -11573,7 +11835,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns } if( sg->src_id != bl->id && i <= 0 ) - sc_start4(bl, type, 100, 0, 0, 0, src->bl.id, sg->interval + 100); + sc_start4(ss, bl, type, 100, 0, 0, 0, src->bl.id, sg->interval + 100); } break; @@ -11597,14 +11859,18 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns &src->bl,tick); sg->unit_id = UNT_USED_TRAPS; //clif->changetraplook(&src->bl, UNT_FIREPILLAR_ACTIVE); - sg->limit=DIFF_TICK(tick,sg->tick)+1500; + sg->limit=DIFF_TICK32(tick,sg->tick)+1500; break; /** * 3rd stuff **/ case UNT_POISONSMOKE: - if( battle->check_target(ss,bl,BCT_ENEMY) > 0 && !(tsc && tsc->data[sg->val2]) && rnd()%100 < 20 ) - sc_start(bl,sg->val2,100,sg->val3,skill->get_time2(GC_POISONINGWEAPON, 1)); + if( battle->check_target(ss,bl,BCT_ENEMY) > 0 && !(tsc && tsc->data[sg->val2]) && rnd()%100 < 50 ) { + short rate = 100; + if ( sg->val1 == 9 )//Oblivion Curse gives a 2nd success chance after the 1st one passes which is reduceable. [Rytech] + rate = 100 - tstatus->int_ * 4 / 5 ; + sc_start(ss,bl,sg->val2,rate,sg->val1,skill->get_time2(GC_POISONINGWEAPON,1) - (tstatus->vit + tstatus->luk) / 2 * 1000); + } break; case UNT_EPICLESIS: @@ -11619,13 +11885,14 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns hp = tstatus->max_hp * hp / 100; sp = tstatus->max_sp * sp / 100; status->heal(bl, hp, sp, 2); - sc_start(bl, type, 100, sg->skill_lv, (sg->interval * 3) + 100); + sc_start(ss, bl, type, 100, sg->skill_lv, (sg->interval * 3) + 100); } // Reveal hidden players every 5 seconds. if( sg->val2 % 5 == 0 ) { // TODO: check if other hidden status can be removed. status_change_end(bl,SC_HIDING,INVALID_TIMER); status_change_end(bl,SC_CLOAKING,INVALID_TIMER); + status_change_end(bl,SC_CLOAKINGEXCEED,INVALID_TIMER); } } /* Enable this if kRO fix the current skill. Currently no damage on undead and demon monster. [Jobbie] @@ -11637,7 +11904,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns if( bl->id == sg->src_id ) break; // Dont work on Self (video shows that) case UNT_NEUTRALBARRIER: - sc_start(bl,type,100,sg->skill_lv,sg->interval + 100); + sc_start(ss,bl,type,100,sg->skill_lv,sg->interval + 100); break; case UNT_DIMENSIONDOOR: @@ -11650,20 +11917,18 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns case UNT_REVERBERATION: clif->changetraplook(&src->bl,UNT_USED_TRAPS); map->foreachinrange(skill->trap_splash,&src->bl, skill->get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, &src->bl,tick); - sg->limit = DIFF_TICK(tick,sg->tick)+1000; + sg->limit = DIFF_TICK32(tick,sg->tick)+1500; sg->unit_id = UNT_USED_TRAPS; break; case UNT_SEVERE_RAINSTORM: - if( battle->check_target(&src->bl, bl, BCT_ENEMY) > 0 ) + if( battle->check_target(&src->bl, bl, BCT_ENEMY)) skill->attack(BF_WEAPON,ss,&src->bl,bl,WM_SEVERE_RAINSTORM_MELEE,sg->skill_lv,tick,0); break; case UNT_NETHERWORLD: - if( !(status_get_mode(bl)&MD_BOSS) && ss != bl && battle->check_target(&src->bl, bl, BCT_PARTY) > 0 ) { + if( !(status_get_mode(bl)&MD_BOSS)) { if( !(tsc && tsc->data[type]) ){ - sc_start(bl, type, 100, sg->skill_lv, skill->get_time2(sg->skill_id,sg->skill_lv)); - sg->limit = DIFF_TICK(tick,sg->tick); - sg->unit_id = UNT_USED_TRAPS; + sc_start(ss, bl, type, 100, sg->skill_lv, skill->get_time2(sg->skill_id,sg->skill_lv)); } } break; @@ -11671,16 +11936,16 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns if( tsc ) { if( !sg->val2 ) { int sec = skill->get_time2(sg->skill_id, sg->skill_lv); - if( sc_start(bl, type, 100, sg->skill_lv, sec) ) { + if( sc_start(ss, bl, type, 100, sg->skill_lv, sec) ) { const struct TimerData* td = tsc->data[type]?timer->get(tsc->data[type]->timer):NULL; if( td ) - sec = DIFF_TICK(td->tick, tick); + sec = DIFF_TICK32(td->tick, tick); ///map->moveblock(bl, src->bl.x, src->bl.y, tick); // in official server it doesn't behave like this. [malufett] clif->fixpos(bl); sg->val2 = bl->id; } else sec = 3000; // Couldn't trap it? - sg->limit = DIFF_TICK(tick, sg->tick) + sec; + sg->limit = DIFF_TICK32(tick, sg->tick) + sec; } else if( tsc->data[SC_THORNS_TRAP] && bl->id == sg->val2 ) skill->attack(skill->get_type(GN_THORNS_TRAP), ss, ss, bl, sg->skill_id, sg->skill_lv, tick, SD_LEVEL|SD_ANIMATION); } @@ -11692,7 +11957,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns case 1: case 2: default: - sc_start4(bl, SC_BURNING, 4 + 4 * sg->skill_lv, sg->skill_lv, 0, ss->id, 0, + sc_start4(ss, bl, SC_BURNING, 4 + 4 * sg->skill_lv, sg->skill_lv, 0, ss->id, 0, skill->get_time2(sg->skill_id, sg->skill_lv)); skill->attack(skill->get_type(sg->skill_id), ss, &src->bl, bl, sg->skill_id, sg->skill_lv + 10 * sg->val2, tick, 0); @@ -11707,38 +11972,40 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns break; case UNT_FIRE_EXPANSION_SMOKE_POWDER: - sc_start(bl, status->skill2sc(GN_FIRE_EXPANSION_SMOKE_POWDER), 100, sg->skill_lv, 1000); + sc_start(ss, bl, status->skill2sc(GN_FIRE_EXPANSION_SMOKE_POWDER), 100, sg->skill_lv, 1000); break; case UNT_FIRE_EXPANSION_TEAR_GAS: - sc_start(bl, status->skill2sc(GN_FIRE_EXPANSION_TEAR_GAS), 100, sg->skill_lv, 1000); + sc_start(ss, bl, status->skill2sc(GN_FIRE_EXPANSION_TEAR_GAS), 100, sg->skill_lv, 1000); break; case UNT_HELLS_PLANT: if( battle->check_target(&src->bl,bl,BCT_ENEMY) > 0 ) skill->attack(skill->get_type(GN_HELLS_PLANT_ATK), ss, &src->bl, bl, GN_HELLS_PLANT_ATK, sg->skill_lv, tick, 0); if( ss != bl) //The caster is the only one who can step on the Plants, without destroying them - sg->limit = DIFF_TICK(tick, sg->tick) + 100; + sg->limit = DIFF_TICK32(tick, sg->tick) + 100; break; case UNT_CLOUD_KILL: if(tsc && !tsc->data[type]) - status->change_start(bl,type,10000,sg->skill_lv,sg->group_id,0,0,skill->get_time2(sg->skill_id,sg->skill_lv),8); + status->change_start(ss,bl,type,10000,sg->skill_lv,sg->group_id,0,0,skill->get_time2(sg->skill_id,sg->skill_lv),8); skill->attack(skill->get_type(sg->skill_id),ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0); break; case UNT_WARMER: if( bl->type == BL_PC && !battle->check_undead(tstatus->race, tstatus->def_ele) && tstatus->race != RC_DEMON ) { - int hp = 125 * sg->skill_lv; // Officially is 125 * skill_lv. - struct status_change *ssc = status->get_sc(ss); + int hp = 0; if( ssc && ssc->data[SC_HEATER_OPTION] ) - hp += hp * ssc->data[SC_HEATER_OPTION]->val3 / 100; + hp = tstatus->max_hp * 3 * sg->skill_lv / 100; + else + hp = tstatus->max_hp * sg->skill_lv / 100; + status->heal(bl, hp, 0, 0); if( tstatus->hp != tstatus->max_hp ) clif->skill_nodamage(&src->bl, bl, AL_HEAL, hp, 0); if( tsc && tsc->data[SC_AKAITSUKI] && hp ) hp = ~hp + 1; status->heal(bl, hp, 0, 0); - sc_start(bl, SC_WARMER, 100, sg->skill_lv, skill->get_time2(sg->skill_id,sg->skill_lv)); + sc_start(ss, bl, SC_WARMER, 100, sg->skill_lv, skill->get_time2(sg->skill_id,sg->skill_lv)); } break; @@ -11747,7 +12014,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns case UNT_WIND_INSIGNIA: case UNT_EARTH_INSIGNIA: case UNT_ZEPHYR: - sc_start(bl,type, 100, sg->skill_lv, sg->interval); + sc_start(ss, bl,type, 100, sg->skill_lv, sg->interval); if (sg->unit_id != UNT_ZEPHYR && !battle->check_undead(tstatus->race, tstatus->def_ele)) { int hp = tstatus->max_hp / 100; //+1% each 5s if ((sg->val3) % 5) { //each 5s @@ -11767,31 +12034,11 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns break; case UNT_VACUUM_EXTREME: - {// TODO: official behavior in gvg area. [malufett] - int sec = sg->limit - DIFF_TICK(tick, sg->tick); - int range = skill->get_unit_range(sg->skill_id, sg->skill_lv); - - if( tsc && !tsc->data[type] && - distance_xy(src->bl.x, src->bl.y, bl->x, bl->y) <= range)// don't consider outer bounderies - sc_start(bl, type, 100, sg->skill_lv, sec); - - if( unit->is_walking(bl) && // wait until target stop walking - ( tsc && tsc->data[type] && tsc->data[type]->val4 >= tsc->data[type]->val3-range )) - break; - - if( tsc && ( !tsc->data[type] || (tsc->data[type] && tsc->data[type]->val4 < 1 ) ) ) - break; - - if( unit->is_walking(bl) && - distance_xy(src->bl.x, src->bl.y, bl->x, bl->y) > range )// going outside of boundaries? then force it to stop - unit->stop_walking(bl,1); - - if( !unit->is_walking(bl) && - distance_xy(src->bl.x, src->bl.y, bl->x, bl->y) <= range && // only snap if the target is inside the range or - src->bl.x != bl->x && src->bl.y != bl->y){// diagonal position parallel to VE's center - unit->movepos(bl, src->bl.x, src->bl.y, 0, 0); - clif->fixpos(bl); - } + if ( tsc && tsc->data[SC_HALLUCINATIONWALK] ) { + return 0; + } else { + sg->limit -= 100 * tstatus->str/20; + sc_start(ss, bl, SC_VACUUM_EXTREME, 100, sg->skill_lv, sg->limit); } break; @@ -11807,36 +12054,36 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns if( battle->check_target(&src->bl,bl,BCT_ENEMY) > 0 ){ switch( sg->unit_id ){ case UNT_ZENKAI_WATER: - sc_start(bl, SC_COLD, sg->val1*5, sg->skill_lv, skill->get_time2(sg->skill_id, sg->skill_lv)); - sc_start(bl, SC_FREEZE, sg->val1*5, sg->skill_lv, skill->get_time2(sg->skill_id, sg->skill_lv)); - sc_start(bl, SC_FROSTMISTY, sg->val1*5, sg->skill_lv, skill->get_time2(sg->skill_id, sg->skill_lv)); + sc_start(ss, bl, SC_COLD, sg->val1*5, sg->skill_lv, skill->get_time2(sg->skill_id, sg->skill_lv)); + sc_start(ss, bl, SC_FREEZE, sg->val1*5, sg->skill_lv, skill->get_time2(sg->skill_id, sg->skill_lv)); + sc_start(ss, bl, SC_FROSTMISTY, sg->val1*5, sg->skill_lv, skill->get_time2(sg->skill_id, sg->skill_lv)); break; case UNT_ZENKAI_LAND: - sc_start(bl, SC_STONE, sg->val1*5, sg->skill_lv, skill->get_time2(sg->skill_id, sg->skill_lv)); - sc_start(bl, SC_POISON, sg->val1*5, sg->skill_lv, skill->get_time2(sg->skill_id, sg->skill_lv)); + sc_start(ss, bl, SC_STONE, sg->val1*5, sg->skill_lv, skill->get_time2(sg->skill_id, sg->skill_lv)); + sc_start(ss, bl, SC_POISON, sg->val1*5, sg->skill_lv, skill->get_time2(sg->skill_id, sg->skill_lv)); break; case UNT_ZENKAI_FIRE: - sc_start4(bl, SC_BURNING, sg->val1*5, sg->skill_lv, 0, ss->id, 0, skill->get_time2(sg->skill_id, sg->skill_lv)); + sc_start4(ss, bl, SC_BURNING, sg->val1*5, sg->skill_lv, 0, ss->id, 0, skill->get_time2(sg->skill_id, sg->skill_lv)); break; case UNT_ZENKAI_WIND: - sc_start(bl, SC_SILENCE, sg->val1*5, sg->skill_lv, skill->get_time2(sg->skill_id, sg->skill_lv)); - sc_start(bl, SC_SLEEP, sg->val1*5, sg->skill_lv, skill->get_time2(sg->skill_id, sg->skill_lv)); - sc_start(bl, SC_DEEP_SLEEP, sg->val1*5, sg->skill_lv, skill->get_time2(sg->skill_id, sg->skill_lv)); + sc_start(ss, bl, SC_SILENCE, sg->val1*5, sg->skill_lv, skill->get_time2(sg->skill_id, sg->skill_lv)); + sc_start(ss, bl, SC_SLEEP, sg->val1*5, sg->skill_lv, skill->get_time2(sg->skill_id, sg->skill_lv)); + sc_start(ss, bl, SC_DEEP_SLEEP, sg->val1*5, sg->skill_lv, skill->get_time2(sg->skill_id, sg->skill_lv)); break; } }else - sc_start2(bl,type,100,sg->val1,sg->val2,skill->get_time2(sg->skill_id, sg->skill_lv)); + sc_start2(ss, bl,type,100,sg->val1,sg->val2,skill->get_time2(sg->skill_id, sg->skill_lv)); break; case UNT_LAVA_SLIDE: skill->attack(BF_WEAPON, ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0); if(++sg->val1 > 4) //after 5 stop hit and destroy me - sg->limit = DIFF_TICK(tick, sg->tick); + sg->limit = DIFF_TICK32(tick, sg->tick); break; case UNT_POISON_MIST: skill->attack(BF_MAGIC, ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0); - status->change_start(bl, SC_BLIND, rnd() % 100 > sg->skill_lv * 10, sg->skill_lv, sg->skill_id, 0, 0, skill->get_time2(sg->skill_id, sg->skill_lv), 2|8); + status->change_start(ss, bl, SC_BLIND, rnd() % 100 > sg->skill_lv * 10, sg->skill_lv, sg->skill_id, 0, 0, skill->get_time2(sg->skill_id, sg->skill_lv), 2|8); break; } @@ -11848,7 +12095,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns /*========================================== * Triggered when a char steps out of a skill cell *------------------------------------------*/ -int skill_unit_onout (struct skill_unit *src, struct block_list *bl, unsigned int tick) { +int skill_unit_onout(struct skill_unit *src, struct block_list *bl, int64 tick) { struct skill_unit_group *sg; struct status_change *sc; struct status_change_entry *sce; @@ -11862,7 +12109,7 @@ int skill_unit_onout (struct skill_unit *src, struct block_list *bl, unsigned in sce = (sc && type != -1)?sc->data[type]:NULL; if( bl->prev == NULL - || (status->isdead(bl) && sg->unit_id != UNT_ANKLESNARE && sg->unit_id != UNT_SPIDERWEB) + || (status->isdead(bl) && sg->unit_id != UNT_ANKLESNARE && sg->unit_id != UNT_SPIDERWEB && sg->unit_id != UNT_THORNS_TRAP) ) //Need to delete the trap if the source died. return 0; @@ -11872,6 +12119,7 @@ int skill_unit_onout (struct skill_unit *src, struct block_list *bl, unsigned in case UNT_EPICLESIS://Arch Bishop case UNT_NEUTRALBARRIER: case UNT_STEALTHFIELD: + case UNT_WARMER: if (sce) status_change_end(bl, type, INVALID_TIMER); break; @@ -11885,13 +12133,14 @@ int skill_unit_onout (struct skill_unit *src, struct block_list *bl, unsigned in status_change_end(bl, type, INVALID_TIMER); break; + case UNT_THORNS_TRAP: case UNT_SPIDERWEB: { struct block_list *target = map->id2bl(sg->val2); if (target && target==bl) { if (sce && sce->val3 == sg->group_id) status_change_end(bl, type, INVALID_TIMER); - sg->limit = DIFF_TICK(tick,sg->tick)+1000; + sg->limit = DIFF_TICK32(tick,sg->tick)+1000; } } break; @@ -11902,7 +12151,7 @@ int skill_unit_onout (struct skill_unit *src, struct block_list *bl, unsigned in /*========================================== * Triggered when a char steps out of a skill group (entirely) [Skotlex] *------------------------------------------*/ -int skill_unit_onleft (uint16 skill_id, struct block_list *bl, unsigned int tick) { +int skill_unit_onleft(uint16 skill_id, struct block_list *bl, int64 tick) { struct status_change *sc; struct status_change_entry *sce; enum sc_type type; @@ -11956,6 +12205,7 @@ int skill_unit_onleft (uint16 skill_id, struct block_list *bl, unsigned int tick case SO_WATER_INSIGNIA: case SO_WIND_INSIGNIA: case SO_EARTH_INSIGNIA: + case SO_ELEMENTAL_SHIELD: case SC_BLOODYLUST: if (sce) status_change_end(bl, type, INVALID_TIMER); @@ -12008,10 +12258,10 @@ int skill_unit_onleft (uint16 skill_id, struct block_list *bl, unsigned int tick * flag&1: Invoke onplace function (otherwise invoke onout) * flag&4: Invoke a onleft call (the unit might be scheduled for deletion) *------------------------------------------*/ -int skill_unit_effect (struct block_list* bl, va_list ap) { +int skill_unit_effect(struct block_list* bl, va_list ap) { struct skill_unit* su = va_arg(ap,struct skill_unit*); struct skill_unit_group* group = su->group; - unsigned int tick = va_arg(ap,unsigned int); + int64 tick = va_arg(ap,int64); unsigned int flag = va_arg(ap,unsigned int); uint16 skill_id; bool dissonance; @@ -12047,8 +12297,7 @@ int skill_unit_effect (struct block_list* bl, va_list ap) { /*========================================== * *------------------------------------------*/ -int skill_unit_ondamaged (struct skill_unit *src, struct block_list *bl, int64 damage, unsigned int tick) -{ +int skill_unit_ondamaged(struct skill_unit *src, struct block_list *bl, int64 damage, int64 tick) { struct skill_unit_group *sg; nullpo_ret(src); @@ -12066,10 +12315,12 @@ int skill_unit_ondamaged (struct skill_unit *src, struct block_list *bl, int64 d case UNT_TALKIEBOX: case UNT_ANKLESNARE: case UNT_ICEWALL: - case UNT_REVERBERATION: case UNT_WALLOFTHORN: src->val1 -= (int)cap_value(damage,INT_MIN,INT_MAX); break; + case UNT_REVERBERATION: + src->val1--; + break; default: damage = 0; break; @@ -12173,7 +12424,7 @@ int skill_check_pc_partner (struct map_session_data *sd, uint16 skill_id, uint16 int i; bool is_chorus = ( skill->get_inf2(skill_id)&INF2_CHORUS_SKILL ); - if (!battle_config.player_skill_partner_check || pc->has_permission(sd, PC_PERM_SKILL_UNCONDITIONAL)) + if (!battle_config.player_skill_partner_check || pc_has_permission(sd, PC_PERM_SKILL_UNCONDITIONAL)) return is_chorus ? MAX_PARTY : 99; //As if there were infinite partners. if (cast_flag) { //Execute the skill on the partners. @@ -12191,18 +12442,12 @@ int skill_check_pc_partner (struct map_session_data *sd, uint16 skill_id, uint16 status->charge(&tsd->bl, 0, i); } break; - case WM_GREAT_ECHO: - for( i = 0; i < c; i++ ) { - if( (tsd = map->id2sd(p_sd[i])) != NULL ) - status_zap(&tsd->bl,0,skill->get_sp(skill_id,*skill_lv)/c); - } - break; default: //Warning: Assuming Ensemble skills here (for speed) if( is_chorus ) break;//Chorus skills are not to be parsed as ensambles if (c > 0 && sd->sc.data[SC_DANCING] && (tsd = map->id2sd(p_sd[0])) != NULL) { sd->sc.data[SC_DANCING]->val4 = tsd->bl.id; - sc_start4(&tsd->bl,SC_DANCING,100,skill_id,sd->sc.data[SC_DANCING]->val2,*skill_lv,sd->bl.id,skill->get_time(skill_id,*skill_lv)+1000); + sc_start4(&tsd->bl,&tsd->bl,SC_DANCING,100,skill_id,sd->sc.data[SC_DANCING]->val2,*skill_lv,sd->bl.id,skill->get_time(skill_id,*skill_lv)+1000); clif->skill_nodamage(&tsd->bl, &sd->bl, skill_id, *skill_lv, 1); tsd->skill_id_dance = skill_id; tsd->skill_lv_dance = *skill_lv; @@ -12264,13 +12509,12 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id struct status_data *st; struct status_change *sc; struct skill_condition require; - int i; nullpo_ret(sd); if (sd->chatID) return 0; - if( pc->has_permission(sd, PC_PERM_SKILL_UNCONDITIONAL) && sd->skillitem != skill_id ) + if( pc_has_permission(sd, PC_PERM_SKILL_UNCONDITIONAL) && sd->skillitem != skill_id ) { //GMs don't override the skillItem check, otherwise they can use items without them being consumed! [Skotlex] sd->state.arrow_atk = skill->get_ammotype(skill_id)?1:0; //Need to do arrow state check. sd->spiritball_old = sd->spiritball; //Need to do Spiritball check. @@ -12306,6 +12550,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id if( sd->state.abra_flag ) // Hocus-Pocus was used. [Inkfish] sd->state.abra_flag = 0; else { + int i; // When a target was selected, consume items that were skipped in pc_use_item [Skotlex] if( (i = sd->itemindex) == -1 || sd->status.inventory[i].nameid != sd->itemid || @@ -12459,34 +12704,38 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id return 0; if(sc->data[SC_BLADESTOP]) break; - if( (i=(sc && sc->data[SC_COMBOATTACK])) && sc->data[SC_COMBOATTACK]->val1 == MO_TRIPLEATTACK ) - break; - if( i ) + if( sc && sc->data[SC_COMBOATTACK] ) { + if( sc->data[SC_COMBOATTACK]->val1 == MO_TRIPLEATTACK ) + break; clif->skill_fail(sd, skill_id, USESKILL_FAIL_COMBOSKILL, MO_TRIPLEATTACK); + } return 0; case MO_COMBOFINISH: if(!sc) return 0; - if( (i=(sc && sc->data[SC_COMBOATTACK])) && sc->data[SC_COMBOATTACK]->val1 == MO_CHAINCOMBO ) - break; - if( i ) + if( sc && sc->data[SC_COMBOATTACK] ) { + if ( sc->data[SC_COMBOATTACK]->val1 == MO_CHAINCOMBO ) + break; clif->skill_fail(sd, skill_id, USESKILL_FAIL_COMBOSKILL, MO_CHAINCOMBO); + } return 0; case CH_TIGERFIST: if(!sc) return 0; - if( (i=(sc && sc->data[SC_COMBOATTACK])) && sc->data[SC_COMBOATTACK]->val1 == MO_COMBOFINISH ) - break; - if( i ) + if( sc && sc->data[SC_COMBOATTACK] ) { + if ( sc->data[SC_COMBOATTACK]->val1 == MO_COMBOFINISH ) + break; clif->skill_fail(sd, skill_id, USESKILL_FAIL_COMBOSKILL, MO_COMBOFINISH); + } return 0; case CH_CHAINCRUSH: if(!sc) return 0; - if( (i=(sc && sc->data[SC_COMBOATTACK])) && sc->data[SC_COMBOATTACK]->val1 == CH_TIGERFIST ) - break; - if( i ) + if( sc && sc->data[SC_COMBOATTACK] ) { + if( sc->data[SC_COMBOATTACK]->val1 == CH_TIGERFIST ) + break; clif->skill_fail(sd, skill_id, USESKILL_FAIL_COMBOSKILL, CH_TIGERFIST); + } return 0; case MO_EXTREMITYFIST: // if(sc && sc->data[SC_EXTREMITYFIST]) //To disable Asura during the 5 min skill block uncomment this... @@ -12634,8 +12883,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id case SG_STAR_WARM: if (sc && sc->data[SC_MIRACLE]) break; - i = skill_id-SG_SUN_WARM; - if (sd->bl.m == sd->feel_map[i].m) + if (sd->bl.m == sd->feel_map[skill_id-SG_SUN_WARM].m) break; clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); return 0; @@ -12645,9 +12893,8 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id case SG_STAR_COMFORT: if (sc && sc->data[SC_MIRACLE]) break; - i = skill_id-SG_SUN_COMFORT; - if (sd->bl.m == sd->feel_map[i].m && - (battle_config.allow_skill_without_day || pc->sg_info[i].day_func())) + if (sd->bl.m == sd->feel_map[skill_id-SG_SUN_COMFORT].m && + (battle_config.allow_skill_without_day || pc->sg_info[skill_id-SG_SUN_COMFORT].day_func())) break; clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); return 0; @@ -12728,7 +12975,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id **/ case AB_ANCILLA: { - int count = 0; + int count = 0, i; for( i = 0; i < MAX_INVENTORY; i ++ ) if( sd->status.inventory[i].nameid == ITEMID_ANCILLA ) count += sd->status.inventory[i].amount; @@ -12755,12 +13002,15 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id * Warlock **/ case WL_COMET: - if( skill->check_pc_partner(sd,skill_id,&skill_lv,1,0) <= 0 && ((i = pc->search_inventory(sd,require.itemid[0])) < 0 || sd->status.inventory[i].amount < require.amount[0]) ) + { + int idx; + if( skill->check_pc_partner(sd,skill_id,&skill_lv,1,0) <= 0 && ((idx = pc->search_inventory(sd,require.itemid[0])) < 0 || sd->status.inventory[idx].amount < require.amount[0]) ) { //clif->skill_fail(sd,skill_id,USESKILL_FAIL_NEED_ITEM,require.amount[0],require.itemid[0]); clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); return 0; } + } break; case WL_SUMMONFB: case WL_SUMMONBL: @@ -12769,10 +13019,9 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id case WL_TETRAVORTEX: case WL_RELEASE: { - int x = SC_SUMMON1; - i = 0; - for(; x <= SC_SUMMON5; x++) - if( sc && sc->data[x] ) + int j, i = 0; + for(j = SC_SUMMON1; j <= SC_SUMMON5; j++) + if( sc && sc->data[j] ) i++; switch(skill_id){ @@ -12783,8 +13032,8 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id } break; case WL_RELEASE: - for(x = SC_SPELLBOOK7; x >= SC_SPELLBOOK1; x--) - if( sc && sc->data[x] ) + for(j = SC_SPELLBOOK7; j >= SC_SPELLBOOK1; j--) + if( sc && sc->data[j] ) i++; if( i == 0 ){ clif->skill_fail(sd,skill_id,USESKILL_FAIL_SUMMON_NONE,0); @@ -12857,13 +13106,6 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id return 0; } break; - case LG_RAGEBURST: - if( sd->spiritball == 0 ) { - clif->skill_fail(sd,skill_id,USESKILL_FAIL_SKILLINTERVAL,0); - return 0; - } - sd->spiritball_old = require.spiritball = sd->spiritball; - break; case LG_RAYOFGENESIS: if( sc && sc->data[SC_INSPIRATION] ) return 1; // Don't check for partner. @@ -12880,12 +13122,11 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id } break; case SR_FALLENEMPIRE: - if( !sc ) - return 0; - if( (i=(sc && sc->data[SC_COMBOATTACK])) && sc->data[SC_COMBOATTACK]->val1 == SR_DRAGONCOMBO ) - break; - if( i ) + if( sc && sc->data[SC_COMBOATTACK] ) { + if( sc->data[SC_COMBOATTACK]->val1 == SR_DRAGONCOMBO ) + break; clif->skill_fail(sd, skill_id, USESKILL_FAIL_COMBOSKILL, SR_DRAGONCOMBO); + } return 0; case SR_CRESCENTELBOW: if( sc && sc->data[SC_CRESCENTELBOW] ) { @@ -12898,7 +13139,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id if (map->foreachinrange(mob->count_sub, &sd->bl, skill->get_splash(skill_id, skill_lv), BL_MOB, MOBID_EMPERIUM, MOBID_GUARIDAN_STONE1, MOBID_GUARIDAN_STONE2)) { char output[128]; - sprintf(output, "You're too close to a stone or emperium to do this skill"); + sprintf(output, "You're too close to a stone or emperium to do this skill"); /* TODO official response? or message.conf it */ clif->colormes(sd->fd, COLOR_RED, output); return 0; } @@ -12906,7 +13147,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id if( sd->spiritball > 0 ) sd->spiritball_old = require.spiritball = sd->spiritball; else { - clif->skill_fail(sd,skill_id,0,0); + clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); return 0; } break; @@ -12917,7 +13158,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id case SC_MANHOLE: case SC_DIMENSIONDOOR: if( sc && sc->data[SC_MAGNETICFIELD] ) { - clif->skill_fail(sd,skill_id,0,0); + clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); return 0; } break; @@ -12931,11 +13172,17 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id require.sp -= require.sp * 20 * count / 100; // -20% each W/M in the party. } break; + case NC_PILEBUNKER: + if ( sd->equip_index[EQI_HAND_R] < 0 || sd->status.inventory[sd->equip_index[EQI_HAND_R]].nameid != ITEMID_PILEBUNCKER ) { + clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); + return 0; + } + break; case SO_FIREWALK: case SO_ELECTRICWALK: // Can't be casted until you've walked all cells. if( sc && sc->data[SC_PROPERTYWALK] && sc->data[SC_PROPERTYWALK]->val3 < skill->get_maxcount(sc->data[SC_PROPERTYWALK]->val1,sc->data[SC_PROPERTYWALK]->val2) ) { - clif->skill_fail(sd,skill_id,0x0,0); + clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); return 0; } break; @@ -12951,9 +13198,8 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id return 0; } break; - case LG_REFLECTDAMAGE: case CR_REFLECTSHIELD: - if( sc && sc->data[SC_KYOMU] && rand()%100 < 5 * sc->data[SC_KYOMU]->val1 ){ + if( sc && sc->data[SC_KYOMU] && rnd()%100 < 5 * sc->data[SC_KYOMU]->val1 ){ clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); return 0; } @@ -12972,11 +13218,14 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id break; case KO_KAIHOU: case KO_ZENKAI: - ARR_FIND(1, 6, i, sd->charm[i] > 0); + { + int i; + ARR_FIND(1, 6, i, sd->charm[i] > 0); // FIXME: 4 or 6? if( i > 4 ) { clif->skill_fail(sd,skill_id,USESKILL_FAIL_SUMMON,0); return 0; } + } break; } @@ -13187,7 +13436,7 @@ int skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id, if( sd->chatID ) return 0; - if( pc->has_permission(sd, PC_PERM_SKILL_UNCONDITIONAL) && sd->skillitem != skill_id ) { + if( pc_has_permission(sd, PC_PERM_SKILL_UNCONDITIONAL) && sd->skillitem != skill_id ) { //GMs don't override the skillItem check, otherwise they can use items without them being consumed! [Skotlex] sd->state.arrow_atk = skill->get_ammotype(skill_id)?1:0; //Need to do arrow state check. sd->spiritball_old = sd->spiritball; //Need to do Spiritball check. @@ -13534,7 +13783,7 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16 if( sc->data[SC__LAZINESS] ) req.sp += req.sp + sc->data[SC__LAZINESS]->val1 * 10; if( sc->data[SC_UNLIMITED_HUMMING_VOICE] ) - req.sp += req.sp * sc->data[SC_UNLIMITED_HUMMING_VOICE]->val2 / 100; + req.sp += req.sp * sc->data[SC_UNLIMITED_HUMMING_VOICE]->val3 / 100; if( sc->data[SC_RECOGNIZEDSPELL] ) req.sp += req.sp / 4; if( sc->data[SC_TELEKINESIS_INTENSE] && skill->get_ele(skill_id, skill_lv) == ELE_GHOST) @@ -13652,6 +13901,22 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16 req.amount[skill_lv-1] = skill->db[idx].amount[skill_lv-1]; break; } + if (skill_id == NC_REPAIR) { + switch(skill_lv) { + case 1: + case 2: + req.itemid[1] = ITEMID_REPAIR_A; + break; + case 3: + case 4: + req.itemid[1] = ITEMID_REPAIR_B; + break; + case 5: + req.itemid[1] = ITEMID_REPAIR_C; + break; + } + req.amount[1] = 1; + } // Check for cost reductions due to skills & SCs switch(skill_id) { @@ -13728,7 +13993,7 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16 req.sp -= req.sp * (5 + 5 * pc->checkskill(sd,SO_EL_SYMPATHY)) / 100; break; case SO_PSYCHIC_WAVE: - if( sc && sc->data[SC_BLAST_OPTION] ) + if( sc && (sc->data[SC_HEATER_OPTION] || sc->data[SC_COOLER_OPTION] || sc->data[SC_BLAST_OPTION] || sc->data[SC_CURSED_SOIL_OPTION] )) req.sp += req.sp * 150 / 100; break; } @@ -13913,13 +14178,15 @@ int skill_vfcastfix(struct block_list *bl, double time, uint16 skill_id, uint16 // Fixed cast reduction bonuses if( sc->data[SC__LAZINESS] ) fixcast_r = max(fixcast_r, sc->data[SC__LAZINESS]->val2); + if( sc->data[SC_DANCE_WITH_WUG]) + fixcast_r = max(fixcast_r, sc->data[SC_DANCE_WITH_WUG]->val4); if( sc->data[SC_SECRAMENT] ) fixcast_r = max(fixcast_r, sc->data[SC_SECRAMENT]->val2); if( sd && ( skill_lv = pc->checkskill(sd, WL_RADIUS) ) && (skill_id >= WL_WHITEIMPRISON && skill_id < WL_FREEZE_SP) ) fixcast_r = max(fixcast_r, (status_get_int(bl) + status->get_lv(bl)) / 15 + skill_lv * 5); // [{(Caster?s INT / 15) + (Caster?s Base Level / 15) + (Radius Skill Level x 5)}] % // Fixed cast non percentage bonuses if( sc->data[SC_MANDRAGORA] ) - fixed += sc->data[SC_MANDRAGORA]->val1 * 1000 / 2; + fixed += sc->data[SC_MANDRAGORA]->val1 * 500; if( sc->data[SC_IZAYOI] ) fixed = 0; if( sc->data[SC_GUST_OPTION] || sc->data[SC_BLAST_OPTION] || sc->data[SC_WILD_STORM_OPTION] ) @@ -13929,6 +14196,12 @@ int skill_vfcastfix(struct block_list *bl, double time, uint16 skill_id, uint16 if( sd && !(skill->get_castnodex(skill_id, skill_lv)&4) ){ VARCAST_REDUCTION( max(sd->bonus.varcastrate, 0) + max(i, 0) ); fixcast_r = max(fixcast_r, sd->bonus.fixcastrate) + min(sd->bonus.fixcastrate,0); + for( i = 0; i < ARRAYLENGTH(sd->skillcast) && sd->skillcast[i].id; i++ ) + if( sd->skillcast[i].id == skill_id ){ // bonus2 bVariableCastrate + if( (i=sd->skillcast[i].val) > 0) + VARCAST_REDUCTION(i); + break; + } } if( varcast_r < 0 ) // now compute overall factors @@ -14155,8 +14428,7 @@ void skill_brandishspear_dir (struct square* tc, uint8 dir, int are) { } } -void skill_brandishspear(struct block_list* src, struct block_list* bl, uint16 skill_id, uint16 skill_lv, unsigned int tick, int flag) -{ +void skill_brandishspear(struct block_list* src, struct block_list* bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag) { int c,n=4; uint8 dir = map->calc_dir(src,bl->x,bl->y); struct square tc; @@ -14188,7 +14460,7 @@ void skill_brandishspear(struct block_list* src, struct block_list* bl, uint16 s src,skill_id,skill_lv,tick, flag|BCT_ENEMY|n, skill->castend_damage_id); if(skill_lv > 6 && n==3 && c==4) { - skill_brandishspear_dir(&tc,dir,-1); + skill->brandishspear_dir(&tc,dir,-1); n--;c=-1; } } @@ -14207,7 +14479,12 @@ void skill_brandishspear(struct block_list* src, struct block_list* bl, uint16 s *------------------------------------------*/ void skill_repairweapon (struct map_session_data *sd, int idx) { int material; - int materials[4] = { 1002, 998, 999, 756 }; + int materials[4] = { + ITEMID_IRON_ORE, + ITEMID_IRON, + ITEMID_STEEL, + ITEMID_ORIDECON_STONE, + }; struct item *item; struct map_session_data *target_sd; @@ -14231,9 +14508,9 @@ void skill_repairweapon (struct map_session_data *sd, int idx) { } if ( target_sd->inventory_data[idx]->type == IT_WEAPON ) - material = materials [ target_sd->inventory_data[idx]->wlv - 1 ]; // Lv1/2/3/4 weapons consume 1 Iron Ore/Iron/Steel/Rough Oridecon + material = materials[ target_sd->inventory_data[idx]->wlv - 1 ]; // Lv1/2/3/4 weapons consume 1 Iron Ore/Iron/Steel/Rough Oridecon else - material = materials [2]; // Armors consume 1 Steel + material = materials[2]; // Armors consume 1 Steel if ( pc->search_inventory(sd,material) < 0 ) { clif->skill_fail(sd,sd->menuskill_id,USESKILL_FAIL_LEVEL,0); return; @@ -14281,7 +14558,13 @@ void skill_weaponrefine (struct map_session_data *sd, int idx) if (idx >= 0 && idx < MAX_INVENTORY) { int i = 0, ep = 0, per; - int material[5] = { 0, 1010, 1011, 984, 984 }; + int material[5] = { + 0, + ITEMID_PHRACON, + ITEMID_EMVERETARCON, + ITEMID_ORIDECON, + ITEMID_ORIDECON, + }; struct item *item; struct item_data *ditem = sd->inventory_data[idx]; item = &sd->status.inventory[idx]; @@ -14296,8 +14579,8 @@ void skill_weaponrefine (struct map_session_data *sd, int idx) clif->upgrademessage(sd->fd, 2, item->nameid); return; } - if( (i = pc->search_inventory(sd, material [ditem->wlv])) < 0 ){ - clif->upgrademessage(sd->fd, 3, material [ditem->wlv]); + if( (i = pc->search_inventory(sd, material[ditem->wlv])) < 0 ){ + clif->upgrademessage(sd->fd, 3, material[ditem->wlv]); return; } @@ -14392,7 +14675,7 @@ int skill_autospell (struct map_session_data *sd, uint16 skill_id) if(maxlv > lv) maxlv = lv; - sc_start4(&sd->bl,SC_AUTOSPELL,100,skill_lv,skill_id,maxlv,0, + sc_start4(&sd->bl,&sd->bl,SC_AUTOSPELL,100,skill_lv,skill_id,maxlv,0, skill->get_time(SA_AUTOSPELL,skill_lv)); return 0; } @@ -14493,10 +14776,10 @@ int skill_sit (struct map_session_data *sd, int type) /*========================================== * *------------------------------------------*/ -int skill_frostjoke_scream (struct block_list *bl, va_list ap) { +int skill_frostjoke_scream(struct block_list *bl, va_list ap) { struct block_list *src; uint16 skill_id,skill_lv; - unsigned int tick; + int64 tick; nullpo_ret(bl); nullpo_ret(src=va_arg(ap,struct block_list*)); @@ -14504,7 +14787,7 @@ int skill_frostjoke_scream (struct block_list *bl, va_list ap) { skill_id=va_arg(ap,int); skill_lv=va_arg(ap,int); if(!skill_lv) return 0; - tick=va_arg(ap,unsigned int); + tick=va_arg(ap,int64); if (src == bl || status->isdead(bl)) return 0; @@ -14537,22 +14820,22 @@ void skill_unitsetmapcell (struct skill_unit *src, uint16 skill_id, uint16 skill /*========================================== * *------------------------------------------*/ -int skill_attack_area (struct block_list *bl, va_list ap) { +int skill_attack_area(struct block_list *bl, va_list ap) { struct block_list *src,*dsrc; int atk_type,skill_id,skill_lv,flag,type; - unsigned int tick; + int64 tick; if(status->isdead(bl)) return 0; atk_type = va_arg(ap,int); - src=va_arg(ap,struct block_list*); - dsrc=va_arg(ap,struct block_list*); - skill_id=va_arg(ap,int); - skill_lv=va_arg(ap,int); - tick=va_arg(ap,unsigned int); - flag=va_arg(ap,int); - type=va_arg(ap,int); + src = va_arg(ap,struct block_list*); + dsrc = va_arg(ap,struct block_list*); + skill_id = va_arg(ap,int); + skill_lv = va_arg(ap,int); + tick = va_arg(ap,int64); + flag = va_arg(ap,int); + type = va_arg(ap,int); if (skill->area_temp[1] == bl->id) //This is the target of the skill, do a full attack and skip target checks. @@ -14600,6 +14883,10 @@ int skill_clear_group (struct block_list *bl, int flag) if (flag&1) group[count++]= ud->skillunit[i]; break; + case SO_CLOUD_KILL: + if( flag&4 ) + group[count++]= ud->skillunit[i]; + break; case SO_WARMER: if( flag&8 ) group[count++]= ud->skillunit[i]; @@ -14632,6 +14919,7 @@ struct skill_unit_group *skill_locate_element_field(struct block_list *bl) { case SA_VIOLENTGALE: case SA_LANDPROTECTOR: case NJ_SUITON: + case SO_CLOUD_KILL: case SO_WARMER: return ud->skillunit[i]; } @@ -14707,7 +14995,7 @@ int skill_detonator(struct block_list *bl, va_list ap) { map->foreachinrange(skill->trap_splash,bl,skill->get_splash(su->group->skill_id,su->group->skill_lv),su->group->bl_flag,bl,su->group->tick); } clif->changetraplook(bl, UNT_USED_TRAPS); - su->group->limit = DIFF_TICK(timer->gettick(),su->group->tick) + + su->group->limit = DIFF_TICK32(timer->gettick(),su->group->tick) + (unit_id == UNT_TALKIEBOX ? 5000 : (unit_id == UNT_CLUSTERBOMB || unit_id == UNT_ICEBOUNDTRAP? 2500 : (unit_id == UNT_FIRINGTRAP ? 0 : 1500)) ); su->group->unit_id = UNT_USED_TRAPS; break; @@ -14730,6 +15018,9 @@ int skill_cell_overlap(struct block_list *bl, va_list ap) { if( su == NULL || su->group == NULL || (*alive) == 0 ) return 0; + if( su->group->state.guildaura ) /* guild auras are not cancelled! */ + return 0; + switch (skill_id) { case SA_LANDPROTECTOR: if( su->group->skill_id == SA_LANDPROTECTOR ) {//Check for offensive Land Protector to delete both. [Skotlex] @@ -14737,13 +15028,14 @@ int skill_cell_overlap(struct block_list *bl, va_list ap) { skill->delunit(su); return 1; } - if( !(skill->get_inf2(su->group->skill_id)&(INF2_SONG_DANCE|INF2_TRAP)) || su->group->skill_id == WZ_FIREPILLAR ) { //It deletes everything except songs/dances and traps + if( !(skill->get_inf2(su->group->skill_id)&(INF2_SONG_DANCE|INF2_TRAP)) || su->group->skill_id == WZ_FIREPILLAR || su->group->skill_id == GN_HELLS_PLANT) { //It deletes everything except songs/dances and traps skill->delunit(su); return 1; } break; case HW_GANBANTEIN: case LG_EARTHDRIVE: + case GN_CRAZYWEED_ATK: if( !(su->group->state.song_dance&0x1) ) {// Don't touch song/dance. skill->delunit(su); return 1; @@ -14790,25 +15082,6 @@ int skill_cell_overlap(struct block_list *bl, va_list ap) { return 1; } break; - case GN_CRAZYWEED_ATK: - switch(su->group->unit_id) { - //TODO: look for other ground skills that are affected. - case UNT_WALLOFTHORN: - case UNT_THORNS_TRAP: - case UNT_BLOODYLUST: - case UNT_CHAOSPANIC: - case UNT_MAELSTROM: - case UNT_FIREPILLAR_ACTIVE: - case UNT_LANDPROTECTOR: - case UNT_VOLCANO: - case UNT_DELUGE: - case UNT_VIOLENTGALE: - case UNT_SAFETYWALL: - case UNT_PNEUMA: - skill->delunit(su); - return 1; - } - break; } if (su->group->skill_id == SA_LANDPROTECTOR && !(skill->get_inf2(skill_id)&(INF2_SONG_DANCE|INF2_TRAP))) { @@ -14844,20 +15117,20 @@ int skill_chastle_mob_changetarget(struct block_list *bl,va_list ap) /*========================================== * *------------------------------------------*/ -int skill_trap_splash (struct block_list *bl, va_list ap) { +int skill_trap_splash(struct block_list *bl, va_list ap) { struct block_list *src; - int tick; - struct skill_unit *su; + int64 tick; + struct skill_unit *src_su; struct skill_unit_group *sg; struct block_list *ss; src = va_arg(ap,struct block_list *); - su = (struct skill_unit *)src; - tick = va_arg(ap,int); + src_su = (struct skill_unit *)src; + tick = va_arg(ap,int64); - if( !su->alive || bl->prev == NULL ) + if( !src_su->alive || bl->prev == NULL ) return 0; - nullpo_ret(sg = su->group); + nullpo_ret(sg = src_su->group); nullpo_ret(ss = map->id2bl(sg->src_id)); if(battle->check_target(src,bl,sg->target_flag) <= 0) @@ -14871,19 +15144,19 @@ int skill_trap_splash (struct block_list *bl, va_list ap) { break; case UNT_GROUNDDRIFT_WIND: if(skill->attack(BF_WEAPON,ss,src,bl,sg->skill_id,sg->skill_lv,tick,sg->val1)) - sc_start(bl,SC_STUN,5,sg->skill_lv,skill->get_time2(sg->skill_id, sg->skill_lv)); + sc_start(src,bl,SC_STUN,5,sg->skill_lv,skill->get_time2(sg->skill_id, sg->skill_lv)); break; case UNT_GROUNDDRIFT_DARK: if(skill->attack(BF_WEAPON,ss,src,bl,sg->skill_id,sg->skill_lv,tick,sg->val1)) - sc_start(bl,SC_BLIND,5,sg->skill_lv,skill->get_time2(sg->skill_id, sg->skill_lv)); + sc_start(src,bl,SC_BLIND,5,sg->skill_lv,skill->get_time2(sg->skill_id, sg->skill_lv)); break; case UNT_GROUNDDRIFT_POISON: if(skill->attack(BF_WEAPON,ss,src,bl,sg->skill_id,sg->skill_lv,tick,sg->val1)) - sc_start(bl,SC_POISON,5,sg->skill_lv,skill->get_time2(sg->skill_id, sg->skill_lv)); + sc_start(src,bl,SC_POISON,5,sg->skill_lv,skill->get_time2(sg->skill_id, sg->skill_lv)); break; case UNT_GROUNDDRIFT_WATER: if(skill->attack(BF_WEAPON,ss,src,bl,sg->skill_id,sg->skill_lv,tick,sg->val1)) - sc_start(bl,SC_FREEZE,5,sg->skill_lv,skill->get_time2(sg->skill_id, sg->skill_lv)); + sc_start(src,bl,SC_FREEZE,5,sg->skill_lv,skill->get_time2(sg->skill_id, sg->skill_lv)); break; case UNT_GROUNDDRIFT_FIRE: if(skill->attack(BF_WEAPON,ss,src,bl,sg->skill_id,sg->skill_lv,tick,sg->val1)) @@ -14897,11 +15170,13 @@ int skill_trap_splash (struct block_list *bl, va_list ap) { case UNT_MAIZETRAP: case UNT_VERDURETRAP: if( bl->type != BL_PC && !is_boss(bl) ) - sc_start2(bl,SC_ARMOR_PROPERTY,100,sg->skill_lv,skill->get_ele(sg->skill_id,sg->skill_lv),skill->get_time2(sg->skill_id,sg->skill_lv)); + sc_start2(ss,bl,SC_ARMOR_PROPERTY,100,sg->skill_lv,skill->get_ele(sg->skill_id,sg->skill_lv),skill->get_time2(sg->skill_id,sg->skill_lv)); break; case UNT_REVERBERATION: - skill->addtimerskill(ss,tick+50,bl->id,0,0,WM_REVERBERATION_MELEE,sg->skill_lv,BF_WEAPON,0); // for proper skill delay animation when use with Dominion Impulse - skill->addtimerskill(ss,tick+250,bl->id,0,0,WM_REVERBERATION_MAGIC,sg->skill_lv,BF_MAGIC,0); + if( battle->check_target(src,bl,BCT_ENEMY) > 0 ) { + skill->attack(BF_WEAPON,ss,src,bl,WM_REVERBERATION_MELEE,sg->skill_lv,tick,0); + skill->addtimerskill(ss,tick+200,bl->id,0,0,WM_REVERBERATION_MAGIC,sg->skill_lv,BF_MAGIC,SD_LEVEL); + } break; case UNT_FIRINGTRAP: case UNT_ICEBOUNDTRAP: @@ -14930,7 +15205,7 @@ int skill_trap_splash (struct block_list *bl, va_list ap) { case UNT_FIRINGTRAP: case UNT_ICEBOUNDTRAP: clif->changetraplook(bl, UNT_USED_TRAPS); - su->group->limit = DIFF_TICK(timer->gettick(),su->group->tick) + 1500; + su->group->limit = DIFF_TICK32(timer->gettick(),su->group->tick) + 1500; su->group->unit_id = UNT_USED_TRAPS; } break; @@ -14942,39 +15217,12 @@ int skill_trap_splash (struct block_list *bl, va_list ap) { return 1; } -int skill_maelstrom_suction(struct block_list *bl, va_list ap) { - uint16 skill_id, skill_lv; - struct skill_unit *su; - - skill_id = va_arg(ap,int); - skill_lv = va_arg(ap,int); - su = (struct skill_unit *)bl; - - if( su == NULL || su->group == NULL ) - return 0; - - if( skill->get_inf2(skill_id)&INF2_TRAP ) - return 0; - - if( su->group->skill_id == SC_MAELSTROM ) { - struct block_list *src; - if( (src = map->id2bl(su->group->src_id)) ) { - int sp = su->group->skill_lv * skill_lv; - if( src->type == BL_PC ) - sp += ((TBL_PC*)src)->status.job_level / 5; - status->heal(src, 0, sp/2, 1); - } - } - - return 0; -} - /*========================================== * *------------------------------------------*/ int skill_enchant_elemental_end (struct block_list *bl, int type) { struct status_change *sc; - const enum sc_type scs[] = { SC_ENCHANTPOISON, SC_ASPERSIO, SC_PROPERTYFIRE, SC_PROPERTYWATER, SC_PROPERTYWIND, SC_PROPERTYGROUND, SC_PROPERTYDARK, SC_PROPERTYTELEKINESIS, SC_ENCHANTARMS, SC_EXEEDBREAK }; + const enum sc_type scs[] = { SC_ENCHANTPOISON, SC_ASPERSIO, SC_PROPERTYFIRE, SC_PROPERTYWATER, SC_PROPERTYWIND, SC_PROPERTYGROUND, SC_PROPERTYDARK, SC_PROPERTYTELEKINESIS, SC_ENCHANTARMS }; int i; nullpo_ret(bl); nullpo_ret(sc = status->get_sc(bl)); @@ -15049,6 +15297,39 @@ bool skill_check_camouflage(struct block_list *bl, struct status_change_entry *s return wall; } +bool skill_check_shadowform(struct block_list *bl, int64 damage, int hit){ + struct status_change *sc; + struct block_list *src; + + nullpo_retr(false, bl); + + sc = status->get_sc(bl); + + if( sc && sc->data[SC__SHADOWFORM] && damage ) { + src = map->id2bl(sc->data[SC__SHADOWFORM]->val2); + + if( !src || src->m != bl->m ) { + status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER); + return false; + } + + if( src && (status->isdead(src) || !battle->check_target(bl,src,BCT_ENEMY)) ){ + if( src->type == BL_PC ) + ((TBL_PC*)src)->shadowform_id = 0; + status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER); + return false; + } + + status->damage(bl, src, damage, 0, clif->damage(src, src, 500, 500, damage, hit, (hit > 1 ? 8 : 0), 0), 0); + if( (--sc->data[SC__SHADOWFORM]->val3) <= 0 ) { + status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER); + if( src->type == BL_PC ) + ((TBL_PC*)src)->shadowform_id = 0; + } + return true; + } + return false; +} /*========================================== * *------------------------------------------*/ @@ -15059,9 +15340,6 @@ struct skill_unit *skill_initunit (struct skill_unit_group *group, int idx, int nullpo_retr(NULL, group->unit); // crash-protection against poor coding nullpo_retr(NULL, su=&group->unit[idx]); - if( map->getcell(map->id2bl(group->src_id)->m, x, y, CELL_CHKMAELSTROM) ) - return su; - if(!su->alive) group->alive_count++; @@ -15093,16 +15371,13 @@ struct skill_unit *skill_initunit (struct skill_unit_group *group, int idx, int case HP_BASILICA: skill->unitsetmapcell(su,HP_BASILICA,group->skill_lv,CELL_BASILICA,true); break; - case SC_MAELSTROM: - skill->unitsetmapcell(su,SC_MAELSTROM,group->skill_lv,CELL_MAELSTROM,true); - break; default: if (group->state.song_dance&0x1) //Check for dissonance. skill->dance_overlap(su, 1); break; } - clif->skill_setunit(su); + clif->getareachar_skillunit(&su->bl,su,AREA); return su; } @@ -15154,9 +15429,6 @@ int skill_delunit (struct skill_unit* su) { status_change_end(target, SC_ELECTRICSHOCKER, INVALID_TIMER); } break; - case SC_MAELSTROM: - skill->unitsetmapcell(su,SC_MAELSTROM,group->skill_lv,CELL_MAELSTROM,false); - break; case SC_MANHOLE: // Note : Removing the unit don't remove the status (official info) if( group->val2 ) { // Someone Traped struct status_change *tsc = status->get_sc(map->id2bl(group->val2)); @@ -15223,11 +15495,11 @@ struct skill_unit_group* skill_initunitgroup (struct block_list* src, int count, if(i == MAX_SKILLUNITGROUP) { // array is full, make room by discarding oldest group int j=0; - unsigned maxdiff=0,x,tick=timer->gettick(); + int64 maxdiff = 0, x, tick = timer->gettick(); for(i=0;i<MAX_SKILLUNITGROUP && ud->skillunit[i];i++) - if((x=DIFF_TICK(tick,ud->skillunit[i]->tick))>maxdiff){ - maxdiff=x; - j=i; + if( (x=DIFF_TICK(tick,ud->skillunit[i]->tick)) > maxdiff ) { + maxdiff = x; + j = i; } skill->del_unitgroup(ud->skillunit[j],ALC_MARK); //Since elements must have shifted, we use the last slot. @@ -15414,7 +15686,7 @@ int skill_clear_unitgroup (struct block_list *src) /*========================================== * *------------------------------------------*/ -struct skill_unit_group_tickset *skill_unitgrouptickset_search (struct block_list *bl, struct skill_unit_group *group, int tick) { +struct skill_unit_group_tickset *skill_unitgrouptickset_search(struct block_list *bl, struct skill_unit_group *group, int64 tick) { int i,j=-1,k,s,id; struct unit_data *ud; struct skill_unit_group_tickset *set; @@ -15454,10 +15726,10 @@ struct skill_unit_group_tickset *skill_unitgrouptickset_search (struct block_lis /*========================================== * *------------------------------------------*/ -int skill_unit_timer_sub_onplace (struct block_list* bl, va_list ap) { +int skill_unit_timer_sub_onplace(struct block_list* bl, va_list ap) { struct skill_unit* su = va_arg(ap,struct skill_unit *); struct skill_unit_group* group = su->group; - unsigned int tick = va_arg(ap,unsigned int); + int64 tick = va_arg(ap,int64); if( !su->alive || bl->prev == NULL ) return 0; @@ -15481,7 +15753,7 @@ int skill_unit_timer_sub_onplace (struct block_list* bl, va_list ap) { int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) { struct skill_unit* su = DB->data2ptr(data); struct skill_unit_group* group = su->group; - unsigned int tick = va_arg(ap,unsigned int); + int64 tick = va_arg(ap,int64); bool dissonance; struct block_list* bl = &su->bl; @@ -15505,8 +15777,8 @@ int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) { case UNT_GROUNDDRIFT_FIRE: group->unit_id = UNT_USED_TRAPS; //clif->changetraplook(bl, UNT_FIREPILLAR_ACTIVE); - group->limit=DIFF_TICK(tick+1500,group->tick); - su->limit=DIFF_TICK(tick+1500,group->tick); + group->limit=DIFF_TICK32(tick+1500,group->tick); + su->limit=DIFF_TICK32(tick+1500,group->tick); break; case UNT_ANKLESNARE: @@ -15585,15 +15857,15 @@ int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) { } clif->changetraplook(bl,UNT_USED_TRAPS); map->foreachinrange(skill->trap_splash, bl, skill->get_splash(group->skill_id, group->skill_lv), group->bl_flag, bl, tick); - group->limit = DIFF_TICK(tick,group->tick)+1000; - su->limit = DIFF_TICK(tick,group->tick)+1000; + group->limit = DIFF_TICK32(tick,group->tick)+1500; + su->limit = DIFF_TICK32(tick,group->tick)+1500; group->unit_id = UNT_USED_TRAPS; break; case UNT_FEINTBOMB: { struct block_list *src = map->id2bl(group->src_id); if( src ) - map->foreachinrange(skill->area_sub, &group->unit->bl, su->range, splash_target(src), src, SC_FEINTBOMB, group->skill_lv, tick, BCT_ENEMY|SD_ANIMATION|1, skill->castend_damage_id); + map->foreachinrange(skill->area_sub, &group->unit->bl, su->range, splash_target(src), src, SC_FEINTBOMB, group->skill_lv, tick, BCT_ENEMY|1, skill->castend_damage_id); skill->delunit(su); break; } @@ -15607,8 +15879,8 @@ int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) { break; } // This unit isn't removed while SC_BANDING is active. - group->limit = DIFF_TICK(tick+group->interval,group->tick); - su->limit = DIFF_TICK(tick+group->interval,group->tick); + group->limit = DIFF_TICK32(tick+group->interval,group->tick); + su->limit = DIFF_TICK32(tick+group->interval,group->tick); } break; @@ -15621,7 +15893,7 @@ int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) { // icewall loses 50 hp every second su->val1 -= SKILLUNITTIMER_INTERVAL/20; // trap's hp if( su->val1 <= 0 && su->limit + group->tick > tick + 700 ) - su->limit = DIFF_TICK(tick+700,group->tick); + su->limit = DIFF_TICK32(tick+700,group->tick); break; case UNT_BLASTMINE: case UNT_SKIDTRAP: @@ -15638,24 +15910,19 @@ int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) { skill->delunit(su); else { clif->changetraplook(bl, group->unit_id==UNT_LANDMINE?UNT_FIREPILLAR_ACTIVE:UNT_USED_TRAPS); - group->limit = DIFF_TICK(tick, group->tick) + 1500; + group->limit = DIFF_TICK32(tick, group->tick) + 1500; group->unit_id = UNT_USED_TRAPS; } } break; case UNT_REVERBERATION: - if( su->val1 <= 0 ) { - clif->changetraplook(bl,UNT_USED_TRAPS); - map->foreachinrange(skill->trap_splash, bl, skill->get_splash(group->skill_id, group->skill_lv), group->bl_flag, bl, tick); - group->limit = DIFF_TICK(tick,group->tick)+1000; - su->limit = DIFF_TICK(tick,group->tick)+1000; - group->unit_id = UNT_USED_TRAPS; - } + if( su->val1 <= 0 ) + su->limit = DIFF_TICK32(tick + 700,group->tick); break; case UNT_WALLOFTHORN: if( su->val1 <= 0 ) { group->unit_id = UNT_USED_TRAPS; - group->limit = DIFF_TICK(tick, group->tick) + 1500; + group->limit = DIFF_TICK32(tick, group->tick) + 1500; } break; } @@ -15692,7 +15959,7 @@ int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) { /*========================================== * Executes on all skill units every SKILLUNITTIMER_INTERVAL miliseconds. *------------------------------------------*/ -int skill_unit_timer(int tid, unsigned int tick, int id, intptr_t data) { +int skill_unit_timer(int tid, int64 tick, int id, intptr_t data) { map->freeblock_lock(); skill->unit_db->foreach(skill->unit_db, skill->unit_timer_sub, tick); @@ -15705,12 +15972,12 @@ int skill_unit_timer(int tid, unsigned int tick, int id, intptr_t data) { /*========================================== * *------------------------------------------*/ -int skill_unit_move_sub (struct block_list* bl, va_list ap) { +int skill_unit_move_sub(struct block_list* bl, va_list ap) { struct skill_unit* su = (struct skill_unit *)bl; struct skill_unit_group* group = su->group; struct block_list* target = va_arg(ap,struct block_list*); - unsigned int tick = va_arg(ap,unsigned int); + int64 tick = va_arg(ap,int64); int flag = va_arg(ap,int); bool dissonance; @@ -15802,7 +16069,7 @@ int skill_unit_move_sub (struct block_list* bl, va_list ap) { * units to figure out when they have left a group. * flag&4: Force a onleft event (triggered when the bl is killed, for example) *------------------------------------------*/ -int skill_unit_move (struct block_list *bl, unsigned int tick, int flag) { +int skill_unit_move(struct block_list *bl, int64 tick, int flag) { nullpo_ret(bl); if( bl->prev == NULL ) @@ -15827,10 +16094,9 @@ int skill_unit_move (struct block_list *bl, unsigned int tick, int flag) { /*========================================== * *------------------------------------------*/ -int skill_unit_move_unit_group (struct skill_unit_group *group, int16 m, int16 dx, int16 dy) -{ +int skill_unit_move_unit_group(struct skill_unit_group *group, int16 m, int16 dx, int16 dy) { int i,j; - unsigned int tick = timer->gettick(); + int64 tick = timer->gettick(); int *m_flag; struct skill_unit *su1; struct skill_unit *su2; @@ -15906,7 +16172,7 @@ int skill_unit_move_unit_group (struct skill_unit_group *group, int16 m, int16 d if (!(m_flag[i]&0x2)) { //We only moved the cell in 0-1 if (group->state.song_dance&0x1) //Check for dissonance effect. skill->dance_overlap(su1, 1); - clif->skill_setunit(su1); + clif->getareachar_skillunit(&su1->bl,su1,AREA); map->foreachincell(skill->unit_effect,su1->bl.m,su1->bl.x,su1->bl.y,group->bl_flag,&su1->bl,tick,1); } } @@ -16017,11 +16283,11 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid, j = pc->search_inventory(sd,slot[i]); if(j < 0) continue; - if(slot[i]==1000){ /* Star Crumb */ + if( slot[i]==ITEMID_STAR_CRUMB ) { pc->delitem(sd,j,1,1,0,LOG_TYPE_PRODUCE); sc++; } - if(slot[i]>=994 && slot[i]<=997 && ele==0){ /* Flame Heart . . . Great Nature */ + if( slot[i] >= ITEMID_FLAME_HEART && slot[i] <= ITEMID_GREAT_NATURE && ele == 0 ) { static const int ele_table[4]={3,1,4,2}; pc->delitem(sd,j,1,1,0,LOG_TYPE_PRODUCE); ele=ele_table[slot[i]-994]; @@ -16029,11 +16295,11 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid, } if( skill_id == RK_RUNEMASTERY ) { - int temp_qty, skill_lv = pc->checkskill(sd,skill_id); + int temp_qty, rune_skill_lv = pc->checkskill(sd,skill_id); data = itemdb->search(nameid); - if( skill_lv == 10 ) temp_qty = 1 + rnd()%3; - else if( skill_lv > 5 ) temp_qty = 1 + rnd()%2; + if( rune_skill_lv == 10 ) temp_qty = 1 + rnd()%3; + else if( rune_skill_lv > 5 ) temp_qty = 1 + rnd()%2; else temp_qty = 1; if (data->stack.inventory) { @@ -16088,13 +16354,13 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid, i = pc->checkskill(sd,skill_id); make_per = sd->status.job_level*20 + st->dex*10 + st->luk*10; //Base chance switch(nameid){ - case 998: // Iron + case ITEMID_IRON: make_per += 4000+i*500; // Temper Iron bonus: +26/+32/+38/+44/+50 break; - case 999: // Steel + case ITEMID_STEEL: make_per += 3000+i*500; // Temper Steel bonus: +35/+40/+45/+50/+55 break; - case 1000: //Star Crumb + case ITEMID_STAR_CRUMB: make_per = 100000; // Star Crumbs are 100% success crafting rate? (made 1000% so it succeeds even after penalties) [Skotlex] break; default: // Enchanted Stones @@ -16125,32 +16391,32 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid, make_per += skill2_lv*100; //+1% bonus per level } switch(nameid){ - case 501: // Red Potion - case 503: // Yellow Potion - case 504: // White Potion + case ITEMID_RED_POTION: + case ITEMID_YELLOW_POTION: + case ITEMID_WHITE_POTION: make_per += (1+rnd()%100)*10 + 2000; break; - case 970: // Alcohol + case ITEMID_ALCHOL: make_per += (1+rnd()%100)*10 + 1000; break; - case 7135: // Bottle Grenade - case 7136: // Acid Bottle - case 7137: // Plant Bottle - case 7138: // Marine Sphere Bottle + case ITEMID_FIRE_BOTTLE: + case ITEMID_ACID_BOTTLE: + case ITEMID_MENEATER_PLANT_BOTTLE: + case ITEMID_MINI_BOTTLE: make_per += (1+rnd()%100)*10; break; - case 546: // Condensed Yellow Potion + case ITEMID_YELLOW_SLIM_POTION: make_per -= (1+rnd()%50)*10; break; - case 547: // Condensed White Potion - case 7139: // Glistening Coat + case ITEMID_WHITE_SLIM_POTION: + case ITEMID_COATING_BOTTLE: make_per -= (1+rnd()%100)*10; break; //Common items, recieve no bonus or penalty, listed just because they are commonly produced - case 505: // Blue Potion - case 545: // Condensed Red Potion - case 605: // Anodyne - case 606: // Aloevera + case ITEMID_BLUE_POTION: + case ITEMID_RED_SLIM_POTION: + case ITEMID_ANODYNE: + case ITEMID_ALOEBERA: default: break; } @@ -16170,18 +16436,18 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid, int C = 100 * cap_value(sd->itemid,0,100); //itemid depend on makerune() int D = 2500; switch (nameid) { //rune rank it_diff 9 craftable rune - case ITEMID_RAIDO: - case ITEMID_THURISAZ: - case ITEMID_HAGALAZ: - case ITEMID_OTHILA: + case ITEMID_RAIDO: + case ITEMID_THURISAZ: + case ITEMID_HAGALAZ: + case ITEMID_OTHILA: D -= 500; //Rank C - case ITEMID_ISA: - case ITEMID_WYRD: + case ITEMID_ISA: + case ITEMID_WYRD: D -= 500; //Rank B - case ITEMID_NAUTHIZ: - case ITEMID_URUZ: + case ITEMID_NAUTHIZ: + case ITEMID_URUZ: D -= 500; //Rank A - case ITEMID_BERKANA: + case ITEMID_BERKANA: case ITEMID_LUX_ANIMA: D -= 500; //Rank S } @@ -16197,7 +16463,7 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid, const int max[10] = {4, 5, 5, 6, 6, 7, 7, 8, 8, 9}; int lv = max(0, pc->checkskill(sd,GC_RESEARCHNEWPOISON) - 1); qty = min[lv] + rnd()%(max[lv] - min[lv]); - make_per = 3000 + 500 * (lv+1); + make_per = 3000 + 500 * lv + st->dex / 3 * 10 + st->luk * 10 + sd->status.job_level * 10; } break; case GN_CHANGEMATERIAL: @@ -16217,22 +16483,28 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid, (sd->status.base_level-100) + pc->checkskill(sd, AM_LEARNINGPOTION) + pc->checkskill(sd, CR_FULLPROTECTION)*(4+rnd()%6); // (Caster?s Base Level - 100) + (Potion Research x 5) + (Full Chemical Protection Skill Level) x (Random number between 4 ~ 10) switch(nameid){// difficulty factor - case 12422: case 12425: - case 12428: + case ITEMID_HP_INCREASE_POTIONS: + case ITEMID_SP_INCREASE_POTIONS: + case ITEMID_ENRICH_WHITE_POTIONZ: difficulty += 10; break; - case 6212: case 12426: + case ITEMID_BOMB_MUSHROOM_SPORE: + case ITEMID_SP_INCREASE_POTIONM: difficulty += 15; break; - case 13264: case 12423: - case 12427: case 12436: + case ITEMID_BANANA_BOMB: + case ITEMID_HP_INCREASE_POTIONM: + case ITEMID_SP_INCREASE_POTIONL: + case ITEMID_VITATA500: difficulty += 20; break; - case 6210: case 6211: - case 12437: + case ITEMID_SEED_OF_HORNY_PLANT: + case ITEMID_BLOODSUCK_PLANT_SEED: + case ITEMID_ENRICH_CELERMINE_JUICE: difficulty += 30; break; - case 12424: case 12475: + case ITEMID_HP_INCREASE_POTIONL: + case ITEMID_CURE_FREE: difficulty += 40; break; } @@ -16259,18 +16531,23 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid, qty = ~(5 + rnd()%5) + 1; switch(nameid){// difficulty factor - case 13260: + case ITEMID_APPLE_BOMB: difficulty += 5; break; - case 13261: case 13262: + case ITEMID_COCONUT_BOMB: + case ITEMID_MELON_BOMB: difficulty += 10; break; - case 12429: case 12430: case 12431: - case 12432: case 12433: case 12434: - case 13263: + case ITEMID_SAVAGE_BBQ: + case ITEMID_WUG_BLOOD_COCKTAIL: + case ITEMID_MINOR_BRISKET: + case ITEMID_SIROMA_ICETEA: + case ITEMID_DROCERA_HERB_STEW: + case ITEMID_PETTI_TAIL_NOODLE: + case ITEMID_PINEAPPLE_BOMB: difficulty += 15; break; - case 13264: + case ITEMID_BANANA_BOMB: difficulty += 20; break; } @@ -16404,7 +16681,7 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid, } if (rnd()%10000 < make_per || qty == 1) { //Success tmp_item.amount++; - if(nameid < 545 || nameid > 547) + if(nameid < ITEMID_RED_SLIM_POTION || nameid > ITEMID_WHITE_SLIM_POTION) continue; if( skill_id != AM_PHARMACY && skill_id != AM_TWILIGHT1 && @@ -16459,7 +16736,7 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid, { //Cooking items. clif->specialeffect(&sd->bl, 608, AREA); if( sd->cook_mastery < 1999 ) - pc_setglobalreg(sd, "COOK_MASTERY",sd->cook_mastery + ( 1 << ( (skill->produce_db[idx].itemlv - 11) / 2 ) ) * 5); + pc_setglobalreg(sd, script->add_str("COOK_MASTERY"),sd->cook_mastery + ( 1 << ( (skill->produce_db[idx].itemlv - 11) / 2 ) ) * 5); } break; } @@ -16527,7 +16804,13 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid, break; case GN_MIX_COOKING: { struct item tmp_item; - const int compensation[5] = {13265, 13266, 13267, 12435, 13268}; + const int compensation[5] = { + ITEMID_BLACK_LUMP, + ITEMID_BLACK_HARD_LUMP, + ITEMID_VERY_HARD_LUMP, + ITEMID_BLACK_THING, + ITEMID_MYSTERIOUS_POWDER, + }; int rate = rnd()%500; memset(&tmp_item,0,sizeof(tmp_item)); if( rate < 50) i = 4; @@ -16554,7 +16837,7 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid, { //Cooking items. clif->specialeffect(&sd->bl, 609, AREA); if( sd->cook_mastery > 0 ) - pc_setglobalreg(sd, "COOK_MASTERY", sd->cook_mastery - ( 1 << ((skill->produce_db[idx].itemlv - 11) / 2) ) - ( ( ( 1 << ((skill->produce_db[idx].itemlv - 11) / 2) ) >> 1 ) * 3 )); + pc_setglobalreg(sd, script->add_str("COOK_MASTERY"), sd->cook_mastery - ( 1 << ((skill->produce_db[idx].itemlv - 11) / 2) ) - ( ( ( 1 << ((skill->produce_db[idx].itemlv - 11) / 2) ) >> 1 ) * 3 )); } } } @@ -16612,21 +16895,22 @@ int skill_poisoningweapon( struct map_session_data *sd, int nameid) { } switch( nameid ) { // t_lv used to take duration from skill->get_time2 - case PO_PARALYSE: type = SC_PARALYSE; break; - case PO_PYREXIA: type = SC_PYREXIA; break; - case PO_DEATHHURT: type = SC_DEATHHURT; break; - case PO_LEECHESEND: type = SC_LEECHESEND; break; - case PO_VENOMBLEED: type = SC_VENOMBLEED; break; - case PO_TOXIN: type = SC_TOXIN; break; - case PO_MAGICMUSHROOM: type = SC_MAGICMUSHROOM; break; - case PO_OBLIVIONCURSE: type = SC_OBLIVIONCURSE; break; + case ITEMID_POISON_PARALYSIS: type = SC_PARALYSE; break; + case ITEMID_POISON_FEVER: type = SC_PYREXIA; break; + case ITEMID_POISON_CONTAMINATION: type = SC_DEATHHURT; break; + case ITEMID_POISON_LEECH: type = SC_LEECHESEND; break; + case ITEMID_POISON_FATIGUE: type = SC_VENOMBLEED; break; + case ITEMID_POISON_NUMB: type = SC_TOXIN; break; + case ITEMID_POISON_LAUGHING: type = SC_MAGICMUSHROOM; break; + case ITEMID_POISON_OBLIVION: type = SC_OBLIVIONCURSE; break; default: clif->skill_fail(sd,GC_POISONINGWEAPON,USESKILL_FAIL_LEVEL,0); return 0; } + status_change_end(&sd->bl, SC_POISONINGWEAPON, -1);//Status must be forced to end so that a new poison will be applied if a player decides to change poisons. [Rytech] chance = 2 + 2 * sd->menuskill_val; // 2 + 2 * skill_lv - sc_start4(&sd->bl, SC_POISONINGWEAPON, 100, pc->checkskill(sd, GC_RESEARCHNEWPOISON), //in Aegis it store the level of GC_RESEARCHNEWPOISON in val1 + sc_start4(&sd->bl, &sd->bl, SC_POISONINGWEAPON, 100, pc->checkskill(sd, GC_RESEARCHNEWPOISON), //in Aegis it store the level of GC_RESEARCHNEWPOISON in val1 type, chance, 0, skill->get_time(GC_POISONINGWEAPON, sd->menuskill_val)); return 0; @@ -16675,16 +16959,16 @@ int skill_magicdecoy(struct map_session_data *sd, int nameid) { sd->sc.comet_x = sd->sc.comet_y = 0; sd->menuskill_val = 0; - class_ = (nameid == 990 || nameid == 991) ? 2043 + nameid - 990 : (nameid == 992) ? 2046 : 2045; + class_ = (nameid == ITEMID_BOODY_RED || nameid == ITEMID_CRYSTAL_BLUE) ? 2043 + nameid - ITEMID_BOODY_RED : (nameid == ITEMID_WIND_OF_VERDURE) ? 2046 : 2045; - md = mob->once_spawn_sub(&sd->bl, sd->bl.m, x, y, sd->status.name, class_, "", SZ_SMALL, AI_NONE); + md = mob->once_spawn_sub(&sd->bl, sd->bl.m, x, y, sd->status.name, class_, "", SZ_MEDIUM, AI_NONE); if( md ) { md->master_id = sd->bl.id; md->special_state.ai = AI_FLORA; if( md->deletetimer != INVALID_TIMER ) timer->delete(md->deletetimer, mob->timer_delete); - md->deletetimer = timer->add (timer->gettick() + skill->get_time(NC_MAGICDECOY,skill_id), mob->timer_delete, md->bl.id, 0); + md->deletetimer = timer->add(timer->gettick() + skill->get_time(NC_MAGICDECOY,skill_id), mob->timer_delete, md->bl.id, 0); mob->spawn(md); md->status.matk_min = md->status.matk_max = 250 + (50 * skill_id); } @@ -16714,7 +16998,7 @@ int skill_spellbook (struct map_session_data *sd, int nameid) { if( !pc->checkskill(sd, (skill_id = skill->spellbook_db[i].skill_id)) ) { // User don't know the skill - sc_start(&sd->bl, SC_SLEEP, 100, 1, skill->get_time(WL_READING_SB, pc->checkskill(sd,WL_READING_SB))); + sc_start(&sd->bl, &sd->bl, SC_SLEEP, 100, 1, skill->get_time(WL_READING_SB, pc->checkskill(sd,WL_READING_SB))); clif->skill_fail(sd, WL_READING_SB, USESKILL_FAIL_SPELLBOOK_DIFFICULT_SLEEP, 0); return 0; } @@ -16730,13 +17014,13 @@ int skill_spellbook (struct map_session_data *sd, int nameid) { for(i = SC_SPELLBOOK7; i >= SC_SPELLBOOK1; i--){ // This is how official saves spellbook. [malufett] if( !sc->data[i] ){ sc->data[SC_READING_SB]->val2 += point; // increase points - sc_start4(&sd->bl, (sc_type)i, 100, skill_id, pc->checkskill(sd,skill_id), point, 0, INVALID_TIMER); + sc_start4(&sd->bl,&sd->bl, (sc_type)i, 100, skill_id, pc->checkskill(sd,skill_id), point, 0, INVALID_TIMER); break; } } }else{ - sc_start2(&sd->bl, SC_READING_SB, 100, 0, point, INVALID_TIMER); - sc_start4(&sd->bl, SC_SPELLBOOK7, 100, skill_id, pc->checkskill(sd,skill_id), point, 0, INVALID_TIMER); + sc_start2(&sd->bl,&sd->bl, SC_READING_SB, 100, 0, point, INVALID_TIMER); + sc_start4(&sd->bl,&sd->bl, SC_SPELLBOOK7, 100, skill_id, pc->checkskill(sd,skill_id), point, 0, INVALID_TIMER); } return 1; @@ -16761,7 +17045,7 @@ int skill_select_menu(struct map_session_data *sd,uint16 skill_id) { lv = (aslvl + 1) / 2; // The level the skill will be autocasted lv = min(lv,sd->status.skill[idx].lv); prob = (aslvl == 10) ? 15 : (32 - 2 * aslvl); // Probability at level 10 was increased to 15. - sc_start4(&sd->bl,SC__AUTOSHADOWSPELL,100,id,lv,prob,0,skill->get_time(SC_AUTOSHADOWSPELL,aslvl)); + sc_start4(&sd->bl,&sd->bl,SC__AUTOSHADOWSPELL,100,id,lv,prob,0,skill->get_time(SC_AUTOSHADOWSPELL,aslvl)); return 0; } int skill_elementalanalysis(struct map_session_data* sd, int n, uint16 skill_lv, unsigned short* item_list) { @@ -16791,15 +17075,15 @@ int skill_elementalanalysis(struct map_session_data* sd, int n, uint16 skill_lv, switch( nameid ) { // Level 1 - case 994: product = 990; break; // Flame Heart -> Red Blood. - case 995: product = 991; break; // Mystic Frozen -> Crystal Blue. - case 996: product = 992; break; // Rough Wind -> Wind of Verdure. - case 997: product = 993; break; // Great Nature -> Green Live. + case ITEMID_FLAME_HEART: product = ITEMID_BOODY_RED; break; + case ITEMID_MISTIC_FROZEN: product = ITEMID_CRYSTAL_BLUE; break; + case ITEMID_ROUGH_WIND: product = ITEMID_WIND_OF_VERDURE; break; + case ITEMID_GREAT_NATURE: product = ITEMID_YELLOW_LIVE; break; // Level 2 - case 990: product = 994; break; // Red Blood -> Flame Heart. - case 991: product = 995; break; // Crystal Blue -> Mystic Frozen. - case 992: product = 996; break; // Wind of Verdure -> Rough Wind. - case 993: product = 997; break; // Green Live -> Great Nature. + case ITEMID_BOODY_RED: product = ITEMID_FLAME_HEART; break; + case ITEMID_CRYSTAL_BLUE: product = ITEMID_MISTIC_FROZEN; break; + case ITEMID_WIND_OF_VERDURE: product = ITEMID_ROUGH_WIND; break; + case ITEMID_YELLOW_LIVE: product = ITEMID_GREAT_NATURE; break; default: clif->skill_fail(sd,SO_EL_ANALYSIS,USESKILL_FAIL_LEVEL,0); return 1; @@ -16882,13 +17166,13 @@ int skill_changematerial(struct map_session_data *sd, int n, unsigned short *ite /** * for Royal Guard's LG_TRAMPLE **/ -int skill_destroy_trap( struct block_list *bl, va_list ap ) { +int skill_destroy_trap(struct block_list *bl, va_list ap) { struct skill_unit *su = (struct skill_unit *)bl; struct skill_unit_group *sg; - unsigned int tick; + int64 tick; nullpo_ret(su); - tick = va_arg(ap, unsigned int); + tick = va_arg(ap, int64); if (su->alive && (sg = su->group) && skill->get_inf2(sg->skill_id)&INF2_TRAP) { switch( sg->unit_id ) { @@ -16915,13 +17199,14 @@ int skill_destroy_trap( struct block_list *bl, va_list ap ) { /*========================================== * *------------------------------------------*/ -int skill_blockpc_end(int tid, unsigned int tick, int id, intptr_t data) { +int skill_blockpc_end(int tid, int64 tick, int id, intptr_t data) { struct map_session_data *sd = map->id2sd(id); struct skill_cd * cd = NULL; if (data <= 0 || data >= MAX_SKILL) return 0; - if (!sd) return 0; + if (!sd || !sd->blockskill[data]) + return 0; if( ( cd = idb_get(skill->cd_db,sd->status.char_id) ) ) { int i; @@ -16955,22 +17240,21 @@ int skill_blockpc_end(int tid, unsigned int tick, int id, intptr_t data) { } } - if (sd->blockskill[data] != (0x1|(tid&0xFE))) return 0; - - sd->blockskill[data] = 0; + sd->blockskill[data] = false; return 1; } /** * flags a singular skill as being blocked from persistent usage. * @param sd the player the skill delay affects - * @param skill_id the skill which should be delayed + * @param skill_id the skill which should be delayed * @param tick the length of time the delay should last - * @param load whether this assignment is being loaded upon player login * @return 0 if successful, -1 otherwise */ -int skill_blockpc_start_(struct map_session_data *sd, uint16 skill_id, int tick, bool load) { +int skill_blockpc_start_(struct map_session_data *sd, uint16 skill_id, int tick) { + struct skill_cd* cd = NULL; uint16 idx = skill->get_index(skill_id); + int64 now = timer->gettick(); nullpo_retr (-1, sd); @@ -16978,53 +17262,60 @@ int skill_blockpc_start_(struct map_session_data *sd, uint16 skill_id, int tick, return -1; if (tick < 1) { - sd->blockskill[idx] = 0; + sd->blockskill[idx] = false; return -1; } - if( !load && battle_config.display_status_timers ) + if( battle_config.display_status_timers ) clif->skill_cooldown(sd, skill_id, tick); - - if( !load ) {// not being loaded initially so ensure the skill delay is recorded - struct skill_cd* cd = NULL; + + if( !(cd = idb_get(skill->cd_db,sd->status.char_id)) ) {// create a new skill cooldown object for map storage + cd = ers_alloc(skill->cd_ers, struct skill_cd); + + idb_put( skill->cd_db, sd->status.char_id, cd ); + } else { int i; - if( !(cd = idb_get(skill->cd_db,sd->status.char_id)) ) {// create a new skill cooldown object for map storage - cd = ers_alloc(skill->cd_ers, struct skill_cd); - - cd->cursor = 0; - memset(cd->entry, 0, sizeof(cd->entry)); - - idb_put( skill->cd_db, sd->status.char_id, cd ); - } - for(i = 0; i < MAX_SKILL_TREE; i++) { - if( !cd->entry[i] ) + if( cd->entry[i] && cd->entry[i]->skidx == idx ) break; } - - if( i == MAX_SKILL_TREE ) { - ShowError("skill_blockpc_start: '%s' got over '%d' skill cooldowns, no room to save!\n",sd->status.name,MAX_SKILL_TREE); - } else { - cd->entry[cd->cursor] = ers_alloc(skill->cd_entry_ers,struct skill_cd_entry); - - cd->entry[cd->cursor]->duration = tick; + + if( i != MAX_SKILL_TREE ) {/* duplicate, update necessary */ + cd->entry[i]->duration = tick; #if PACKETVER >= 20120604 - cd->entry[cd->cursor]->total = tick; + cd->entry[i]->total = tick; #endif - cd->entry[cd->cursor]->skidx = idx; - cd->entry[cd->cursor]->skill_id = skill_id; - cd->entry[cd->cursor]->started = timer->gettick(); - - cd->cursor++; + cd->entry[i]->started = now; + timer->settick(cd->entry[i]->timer,now+tick); + return 0; } + } + + if( cd->cursor == MAX_SKILL_TREE ) { + ShowError("skill_blockpc_start: '%s' got over '%d' skill cooldowns, no room to save!\n",sd->status.name,MAX_SKILL_TREE); + return -1; + } + + cd->entry[cd->cursor] = ers_alloc(skill->cd_entry_ers,struct skill_cd_entry); + + cd->entry[cd->cursor]->duration = tick; +#if PACKETVER >= 20120604 + cd->entry[cd->cursor]->total = tick; +#endif + cd->entry[cd->cursor]->skidx = idx; + cd->entry[cd->cursor]->skill_id = skill_id; + cd->entry[cd->cursor]->started = now; + cd->entry[cd->cursor]->timer = timer->add(now+tick,skill->blockpc_end,sd->bl.id,idx); + + cd->cursor++; - sd->blockskill[idx] = 0x1|(0xFE&timer->add(timer->gettick()+tick,skill->blockpc_end,sd->bl.id,idx)); + sd->blockskill[idx] = true; return 0; } -int skill_blockhomun_end(int tid, unsigned int tick, int id, intptr_t data) { //[orn] +int skill_blockhomun_end(int tid, int64 tick, int id, intptr_t data) { //[orn] struct homun_data *hd = (TBL_HOM*)map->id2bl(id); if (data <= 0 || data >= MAX_SKILL) return 0; @@ -17049,7 +17340,7 @@ int skill_blockhomun_start(struct homun_data *hd, uint16 skill_id, int tick) { / return timer->add(timer->gettick() + tick, skill->blockhomun_end, hd->bl.id, idx); } -int skill_blockmerc_end(int tid, unsigned int tick, int id, intptr_t data) {//[orn] +int skill_blockmerc_end(int tid, int64 tick, int id, intptr_t data) {//[orn] struct mercenary_data *md = (TBL_MER*)map->id2bl(id); if( data <= 0 || data >= MAX_SKILL ) return 0; @@ -17446,7 +17737,7 @@ int skill_block_check(struct block_list *bl, sc_type type , uint16 skill_id) { switch(type){ case SC_STASIS: inf = skill->get_inf2(skill_id); - if( inf == INF2_SONG_DANCE || /*skill->get_inf2(skill_id) == INF2_CHORUS_SKILL ||*/ inf == INF2_SPIRIT_SKILL ) + if( inf == INF2_SONG_DANCE || skill->get_inf2(skill_id) == INF2_CHORUS_SKILL || inf == INF2_SPIRIT_SKILL ) return 1; // Can't do it. switch( skill_id ) { case NV_FIRSTAID: case TF_HIDING: case AS_CLOAKING: case WZ_SIGHTRASHER: @@ -17517,7 +17808,7 @@ int skill_get_elemental_type( uint16 skill_id , uint16 skill_lv ) { void skill_cooldown_save(struct map_session_data * sd) { int i; struct skill_cd* cd = NULL; - unsigned int now = 0; + int64 now = 0; // always check to make sure the session properly exists nullpo_retv(sd); @@ -17530,7 +17821,11 @@ void skill_cooldown_save(struct map_session_data * sd) { // process each individual cooldown associated with the character for( i = 0; i < cd->cursor; i++ ) { - cd->entry[i]->duration = DIFF_TICK(cd->entry[i]->started+cd->entry[i]->duration,now); + cd->entry[i]->duration = DIFF_TICK32(cd->entry[i]->started+cd->entry[i]->duration,now); + if( cd->entry[i]->timer != INVALID_TIMER ) { + timer->delete(cd->entry[i]->timer,skill->blockpc_end); + cd->entry[i]->timer = INVALID_TIMER; + } } } @@ -17541,7 +17836,7 @@ void skill_cooldown_save(struct map_session_data * sd) { void skill_cooldown_load(struct map_session_data * sd) { int i; struct skill_cd* cd = NULL; - unsigned int now = 0; + int64 now = 0; // always check to make sure the session properly exists nullpo_retv(sd); @@ -17557,8 +17852,8 @@ void skill_cooldown_load(struct map_session_data * sd) { // process each individual cooldown associated with the character for( i = 0; i < cd->cursor; i++ ) { cd->entry[i]->started = now; - // block the skill from usage but ensure it is not recorded (load = true) - skill->blockpc_start( sd, cd->entry[i]->skill_id, cd->entry[i]->duration, true ); + cd->entry[i]->timer = timer->add(timer->gettick()+cd->entry[i]->duration,skill->blockpc_end,sd->bl.id,cd->entry[i]->skidx); + sd->blockskill[cd->entry[i]->skidx] = true; } } @@ -17611,6 +17906,7 @@ bool skill_parse_row_skilldb(char* split[], int columns, int current) { safestrncpy(skill->db[idx].name, trim(split[15]), sizeof(skill->db[idx].name)); safestrncpy(skill->db[idx].desc, trim(split[16]), sizeof(skill->db[idx].desc)); strdb_iput(skill->name2id_db, skill->db[idx].name, skill_id); + script->set_constant2(skill->db[idx].name,(int)skill_id,0); return true; } @@ -17740,8 +18036,8 @@ bool skill_parse_row_unitdb(char* split[], int columns, int current) { if( !idx ) // invalid skill id return false; - skill->db[idx].unit_id[0] = strtol(split[1],NULL,16); - skill->db[idx].unit_id[1] = strtol(split[2],NULL,16); + skill->db[idx].unit_id[0] = (int)strtol(split[1],NULL,16); + skill->db[idx].unit_id[1] = (int)strtol(split[2],NULL,16); skill->split_atoi(split[3],skill->db[idx].unit_layout_type); skill->split_atoi(split[4],skill->db[idx].unit_range); skill->db[idx].unit_interval = atoi(split[5]); @@ -17756,9 +18052,9 @@ bool skill_parse_row_unitdb(char* split[], int columns, int current) { else if( strcmpi(split[6],"self")==0 ) skill->db[idx].unit_target = BCT_SELF; else if( strcmpi(split[6],"sameguild")==0 ) skill->db[idx].unit_target = BCT_GUILD|BCT_SAMEGUILD; else if( strcmpi(split[6],"noone")==0 ) skill->db[idx].unit_target = BCT_NOONE; - else skill->db[idx].unit_target = strtol(split[6],NULL,16); + else skill->db[idx].unit_target = (int)strtol(split[6],NULL,16); - skill->db[idx].unit_flag = strtol(split[7],NULL,16); + skill->db[idx].unit_flag = (int)strtol(split[7],NULL,16); if (skill->db[idx].unit_flag&UF_DEFNOTENEMY && battle_config.defnotenemy) skill->db[idx].unit_target = BCT_NOENEMY; @@ -17954,7 +18250,7 @@ bool skill_parse_row_changematerialdb(char* split[], int columns, int current) { * create_arrow_db.txt * abra_db.txt *------------------------------*/ -void skill_readdb(void) { +void skill_readdb(bool minimal) { // init skill db structures db_clear(skill->name2id_db); @@ -17976,7 +18272,17 @@ void skill_readdb(void) { safestrncpy(skill->db[0].name, "UNKNOWN_SKILL", sizeof(skill->db[0].name)); safestrncpy(skill->db[0].desc, "Unknown Skill", sizeof(skill->db[0].desc)); +#ifdef ENABLE_CASE_CHECK + script->parser_current_file = DBPATH"skill_db.txt"; +#endif // ENABLE_CASE_CHECK sv->readdb(map->db_path, DBPATH"skill_db.txt", ',', 17, 17, MAX_SKILL_DB, skill->parse_row_skilldb); +#ifdef ENABLE_CASE_CHECK + script->parser_current_file = NULL; +#endif // ENABLE_CASE_CHECK + + if (minimal) + return; + sv->readdb(map->db_path, DBPATH"skill_require_db.txt", ',', 32, 32, MAX_SKILL_DB, skill->parse_row_requiredb); #ifdef RENEWAL_CAST sv->readdb(map->db_path, "re/skill_cast_db.txt", ',', 8, 8, MAX_SKILL_DB, skill->parse_row_castdb); @@ -18004,7 +18310,7 @@ void skill_reload (void) { struct map_session_data *sd; int i,c,k; - skill->read_db(); + skill->read_db(false); //[Ind/Hercules] refresh index cache for(c = 0; c < CLASS_COUNT; c++) { @@ -18030,22 +18336,27 @@ void skill_reload (void) { /*========================================== * *------------------------------------------*/ -int do_init_skill (void) { +int do_init_skill(bool minimal) { skill->name2id_db = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, MAX_SKILL_NAME_LENGTH); - skill->read_db(); + skill->read_db(minimal); + + if (minimal) + return 0; skill->group_db = idb_alloc(DB_OPT_BASE); skill->unit_db = idb_alloc(DB_OPT_BASE); skill->cd_db = idb_alloc(DB_OPT_BASE); skill->usave_db = idb_alloc(DB_OPT_RELEASE_DATA); - skill->unit_ers = ers_new(sizeof(struct skill_unit_group),"skill.c::skill_unit_ers",ERS_OPT_NONE); - skill->timer_ers = ers_new(sizeof(struct skill_timerskill),"skill.c::skill_timer_ers",ERS_OPT_NONE); - skill->cd_ers = ers_new(sizeof(struct skill_cd),"skill.c::skill_cd_ers",ERS_OPT_CLEAR); - skill->cd_entry_ers = ers_new(sizeof(struct skill_cd_entry),"skill.c::skill_cd_entry_ers",ERS_OPT_CLEAR); + skill->unit_ers = ers_new(sizeof(struct skill_unit_group),"skill.c::skill_unit_ers",ERS_OPT_CLEAN|ERS_OPT_FLEX_CHUNK); + skill->timer_ers = ers_new(sizeof(struct skill_timerskill),"skill.c::skill_timer_ers",ERS_OPT_NONE|ERS_OPT_FLEX_CHUNK); + skill->cd_ers = ers_new(sizeof(struct skill_cd),"skill.c::skill_cd_ers",ERS_OPT_CLEAR|ERS_OPT_CLEAN|ERS_OPT_FLEX_CHUNK); + skill->cd_entry_ers = ers_new(sizeof(struct skill_cd_entry),"skill.c::skill_cd_entry_ers",ERS_OPT_CLEAR|ERS_OPT_FLEX_CHUNK); ers_chunk_size(skill->cd_ers, 25); ers_chunk_size(skill->cd_entry_ers, 100); + ers_chunk_size(skill->unit_ers, 150); + ers_chunk_size(skill->timer_ers, 150); timer->add_func_list(skill->unit_timer,"skill_unit_timer"); timer->add_func_list(skill->castend_id,"skill_castend_id"); @@ -18235,7 +18546,7 @@ void skill_defaults(void) { skill->check_condition_mercenary = skill_check_condition_mercenary; skill->locate_element_field = skill_locate_element_field; skill->graffitiremover = skill_graffitiremover; - skill->activate_reverberation = skill_activate_reverbetion; + skill->activate_reverberation = skill_activate_reverberation; skill->dance_overlap = skill_dance_overlap; skill->dance_overlap_sub = skill_dance_overlap_sub; skill->get_unit_layout = skill_get_unit_layout; @@ -18292,6 +18603,6 @@ void skill_defaults(void) { skill->changematerial = skill_changematerial; skill->get_elemental_type = skill_get_elemental_type; skill->cooldown_save = skill_cooldown_save; - skill->maelstrom_suction = skill_maelstrom_suction; skill->get_new_group_id = skill_get_new_group_id; + skill->check_shadowform = skill_check_shadowform; } diff --git a/src/map/skill.h b/src/map/skill.h index 0f89cd3be..13d34d267 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -2,8 +2,8 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _SKILL_H_ -#define _SKILL_H_ +#ifndef _MAP_SKILL_H_ +#define _MAP_SKILL_H_ #include "../common/mmo.h" // MAX_SKILL, struct square #include "../common/db.h" @@ -909,7 +909,14 @@ enum e_skill { NPC_VENOMFOG, NPC_MILLENNIUMSHIELD, NPC_COMET, - + NPC_WIDEWEB, + NPC_WIDESUCK, + NPC_STORMGUST2, + NPC_FIRESTORM, + NPC_REVERBERATION, + NPC_REVERBERATION_ATK, + NPC_LEX_AETERNA, + KN_CHARGEATK = 1001, CR_SHRINK, AS_SONICACCEL, @@ -1271,7 +1278,7 @@ enum e_skill { RL_R_TRIP_PLUSATK, RL_B_FLICKER_ATK, RL_GLITTERING_GREED_ATK, - + KO_YAMIKUMO = 3001, KO_RIGHT, KO_LEFT, @@ -1606,17 +1613,6 @@ enum { UNT_MAX = 0x190 }; -enum gx_poison { - PO_PARALYSE = 12717, - PO_LEECHESEND, - PO_OBLIVIONCURSE, - PO_DEATHHURT, - PO_TOXIN, - PO_PYREXIA, - PO_MAGICMUSHROOM, - PO_VENOMBLEED -}; - /** * Structures **/ @@ -1679,7 +1675,7 @@ struct skill_unit_group { int map; int target_flag; //Holds BCT_* flag for battle_check_target int bl_flag; //Holds BL_* flag for map_foreachin* functions - unsigned int tick; + int64 tick; int limit,interval; uint16 skill_id,skill_lv; @@ -1708,7 +1704,7 @@ struct skill_unit { }; struct skill_unit_group_tickset { - unsigned int tick; + int64 tick; int id; }; @@ -1740,10 +1736,11 @@ struct s_skill_magicmushroom_db { struct skill_cd_entry { int duration;//milliseconds #if PACKETVER >= 20120604 - int total; + int total;/* used for display on newer clients */ #endif short skidx;//the skill index entries belong to - unsigned int started; + int64 started;/* gettick() of when it started, used vs duration to measure how much left upon logout */ + int timer;/* timer id */ uint16 skill_id;//skill id }; @@ -1783,16 +1780,16 @@ struct s_skill_spellbook_db { int point; }; -typedef int (*SkillFunc)(struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, unsigned int tick, int flag); +typedef int (*SkillFunc)(struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int64 tick, int flag); /** * Skill.c Interface **/ struct skill_interface { - int (*init) (void); + int (*init) (bool minimal); int (*final) (void); void (*reload) (void); - void (*read_db) (void); + void (*read_db) (bool minimal); /* */ DBMap* cd_db; // char_id -> struct skill_cd DBMap* name2id_db; @@ -1874,14 +1871,14 @@ struct skill_interface { int (*get_casttype) (uint16 skill_id); int (*get_casttype2) (uint16 index); int (*name2id) (const char* name); - int (*isammotype) (struct map_session_data *sd, int skill); - int (*castend_id) (int tid, unsigned int tick, int id, intptr_t data); - int (*castend_pos) (int tid, unsigned int tick, int id, intptr_t data); + int (*isammotype) (struct map_session_data *sd, int skill_id); + int (*castend_id) (int tid, int64 tick, int id, intptr_t data); + int (*castend_pos) (int tid, int64 tick, int id, intptr_t data); int (*castend_map) ( struct map_session_data *sd,uint16 skill_id, const char *mapname); int (*cleartimerskill) (struct block_list *src); - int (*addtimerskill) (struct block_list *src,unsigned int tick,int target,int x,int y,uint16 skill_id,uint16 skill_lv,int type,int flag); - int (*additional_effect) ( struct block_list* src, struct block_list *bl,uint16 skill_id,uint16 skill_lv,int attack_type,int dmg_lv,unsigned int tick); - int (*counter_additional_effect) ( struct block_list* src, struct block_list *bl,uint16 skill_id,uint16 skill_lv,int attack_type,unsigned int tick); + int (*addtimerskill) (struct block_list *src, int64 tick, int target, int x, int y, uint16 skill_id, uint16 skill_lv, int type, int flag); + int (*additional_effect) (struct block_list* src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int attack_type, int dmg_lv, int64 tick); + int (*counter_additional_effect) (struct block_list* src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int attack_type, int64 tick); int (*blown) (struct block_list* src, struct block_list* target, int count, int8 dir, int flag); int (*break_equip) (struct block_list *bl, unsigned short where, int rate, int flag); int (*strip_equip) (struct block_list *bl, unsigned short where, int rate, int lv, int time); @@ -1893,8 +1890,8 @@ struct skill_interface { int (*del_unitgroup) (struct skill_unit_group *group, const char* file, int line, const char* func); int (*clear_unitgroup) (struct block_list *src); int (*clear_group) (struct block_list *bl, int flag); - int (*unit_onplace) (struct skill_unit *src, struct block_list *bl, unsigned int tick); - int (*unit_ondamaged) (struct skill_unit *src,struct block_list *bl,int64 damage,unsigned int tick); + int (*unit_onplace) (struct skill_unit *src, struct block_list *bl, int64 tick); + int (*unit_ondamaged) (struct skill_unit *src, struct block_list *bl, int64 damage, int64 tick); int (*cast_fix) ( struct block_list *bl, uint16 skill_id, uint16 skill_lv); int (*cast_fix_sc) ( struct block_list *bl, int time); int (*vf_cast_fix) ( struct block_list *bl, double time, uint16 skill_id, uint16 skill_lv); @@ -1904,12 +1901,12 @@ struct skill_interface { int (*consume_requirement) (struct map_session_data *sd, uint16 skill_id, uint16 skill_lv, short type); struct skill_condition (*get_requirement) (struct map_session_data *sd, uint16 skill_id, uint16 skill_lv); int (*check_pc_partner) (struct map_session_data *sd, uint16 skill_id, uint16* skill_lv, int range, int cast_flag); - int (*unit_move) (struct block_list *bl,unsigned int tick,int flag); - int (*unit_onleft) (uint16 skill_id, struct block_list *bl,unsigned int tick); - int (*unit_onout) (struct skill_unit *src, struct block_list *bl, unsigned int tick); + int (*unit_move) (struct block_list *bl, int64 tick, int flag); + int (*unit_onleft) (uint16 skill_id, struct block_list *bl, int64 tick); + int (*unit_onout) (struct skill_unit *src, struct block_list *bl, int64 tick); int (*unit_move_unit_group) ( struct skill_unit_group *group, int16 m,int16 dx,int16 dy); int (*sit) (struct map_session_data *sd, int type); - void (*brandishspear) (struct block_list* src, struct block_list* bl, uint16 skill_id, uint16 skill_lv, unsigned int tick, int flag); + void (*brandishspear) (struct block_list* src, struct block_list* bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag); void (*repairweapon) (struct map_session_data *sd, int idx); void (*identify) (struct map_session_data *sd,int idx); void (*weaponrefine) (struct map_session_data *sd,int idx); @@ -1924,25 +1921,25 @@ struct skill_interface { int (*can_produce_mix) ( struct map_session_data *sd, int nameid, int trigger, int qty); int (*produce_mix) ( struct map_session_data *sd, uint16 skill_id, int nameid, int slot1, int slot2, int slot3, int qty ); int (*arrow_create) ( struct map_session_data *sd,int nameid); - int (*castend_nodamage_id) ( struct block_list *src, struct block_list *bl,uint16 skill_id,uint16 skill_lv,unsigned int tick,int flag ); - int (*castend_damage_id) ( struct block_list* src, struct block_list *bl,uint16 skill_id,uint16 skill_lv,unsigned int tick,int flag ); - int (*castend_pos2) ( struct block_list *src, int x,int y,uint16 skill_id,uint16 skill_lv,unsigned int tick,int flag); - int (*blockpc_start) (struct map_session_data *sd, uint16 skill_id, int tick, bool load); + int (*castend_nodamage_id) (struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag); + int (*castend_damage_id) (struct block_list* src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick,int flag); + int (*castend_pos2) (struct block_list *src, int x, int y, uint16 skill_id, uint16 skill_lv, int64 tick, int flag); + int (*blockpc_start) (struct map_session_data *sd, uint16 skill_id, int tick); int (*blockhomun_start) (struct homun_data *hd, uint16 skill_id, int tick); int (*blockmerc_start) (struct mercenary_data *md, uint16 skill_id, int tick); - int (*attack) ( int attack_type, struct block_list* src, struct block_list *dsrc,struct block_list *bl,uint16 skill_id,uint16 skill_lv,unsigned int tick,int flag ); + int (*attack) (int attack_type, struct block_list* src, struct block_list *dsrc, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag); int (*attack_area) (struct block_list *bl,va_list ap); int (*area_sub) (struct block_list *bl, va_list ap); - int (*area_sub_count) (struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, unsigned int tick, int flag); + int (*area_sub_count) (struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int64 tick, int flag); int (*check_unit_range) (struct block_list *bl, int x, int y, uint16 skill_id, uint16 skill_lv); int (*check_unit_range_sub) (struct block_list *bl, va_list ap); int (*check_unit_range2) (struct block_list *bl, int x, int y, uint16 skill_id, uint16 skill_lv); int (*check_unit_range2_sub) (struct block_list *bl, va_list ap); void (*toggle_magicpower) (struct block_list *bl, uint16 skill_id); int (*magic_reflect) (struct block_list* src, struct block_list* bl, int type); - int (*onskillusage) (struct map_session_data *sd, struct block_list *bl, uint16 skill_id, unsigned int tick); + int (*onskillusage) (struct map_session_data *sd, struct block_list *bl, uint16 skill_id, int64 tick); int (*cell_overlap) (struct block_list *bl, va_list ap); - int (*timerskill) (int tid, unsigned int tick, int id, intptr_t data); + int (*timerskill) (int tid, int64 tick, int id, intptr_t data); int (*trap_splash) (struct block_list *bl, va_list ap); int (*check_condition_mercenary) (struct block_list *bl, int skill_id, int lv, int type); struct skill_unit_group *(*locate_element_field) (struct block_list *bl); @@ -1955,26 +1952,26 @@ struct skill_interface { int (*greed) (struct block_list *bl, va_list ap); int (*destroy_trap) ( struct block_list *bl, va_list ap ); int (*icewall_block) (struct block_list *bl,va_list ap); - struct skill_unit_group_tickset *(*unitgrouptickset_search) (struct block_list *bl, struct skill_unit_group *group, int tick); + struct skill_unit_group_tickset *(*unitgrouptickset_search) (struct block_list *bl, struct skill_unit_group *group, int64 tick); bool (*dance_switch) (struct skill_unit* su, int flag); int (*check_condition_char_sub) (struct block_list *bl, va_list ap); int (*check_condition_mob_master_sub) (struct block_list *bl, va_list ap); void (*brandishspear_first) (struct square *tc, uint8 dir, int16 x, int16 y); void (*brandishspear_dir) (struct square* tc, uint8 dir, int are); - int (*get_fixed_cast) ( uint16 skill_id ,uint16 skill_lv ); + int (*get_fixed_cast) ( uint16 skill_id ,uint16 skill_lv ); int (*sit_count) (struct block_list *bl, va_list ap); int (*sit_in) (struct block_list *bl, va_list ap); int (*sit_out) (struct block_list *bl, va_list ap); void (*unitsetmapcell) (struct skill_unit *src, uint16 skill_id, uint16 skill_lv, cell_t cell, bool flag); - int (*unit_onplace_timer) (struct skill_unit *src, struct block_list *bl, unsigned int tick); + int (*unit_onplace_timer) (struct skill_unit *src, struct block_list *bl, int64 tick); int (*unit_effect) (struct block_list* bl, va_list ap); int (*unit_timer_sub_onplace) (struct block_list* bl, va_list ap); int (*unit_move_sub) (struct block_list* bl, va_list ap); - int (*blockpc_end) (int tid, unsigned int tick, int id, intptr_t data); - int (*blockhomun_end) (int tid, unsigned int tick, int id, intptr_t data); - int (*blockmerc_end) (int tid, unsigned int tick, int id, intptr_t data); + int (*blockpc_end) (int tid, int64 tick, int id, intptr_t data); + int (*blockhomun_end) (int tid, int64 tick, int id, intptr_t data); + int (*blockmerc_end) (int tid, int64 tick, int id, intptr_t data); int (*split_atoi) (char *str, int *val); - int (*unit_timer) (int tid, unsigned int tick, int id, intptr_t data); + int (*unit_timer) (int tid, int64 tick, int id, intptr_t data); int (*unit_timer_sub) (DBKey key, DBData *data, va_list ap); void (*init_unit_layout) (void); bool (*parse_row_skilldb) (char* split[], int columns, int current); @@ -2009,12 +2006,12 @@ struct skill_interface { int (*changematerial) (struct map_session_data *sd, int n, unsigned short *item_list); int (*get_elemental_type) (uint16 skill_id, uint16 skill_lv); void (*cooldown_save) (struct map_session_data * sd); - int (*maelstrom_suction) (struct block_list *bl, va_list ap); int (*get_new_group_id) (void); + bool (*check_shadowform) (struct block_list *bl, int64 damage, int hit); }; struct skill_interface *skill; void skill_defaults(void); -#endif /* _SKILL_H_ */ +#endif /* _MAP_SKILL_H_ */ diff --git a/src/map/status.c b/src/map/status.c index 497d02bbf..f4991cff2 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -96,16 +96,12 @@ int status_type2relevant_bl_types(int type) { if( type < 0 || type >= SI_MAX ) { ShowError("status_type2relevant_bl_types: Unsupported type %d\n", type); - return SI_BLANK; + return BL_NUL; } return status->RelevantBLTypes[type]; } -#define add_sc(skill,sc) set_sc(skill,sc,SI_BLANK,SCB_NONE) -// indicates that the status displays a visual effect for the affected unit, and should be sent to the client for all supported units -#define set_sc_with_vfx(skill, sc, icon, flag) set_sc((skill), (sc), (icon), (flag)); if((icon) < SI_MAX) status->RelevantBLTypes[(icon)] |= BL_SCEFFECT - static void set_sc(uint16 skill_id, sc_type sc, int icon, unsigned int flag) { uint16 idx; if( (idx = skill->get_index(skill_id)) == 0 ) { @@ -128,6 +124,10 @@ static void set_sc(uint16 skill_id, sc_type sc, int icon, unsigned int flag) { } void initChangeTables(void) { +#define add_sc(skill,sc) set_sc((skill),(sc),SI_BLANK,SCB_NONE) +// indicates that the status displays a visual effect for the affected unit, and should be sent to the client for all supported units +#define set_sc_with_vfx(skill, sc, icon, flag) do { set_sc((skill), (sc), (icon), (flag)); if((icon) < SI_MAX) status->RelevantBLTypes[(icon)] |= BL_SCEFFECT; } while(0) + int i; for (i = 0; i < SC_MAX; i++) @@ -593,21 +593,19 @@ void initChangeTables(void) { set_sc( NC_INFRAREDSCAN , SC_INFRAREDSCAN , SI_INFRAREDSCAN , SCB_FLEE ); set_sc( NC_ANALYZE , SC_ANALYZE , SI_ANALYZE , SCB_DEF|SCB_DEF2|SCB_MDEF|SCB_MDEF2 ); set_sc( NC_MAGNETICFIELD , SC_MAGNETICFIELD , SI_MAGNETICFIELD , SCB_NONE ); - set_sc( NC_NEUTRALBARRIER , SC_NEUTRALBARRIER , SI_NEUTRALBARRIER , SCB_NONE ); + set_sc( NC_NEUTRALBARRIER , SC_NEUTRALBARRIER , SI_NEUTRALBARRIER , SCB_DEF|SCB_MDEF ); set_sc( NC_STEALTHFIELD , SC_STEALTHFIELD , SI_STEALTHFIELD , SCB_NONE ); /** * Royal Guard **/ set_sc( LG_REFLECTDAMAGE , SC_LG_REFLECTDAMAGE , SI_LG_REFLECTDAMAGE, SCB_NONE ); - set_sc( LG_FORCEOFVANGUARD , SC_FORCEOFVANGUARD , SI_FORCEOFVANGUARD , SCB_MAXHP|SCB_DEF ); + set_sc( LG_FORCEOFVANGUARD , SC_FORCEOFVANGUARD , SI_FORCEOFVANGUARD , SCB_MAXHP ); set_sc( LG_EXEEDBREAK , SC_EXEEDBREAK , SI_EXEEDBREAK , SCB_NONE ); set_sc( LG_PRESTIGE , SC_PRESTIGE , SI_PRESTIGE , SCB_DEF ); set_sc( LG_BANDING , SC_BANDING , SI_BANDING , SCB_DEF2|SCB_WATK );// Renewal: atk2 & def2 set_sc( LG_PIETY , SC_BENEDICTIO , SI_BENEDICTIO , SCB_DEF_ELE ); set_sc( LG_EARTHDRIVE , SC_EARTHDRIVE , SI_EARTHDRIVE , SCB_DEF|SCB_ASPD ); set_sc( LG_INSPIRATION , SC_INSPIRATION , SI_INSPIRATION , SCB_MAXHP|SCB_WATK|SCB_HIT|SCB_VIT|SCB_AGI|SCB_STR|SCB_DEX|SCB_INT|SCB_LUK); - set_sc( LG_SHIELDSPELL , SC_SHIELDSPELL_DEF , SI_SHIELDSPELL_DEF , SCB_WATK ); - set_sc( LG_SHIELDSPELL , SC_SHIELDSPELL_REF , SI_SHIELDSPELL_REF , SCB_DEF ); set_sc( LG_KINGS_GRACE , SC_KINGS_GRACE , SI_KINGS_GRACE , SCB_NONE ); /** * Shadow Chaser @@ -626,8 +624,10 @@ void initChangeTables(void) { set_sc( SC_WEAKNESS , SC__WEAKNESS , SI_WEAKNESS , SCB_FLEE2|SCB_MAXHP ); set_sc( SC_STRIPACCESSARY , SC__STRIPACCESSARY , SI_STRIPACCESSARY , SCB_DEX|SCB_INT|SCB_LUK ); set_sc_with_vfx( SC_MANHOLE , SC__MANHOLE , SI_MANHOLE , SCB_NONE ); - add_sc( SC_CHAOSPANIC , SC_CONFUSION ); - add_sc( SC_BLOODYLUST , SC_BERSERK ); + add_sc( SC_CHAOSPANIC , SC__CHAOS ); + add_sc( SC_MAELSTROM , SC__MAELSTROM ); + add_sc( SC_BLOODYLUST , SC_BERSERK ); + /** * Sura **/ @@ -646,10 +646,10 @@ void initChangeTables(void) { set_sc( WA_SWING_DANCE , SC_SWING , SI_SWINGDANCE , SCB_SPEED|SCB_ASPD ); set_sc( WA_SYMPHONY_OF_LOVER , SC_SYMPHONY_LOVE , SI_SYMPHONYOFLOVERS , SCB_MDEF ); set_sc( WA_MOONLIT_SERENADE , SC_MOONLIT_SERENADE , SI_MOONLITSERENADE , SCB_MATK ); - set_sc( MI_RUSH_WINDMILL , SC_RUSH_WINDMILL , SI_RUSHWINDMILL , SCB_BATK ); + set_sc( MI_RUSH_WINDMILL , SC_RUSH_WINDMILL , SI_RUSHWINDMILL , SCB_WATK ); set_sc( MI_ECHOSONG , SC_ECHOSONG , SI_ECHOSONG , SCB_DEF2 ); set_sc( MI_HARMONIZE , SC_HARMONIZE , SI_HARMONIZE , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK ); - set_sc_with_vfx( WM_POEMOFNETHERWORLD , SC_NETHERWORLD , SI_NETHERWORLD , SCB_NONE ); + set_sc( WM_POEMOFNETHERWORLD , SC_STOP , SI_NETHERWORLD , SCB_NONE ); set_sc_with_vfx( WM_VOICEOFSIREN , SC_SIREN , SI_SIREN , SCB_NONE ); set_sc_with_vfx( WM_LULLABY_DEEPSLEEP , SC_DEEP_SLEEP , SI_DEEPSLEEP , SCB_NONE ); set_sc( WM_SIRCLEOFNATURE , SC_SIRCLEOFNATURE , SI_SIRCLEOFNATURE , SCB_NONE ); @@ -658,8 +658,8 @@ void initChangeTables(void) { set_sc( WM_DANCE_WITH_WUG , SC_DANCE_WITH_WUG , SI_DANCEWITHWUG , SCB_ASPD ); set_sc( WM_SATURDAY_NIGHT_FEVER , SC_SATURDAY_NIGHT_FEVER , SI_SATURDAYNIGHTFEVER , SCB_BATK|SCB_DEF|SCB_FLEE|SCB_REGEN ); set_sc( WM_LERADS_DEW , SC_LERADS_DEW , SI_LERADSDEW , SCB_MAXHP ); - set_sc( WM_MELODYOFSINK , SC_MELODYOFSINK , SI_MELODYOFSINK , SCB_BATK|SCB_MATK ); - set_sc( WM_BEYOND_OF_WARCRY , SC_BEYOND_OF_WARCRY , SI_WARCRYOFBEYOND , SCB_BATK|SCB_MATK ); + set_sc( WM_MELODYOFSINK , SC_MELODYOFSINK , SI_MELODYOFSINK , SCB_INT ); + set_sc( WM_BEYOND_OF_WARCRY , SC_BEYOND_OF_WARCRY , SI_WARCRYOFBEYOND , SCB_STR|SCB_CRI|SCB_MAXHP ); set_sc( WM_UNLIMITED_HUMMING_VOICE, SC_UNLIMITED_HUMMING_VOICE, SI_UNLIMITEDHUMMINGVOICE, SCB_NONE ); set_sc( WM_FRIGG_SONG , SC_FRIGG_SONG , SI_FRIGG_SONG , SCB_MAXHP ); @@ -670,7 +670,7 @@ void initChangeTables(void) { set_sc( SO_ELECTRICWALK , SC_PROPERTYWALK , SI_PROPERTYWALK , SCB_NONE ); set_sc( SO_SPELLFIST , SC_SPELLFIST , SI_SPELLFIST , SCB_NONE ); set_sc_with_vfx( SO_DIAMONDDUST , SC_COLD , SI_COLD , SCB_NONE ); // it does show the snow icon on mobs but doesn't affect it. - add_sc( SO_CLOUD_KILL , SC_POISON ); + set_sc( SO_CLOUD_KILL , SC_POISON , SI_CLOUDKILL , SCB_NONE ); set_sc( SO_STRIKING , SC_STRIKING , SI_STRIKING , SCB_WATK|SCB_CRI ); set_sc( SO_WARMER , SC_WARMER , SI_WARMER , SCB_NONE ); set_sc( SO_VACUUM_EXTREME , SC_VACUUM_EXTREME , SI_VACUUM_EXTREME , SCB_NONE ); @@ -679,6 +679,7 @@ void initChangeTables(void) { set_sc( SO_WATER_INSIGNIA , SC_WATER_INSIGNIA , SI_WATER_INSIGNIA , SCB_WATK | SCB_ATK_ELE | SCB_REGEN ); set_sc( SO_WIND_INSIGNIA , SC_WIND_INSIGNIA , SI_WIND_INSIGNIA , SCB_WATK | SCB_ATK_ELE | SCB_REGEN ); set_sc( SO_EARTH_INSIGNIA , SC_EARTH_INSIGNIA , SI_EARTH_INSIGNIA , SCB_MDEF|SCB_DEF|SCB_MAXHP|SCB_MAXSP|SCB_WATK | SCB_ATK_ELE | SCB_REGEN ); + add_sc( SO_ELEMENTAL_SHIELD , SC_SAFETYWALL ); /** * Genetic **/ @@ -712,8 +713,8 @@ void initChangeTables(void) { set_sc( EL_BLAST , SC_BLAST_OPTION , SI_BLAST_OPTION , SCB_ASPD ); set_sc( EL_WILD_STORM , SC_WILD_STORM_OPTION , SI_WILD_STORM_OPTION , SCB_ASPD ); set_sc( EL_PETROLOGY , SC_PETROLOGY_OPTION , SI_PETROLOGY_OPTION , SCB_MAXHP ); - set_sc( EL_CURSED_SOIL , SC_CURSED_SOIL_OPTION , SI_CURSED_SOIL_OPTION , SCB_NONE ); - set_sc( EL_UPHEAVAL , SC_UPHEAVAL_OPTION , SI_UPHEAVAL_OPTION , SCB_NONE ); + set_sc( EL_CURSED_SOIL , SC_CURSED_SOIL_OPTION , SI_CURSED_SOIL_OPTION , SCB_MAXHP ); + set_sc( EL_UPHEAVAL , SC_UPHEAVAL_OPTION , SI_UPHEAVAL_OPTION , SCB_MAXHP ); set_sc( EL_TIDAL_WEAPON , SC_TIDAL_WEAPON_OPTION , SI_TIDAL_WEAPON_OPTION , SCB_ALL ); set_sc( EL_ROCK_CRUSHER , SC_ROCK_CRUSHER , SI_ROCK_CRUSHER , SCB_DEF ); set_sc( EL_ROCK_CRUSHER_ATK, SC_ROCK_CRUSHER_ATK , SI_ROCK_CRUSHER_ATK , SCB_SPEED ); @@ -854,8 +855,6 @@ void initChangeTables(void) { status->IconChangeTable[SC_SHIELDSPELL_REF] = SI_SHIELDSPELL_REF; status->IconChangeTable[SC_BANDING_DEFENCE] = SI_BANDING_DEFENCE; - status->IconChangeTable[SC_GLOOMYDAY_SK] = SI_GLOOMYDAY; - status->IconChangeTable[SC_CURSEDCIRCLE_ATKER] = SI_CURSEDCIRCLE_ATKER; status->IconChangeTable[SC_STOMACHACHE] = SI_STOMACHACHE; @@ -906,6 +905,10 @@ void initChangeTables(void) { status->IconChangeTable[SC_REBOUND] = SI_REBOUND; status->IconChangeTable[SC_ALL_RIDING] = SI_ALL_RIDING; status->IconChangeTable[SC_MONSTER_TRANSFORM] = SI_MONSTER_TRANSFORM; + status->IconChangeTable[SC_MOONSTAR] = SI_MOONSTAR; + status->IconChangeTable[SC_SUPER_STAR] = SI_SUPER_STAR; + status->IconChangeTable[SC_STRANGELIGHTS] = SI_STRANGELIGHTS; + status->IconChangeTable[SC_DECORATION_OF_MUSIC] = SI_DECORATION_OF_MUSIC; //Other SC which are not necessarily associated to skills. status->ChangeFlagTable[SC_ATTHASTE_POTION1] = SCB_ASPD; @@ -967,10 +970,17 @@ void initChangeTables(void) { status->ChangeFlagTable[SC_MER_SP] |= SCB_MAXSP; status->ChangeFlagTable[SC_MER_HIT] |= SCB_HIT; // Guillotine Cross Poison Effects - status->ChangeFlagTable[SC_PARALYSE] |= SCB_ASPD|SCB_FLEE|SCB_SPEED; - status->ChangeFlagTable[SC_DEATHHURT] |= SCB_REGEN; + status->ChangeFlagTable[SC_PARALYSE] |= SCB_FLEE|SCB_SPEED|SCB_ASPD; status->ChangeFlagTable[SC_VENOMBLEED] |= SCB_MAXHP; + status->ChangeFlagTable[SC_MAGICMUSHROOM] |= SCB_REGEN; + status->ChangeFlagTable[SC_DEATHHURT] |= SCB_REGEN; + status->ChangeFlagTable[SC_PYREXIA] |= SCB_HIT|SCB_FLEE; status->ChangeFlagTable[SC_OBLIVIONCURSE] |= SCB_REGEN; + // RG status + status->ChangeFlagTable[SC_SHIELDSPELL_DEF] |= SCB_WATK; + status->ChangeFlagTable[SC_SHIELDSPELL_REF] |= SCB_DEF; + // Meca status + status->ChangeFlagTable[SC_STEALTHFIELD_MASTER] |= SCB_SPEED; status->ChangeFlagTable[SC_SAVAGE_STEAK] |= SCB_STR; status->ChangeFlagTable[SC_COCKTAIL_WARG_BLOOD] |= SCB_INT; @@ -991,6 +1001,14 @@ void initChangeTables(void) { status->ChangeFlagTable[SC_ALL_RIDING] = SCB_SPEED; status->ChangeFlagTable[SC_WEDDING] = SCB_SPEED; + status->ChangeFlagTable[SC_MTF_ASPD] = SCB_ASPD|SCB_HIT; + status->ChangeFlagTable[SC_MTF_MATK] = SCB_MATK; + status->ChangeFlagTable[SC_MTF_MLEATKED] |= SCB_ALL; + + status->ChangeFlagTable[SC_MOONSTAR] |= SCB_NONE; + status->ChangeFlagTable[SC_SUPER_STAR] |= SCB_NONE; + status->ChangeFlagTable[SC_STRANGELIGHTS] |= SCB_NONE; + status->ChangeFlagTable[SC_DECORATION_OF_MUSIC] |= SCB_NONE; /* status->DisplayType Table [Ind/Hercules] */ status->DisplayType[SC_ALL_RIDING] = true; @@ -1014,8 +1032,11 @@ void initChangeTables(void) { status->DisplayType[SC_CURSEDCIRCLE_TARGET]= true; status->DisplayType[SC_BLOOD_SUCKER] = true; status->DisplayType[SC__SHADOWFORM] = true; - status->DisplayType[SC__MANHOLE] = true; status->DisplayType[SC_MONSTER_TRANSFORM] = true; + status->DisplayType[SC_MOONSTAR] = true; + status->DisplayType[SC_SUPER_STAR] = true; + status->DisplayType[SC_STRANGELIGHTS] = true; + status->DisplayType[SC_DECORATION_OF_MUSIC] = true; #ifdef RENEWAL_EDP // renewal EDP increases your weapon atk @@ -1024,6 +1045,8 @@ void initChangeTables(void) { if( !battle_config.display_hallucination ) //Disable Hallucination. status->IconChangeTable[SC_ILLUSION] = SI_BLANK; +#undef add_sc +#undef set_sc_with_vfx } void initDummyData(void) @@ -1156,6 +1179,21 @@ int status_damage(struct block_list *src,struct block_list *target,int64 in_hp, if( hp && !(flag&1) ) { if( sc ) { struct status_change_entry *sce; + +#ifdef DEVOTION_REFLECT_DAMAGE + if(src && (sce = sc->data[SC_DEVOTION])) { + struct block_list *d_bl = map->id2bl(sce->val1); + + if(d_bl &&((d_bl->type == BL_MER && ((TBL_MER *)d_bl)->master && ((TBL_MER *)d_bl)->master->bl.id == target->id) + || (d_bl->type == BL_PC && ((TBL_PC *)d_bl)->devotion[sce->val2] == target->id)) && check_distance_bl(target, d_bl, sce->val3)) { + clif->damage(d_bl, d_bl, 0, 0, hp, 0, 0, 0); + status_fix_damage(NULL, d_bl, hp, 0); + return 0; + } + status_change_end(target, SC_DEVOTION, INVALID_TIMER); + } +#endif + if (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE) status_change_end(target, SC_STONE, INVALID_TIMER); status_change_end(target, SC_FREEZE, INVALID_TIMER); @@ -1167,8 +1205,6 @@ int status_damage(struct block_list *src,struct block_list *target,int64 in_hp, status_change_end(target, SC_CLOAKING, INVALID_TIMER); status_change_end(target, SC_CHASEWALK, INVALID_TIMER); status_change_end(target, SC_CAMOUFLAGE, INVALID_TIMER); - status_change_end(target, SC__INVISIBILITY, INVALID_TIMER); - status_change_end(target, SC_DEEP_SLEEP, INVALID_TIMER); if ((sce=sc->data[SC_ENDURE]) && !sce->val4 && !sc->data[SC_LKCONCENTRATION]) { //Endure count is only reduced by non-players on non-gvg maps. //val4 signals infinite endure. [Skotlex] @@ -1200,7 +1236,7 @@ int status_damage(struct block_list *src,struct block_list *target,int64 in_hp, if (sc->data[SC_AUTOBERSERK] && (!sc->data[SC_PROVOKE] || !sc->data[SC_PROVOKE]->val2) && st->hp < st->max_hp>>2) - sc_start4(target,SC_PROVOKE,100,10,1,0,0,0); + sc_start4(src,target,SC_PROVOKE,100,10,1,0,0,0); if (sc->data[SC_BERSERK] && st->hp <= 100) status_change_end(target, SC_BERSERK, INVALID_TIMER); if( sc->data[SC_RAISINGDRAGON] && st->hp <= 1000 ) @@ -1276,7 +1312,7 @@ int status_damage(struct block_list *src,struct block_list *target,int64 in_hp, status->revive(target, sc->data[SC_KAIZEL]->val2, 0); status->change_clear(target,0); clif->skill_nodamage(target,target,ALL_RESURRECTION,1,1); - sc_start(target,status->skill2sc(PR_KYRIE),100,10,time); + sc_start(target,target,status->skill2sc(PR_KYRIE),100,10,time); if( target->type == BL_MOB ) ((TBL_MOB*)target)->state.rebirth = 1; @@ -1406,34 +1442,28 @@ int status_percent_change(struct block_list *src,struct block_list *target,signe st = status->get_status_data(target); - - //It's safe now [MarkZD] - if (hp_rate > 99) - hp = st->hp; - else if (hp_rate > 0) - hp = st->hp>10000? - hp_rate*(st->hp/100): - ((int64)hp_rate*st->hp)/100; - else if (hp_rate < -99) - hp = st->max_hp; - else if (hp_rate < 0) - hp = st->max_hp>10000? - (-hp_rate)*(st->max_hp/100): - ((int64)-hp_rate*st->max_hp)/100; + if (hp_rate > 100) + hp_rate = 100; + else if (hp_rate < -100) + hp_rate = -100; + if (hp_rate > 0) + hp = APPLY_RATE(st->hp, hp_rate); + else + hp = APPLY_RATE(st->max_hp, -hp_rate); if (hp_rate && !hp) hp = 1; if (flag == 2 && hp >= st->hp) hp = st->hp-1; //Must not kill target. - if (sp_rate > 99) - sp = st->sp; - else if (sp_rate > 0) - sp = ((int64)sp_rate*st->sp)/100; - else if (sp_rate < -99) - sp = st->max_sp; - else if (sp_rate < 0) - sp = ((int64)-sp_rate)*st->max_sp/100; + if (sp_rate > 100) + sp_rate = 100; + else if (sp_rate < -100) + sp_rate = -100; + if (sp_rate > 0) + sp = APPLY_RATE(st->sp, sp_rate); + else + sp = APPLY_RATE(st->max_sp, -sp_rate); if (sp_rate && !sp) sp = 1; @@ -1467,8 +1497,8 @@ int status_revive(struct block_list *bl, unsigned char per_hp, unsigned char per if (st == &status->dummy) return 0; //Invalid target. - hp = (int64)st->max_hp * per_hp/100; - sp = (int64)st->max_sp * per_sp/100; + hp = APPLY_RATE(st->max_hp, per_hp); + sp = APPLY_RATE(st->max_sp, per_sp); if(hp > st->max_hp - st->hp) hp = st->max_hp - st->hp; @@ -1495,6 +1525,41 @@ int status_revive(struct block_list *bl, unsigned char per_hp, unsigned char per return 1; } +int status_fixed_revive(struct block_list *bl, unsigned int per_hp, unsigned int per_sp) { + struct status_data *st; + unsigned int hp, sp; + if (!status->isdead(bl)) return 0; + + st = status->get_status_data(bl); + if (st == &status->dummy) + return 0; //Invalid target. + + hp = per_hp; + sp = per_sp; + + if(hp > st->max_hp - st->hp) + hp = st->max_hp - st->hp; + else if (per_hp && !hp) + hp = 1; + + if(sp > st->max_sp - st->sp) + sp = st->max_sp - st->sp; + else if (per_sp && !sp) + sp = 1; + + st->hp += hp; + st->sp += sp; + + if (bl->prev) //Animation only if character is already on a map. + clif->resurrection(bl, 1); + switch (bl->type) { + case BL_PC: pc->revive((TBL_PC*)bl, hp, sp); break; + case BL_MOB: mob->revive((TBL_MOB*)bl, hp); break; + case BL_HOM: homun->revive((TBL_HOM*)bl, hp, sp); break; + } + return 1; +} + /*========================================== * Checks whether the src can use the skill on the target, * taking into account status/option of both source/target. [Skotlex] @@ -1667,7 +1732,6 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin switch(skill_id) {//##TODO## make this a flag in skill_db? // Skills that can be used even under Man Hole effects. case SC_SHADOWFORM: - case SC_STRIPACCESSARY: break; default: return 0; @@ -1694,8 +1758,13 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin return 0; } } - if (sc->option&OPTION_CHASEWALK && skill_id != ST_CHASEWALK) - return 0; + if ( sc->option&OPTION_CHASEWALK ) { + if ( sc->data[SC__INVISIBILITY] ) { + if ( skill_id != 0 && skill_id != SC_INVISIBILITY ) + return 0; + } else if ( skill_id != ST_CHASEWALK ) + return 0; + } if( sc->data[SC_ALL_RIDING] ) return 0;//New mounts can't attack nor use skills in the client; this check makes it cheat-safe [Ind] } @@ -1716,6 +1785,8 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin return 0; if(skill_id == PR_LEXAETERNA && (tsc->data[SC_FREEZE] || (tsc->data[SC_STONE] && tsc->opt1 == OPT1_STONE))) return 0; + if( ( tsc->data[SC_STEALTHFIELD] || tsc->data[SC_CAMOUFLAGE] ) && !(st->mode&(MD_BOSS|MD_DETECTOR)) && flag == 4 ) + return 0; } //If targetting, cloak+hide protect you, otherwise only hiding does. hide_flag = flag?OPTION_HIDE:(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK); @@ -1725,10 +1796,8 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin hide_flag &= ~OPTION_HIDE; else { switch ( skill_id ) { - case LG_OVERBRAND: - case LG_OVERBRAND_BRANDISH: - case LG_OVERBRAND_PLUSATK: - hide_flag &=~ OPTION_CLOAK|OPTION_CHASEWALK; + case MO_ABSORBSPIRITS: // it works when already casted and target suddenly hides. + hide_flag &= ~OPTION_HIDE; break; } } @@ -1740,14 +1809,16 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin bool is_detect = ((st->mode&MD_DETECTOR)?true:false);//god-knows-why gcc doesn't shut up until this happens if (pc_isinvisible(sd)) return 0; - if (tsc->option&hide_flag && !is_boss && - ((sd->special_state.perfect_hiding || !is_detect) || - (tsc->data[SC_CLOAKINGEXCEED] && is_detect))) - return 0; - if( tsc->data[SC_CAMOUFLAGE] && !(is_boss || is_detect) && !skill_id ) - return 0; - if( tsc->data[SC_STEALTHFIELD] && !is_boss ) - return 0; + if( tsc ) { + if (tsc->option&hide_flag && !is_boss && + ((sd->special_state.perfect_hiding || !is_detect) || + (tsc->data[SC_CLOAKINGEXCEED] && is_detect))) + return 0; + if( tsc->data[SC_CAMOUFLAGE] && !(is_boss || is_detect) && (!skill_id || (flag == 0 && src && src->type != BL_PC)) ) + return 0; + if( tsc->data[SC_STEALTHFIELD] && !is_boss ) + return 0; + } } break; case BL_ITEM: //Allow targetting of items to pick'em up (or in the case of mobs, to loot them). @@ -1780,38 +1851,38 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin //Checks whether the source can see and chase target. int status_check_visibility(struct block_list *src, struct block_list *target) { int view_range; - struct status_data *st = status->get_status_data(src); - struct status_change *tsc = status->get_sc(target); + struct status_change *tsc = NULL; + switch (src->type) { - case BL_MOB: - view_range = ((TBL_MOB*)src)->min_chase; - break; - case BL_PET: - view_range = ((TBL_PET*)src)->db->range2; - break; - default: - view_range = AREA_SIZE; + case BL_MOB: + view_range = ((TBL_MOB*)src)->min_chase; + break; + case BL_PET: + view_range = ((TBL_PET*)src)->db->range2; + break; + default: + view_range = AREA_SIZE; } if (src->m != target->m || !check_distance_bl(src, target, view_range)) return 0; - if( tsc && tsc->data[SC_STEALTHFIELD] ) - return 0; + if( ( tsc = status->get_sc(target) ) ) { + struct status_data *st = status->get_status_data(src); - switch (target->type) - { //Check for chase-walk/hiding/cloaking opponents. - case BL_PC: - if ( tsc->data[SC_CLOAKINGEXCEED] && !(st->mode&MD_BOSS) ) - return 0; - if( (tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) || tsc->data[SC__INVISIBILITY] || tsc->data[SC_CAMOUFLAGE]) && !(st->mode&MD_BOSS) && - ( ((TBL_PC*)target)->special_state.perfect_hiding || !(st->mode&MD_DETECTOR) ) ) - return 0; - break; - default: - if( tsc && (tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) || tsc->data[SC__INVISIBILITY] || tsc->data[SC_CAMOUFLAGE]) && !(st->mode&(MD_BOSS|MD_DETECTOR)) ) - return 0; + switch (target->type) { //Check for chase-walk/hiding/cloaking opponents. + case BL_PC: + if ( tsc->data[SC_CLOAKINGEXCEED] && !(st->mode&MD_BOSS) ) + return 0; + if( (tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) || tsc->data[SC_STEALTHFIELD] || tsc->data[SC__INVISIBILITY] || tsc->data[SC_CAMOUFLAGE]) && !(st->mode&MD_BOSS) && + ( ((TBL_PC*)target)->special_state.perfect_hiding || !(st->mode&MD_DETECTOR) ) ) + return 0; + break; + default: + if( (tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) || tsc->data[SC_CAMOUFLAGE]) && !(st->mode&(MD_BOSS|MD_DETECTOR)) ) + return 0; + } } return 1; @@ -1824,11 +1895,11 @@ int status_base_amotion_pc(struct map_session_data *sd, struct status_data *st) short mod = -1; switch( sd->weapontype2 ){ // adjustment for dual weilding - case W_DAGGER: mod = 0; break; // 0, 1, 1 - case W_1HSWORD: - case W_1HAXE: mod = 1; - if( (sd->class_&MAPID_THIRDMASK) == MAPID_GUILLOTINE_CROSS ) // 0, 2, 3 - mod = sd->weapontype2 / W_1HSWORD + W_1HSWORD / sd->weapontype2 ; + case W_DAGGER: mod = 0; break; // 0, 1, 1 + case W_1HSWORD: + case W_1HAXE: mod = 1; + if( (sd->class_&MAPID_THIRDMASK) == MAPID_GUILLOTINE_CROSS ) // 0, 2, 3 + mod = sd->weapontype2 / W_1HSWORD + W_1HSWORD / sd->weapontype2 ; } amotion = ( sd->status.weapon < MAX_WEAPON_TYPE && mod < 0 ) @@ -1851,9 +1922,14 @@ int status_base_amotion_pc(struct map_session_data *sd, struct status_data *st) // percentual delay reduction from stats amotion -= amotion * (4*st->agi + st->dex)/1000; #endif + // raw delay adjustment from bAspd bonus amotion += sd->bonus.aspd_add; + /* angra manyu disregards aspd_base and similar */ + if( sd->equip_index[EQI_HAND_R] >= 0 && sd->status.inventory[sd->equip_index[EQI_HAND_R]].nameid == ITEMID_ANGRA_MANYU ) + return 0; + return amotion; } @@ -1989,13 +2065,12 @@ void status_calc_misc(struct block_list *bl, struct status_data *st, int level) //Skotlex: Calculates the initial status for the given mob //first will only be false when the mob leveled up or got a GuardUp level. -int status_calc_mob_(struct mob_data* md, bool first) { +int status_calc_mob_(struct mob_data* md, enum e_status_calc_opt opt) { struct status_data *mstatus; struct block_list *mbl = NULL; int flag=0; - if(first) - { //Set basic level on respawn. + if(opt&SCO_FIRST) { //Set basic level on respawn. if (md->level > 0 && md->level <= MAX_LEVEL && md->level != md->db->lv) ; else @@ -2011,8 +2086,6 @@ int status_calc_mob_(struct mob_data* md, bool first) { if (md->guardian_data && md->guardian_data->guardup_lv) flag|=4; - if (md->class_ == MOBID_EMPERIUM) - flag|=4; if (battle_config.slaves_inherit_speed && md->master_id) flag|=8; @@ -2026,7 +2099,7 @@ int status_calc_mob_(struct mob_data* md, bool first) { aFree(md->base_status); md->base_status = NULL; } - if(first) + if(opt&SCO_FIRST) memcpy(&md->status, &md->db->status, sizeof(struct status_data)); return 0; } @@ -2040,12 +2113,13 @@ int status_calc_mob_(struct mob_data* md, bool first) { mbl = map->id2bl(md->master_id); if (flag&8 && mbl) { - struct status_data *mstatus = status->get_base_status(mbl); - if (mstatus && - battle_config.slaves_inherit_speed&(mstatus->mode&MD_CANMOVE?1:2)) - mstatus->speed = mstatus->speed; - if( mstatus->speed < 2 ) /* minimum for the unit to function properly */ - mstatus->speed = 2; + struct status_data *masterstatus = status->get_base_status(mbl); + if ( masterstatus ) { + if (battle_config.slaves_inherit_speed&(masterstatus->mode&MD_CANMOVE ? 1 : 2)) + mstatus->speed = masterstatus->speed; + if (mstatus->speed < 2) /* minimum for the unit to function properly */ + mstatus->speed = 2; + } } if (flag&16 && mbl) { @@ -2065,6 +2139,8 @@ int status_calc_mob_(struct mob_data* md, bool first) { mstatus->mode|= MD_CANATTACK|MD_AGGRESSIVE; } mstatus->hp = mstatus->max_hp; + if( ud->skill_id == NC_SILVERSNIPER ) + mstatus->rhw.atk = mstatus->rhw.atk2 = 200 * ud->skill_lv; } } @@ -2087,7 +2163,7 @@ int status_calc_mob_(struct mob_data* md, bool first) { if (flag&2 && battle_config.mob_size_influence) { // change for sized monsters [Valaris] - if (md->special_state.size==SZ_MEDIUM) { + if (md->special_state.size==SZ_SMALL) { mstatus->max_hp>>=1; mstatus->max_sp>>=1; if (!mstatus->max_hp) mstatus->max_hp = 1; @@ -2150,18 +2226,18 @@ int status_calc_mob_(struct mob_data* md, bool first) { } } - if( first ) //Initial battle status + if( opt&SCO_FIRST ) //Initial battle status memcpy(&md->status, mstatus, sizeof(struct status_data)); return 1; } //Skotlex: Calculates the stats of the given pet. -int status_calc_pet_(struct pet_data *pd, bool first) +int status_calc_pet_(struct pet_data *pd, enum e_status_calc_opt opt) { nullpo_ret(pd); - if (first) { + if (opt&SCO_FIRST) { memcpy(&pd->status, &pd->db->status, sizeof(struct status_data)); pd->status.mode = MD_CANMOVE; // pets discard all modes, except walking pd->status.speed = pd->petDB->speed; @@ -2179,10 +2255,10 @@ int status_calc_pet_(struct pet_data *pd, bool first) lv =sd->status.base_level*battle_config.pet_lv_rate/100; if (lv < 0) lv = 1; - if (lv != pd->pet.level || first) { + if (lv != pd->pet.level || opt&SCO_FIRST) { struct status_data *bstat = &pd->db->status, *pstatus = &pd->status; pd->pet.level = lv; - if (!first) //Lv Up animation + if (! (opt&SCO_FIRST) ) //Lv Up animation clif->misceffect(&pd->bl, 0); pstatus->rhw.atk = (bstat->rhw.atk*lv)/pd->db->lv; pstatus->rhw.atk2 = (bstat->rhw.atk2*lv)/pd->db->lv; @@ -2204,10 +2280,10 @@ int status_calc_pet_(struct pet_data *pd, bool first) status->calc_misc(&pd->bl, &pd->status, lv); - if (!first) //Not done the first time because the pet is not visible yet + if (! (opt&SCO_FIRST) ) //Not done the first time because the pet is not visible yet clif->send_petstatus(sd); } - } else if (first) { + } else if ( opt&SCO_FIRST ) { status->calc_misc(&pd->bl, &pd->status, pd->db->lv); if (!battle_config.pet_lv_rate && pd->pet.level != pd->db->lv) pd->pet.level = pd->db->lv; @@ -2285,7 +2361,7 @@ unsigned int status_base_pc_maxsp(struct map_session_data* sd, struct status_dat //Calculates player data from scratch without counting SC adjustments. //Should be invoked whenever players raise stats, learn passive skills or change equipment. -int status_calc_pc_(struct map_session_data* sd, bool first) { +int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) { static int calculating = 0; //Check for recursive call preemption. [Skotlex] struct status_data *bstatus; // pointer to the player's base status const struct status_change *sc = &sd->sc; @@ -2307,7 +2383,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first) { sd->max_weight = status->max_weight_base[pc->class2idx(sd->status.class_)]+sd->status.str*300; - if(first) { + if(opt&SCO_FIRST) { //Load Hp/SP from char-received data. sd->battle_status.hp = sd->status.hp; sd->battle_status.sp = sd->status.sp; @@ -2379,21 +2455,27 @@ int status_calc_pc_(struct map_session_data* sd, bool first) { clif->sc_end(&sd->bl,sd->bl.id,SELF,SI_CLAIRVOYANCE); memset(&sd->special_state,0,sizeof(sd->special_state)); - memset(&bstatus->max_hp, 0, sizeof(struct status_data)-(sizeof(bstatus->hp)+sizeof(bstatus->sp))); - - //FIXME: Most of these stuff should be calculated once, but how do I fix the memset above to do that? [Skotlex] - if (!sd->state.permanent_speed) + + if (!sd->state.permanent_speed) { + memset(&bstatus->max_hp, 0, sizeof(struct status_data)-(sizeof(bstatus->hp)+sizeof(bstatus->sp))); bstatus->speed = DEFAULT_WALK_SPEED; + } else { + int pSpeed = bstatus->speed; + memset(&bstatus->max_hp, 0, sizeof(struct status_data)-(sizeof(bstatus->hp)+sizeof(bstatus->sp))); + bstatus->speed = pSpeed; + } + + //FIXME: Most of these stuff should be calculated once, but how do I fix the memset above to do that? [Skotlex] //Give them all modes except these (useful for clones) bstatus->mode = MD_MASK&~(MD_BOSS|MD_PLANT|MD_DETECTOR|MD_ANGRY|MD_TARGETWEAK); - bstatus->size = (sd->class_&JOBL_BABY)?SZ_SMALL:SZ_MEDIUM; + bstatus->size = (sd->class_&JOBL_BABY)?SZ_MEDIUM:SZ_SMALL; if (battle_config.character_size && (pc_isriding(sd) || pc_isridingdragon(sd)) ) { //[Lupus] if (sd->class_&JOBL_BABY) { if (battle_config.character_size&SZ_BIG) bstatus->size++; } else - if(battle_config.character_size&SZ_MEDIUM) + if(battle_config.character_size&SZ_SMALL) bstatus->size++; } bstatus->aspd_rate = 1000; @@ -2438,10 +2520,11 @@ int status_calc_pc_(struct map_session_data* sd, bool first) { pc->delautobonus(sd,sd->autobonus3,ARRAYLENGTH(sd->autobonus3),true); // Parse equipment. - for(i=0;i<EQI_MAX-1;i++) { + for(i=0;i<EQI_MAX;i++) { status->current_equip_item_index = index = sd->equip_index[i]; //We pass INDEX to status->current_equip_item_index - for EQUIP_SCRIPT (new cards solution) [Lupus] if(index < 0) continue; + if(i == EQI_AMMO) continue;/* ammo has special handler down there */ if(i == EQI_HAND_R && sd->equip_index[EQI_HAND_L] == index) continue; if(i == EQI_HEAD_MID && sd->equip_index[EQI_HEAD_LOW] == index) @@ -2466,7 +2549,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first) { bstatus->def += sd->inventory_data[index]->def; - if(first && sd->inventory_data[index]->equip_script) + if(opt&SCO_FIRST && sd->inventory_data[index]->equip_script) { //Execute equip-script on login script->run(sd->inventory_data[index]->equip_script,0,sd->bl.id,0); if (!calculating) @@ -2558,12 +2641,29 @@ int status_calc_pc_(struct map_session_data* sd, bool first) { } /* we've got combos to process */ - if( sd->combos.count ) { - for( i = 0; i < sd->combos.count; i++ ) { - script->run(sd->combos.bonus[i],0,sd->bl.id,0); - if (!calculating) //Abort, script->run retriggered this. - return 1; + for( i = 0; i < sd->combo_count; i++ ) { + struct item_combo *combo = itemdb->id2combo(sd->combos[i].id); + unsigned char j; + + /** + * ensure combo usage is allowed at this location + **/ + for(j = 0; j < combo->count; j++) { + for(k = 0; k < map->list[sd->bl.m].zone->disabled_items_count; k++) { + if( map->list[sd->bl.m].zone->disabled_items[k] == combo->nameid[j] ) { + break; + } + } + if( k != map->list[sd->bl.m].zone->disabled_items_count ) + break; } + + if( j != combo->count ) + continue; + + script->run(sd->combos[i].bonus,0,sd->bl.id,0); + if (!calculating) //Abort, script->run retriggered this. + return 1; } //Store equipment script bonuses @@ -2573,10 +2673,11 @@ int status_calc_pc_(struct map_session_data* sd, bool first) { bstatus->def += (refinedef+50)/100; //Parse Cards - for(i=0;i<EQI_MAX-1;i++) { + for(i=0;i<EQI_MAX;i++) { status->current_equip_item_index = index = sd->equip_index[i]; //We pass INDEX to status->current_equip_item_index - for EQUIP_SCRIPT (new cards solution) [Lupus] if(index < 0) continue; + if(i == EQI_AMMO) continue;/* ammo doesn't have cards */ if(i == EQI_HAND_R && sd->equip_index[EQI_HAND_L] == index) continue; if(i == EQI_HEAD_MID && sd->equip_index[EQI_HEAD_LOW] == index) @@ -2609,7 +2710,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first) { if( k < map->list[sd->bl.m].zone->disabled_items_count ) continue; - if(first && data->equip_script) {//Execute equip-script on login + if(opt&SCO_FIRST && data->equip_script) {//Execute equip-script on login script->run(data->equip_script,0,sd->bl.id,0); if (!calculating) return 1; @@ -2750,9 +2851,9 @@ int status_calc_pc_(struct map_session_data* sd, bool first) { if(sd->hprate < 0) sd->hprate = 0; if(sd->hprate!=100) - bstatus->max_hp = (int64)bstatus->max_hp * sd->hprate/100; + bstatus->max_hp = APPLY_RATE(bstatus->max_hp, sd->hprate); if(battle_config.hp_rate != 100) - bstatus->max_hp = (int64)bstatus->max_hp * battle_config.hp_rate/100; + bstatus->max_hp = APPLY_RATE(bstatus->max_hp, battle_config.hp_rate); if(bstatus->max_hp > (unsigned int)battle_config.max_hp) bstatus->max_hp = battle_config.max_hp; @@ -2784,9 +2885,9 @@ int status_calc_pc_(struct map_session_data* sd, bool first) { if(sd->sprate < 0) sd->sprate = 0; if(sd->sprate!=100) - bstatus->max_sp = (int64)bstatus->max_sp * sd->sprate/100; + bstatus->max_sp = APPLY_RATE(bstatus->max_sp, sd->sprate); if(battle_config.sp_rate != 100) - bstatus->max_sp = (int64)bstatus->max_sp * battle_config.sp_rate/100; + bstatus->max_sp = APPLY_RATE(bstatus->max_sp, battle_config.sp_rate); if(bstatus->max_sp > (unsigned int)battle_config.max_sp) bstatus->max_sp = battle_config.max_sp; @@ -2805,11 +2906,11 @@ int status_calc_pc_(struct map_session_data* sd, bool first) { && battle_config.restart_hp_rate < 50) bstatus->hp = bstatus->max_hp>>1; else - bstatus->hp = (int64)bstatus->max_hp * battle_config.restart_hp_rate/100; + bstatus->hp = APPLY_RATE(bstatus->max_hp, battle_config.restart_hp_rate); if(!bstatus->hp) bstatus->hp = 1; - bstatus->sp = (int64)bstatus->max_sp * battle_config.restart_sp_rate /100; + bstatus->sp = APPLY_RATE(bstatus->max_sp, battle_config.restart_sp_rate); if( !bstatus->sp ) /* the minimum for the respawn setting is SP:1 */ bstatus->sp = 1; @@ -2879,6 +2980,10 @@ int status_calc_pc_(struct map_session_data* sd, bool first) { bstatus->rhw.range += skill_lv; } } + if( (sd->status.weapon == W_1HAXE || sd->status.weapon == W_2HAXE) && (skill_lv = pc->checkskill(sd,NC_TRAININGAXE)) > 0 ) + bstatus->hit += 3*skill_lv; + if((sd->status.weapon == W_MACE || sd->status.weapon == W_2HMACE) && ((skill_lv = pc->checkskill(sd,NC_TRAININGAXE)) > 0)) + bstatus->hit += 2*skill_lv; // ----- FLEE CALCULATION ----- @@ -2897,6 +3002,9 @@ int status_calc_pc_(struct map_session_data* sd, bool first) { bstatus->def = cap_value(i, DEFTYPE_MIN, DEFTYPE_MAX); } + if( pc_ismadogear(sd) && (skill_lv = pc->checkskill(sd,NC_MAINFRAME)) > 0 ) + bstatus->def += 20 + 20 * skill_lv; + #ifndef RENEWAL if (!battle_config.weapon_defense_type && bstatus->def > battle_config.max_def) { bstatus->def2 += battle_config.over_def_bonus*(bstatus->def -battle_config.max_def); @@ -3030,6 +3138,17 @@ int status_calc_pc_(struct map_session_data* sd, bool first) { sd->subrace[RC_DRAGON]+=skill_lv; } + if( (skill_lv = pc->checkskill(sd, AB_EUCHARISTICA)) > 0 ) { + sd->right_weapon.addrace[RC_DEMON] += skill_lv; + sd->right_weapon.addele[ELE_DARK] += skill_lv; + sd->left_weapon.addrace[RC_DEMON] += skill_lv; + sd->left_weapon.addele[ELE_DARK] += skill_lv; + sd->magic_addrace[RC_DEMON] += skill_lv; + sd->magic_addele[ELE_DARK] += skill_lv; + sd->subrace[RC_DEMON] += skill_lv; + sd->subele[ELE_DARK] += skill_lv; + } + if(sc->count) { if(sc->data[SC_CONCENTRATION]) { //Update the card-bonus data sc->data[SC_CONCENTRATION]->val3 = sd->param_bonus[1]; //Agi @@ -3083,6 +3202,8 @@ int status_calc_pc_(struct map_session_data* sd, bool first) { sd->subele[ELE_EARTH] += i; sd->subele[ELE_FIRE] -= i; } + if( sc->data[SC_MTF_MLEATKED] ) + sd->subele[ELE_NEUTRAL] += 2; if( sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 3 ) sd->magic_addele[ELE_FIRE] += 25; if( sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 3 ) @@ -3117,11 +3238,11 @@ int status_calc_pc_(struct map_session_data* sd, bool first) { return 0; } -int status_calc_mercenary_(struct mercenary_data *md, bool first) { +int status_calc_mercenary_(struct mercenary_data *md, enum e_status_calc_opt opt) { struct status_data *mstatus = &md->base_status; struct s_mercenary *merc = &md->mercenary; - if( first ) { + if( opt&SCO_FIRST ) { memcpy(mstatus, &md->db->status, sizeof(struct status_data)); mstatus->mode = MD_CANMOVE|MD_CANATTACK; mstatus->hp = mstatus->max_hp; @@ -3136,7 +3257,7 @@ int status_calc_mercenary_(struct mercenary_data *md, bool first) { return 0; } -int status_calc_homunculus_(struct homun_data *hd, bool first) { +int status_calc_homunculus_(struct homun_data *hd, enum e_status_calc_opt opt) { struct status_data *hstatus = &hd->base_status; struct s_homunculus *hom = &hd->homunculus; int skill_lv; @@ -3149,7 +3270,7 @@ int status_calc_homunculus_(struct homun_data *hd, bool first) { hstatus->int_ = hom->int_ / 10; hstatus->luk = hom->luk / 10; - if (first) { //[orn] + if ( opt&SCO_FIRST ) { //[orn] const struct s_homunculus_db *db = hd->homunculusDB; hstatus->def_ele = db->element; hstatus->ele_lv = 1; @@ -3189,7 +3310,7 @@ int status_calc_homunculus_(struct homun_data *hd, bool first) { if((skill_lv = homun->checkskill(hd,HLIF_BRAIN)) > 0) hstatus->max_sp += (1 +skill_lv/2 -skill_lv/4 +skill_lv/5) * hstatus->max_sp / 100; - if (first) { + if ( opt&SCO_FIRST ) { hd->battle_status.hp = hom->hp; hd->battle_status.sp = hom->sp; } @@ -3213,7 +3334,7 @@ int status_calc_homunculus_(struct homun_data *hd, bool first) { return 1; } -int status_calc_elemental_(struct elemental_data *ed, bool first) { +int status_calc_elemental_(struct elemental_data *ed, enum e_status_calc_opt opt) { struct status_data *estatus = &ed->base_status; struct s_elemental *ele = &ed->elemental; struct map_session_data *sd = ed->master; @@ -3221,7 +3342,7 @@ int status_calc_elemental_(struct elemental_data *ed, bool first) { if( !sd ) return 0; - if( first ) { + if( opt&SCO_FIRST ) { memcpy(estatus, &ed->db->status, sizeof(struct status_data)); if( !ele->mode ) estatus->mode = EL_MODE_PASSIVE; @@ -3252,13 +3373,13 @@ int status_calc_elemental_(struct elemental_data *ed, bool first) { return 0; } -int status_calc_npc_(struct npc_data *nd, bool first) { +int status_calc_npc_(struct npc_data *nd, enum e_status_calc_opt opt) { struct status_data *nstatus = &nd->status; if (!nd) return 0; - if (first) { + if ( opt&SCO_FIRST ) { nstatus->hp = 1; nstatus->sp = 1; nstatus->max_hp = 1; @@ -3334,7 +3455,7 @@ void status_calc_regen(struct block_list *bl, struct status_data *st, struct reg if( (skill_lv=pc->checkskill(sd,NJ_NINPOU)) > 0 ) val += skill_lv*3 + skill_lv*st->max_sp/500; if( (skill_lv=pc->checkskill(sd,WM_LESSON)) > 0 ) - val += 3 + 3 * skill_lv; + val += skill_lv*3 + skill_lv*st->max_sp/500; sregen->sp = cap_value(val, 0, SHRT_MAX); @@ -3415,50 +3536,43 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str if (!sc || !sc->count) return; - if ( - (sc->data[SC_POISON] && !sc->data[SC_SLOWPOISON]) - || (sc->data[SC_DPOISON] && !sc->data[SC_SLOWPOISON]) - || sc->data[SC_BERSERK] - || sc->data[SC_TRICKDEAD] - || sc->data[SC_BLOODING] - || sc->data[SC_MAGICMUSHROOM] - || sc->data[SC_RAISINGDRAGON] - || sc->data[SC_SATURDAY_NIGHT_FEVER] + if ((sc->data[SC_POISON] && !sc->data[SC_SLOWPOISON]) + || (sc->data[SC_DPOISON] && !sc->data[SC_SLOWPOISON]) + || sc->data[SC_BERSERK] + || sc->data[SC_TRICKDEAD] + || sc->data[SC_BLOODING] + || sc->data[SC_MAGICMUSHROOM] + || sc->data[SC_RAISINGDRAGON] + || sc->data[SC_SATURDAY_NIGHT_FEVER] ) //No regen regen->flag = 0; - if ( - sc->data[SC_DANCING] || sc->data[SC_OBLIVIONCURSE] || sc->data[SC_MAXIMIZEPOWER] || sc->data[SC_REBOUND] - || ( - (bl->type == BL_PC && ((TBL_PC*)bl)->class_&MAPID_UPPERMASK) == MAPID_MONK && - (sc->data[SC_EXTREMITYFIST] || (sc->data[SC_EXPLOSIONSPIRITS] && (!sc->data[SC_SOULLINK] || sc->data[SC_SOULLINK]->val2 != SL_MONK))) - ) - ) //No natural SP regen - regen->flag &=~RGN_SP; - - if( - sc->data[SC_TENSIONRELAX] + if ( sc->data[SC_DANCING] || sc->data[SC_OBLIVIONCURSE] || sc->data[SC_MAXIMIZEPOWER] || sc->data[SC_REBOUND] + || ( bl->type == BL_PC && (((TBL_PC*)bl)->class_&MAPID_UPPERMASK) == MAPID_MONK + && (sc->data[SC_EXTREMITYFIST] || (sc->data[SC_EXPLOSIONSPIRITS] && (!sc->data[SC_SOULLINK] || sc->data[SC_SOULLINK]->val2 != SL_MONK))) + ) ) { + regen->flag &=~RGN_SP; //No natural SP regen + } + + if (sc->data[SC_TENSIONRELAX]) { regen->rate.hp += 2; if (regen->sregen) regen->sregen->rate.hp += 3; } - if (sc->data[SC_MAGNIFICAT]) - { + if (sc->data[SC_MAGNIFICAT]) { regen->rate.hp += 1; regen->rate.sp += 1; } - if (sc->data[SC_GDSKILL_REGENERATION]) - { + if (sc->data[SC_GDSKILL_REGENERATION]) { const struct status_change_entry *sce = sc->data[SC_GDSKILL_REGENERATION]; - if (!sce->val4) - { + if (!sce->val4) { regen->rate.hp += sce->val2; regen->rate.sp += sce->val3; } else regen->flag&=~sce->val4; //Remove regen as specified by val4 } - if(sc->data[SC_GENTLETOUCH_REVITALIZE]){ + if(sc->data[SC_GENTLETOUCH_REVITALIZE]) { regen->hp = cap_value(regen->hp*sc->data[SC_GENTLETOUCH_REVITALIZE]->val3/100, 1, SHRT_MAX); regen->state.walk= 1; } @@ -3467,7 +3581,12 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str || (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 1) || (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 1)) regen->rate.hp *= 2; - + if( sc->data[SC_VITALITYACTIVATION] ) + regen->flag &=~RGN_SP; + if(sc->data[SC_EXTRACT_WHITE_POTION_Z]) + regen->rate.hp += regen->rate.hp * sc->data[SC_EXTRACT_WHITE_POTION_Z]->val1/100; + if(sc->data[SC_VITATA_500]) + regen->rate.sp += regen->rate.sp * sc->data[SC_VITATA_500]->val1/100; } /// Recalculates parts of an object's battle status according to the specified flags. /// @param flag bitfield of values from enum scb_flag @@ -3658,6 +3777,7 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) { if(flag&SCB_SPEED) { struct unit_data *ud = unit->bl2ud(bl); + st->speed = status->calc_speed(bl, sc, bst->speed); //Re-walk to adjust speed (we do not check if walktimer != INVALID_TIMER @@ -3666,13 +3786,11 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) { if (ud) ud->state.change_walk_target = ud->state.speed_changed = 1; - if( bl->type&BL_PC && st->speed < battle_config.max_walk_speed ) + if( bl->type&BL_PC && !(sd && sd->state.permanent_speed) && st->speed < battle_config.max_walk_speed ) st->speed = battle_config.max_walk_speed; if( bl->type&BL_HOM && battle_config.hom_setting&0x8 && ((TBL_HOM*)bl)->master) st->speed = status->get_speed(&((TBL_HOM*)bl)->master->bl); - - } if(flag&SCB_CRI && bst->cri) { @@ -3846,13 +3964,17 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) { /// Also sends updates to the client wherever applicable. /// @param flag bitfield of values from enum scb_flag /// @param first if true, will cause status_calc_* functions to run their base status initialization code -void status_calc_bl_(struct block_list *bl, enum scb_flag flag, bool first) { +void status_calc_bl_(struct block_list *bl, enum scb_flag flag, enum e_status_calc_opt opt) { struct status_data bst; // previous battle status struct status_data *st; // pointer to current battle status if( bl->type == BL_PC && ((TBL_PC*)bl)->delayed_damage != 0 ) { - ((TBL_PC*)bl)->state.hold_recalc = 1; - return; + if( opt&SCO_FORCE ) + ((TBL_PC*)bl)->state.hold_recalc = 0;/* clear and move on */ + else { + ((TBL_PC*)bl)->state.hold_recalc = 1;/* flag and stop */ + return; + } } // remember previous values @@ -3861,25 +3983,25 @@ void status_calc_bl_(struct block_list *bl, enum scb_flag flag, bool first) { if( flag&SCB_BASE ) {// calculate the object's base status too switch( bl->type ) { - case BL_PC: status->calc_pc_(BL_CAST(BL_PC,bl), first); break; - case BL_MOB: status->calc_mob_(BL_CAST(BL_MOB,bl), first); break; - case BL_PET: status->calc_pet_(BL_CAST(BL_PET,bl), first); break; - case BL_HOM: status->calc_homunculus_(BL_CAST(BL_HOM,bl), first); break; - case BL_MER: status->calc_mercenary_(BL_CAST(BL_MER,bl), first); break; - case BL_ELEM: status->calc_elemental_(BL_CAST(BL_ELEM,bl), first); break; - case BL_NPC: status->calc_npc_(BL_CAST(BL_NPC,bl), first); break; + case BL_PC: status->calc_pc_(BL_CAST(BL_PC,bl), opt); break; + case BL_MOB: status->calc_mob_(BL_CAST(BL_MOB,bl), opt); break; + case BL_PET: status->calc_pet_(BL_CAST(BL_PET,bl), opt); break; + case BL_HOM: status->calc_homunculus_(BL_CAST(BL_HOM,bl), opt); break; + case BL_MER: status->calc_mercenary_(BL_CAST(BL_MER,bl), opt); break; + case BL_ELEM: status->calc_elemental_(BL_CAST(BL_ELEM,bl), opt); break; + case BL_NPC: status->calc_npc_(BL_CAST(BL_NPC,bl), opt); break; } } if( bl->type == BL_PET ) return; // pets are not affected by statuses - if( first && bl->type == BL_MOB ) + if( opt&SCO_FIRST && bl->type == BL_MOB ) return; // assume there will be no statuses active status->calc_bl_main(bl, flag); - if( first && bl->type == BL_HOM ) + if( opt&SCO_FIRST && bl->type == BL_HOM ) return; // client update handled by caller // compare against new values and send client updates @@ -4029,6 +4151,8 @@ unsigned short status_calc_str(struct block_list *bl, struct status_change *sc, str -= sc->data[SC_HARMONIZE]->val2; return (unsigned short)cap_value(str,0,USHRT_MAX); } + if(sc->data[SC_BEYOND_OF_WARCRY]) + str += sc->data[SC_BEYOND_OF_WARCRY]->val3; if(sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_HIGH && str < 50) return 50; if(sc->data[SC_INCALLSTATUS]) @@ -4192,6 +4316,8 @@ unsigned short status_calc_int(struct block_list *bl, struct status_change *sc, int_ -= sc->data[SC_HARMONIZE]->val2; return (unsigned short)cap_value(int_,0,USHRT_MAX); } + if(sc->data[SC_MELODYOFSINK]) + int_ -= sc->data[SC_MELODYOFSINK]->val3; if(sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_HIGH && int_ < 50) return 50; if(sc->data[SC_INCALLSTATUS]) @@ -4231,10 +4357,12 @@ unsigned short status_calc_int(struct block_list *bl, struct status_change *sc, if(sc->data[SC_KYOUGAKU]) int_ -= sc->data[SC_KYOUGAKU]->val2; - if(sc->data[SC_NOEQUIPHELM]) - int_ -= int_ * sc->data[SC_NOEQUIPHELM]->val2/100; - if(sc->data[SC__STRIPACCESSARY]) - int_ -= int_ * sc->data[SC__STRIPACCESSARY]->val2 / 100; + if(bl->type != BL_PC){ + if(sc->data[SC_NOEQUIPHELM]) + int_ -= int_ * sc->data[SC_NOEQUIPHELM]->val2/100; + if(sc->data[SC__STRIPACCESSARY]) + int_ -= int_ * sc->data[SC__STRIPACCESSARY]->val2 / 100; + } if(sc->data[SC_FULL_THROTTLE]) int_ += int_ * 20 / 100; @@ -4293,7 +4421,7 @@ unsigned short status_calc_dex(struct block_list *bl, struct status_change *sc, if(sc->data[SC_MARSHOFABYSS]) dex -= dex * sc->data[SC_MARSHOFABYSS]->val2 / 100; - if(sc->data[SC__STRIPACCESSARY]) + if(sc->data[SC__STRIPACCESSARY] && bl->type != BL_PC) dex -= dex * sc->data[SC__STRIPACCESSARY]->val2 / 100; if(sc->data[SC_FULL_THROTTLE]) dex += dex * 20 / 100; @@ -4341,7 +4469,7 @@ unsigned short status_calc_luk(struct block_list *bl, struct status_change *sc, if(sc->data[SC_LAUDARAMUS]) luk += 4 + sc->data[SC_LAUDARAMUS]->val1; - if(sc->data[SC__STRIPACCESSARY]) + if(sc->data[SC__STRIPACCESSARY] && bl->type != BL_PC) luk -= luk * sc->data[SC__STRIPACCESSARY]->val2 / 100; if(sc->data[SC_BANANA_BOMB]) luk -= luk * sc->data[SC_BANANA_BOMB]->val1 / 100; @@ -4383,7 +4511,7 @@ unsigned short status_calc_batk(struct block_list *bl, struct status_change *sc, if(sc->data[SC_FULL_SWING_K]) batk += sc->data[SC_FULL_SWING_K]->val1; if(sc->data[SC_ODINS_POWER]) - batk += 70; + batk += 40 + 30 * sc->data[SC_ODINS_POWER]->val1; if(sc->data[SC_VOLCANIC_ASH] && (bl->type==BL_MOB)){ if(status_get_element(bl) == ELE_WATER) //water type batk /= 2; @@ -4418,14 +4546,8 @@ unsigned short status_calc_batk(struct block_list *bl, struct status_change *sc, batk += batk * sc->data[SC_HLIF_FLEET]->val3/100; if(sc->data[SC__ENERVATION]) batk -= batk * sc->data[SC__ENERVATION]->val2 / 100; - if(sc->data[SC_RUSH_WINDMILL]) - batk += batk * sc->data[SC_RUSH_WINDMILL]->val2/100; if(sc->data[SC_SATURDAY_NIGHT_FEVER]) batk += 100 * sc->data[SC_SATURDAY_NIGHT_FEVER]->val1; - if(sc->data[SC_MELODYOFSINK]) - batk -= batk * sc->data[SC_MELODYOFSINK]->val3/100; - if(sc->data[SC_BEYOND_OF_WARCRY]) - batk += batk * sc->data[SC_BEYOND_OF_WARCRY]->val3/100; return (unsigned short)cap_value(batk,0,USHRT_MAX); } @@ -4496,16 +4618,16 @@ unsigned short status_calc_watk(struct block_list *bl, struct status_change *sc, watk += watk * sc->data[SC_PROVOKE]->val3/100; if(sc->data[SC_SKE]) watk += watk * 3; - if(sc->data[SC__ENERVATION]) - watk -= watk * sc->data[SC__ENERVATION]->val2 / 100; if(sc->data[SC_HLIF_FLEET]) watk += watk * sc->data[SC_HLIF_FLEET]->val3/100; if(sc->data[SC_CURSE]) watk -= watk * 25/100; - if(sc->data[SC_NOEQUIPWEAPON]) + if(sc->data[SC_NOEQUIPWEAPON] && bl->type != BL_PC) watk -= watk * sc->data[SC_NOEQUIPWEAPON]->val2/100; if(sc->data[SC__ENERVATION]) watk -= watk * sc->data[SC__ENERVATION]->val2 / 100; + if(sc->data[SC_RUSH_WINDMILL]) + watk += sc->data[SC_RUSH_WINDMILL]->val2; if((sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 2) || (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 2) || (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 2) @@ -4534,6 +4656,8 @@ unsigned short status_calc_ematk(struct block_list *bl, struct status_change *sc matk += sc->data[SC_AQUAPLAY_OPTION]->val2; if(sc->data[SC_CHILLY_AIR_OPTION]) matk += sc->data[SC_CHILLY_AIR_OPTION]->val2; + if(sc->data[SC_COOLER_OPTION]) + matk += sc->data[SC_COOLER_OPTION]->val2; if(sc->data[SC_WATER_BARRIER]) matk -= sc->data[SC_WATER_BARRIER]->val3; if(sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 3) @@ -4569,6 +4693,8 @@ unsigned short status_calc_matk(struct block_list *bl, struct status_change *sc, matk += sc->data[SC_AQUAPLAY_OPTION]->val2; if (sc->data[SC_CHILLY_AIR_OPTION]) matk += sc->data[SC_CHILLY_AIR_OPTION]->val2; + if(sc->data[SC_COOLER_OPTION]) + matk += sc->data[SC_COOLER_OPTION]->val2; if (sc->data[SC_WATER_BARRIER]) matk -= sc->data[SC_WATER_BARRIER]->val3; if (sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 3) @@ -4588,10 +4714,8 @@ unsigned short status_calc_matk(struct block_list *bl, struct status_change *sc, matk += matk * sc->data[SC_INCMATKRATE]->val1/100; if (sc->data[SC_MOONLIT_SERENADE]) matk += matk * sc->data[SC_MOONLIT_SERENADE]->val2/100; - if (sc->data[SC_MELODYOFSINK]) - matk += matk * sc->data[SC_MELODYOFSINK]->val3/100; - if (sc->data[SC_BEYOND_OF_WARCRY]) - matk -= matk * sc->data[SC_BEYOND_OF_WARCRY]->val3/100; + if (sc->data[SC_MTF_MATK]) + matk += matk * 25 / 100; return (unsigned short)cap_value(matk,0,USHRT_MAX); } @@ -4624,9 +4748,11 @@ signed short status_calc_critical(struct block_list *bl, struct status_change *s #endif if(sc->data[SC__INVISIBILITY]) - critical += critical * sc->data[SC__INVISIBILITY]->val3 / 100; + critical += sc->data[SC__INVISIBILITY]->val3; if(sc->data[SC__UNLUCKY]) critical -= critical * sc->data[SC__UNLUCKY]->val2 / 100; + if(sc->data[SC_BEYOND_OF_WARCRY]) + critical += 10 * sc->data[SC_BEYOND_OF_WARCRY]->val3; return (short)cap_value(critical,10,SHRT_MAX); } @@ -4639,6 +4765,8 @@ signed short status_calc_hit(struct block_list *bl, struct status_change *sc, in if( !viewable ){ /* some statuses that are hidden in the status window */ + if(sc->data[SC_MTF_ASPD]) + hit += 5; return (short)cap_value(hit,1,SHRT_MAX); } @@ -4653,7 +4781,7 @@ signed short status_calc_hit(struct block_list *bl, struct status_change *sc, in if(sc->data[SC_LKCONCENTRATION]) hit += sc->data[SC_LKCONCENTRATION]->val3; if(sc->data[SC_INSPIRATION]) - hit += 5 * sc->data[SC_INSPIRATION]->val1; + hit += 5 * sc->data[SC_INSPIRATION]->val1 + 25; if(sc->data[SC_GS_ADJUSTMENT]) hit -= 30; if(sc->data[SC_GS_ACCURACY]) @@ -4741,19 +4869,19 @@ signed short status_calc_flee(struct block_list *bl, struct status_change *sc, i if(sc->data[SC_FEAR]) flee -= flee * 20 / 100; if(sc->data[SC_PARALYSE]) - flee -= flee * 10 / 100; // 10% Flee reduction + flee -= flee / 10; // 10% Flee reduction if(sc->data[SC_INFRAREDSCAN]) flee -= flee * 30 / 100; if( sc->data[SC__LAZINESS] ) flee -= flee * sc->data[SC__LAZINESS]->val3 / 100; if( sc->data[SC_GLOOMYDAY] ) - flee -= flee * sc->data[SC_GLOOMYDAY]->val2 / 100; + flee -= flee * ( 20 + 5 * sc->data[SC_GLOOMYDAY]->val1 ) / 100; if( sc->data[SC_SATURDAY_NIGHT_FEVER] ) flee -= flee * (40 + 10 * sc->data[SC_SATURDAY_NIGHT_FEVER]->val1) / 100; if( sc->data[SC_WIND_STEP_OPTION] ) flee += flee * sc->data[SC_WIND_STEP_OPTION]->val2 / 100; if( sc->data[SC_ZEPHYR] ) - flee += flee * sc->data[SC_ZEPHYR]->val2 / 100; + flee += sc->data[SC_ZEPHYR]->val2; if(sc->data[SC_VOLCANIC_ASH] && (bl->type==BL_MOB)){ //mob if(status_get_element(bl) == ELE_WATER) //water type flee /= 2; @@ -4792,6 +4920,8 @@ defType status_calc_def(struct block_list *bl, struct status_change *sc, int def def -= def * 5 * (10-sc->data[SC_CAMOUFLAGE]->val4) / 100; if( sc && sc->data[SC_GENTLETOUCH_REVITALIZE] && sc->data[SC_GENTLETOUCH_REVITALIZE]->val4 ) def += 2 * sc->data[SC_GENTLETOUCH_REVITALIZE]->val4; + if( sc->data[SC_FORCEOFVANGUARD] ) + def += def * 2 * sc->data[SC_FORCEOFVANGUARD]->val1 / 100; return (defType)cap_value(def,DEFTYPE_MIN,DEFTYPE_MAX); } @@ -4836,24 +4966,28 @@ defType status_calc_def(struct block_list *bl, struct status_change *sc, int def def >>=1; if(sc->data[SC_PROVOKE] && bl->type != BL_PC) // Provoke doesn't alter player defense-> def -= def * sc->data[SC_PROVOKE]->val4/100; - if(sc->data[SC_NOEQUIPSHIELD]) + if(sc->data[SC_NOEQUIPSHIELD] && bl->type != BL_PC) def -= def * sc->data[SC_NOEQUIPSHIELD]->val2/100; if (sc->data[SC_FLING]) def -= def * (sc->data[SC_FLING]->val2)/100; if( sc->data[SC_ANALYZE] ) def -= def * ( 14 * sc->data[SC_ANALYZE]->val1 ) / 100; - if( sc->data[SC_FORCEOFVANGUARD] ) - def += def * 2 * sc->data[SC_FORCEOFVANGUARD]->val1 / 100; if(sc->data[SC_SATURDAY_NIGHT_FEVER]) def -= def * (10 + 10 * sc->data[SC_SATURDAY_NIGHT_FEVER]->val1) / 100; if(sc->data[SC_EARTHDRIVE]) def -= def * 25 / 100; + if(sc->data[SC_SOLID_SKIN_OPTION]) + def += def * sc->data[SC_SOLID_SKIN_OPTION]->val2 / 100; if( sc->data[SC_ROCK_CRUSHER] ) def -= def * sc->data[SC_ROCK_CRUSHER]->val2 / 100; if( sc->data[SC_POWER_OF_GAIA] ) def += def * sc->data[SC_POWER_OF_GAIA]->val2 / 100; + if( sc->data[SC_NEUTRALBARRIER] ) + def += def * (5 * sc->data[SC_NEUTRALBARRIER]->val1 + 10) / 100; + if( sc->data[SC_SHIELDSPELL_REF] && sc->data[SC_SHIELDSPELL_REF]->val1 == 2 ) + def += sc->data[SC_SHIELDSPELL_REF]->val2; if( sc->data[SC_PRESTIGE] ) - def += def * sc->data[SC_PRESTIGE]->val1 / 100; + def += sc->data[SC_PRESTIGE]->val1; if( sc->data[SC_FROSTMISTY] ) def -= def * 10 / 100; if(sc->data[SC_VOLCANIC_ASH] && (bl->type==BL_MOB)){ @@ -4894,11 +5028,8 @@ signed short status_calc_def2(struct block_list *bl, struct status_change *sc, i return 0; if(sc->data[SC_SUN_COMFORT]) def2 += sc->data[SC_SUN_COMFORT]->val2; - if( sc->data[SC_SHIELDSPELL_REF] && sc->data[SC_SHIELDSPELL_REF]->val1 == 1 ) - def2 += sc->data[SC_SHIELDSPELL_REF]->val2; if( sc->data[SC_BANDING] && sc->data[SC_BANDING]->val2 > 0 ) def2 += (5 + sc->data[SC_BANDING]->val1) * (sc->data[SC_BANDING]->val2); - if(sc->data[SC_ANGELUS]) #ifdef RENEWAL //in renewal only the VIT stat bonus is boosted by angelus def2 += status_get_vit(bl) / 2 * sc->data[SC_ANGELUS]->val2/100; @@ -4923,7 +5054,7 @@ signed short status_calc_def2(struct block_list *bl, struct status_change *sc, i if(sc->data[SC_ANALYZE]) def2 -= def2 * ( 14 * sc->data[SC_ANALYZE]->val1 ) / 100; if( sc->data[SC_ECHOSONG] ) - def2 += def2 * sc->data[SC_ECHOSONG]->val2/100; + def2 += def2 * sc->data[SC_ECHOSONG]->val3/100; if(sc->data[SC_VOLCANIC_ASH] && (bl->type==BL_MOB)){ if(status_get_race(bl)==RC_PLANT) def2 /= 2; @@ -4979,8 +5110,10 @@ defType status_calc_mdef(struct block_list *bl, struct status_change *sc, int md mdef += mdef * sc->data[SC_SYMPHONY_LOVE]->val2 / 100; if(sc->data[SC_GENTLETOUCH_CHANGE] && sc->data[SC_GENTLETOUCH_CHANGE]->val4) mdef -= mdef * sc->data[SC_GENTLETOUCH_CHANGE]->val4 / 100; + if(sc->data[SC_NEUTRALBARRIER] ) + mdef += mdef * (5 * sc->data[SC_NEUTRALBARRIER]->val1 + 10) / 100; if (sc->data[SC_ODINS_POWER]) - mdef -= 20 * sc->data[SC_ODINS_POWER]->val1; + mdef -= 20; if(sc->data[SC_BURNING]) mdef -= mdef *25 / 100; @@ -5028,16 +5161,13 @@ unsigned short status_calc_speed(struct block_list *bl, struct status_change *sc TBL_PC* sd = BL_CAST(BL_PC, bl); int speed_rate; - if( sc == NULL ) - return cap_value(speed,10,USHRT_MAX); - - if (sd && sd->state.permanent_speed) - return (short)cap_value(speed,10,USHRT_MAX); + if( sc == NULL || ( sd && sd->state.permanent_speed ) ) + return (unsigned short)cap_value(speed,MIN_WALK_SPEED,MAX_WALK_SPEED); if( sd && sd->ud.skilltimer != INVALID_TIMER && (pc->checkskill(sd,SA_FREECAST) > 0 || sd->ud.skill_id == LG_EXEEDBREAK) ) { if( sd->ud.skill_id == LG_EXEEDBREAK ) - speed_rate = 100 + 60 - (sd->ud.skill_lv * 10); + speed_rate = 160 - 10 * sd->ud.skill_lv; else speed_rate = 175 - 5 * pc->checkskill(sd,SA_FREECAST); } @@ -5086,7 +5216,7 @@ unsigned short status_calc_speed(struct block_list *bl, struct status_change *sc if( sc->data[SC_DEC_AGI] ) val = max( val, 25 ); - if( sc->data[SC_QUAGMIRE] || sc->data[SC_HALLUCINATIONWALK_POSTDELAY] || (sc->data[SC_GLOOMYDAY] && sc->data[SC_GLOOMYDAY]->val4) ) + if( sc->data[SC_QUAGMIRE] || sc->data[SC_HALLUCINATIONWALK_POSTDELAY] ) val = max( val, 50 ); if( sc->data[SC_DONTFORGETME] ) val = max( val, sc->data[SC_DONTFORGETME]->val3 ); @@ -5116,6 +5246,8 @@ unsigned short status_calc_speed(struct block_list *bl, struct status_change *sc val = max( val, sc->data[SC_CAMOUFLAGE]->val1 < 3 ? 0 : 25 * (5 - sc->data[SC_CAMOUFLAGE]->val1) ); if( sc->data[SC__GROOMY] ) val = max( val, sc->data[SC__GROOMY]->val2); + if( sc->data[SC_GLOOMYDAY] ) + val = max( val, sc->data[SC_GLOOMYDAY]->val3 ); // Should be 50 (-50% speed) if( sc->data[SC_STEALTHFIELD_MASTER] ) val = max( val, 30 ); if( sc->data[SC_BANDING_DEFENCE] ) @@ -5168,7 +5300,7 @@ unsigned short status_calc_speed(struct block_list *bl, struct status_change *sc if( sc->data[SC_GN_CARTBOOST] ) val = max( val, sc->data[SC_GN_CARTBOOST]->val2 ); if( sc->data[SC_SWING] ) - val = max( val, sc->data[SC_SWING]->val2 ); + val = max( val, sc->data[SC_SWING]->val3 ); if( sc->data[SC_WIND_STEP_OPTION] ) val = max( val, sc->data[SC_WIND_STEP_OPTION]->val2 ); if( sc->data[SC_FULL_THROTTLE] ) @@ -5205,7 +5337,7 @@ unsigned short status_calc_speed(struct block_list *bl, struct status_change *sc } - return (short)cap_value(speed,10,USHRT_MAX); + return (unsigned short)cap_value(speed,MIN_WALK_SPEED,MAX_WALK_SPEED); } // flag&1 - fixed value [malufett] @@ -5277,20 +5409,20 @@ short status_calc_aspd(struct block_list *bl, struct status_change *sc, short fl if( sc->data[SC_PARALYSE] ) skills2 -= 10; if( sc->data[SC__BODYPAINT] ) - skills2 -= 2 + 5 * sc->data[SC__BODYPAINT]->val1; + skills2 -= sc->data[SC__BODYPAINT]->val1; if( sc->data[SC__INVISIBILITY] ) skills2 -= sc->data[SC__INVISIBILITY]->val2 ; if( sc->data[SC__GROOMY] ) skills2 -= sc->data[SC__GROOMY]->val2; if( sc->data[SC_GLOOMYDAY] ) - skills2 -= sc->data[SC_GLOOMYDAY]->val3; + skills2 -= ( 15 + 5 * sc->data[SC_GLOOMYDAY]->val1 ); if( sc->data[SC_EARTHDRIVE] ) skills2 -= 25; if( sc->data[SC_MELON_BOMB] ) skills2 -= sc->data[SC_MELON_BOMB]->val1; if( sc->data[SC_SWING] ) - skills2 += sc->data[SC_SWING]->val2; + skills2 += sc->data[SC_SWING]->val3; if( sc->data[SC_DANCE_WITH_WUG] ) skills2 += sc->data[SC_DANCE_WITH_WUG]->val3; if( sc->data[SC_GENTLETOUCH_CHANGE] ) @@ -5342,6 +5474,8 @@ short status_calc_fix_aspd(struct block_list *bl, struct status_change *sc, int aspd -= 50; // +5 ASPD if( sc && sc->data[SC_FIGHTINGSPIRIT] && sc->data[SC_FIGHTINGSPIRIT]->val2 ) aspd -= (bl->type==BL_PC?pc->checkskill((TBL_PC *)bl, RK_RUNEMASTERY):10) / 10 * 40; + if( sc && sc->data[SC_MTF_ASPD] ) + aspd -= 10; return cap_value(aspd, 0, 2000); // will be recap for proper bl anyway } @@ -5454,17 +5588,17 @@ short status_calc_aspd_rate(struct block_list *bl, struct status_change *sc, int if( sc->data[SC_PARALYSE] ) aspd_rate += 100; if( sc->data[SC__BODYPAINT] ) - aspd_rate += 200 + 50 * sc->data[SC__BODYPAINT]->val1; + aspd_rate += 10 * 5 * sc->data[SC__BODYPAINT]->val1; if( sc->data[SC__INVISIBILITY] ) aspd_rate += sc->data[SC__INVISIBILITY]->val2 * 10 ; if( sc->data[SC__GROOMY] ) aspd_rate += sc->data[SC__GROOMY]->val2 * 10; if( sc->data[SC_SWING] ) - aspd_rate -= sc->data[SC_SWING]->val2 * 10; + aspd_rate -= sc->data[SC_SWING]->val3 * 10; if( sc->data[SC_DANCE_WITH_WUG] ) aspd_rate -= sc->data[SC_DANCE_WITH_WUG]->val3 * 10; if( sc->data[SC_GLOOMYDAY] ) - aspd_rate += sc->data[SC_GLOOMYDAY]->val3 * 10; + aspd_rate += ( 15 + 5 * sc->data[SC_GLOOMYDAY]->val1 ); if( sc->data[SC_EARTHDRIVE] ) aspd_rate += 250; if( sc->data[SC_GENTLETOUCH_CHANGE] ) @@ -5486,12 +5620,14 @@ short status_calc_aspd_rate(struct block_list *bl, struct status_change *sc, int } unsigned short status_calc_dmotion(struct block_list *bl, struct status_change *sc, int dmotion) { + // It has been confirmed on official servers that MvP mobs have no dmotion even without endure + if( bl->type == BL_MOB && (((TBL_MOB*)bl)->status.mode&MD_BOSS) ) + return 0; + if( !sc || !sc->count || map_flag_gvg2(bl->m) || map->list[bl->m].flag.battleground ) return cap_value(dmotion,0,USHRT_MAX); - /** - * It has been confirmed on official servers that MvP mobs have no dmotion even without endure - **/ - if( sc->data[SC_ENDURE] || ( bl->type == BL_MOB && (((TBL_MOB*)bl)->status.mode&MD_BOSS) ) ) + + if( sc->data[SC_ENDURE] ) return 0; if( sc->data[SC_RUN] || sc->data[SC_WUGDASH] ) return 0; @@ -5533,11 +5669,13 @@ unsigned int status_calc_maxhp(struct block_list *bl, struct status_change *sc, if(sc->data[SC__WEAKNESS]) maxhp -= maxhp * sc->data[SC__WEAKNESS]->val2 / 100; if(sc->data[SC_LERADS_DEW]) - maxhp += maxhp * sc->data[SC_LERADS_DEW]->val3 / 100; + maxhp += sc->data[SC_LERADS_DEW]->val3; + if(sc->data[SC_BEYOND_OF_WARCRY]) + maxhp -= maxhp * sc->data[SC_BEYOND_OF_WARCRY]->val4 / 100; if(sc->data[SC_FORCEOFVANGUARD]) maxhp += maxhp * 3 * sc->data[SC_FORCEOFVANGUARD]->val1 / 100; - if(sc->data[SC_INSPIRATION]) //Custom value. - maxhp += maxhp * 3 * sc->data[SC_INSPIRATION]->val1 / 100; + if(sc->data[SC_INSPIRATION]) + maxhp += maxhp * 5 * sc->data[SC_INSPIRATION]->val1 / 100 + 600 * sc->data[SC_INSPIRATION]->val1; if(sc->data[SC_RAISINGDRAGON]) maxhp += maxhp * (2 + sc->data[SC_RAISINGDRAGON]->val1) / 100; if(sc->data[SC_GENTLETOUCH_CHANGE]) // Max HP decrease: [Skill Level x 4] % @@ -5550,6 +5688,10 @@ unsigned int status_calc_maxhp(struct block_list *bl, struct status_change *sc, maxhp -= sc->data[SC_MYSTERIOUS_POWDER]->val1 / 100; if(sc->data[SC_PETROLOGY_OPTION]) maxhp += maxhp * sc->data[SC_PETROLOGY_OPTION]->val2 / 100; + if(sc->data[SC_CURSED_SOIL_OPTION]) + maxhp += maxhp * sc->data[SC_CURSED_SOIL_OPTION]->val2 / 100; + if(sc->data[SC_UPHEAVAL_OPTION]) + maxhp += maxhp * sc->data[SC_UPHEAVAL_OPTION]->val3 / 100; if (sc->data[SC_ANGRIFFS_MODUS]) maxhp += maxhp * 5 * sc->data[SC_ANGRIFFS_MODUS]->val1 /100; if (sc->data[SC_GOLDENE_FERSE]) @@ -6021,6 +6163,8 @@ void status_set_viewdata(struct block_list *bl, int class_) sd->vd.cloth_color = 0; if( sd->sc.option&OPTION_HANBOK && battle_config.hanbok_ignorepalette ) sd->vd.cloth_color = 0; + if( sd->sc.option&OPTION_OKTOBERFEST /* TODO: config? */ ) + sd->vd.cloth_color = 0; } } else if (vd) memcpy(&sd->vd, vd, sizeof(struct view_data)); @@ -6117,18 +6261,33 @@ void status_change_init(struct block_list *bl) { //Applies SC defense to a given status change. //Returns the adjusted duration based on flag values. //the flag values are the same as in status->change_start. -int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int tick, int flag) { +int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int tick, int flag) { //Percentual resistance: 10000 = 100% Resist //Example: 50% -> sc_def=5000 -> 25%; 5000ms -> tick_def=5000 -> 2500ms int sc_def = 0, tick_def = -1; //-1 = use sc_def //Linear resistance substracted from rate and tick after percentual resistance was applied //Example: 25% -> sc_def2=2000 -> 5%; 2500ms -> tick_def2=2000 -> 500ms - int sc_def2 = 0, tick_def2 = -1; //-1 = use sc_def2 + int sc_def2 = 0, tick_def2 = -1; //-1 = use sc_def2 (pre-re only) + struct status_data *st; struct status_change *sc; struct map_session_data *sd; nullpo_ret(bl); + + if(!src) + return tick ? tick : 1; // If no source, it can't be resisted (NPC given) + +/// Returns the 'bl's level, capped to 'cap' +#define SCDEF_LVL_CAP(bl, cap) ( (bl) ? (status->get_lv(bl) > (cap) ? (cap) : status->get_lv(bl)) : 0 ) +/// Renewal level modifier. +/// In renewal, returns the difference between the levels of 'bl' and 'src', both capped to 'maxlv', multiplied by 'factor' +/// In pre-renewal, returns zero. +#ifdef RENEWAL +#define SCDEF_LVL_DIFF(bl, src, maxlv, factor) ( ( SCDEF_LVL_CAP((bl), (maxlv)) - SCDEF_LVL_CAP((src), (maxlv)) ) * (factor) ) +#else +#define SCDEF_LVL_DIFF(bl, src, maxlv, factor) 0 +#endif //Status that are blocked by Golden Thief Bug card or Wand of Hermod if (status->isimmune(bl)) @@ -6170,53 +6329,145 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti sc = status->get_sc(bl); if( sc && !sc->count ) sc = NULL; + + if (sc && sc->data[SC_KINGS_GRACE]) { + // Protects against status effects + switch (type) { + case SC_POISON: + case SC_BLIND: + case SC_FREEZE: + case SC_STONE: + case SC_STUN: + case SC_SLEEP: + case SC_BLOODING: + case SC_CURSE: + case SC_CONFUSION: + case SC_ILLUSION: + case SC_SILENCE: + case SC_BURNING: + case SC_COLD: + case SC_FROSTMISTY: + case SC_DEEP_SLEEP: + case SC_FEAR: + case SC_MANDRAGORA: + case SC__CHAOS: + return 0; + } + } + switch (type) { case SC_STUN: + sc_def = st->vit*100; + sc_def2 = st->luk*10 + SCDEF_LVL_DIFF(bl, src, 99, 10); +#ifdef RENEWAL + tick_def2 = st->luk*10; +#endif + break; case SC_POISON: - if( sc && sc->data[SC__UNLUCKY] ) - return tick; case SC_DPOISON: + sc_def = st->vit*100; + sc_def2 = st->luk*10 + SCDEF_LVL_DIFF(bl, src, 99, 10); +#ifdef RENEWAL + if (sd) { + //For players: 60000 - 450*vit - 100*luk + tick_def = st->vit*75; + tick_def2 = st->luk*100; + } else { + //For monsters: 30000 - 200*vit + tick>>=1; + tick_def = (st->vit*200)/3; + } +#endif + break; case SC_SILENCE: +#ifdef RENEWAL + sc_def = st->int_*100; + sc_def2 = (st->vit + st->luk) * 5 + SCDEF_LVL_DIFF(bl, src, 99, 10); + tick_def2 = st->luk * 10; +#else + sc_def = st->vit*100; + sc_def2 = st->luk*10 + SCDEF_LVL_DIFF(bl, src, 99, 10); +#endif + break; case SC_BLOODING: +#ifdef RENEWAL + sc_def = st->agi*100; + tick_def2 = st->luk*10; +#else sc_def = st->vit*100; - sc_def2 = st->luk*10; +#endif + sc_def2 = st->luk*10 + SCDEF_LVL_DIFF(bl, src, 99, 10); break; case SC_SLEEP: sc_def = st->int_*100; - sc_def2 = st->luk*10; + sc_def2 = st->luk*10 + SCDEF_LVL_DIFF(bl, src, 99, 10); +#ifdef RENEWAL + tick_def2 = st->luk*10; +#endif break; case SC_DEEP_SLEEP: sc_def = st->int_*50; - tick_def = st->int_*10 + status->get_lv(bl) * 65 / 10; //Seems to be -1 sec every 10 int and -5% chance every 10 int. + tick_def = 0; // Linear reduction instead + tick_def2 = st->int_ * 50 + SCDEF_LVL_CAP(bl, 150) * 50; // kRO balance update lists this formula break; case SC_DEC_AGI: - case SC_ADORAMUS: //Arch Bishop - if (sd) tick>>=1; //Half duration for players. + case SC_ADORAMUS: + if (sd) tick >>= 1; //Half duration for players. + sc_def = st->mdef*100; +#ifndef RENEWAL + sc_def2 = st->luk*10; + tick_def2 = 0; //No duration reduction +#endif + tick_def = 0; //No duration reduction + break; case SC_STONE: - //Impossible to reduce duration with stats - tick_def = 0; - tick_def2 = 0; + sc_def = st->mdef*100; + sc_def2 = st->luk*10 + SCDEF_LVL_DIFF(bl, src, 99, 10); + tick_def = 0; //No duration reduction +#ifndef RENEWAL + tick_def2 = 0; //No duration reduction +#endif + break; case SC_FREEZE: sc_def = st->mdef*100; - sc_def2 = st->luk*10; + sc_def2 = st->luk*10 + SCDEF_LVL_DIFF(bl, src, 99, 10); + tick_def = 0; //No duration reduction +#ifdef RENEWAL + tick_def2 = status_get_luk(src) * -10; //Caster can increase final duration with luk +#else + tick_def2 = 0; //No duration reduction +#endif break; case SC_CURSE: - //Special property: inmunity when luk is greater than level or zero - if (st->luk > status->get_lv(bl) || st->luk == 0) + // Special property: immunity when luk is zero + if (st->luk == 0) + return 0; +#ifndef RENEWAL + // Special property: immunity when luk is greater than level + if (st->luk > status->get_lv(bl)) return 0; +#endif sc_def = st->luk*100; - sc_def2 = st->luk*10; + sc_def2 = st->luk*10 + SCDEF_LVL_DIFF(NULL, src, 99, 10); // Curse only has a level penalty and no resistance tick_def = st->vit*100; +#ifdef RENEWAL + tick_def2 = st->luk*10; +#endif break; case SC_BLIND: - if( sc && sc->data[SC__UNLUCKY] ) - return tick; sc_def = (st->vit + st->int_)*50; - sc_def2 = st->luk*10; + sc_def2 = st->luk*10 + SCDEF_LVL_DIFF(bl, src, 99, 10); +#ifdef RENEWAL + tick_def2 = st->luk*10; +#endif break; case SC_CONFUSION: sc_def = (st->str + st->int_)*50; - sc_def2 = st->luk*10; + sc_def2 = st->luk*10 + SCDEF_LVL_DIFF(bl, src, 99, 10); +#ifdef RENEWAL + sc_def2 = -sc_def2; // Reversed sc_def2 + tick_def2 = st->luk*10; +#endif break; case SC_ANKLESNARE: if(st->mode&MD_BOSS) // Lasts 5 times less on bosses @@ -6227,7 +6478,7 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti case SC_STONESKIN: if (sd) //Duration greatly reduced for players. tick /= 15; - sc_def2 = status->get_lv(bl)*20 + st->vit*25 + st->agi*10; // Lineal Reduction of Rate + sc_def2 = st->vit*25 + st->agi*10 + SCDEF_LVL_CAP(bl, 99) * 20; // Linear Reduction of Rate tick_def2 = 0; //No duration reduction break; case SC_MARSHOFABYSS: @@ -6238,49 +6489,60 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti //5 second (fixed) + { Stasis Skill level * 5 - (Target's VIT + DEX) / 20 } tick_def2 = (st->vit + st->dex)*50; break; - if( bl->type == BL_PC ) - tick -= (status->get_lv(bl) / 5 + st->vit / 4 + st->agi / 10)*100; + case SC_WHITEIMPRISON: + if( tick == 5000 ) // 100% on caster + break; + if (bl->type == BL_PC) + tick_def2 = st->vit*25 + st->agi*10 + SCDEF_LVL_CAP(bl, 150) * 20; else - tick -= (st->vit + st->luk) / 20 * 1000; + tick_def2 = (st->vit + st->luk)*50; break; case SC_BURNING: - tick -= 75 * st->luk + 125 * st->agi; - tick = max(tick,5000); // Minimum Duration 5s. + tick_def2 = 75*st->luk + 125*st->agi; break; case SC_FROSTMISTY: - tick -= 1000 * ((st->vit + st->dex) / 20); - tick = max(tick,6000); // Minimum Duration 6s. + tick_def2 = (st->vit + st->dex)*50; break; case SC_OBLIVIONCURSE: // 100% - (100 - 0.8 x INT) - sc_def = 100 - ( 100 - st->int_* 8 / 10 ); - sc_def = max(sc_def, 5); // minimum of 5% + sc_def = st->int_*80; + case SC_TOXIN: + case SC_PARALYSE: + case SC_VENOMBLEED: + case SC_MAGICMUSHROOM: + case SC_DEATHHURT: + case SC_PYREXIA: + case SC_LEECHESEND: + tick_def2 = (st->vit + st->luk) * 500; break; case SC_WUGBITE: // {(Base Success chance) - (Target's AGI / 4)} - rate -= st->agi*100/4; - rate = max(rate,5000); // minimum of 50% + sc_def2 = st->agi*25; break; case SC_ELECTRICSHOCKER: - if( bl->type == BL_MOB ) - tick -= 1000 * (st->agi/10); + tick_def2 = (st->vit + st->agi) * 70; break; case SC_COLD: - tick -= (1000*(st->vit/10))+(status->get_lv(bl)/50); + tick_def2 = st->vit*100 + status->get_lv(bl)*20; + break; + case SC_VACUUM_EXTREME: + tick_def2 = st->str*50; + break; + case SC_MANDRAGORA: + sc_def = (st->vit + st->luk)*20; break; case SC_SIREN: - tick -= 1000 * ((status->get_lv(bl) / 10) + ((sd?sd->status.job_level:0) / 5)); - tick = max(tick,10000); + tick_def2 = (status->get_lv(bl) * 100) + ((bl->type == BL_PC)?((TBL_PC*)bl)->status.job_level : 0); break; case SC_KYOUGAKU: - tick -= 1000 * status_get_int(bl) / 20; + tick_def2 = st->int_ * 50; break; case SC_NEEDLE_OF_PARALYZE: - tick -= 50 * (st->vit + st->luk); //(1000/20); + tick_def2 = (st->vit + st->luk) * 50; break; default: //Effect that cannot be reduced? Likely a buff. if (!(rnd()%10000 < rate)) return 0; - return tick?tick:1; + return tick ? tick : 1; } if (sd) { @@ -6320,11 +6582,16 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti sc_def += sc->data[SC_SIEGFRIED]->val3*100; //Status resistance. } - //When no tick def, reduction is the same for both. - if(tick_def < 0) + //When tick def not set, reduction is the same for both. + if(tick_def == -1) tick_def = sc_def; - if(tick_def2 < 0) + if(tick_def2 == -1) { +#ifdef RENEWAL + tick_def2 = 0; +#else tick_def2 = sc_def2; +#endif + } //Natural resistance if (!(flag&8)) { @@ -6333,8 +6600,11 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti //Minimum chances switch (type) { + case SC_OBLIVIONCURSE: + rate = max(rate,500); //Minimum of 5% + break; case SC_WUGBITE: - rate = max(rate, 5000); //Minimum of 50% + rate = max(rate,5000); //Minimum of 50% break; } @@ -6346,6 +6616,9 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti if( sd->sc.data[SC_TARGET_BLOOD] ) rate -= rate*sd->sc.data[SC_TARGET_BLOOD]->val1/100; } + + //Aegis accuracy + if(rate > 0 && rate%10 != 0) rate += (10 - rate%10); } if (!(rnd()%10000 < rate)) @@ -6364,13 +6637,14 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti //Minimum durations switch (type) { case SC_ANKLESNARE: + case SC_BURNING: case SC_MARSHOFABYSS: case SC_STASIS: + case SC_DEEP_SLEEP: tick = max(tick, 5000); //Minimum duration 5s break; - case SC_BURNING: case SC_FROSTMISTY: - tick = max(tick, 10000); //Minimum duration 10s + tick = max(tick, 6000); break; default: //Skills need to trigger even if the duration is reduced below 1ms @@ -6379,6 +6653,8 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti } return tick; +#undef SCDEF_LVL_CAP +#undef SCDEF_LVL_DIFF } /* [Ind/Hercules] fast-checkin sc-display array */ void status_display_add(struct map_session_data *sd, enum sc_type type, int dval1, int dval2, int dval3) { @@ -6450,7 +6726,7 @@ void status_display_remove(struct map_session_data *sd, enum sc_type type) { * &4: sc_data loaded, no value has to be altered. * &8: rate should not be reduced *------------------------------------------*/ -int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val1,int val2,int val3,int val4,int tick,int flag) { +int status_change_start(struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int val1, int val2, int val3, int val4, int tick, int flag) { struct map_session_data *sd = NULL; struct status_change* sc; struct status_change_entry* sce; @@ -6485,46 +6761,67 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val if( type >= SC_COMMON_MIN && type <= SC_COMMON_MAX) // Confirmed. return 0; // Immune to status ailements switch( type ) { - case SC_QUAGMIRE://Tester said it protects against this and decrease agi. - case SC_DEC_AGI: - case SC_BURNING: - case SC_FROSTMISTY: - //case SC_WHITEIMPRISON://Need confirm. Protected against this in the past. [Rytech] - case SC_MARSHOFABYSS: - case SC_TOXIN: - case SC_PARALYSE: - case SC_VENOMBLEED: - case SC_MAGICMUSHROOM: - case SC_DEATHHURT: - case SC_PYREXIA: - case SC_OBLIVIONCURSE: - case SC_LEECHESEND: - case SC_COLD: ////08/31/2011 - Class Balance Changes - case SC_DEEP_SLEEP: - case SC_MANDRAGORA: - return 0; + case SC_DEEP_SLEEP: + case SC__CHAOS: + case SC_BURNING: + case SC_STUN: + case SC_SLEEP: + case SC_CURSE: + case SC_STONE: + case SC_POISON: + case SC_BLIND: + case SC_SILENCE: + case SC_BLOODING: + case SC_FREEZE: + case SC_FROSTMISTY: + case SC_COLD: + case SC_TOXIN: + case SC_PARALYSE: + case SC_VENOMBLEED: + case SC_MAGICMUSHROOM: + case SC_DEATHHURT: + case SC_PYREXIA: + case SC_OBLIVIONCURSE: + case SC_MARSHOFABYSS: + case SC_MANDRAGORA: + return 0; } } else if( sc->data[SC_INSPIRATION] ) { if( type >= SC_COMMON_MIN && type <= SC_COMMON_MAX ) return 0; // Immune to status ailements switch( type ) { - case SC_DEEP_SLEEP: - case SC_SATURDAY_NIGHT_FEVER: - case SC_PYREXIA: - case SC_DEATHHURT: - case SC_MAGICMUSHROOM: - case SC_VENOMBLEED: - case SC_TOXIN: - case SC_OBLIVIONCURSE: - case SC_LEECHESEND: - case SC__ENERVATION: - case SC__GROOMY: - case SC__LAZINESS: - case SC__UNLUCKY: - case SC__WEAKNESS: - case SC__BODYPAINT: - case SC__IGNORANCE: - return 0; + case SC_POISON: + case SC_BLIND: + case SC_STUN: + case SC_SILENCE: + case SC__CHAOS: + case SC_STONE: + case SC_SLEEP: + case SC_BLOODING: + case SC_CURSE: + case SC_BURNING: + case SC_FROSTMISTY: + case SC_FREEZE: + case SC_COLD: + case SC_FEAR: + case SC_TOXIN: + case SC_PARALYSE: + case SC_VENOMBLEED: + case SC_MAGICMUSHROOM: + case SC_DEATHHURT: + case SC_PYREXIA: + case SC_OBLIVIONCURSE: + case SC_LEECHESEND: + case SC_DEEP_SLEEP: + case SC_SATURDAY_NIGHT_FEVER: + case SC__BODYPAINT: + case SC__ENERVATION: + case SC__GROOMY: + case SC__IGNORANCE: + case SC__LAZINESS: + case SC__UNLUCKY: + case SC__WEAKNESS: + return 0; } } @@ -6532,1874 +6829,2233 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val //Adjust tick according to status resistances if( !(flag&(1|4)) ) { - tick = status->get_sc_def(bl, type, rate, tick, flag); + tick = status->get_sc_def(src, bl, type, rate, tick, flag); if( !tick ) return 0; } undead_flag = battle->check_undead(st->race,st->def_ele); //Check for inmunities / sc fails switch (type) { - case SC_DRUMBATTLE: - case SC_NIBELUNGEN: - case SC_INTOABYSS: - case SC_SIEGFRIED: - if( bl->type == BL_PC) { - struct map_session_data *sd = BL_CAST(BL_PC,bl); - if (!sd->status.party_id) return 0; - } - break; - case SC_ANGRIFFS_MODUS: - case SC_GOLDENE_FERSE: - if ((type==SC_GOLDENE_FERSE && sc->data[SC_ANGRIFFS_MODUS]) - || (type==SC_ANGRIFFS_MODUS && sc->data[SC_GOLDENE_FERSE]) - ) - return 0; - case SC_STONE: - if(sc->data[SC_POWER_OF_GAIA]) - return 0; - case SC_FREEZE: - //Undead are immune to Freeze/Stone - if (undead_flag && !(flag&1)) - return 0; - case SC_DEEP_SLEEP: - case SC_SLEEP: - case SC_STUN: - case SC_FROSTMISTY: - case SC_COLD: - if (sc->opt1) - return 0; //Cannot override other opt1 status changes. [Skotlex] - if((type == SC_FREEZE || type == SC_FROSTMISTY || type == SC_COLD) && sc->data[SC_WARMER]) - return 0; //Immune to Frozen and Freezing status if under Warmer status. [Jobbie] - break; + case SC_DRUMBATTLE: + case SC_NIBELUNGEN: + case SC_INTOABYSS: + case SC_SIEGFRIED: + if( sd && !sd->status.party_id ) + return 0; + break; + case SC_ANGRIFFS_MODUS: + case SC_GOLDENE_FERSE: + if ((type==SC_GOLDENE_FERSE && sc->data[SC_ANGRIFFS_MODUS]) + || (type==SC_ANGRIFFS_MODUS && sc->data[SC_GOLDENE_FERSE]) + ) + return 0; + case SC_VACUUM_EXTREME: + if(sc->data[SC_HALLUCINATIONWALK] || sc->data[SC_HOVERING]) + return 0; + break; + case SC_STONE: + if(sc->data[SC_POWER_OF_GAIA]) + return 0; + case SC_FREEZE: + //Undead are immune to Freeze/Stone + if (undead_flag && !(flag&1)) + return 0; + case SC_SLEEP: + case SC_STUN: + case SC_FROSTMISTY: + case SC_COLD: + if (sc->opt1) + return 0; //Cannot override other opt1 status changes. [Skotlex] + if((type == SC_FREEZE || type == SC_FROSTMISTY || type == SC_COLD) && sc->data[SC_WARMER]) + return 0; //Immune to Frozen and Freezing status if under Warmer status. [Jobbie] + break; - //There all like berserk, do not everlap each other - case SC_BERSERK: - if( sc->data[SC__BLOODYLUST] || sc->data[SC_SATURDAY_NIGHT_FEVER] ) - return 0; - break; + //There all like berserk, do not everlap each other + case SC_BERSERK: + if( sc->data[SC__BLOODYLUST] ) + return 0; + break; - case SC_BURNING: - if(sc->opt1 || sc->data[SC_FROSTMISTY]) - return 0; - break; + case SC_BURNING: + if(sc->opt1 || sc->data[SC_FROSTMISTY]) + return 0; + break; - case SC_CRUCIS: - //Only affects demons and undead element (but not players) - if((!undead_flag && st->race!=RC_DEMON) || bl->type == BL_PC) - return 0; - break; - case SC_LEXAETERNA: - if( (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE) || sc->data[SC_FREEZE] ) - return 0; - break; - case SC_KYRIE: - if (bl->type == BL_MOB) - return 0; - break; - case SC_OVERTHRUST: - if (sc->data[SC_OVERTHRUSTMAX]) - return 0; //Overthrust can't take effect if under Max Overthrust. [Skotlex] - case SC_OVERTHRUSTMAX: - if( sc->option&OPTION_MADOGEAR ) - return 0;//Overthrust and Overthrust Max cannot be used on Mado Gear [Ind] - break; - case SC_ADRENALINE: - if(sd && !pc_check_weapontype(sd,skill->get_weapontype(BS_ADRENALINE))) - return 0; - if (sc->data[SC_QUAGMIRE] || - sc->data[SC_DEC_AGI] || - sc->option&OPTION_MADOGEAR //Adrenaline doesn't affect Mado Gear [Ind] + case SC_CRUCIS: + //Only affects demons and undead element (but not players) + if((!undead_flag && st->race!=RC_DEMON) || bl->type == BL_PC) + return 0; + break; + case SC_LEXAETERNA: + if( (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE) || sc->data[SC_FREEZE] ) + return 0; + break; + case SC_KYRIE: + if (bl->type == BL_MOB) + return 0; + break; + case SC_OVERTHRUST: + if (sc->data[SC_OVERTHRUSTMAX]) + return 0; //Overthrust can't take effect if under Max Overthrust. [Skotlex] + case SC_OVERTHRUSTMAX: + if( sc->option&OPTION_MADOGEAR ) + return 0;//Overthrust and Overthrust Max cannot be used on Mado Gear [Ind] + break; + case SC_ADRENALINE: + if(sd && !pc_check_weapontype(sd,skill->get_weapontype(BS_ADRENALINE))) + return 0; + if (sc->data[SC_QUAGMIRE] || + sc->data[SC_DEC_AGI] || + sc->option&OPTION_MADOGEAR //Adrenaline doesn't affect Mado Gear [Ind] + ) + return 0; + break; + case SC_ADRENALINE2: + if(sd && !pc_check_weapontype(sd,skill->get_weapontype(BS_ADRENALINE2))) + return 0; + if (sc->data[SC_QUAGMIRE] || + sc->data[SC_DEC_AGI] ) - return 0; - break; - case SC_ADRENALINE2: - if(sd && !pc_check_weapontype(sd,skill->get_weapontype(BS_ADRENALINE2))) - return 0; - if (sc->data[SC_QUAGMIRE] || - sc->data[SC_DEC_AGI] - ) - return 0; - break; - case SC_MAGNIFICAT: - if( sc->data[SC_OFFERTORIUM] || sc->option&OPTION_MADOGEAR ) //Mado is immune to magnificat - return 0; - break; - case SC_ONEHANDQUICKEN: - case SC_MER_QUICKEN: - case SC_TWOHANDQUICKEN: - if(sc->data[SC_DEC_AGI]) - return 0; + return 0; + break; + case SC_MAGNIFICAT: + if( sc->data[SC_OFFERTORIUM] || sc->option&OPTION_MADOGEAR ) //Mado is immune to magnificat + return 0; + break; + case SC_ONEHANDQUICKEN: + case SC_MER_QUICKEN: + case SC_TWOHANDQUICKEN: + if(sc->data[SC_DEC_AGI]) + return 0; - case SC_CONCENTRATION: - case SC_SPEARQUICKEN: - case SC_TRUESIGHT: - case SC_WINDWALK: - case SC_CARTBOOST: - case SC_ASSNCROS: - if(sc->option&OPTION_MADOGEAR) - return 0;//Mado is immune to wind walk, cart boost, etc (others above) [Ind] - case SC_INC_AGI: - if (sc->data[SC_QUAGMIRE]) - return 0; - break; - case SC_CLOAKING: - //Avoid cloaking with no wall and low skill level. [Skotlex] - //Due to the cloaking card, we have to check the wall versus to known - //skill level rather than the used one. [Skotlex] - //if (sd && val1 < 3 && skill_check_cloaking(bl,NULL)) - if( sd && pc->checkskill(sd, AS_CLOAKING) < 3 && !skill->check_cloaking(bl,NULL) ) - return 0; - break; - case SC_MODECHANGE: - { - int mode; - struct status_data *bst = status->get_base_status(bl); - if (!bst) return 0; - if (sc->data[type]) { - //Pile up with previous values. - if(!val2) val2 = sc->data[type]->val2; - val3 |= sc->data[type]->val3; - val4 |= sc->data[type]->val4; - } - mode = val2 ? val2 : bst->mode; //Base mode - if (val4) mode&=~val4; //Del mode - if (val3) mode|= val3; //Add mode - if (mode == bst->mode) { //No change. - if (sc->data[type]) //Abort previous status - return status_change_end(bl, type, INVALID_TIMER); - return 0; - } - } - break; - //Strip skills, need to divest something or it fails. - case SC_NOEQUIPWEAPON: - if (sd && !(flag&4)) { //apply sc anyway if loading saved sc_data - int i; - opt_flag = 0; //Reuse to check success condition. - if(sd->bonus.unstripable_equip&EQP_WEAPON) + case SC_CONCENTRATION: + case SC_SPEARQUICKEN: + case SC_TRUESIGHT: + case SC_WINDWALK: + case SC_CARTBOOST: + case SC_ASSNCROS: + if(sc->option&OPTION_MADOGEAR) + return 0;//Mado is immune to wind walk, cart boost, etc (others above) [Ind] + case SC_INC_AGI: + if (sc->data[SC_QUAGMIRE]) + return 0; + break; + case SC_CLOAKING: + //Avoid cloaking with no wall and low skill level. [Skotlex] + //Due to the cloaking card, we have to check the wall versus to known + //skill level rather than the used one. [Skotlex] + //if (sd && val1 < 3 && skill_check_cloaking(bl,NULL)) + if( sd && pc->checkskill(sd, AS_CLOAKING) < 3 && !skill->check_cloaking(bl,NULL) ) return 0; + break; + case SC_MODECHANGE: + { + int mode; + struct status_data *bst = status->get_base_status(bl); + if (!bst) return 0; + if (sc->data[type]) { + //Pile up with previous values. + if(!val2) val2 = sc->data[type]->val2; + val3 |= sc->data[type]->val3; + val4 |= sc->data[type]->val4; + } + mode = val2 ? val2 : bst->mode; //Base mode + if (val4) mode&=~val4; //Del mode + if (val3) mode|= val3; //Add mode + if (mode == bst->mode) { //No change. + if (sc->data[type]) //Abort previous status + return status_change_end(bl, type, INVALID_TIMER); + return 0; + } + } + break; + //Strip skills, need to divest something or it fails. + case SC_NOEQUIPWEAPON: + if (sd && !(flag&4)) { //apply sc anyway if loading saved sc_data + int i; + opt_flag = 0; //Reuse to check success condition. + if(sd->bonus.unstripable_equip&EQP_WEAPON) + return 0; - i = sd->equip_index[EQI_HAND_R]; - if (i>=0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_WEAPON) { - opt_flag|=2; + i = sd->equip_index[EQI_HAND_R]; + if (i>=0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_WEAPON) { + opt_flag|=2; + pc->unequipitem(sd,i,3); + } + if (!opt_flag) return 0; + } + if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC + break; + case SC_NOEQUIPSHIELD: + if( val2 == 1 ) val2 = 0; //GX effect. Do not take shield off.. + else + if (sd && !(flag&4)) { + int i; + if(sd->bonus.unstripable_equip&EQP_SHIELD) + return 0; + i = sd->equip_index[EQI_HAND_L]; + if ( i < 0 || !sd->inventory_data[i] || sd->inventory_data[i]->type != IT_ARMOR ) + return 0; + pc->unequipitem(sd,i,3); + } + if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC + break; + case SC_NOEQUIPARMOR: + if (sd && !(flag&4)) { + int i; + if(sd->bonus.unstripable_equip&EQP_ARMOR) + return 0; + i = sd->equip_index[EQI_ARMOR]; + if ( i < 0 || !sd->inventory_data[i] ) + return 0; pc->unequipitem(sd,i,3); } - if (!opt_flag) return 0; - } - if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC - break; - case SC_NOEQUIPSHIELD: - if( val2 == 1 ) val2 = 0; //GX effect. Do not take shield off.. - else + if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC + break; + case SC_NOEQUIPHELM: if (sd && !(flag&4)) { int i; - if(sd->bonus.unstripable_equip&EQP_SHIELD) + if(sd->bonus.unstripable_equip&EQP_HELM) return 0; - i = sd->equip_index[EQI_HAND_L]; - if ( i < 0 || !sd->inventory_data[i] || sd->inventory_data[i]->type != IT_ARMOR ) + i = sd->equip_index[EQI_HEAD_TOP]; + if ( i < 0 || !sd->inventory_data[i] ) return 0; pc->unequipitem(sd,i,3); } if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC break; - case SC_NOEQUIPARMOR: - if (sd && !(flag&4)) { - int i; - if(sd->bonus.unstripable_equip&EQP_ARMOR) + case SC_MER_FLEE: + case SC_MER_ATK: + case SC_MER_HP: + case SC_MER_SP: + case SC_MER_HIT: + if( bl->type != BL_MER ) + return 0; // Stats only for Mercenaries + break; + case SC_FOOD_STR: + if (sc->data[SC_FOOD_STR_CASH] && sc->data[SC_FOOD_STR_CASH]->val1 > val1) return 0; - i = sd->equip_index[EQI_ARMOR]; - if ( i < 0 || !sd->inventory_data[i] ) + break; + case SC_FOOD_AGI: + if (sc->data[SC_FOOD_AGI_CASH] && sc->data[SC_FOOD_AGI_CASH]->val1 > val1) return 0; - pc->unequipitem(sd,i,3); - } - if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC - break; - case SC_NOEQUIPHELM: - if (sd && !(flag&4)) { - int i; - if(sd->bonus.unstripable_equip&EQP_HELM) + break; + case SC_FOOD_VIT: + if (sc->data[SC_FOOD_VIT_CASH] && sc->data[SC_FOOD_VIT_CASH]->val1 > val1) return 0; - i = sd->equip_index[EQI_HEAD_TOP]; - if ( i < 0 || !sd->inventory_data[i] ) + break; + case SC_FOOD_INT: + if (sc->data[SC_FOOD_INT_CASH] && sc->data[SC_FOOD_INT_CASH]->val1 > val1) return 0; - pc->unequipitem(sd,i,3); - } - if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC - break; - case SC_MER_FLEE: - case SC_MER_ATK: - case SC_MER_HP: - case SC_MER_SP: - case SC_MER_HIT: - if( bl->type != BL_MER ) - return 0; // Stats only for Mercenaries - break; - case SC_FOOD_STR: - if (sc->data[SC_FOOD_STR_CASH] && sc->data[SC_FOOD_STR_CASH]->val1 > val1) - return 0; - break; - case SC_FOOD_AGI: - if (sc->data[SC_FOOD_AGI_CASH] && sc->data[SC_FOOD_AGI_CASH]->val1 > val1) - return 0; - break; - case SC_FOOD_VIT: - if (sc->data[SC_FOOD_VIT_CASH] && sc->data[SC_FOOD_VIT_CASH]->val1 > val1) - return 0; - break; - case SC_FOOD_INT: - if (sc->data[SC_FOOD_INT_CASH] && sc->data[SC_FOOD_INT_CASH]->val1 > val1) - return 0; - break; - case SC_FOOD_DEX: - if (sc->data[SC_FOOD_DEX_CASH] && sc->data[SC_FOOD_DEX_CASH]->val1 > val1) - return 0; - break; - case SC_FOOD_LUK: - if (sc->data[SC_FOOD_LUK_CASH] && sc->data[SC_FOOD_LUK_CASH]->val1 > val1) - return 0; - break; - case SC_FOOD_STR_CASH: - if (sc->data[SC_FOOD_STR] && sc->data[SC_FOOD_STR]->val1 > val1) - return 0; - break; - case SC_FOOD_AGI_CASH: - if (sc->data[SC_FOOD_AGI] && sc->data[SC_FOOD_AGI]->val1 > val1) - return 0; - break; - case SC_FOOD_VIT_CASH: - if (sc->data[SC_FOOD_VIT] && sc->data[SC_FOOD_VIT]->val1 > val1) - return 0; - break; - case SC_FOOD_INT_CASH: - if (sc->data[SC_FOOD_INT] && sc->data[SC_FOOD_INT]->val1 > val1) - return 0; - break; - case SC_FOOD_DEX_CASH: - if (sc->data[SC_FOOD_DEX] && sc->data[SC_FOOD_DEX]->val1 > val1) - return 0; - break; - case SC_FOOD_LUK_CASH: - if (sc->data[SC_FOOD_LUK] && sc->data[SC_FOOD_LUK]->val1 > val1) - return 0; - break; - case SC_CAMOUFLAGE: - if( sd && pc->checkskill(sd, RA_CAMOUFLAGE) < 3 && !skill->check_camouflage(bl,NULL) ) - return 0; - break; - case SC__STRIPACCESSARY: - if( sd ) { - int i = -1; - if( !(sd->bonus.unstripable_equip&EQP_ACC_L) ) { - i = sd->equip_index[EQI_ACC_L]; - if( i >= 0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_ARMOR ) - pc->unequipitem(sd,i,3); //L-Accessory - } if( !(sd->bonus.unstripable_equip&EQP_ACC_R) ) { - i = sd->equip_index[EQI_ACC_R]; - if( i >= 0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_ARMOR ) - pc->unequipitem(sd,i,3); //R-Accessory - } - if( i < 0 ) + break; + case SC_FOOD_DEX: + if (sc->data[SC_FOOD_DEX_CASH] && sc->data[SC_FOOD_DEX_CASH]->val1 > val1) return 0; - } - if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC - break; - case SC_TOXIN: - case SC_PARALYSE: - case SC_VENOMBLEED: - case SC_MAGICMUSHROOM: - case SC_DEATHHURT: - case SC_PYREXIA: - case SC_OBLIVIONCURSE: - case SC_LEECHESEND: - { // it doesn't stack or even renewed - int i = SC_TOXIN; - for(; i<= SC_LEECHESEND; i++) - if(sc->data[i]) return 0; - } - break; - case SC_SATURDAY_NIGHT_FEVER: - if (sc->data[SC_BERSERK] || sc->data[SC_INSPIRATION]) - return 0; - break; - case SC_OFFERTORIUM: - if (sc->data[SC_MAGNIFICAT]) - return 0; - break; - } - - //Check for BOSS resistances - if(st->mode&MD_BOSS && !(flag&1)) { - if (type>=SC_COMMON_MIN && type <= SC_COMMON_MAX) - return 0; - switch (type) { - case SC_BLESSING: - case SC_DEC_AGI: - case SC_PROVOKE: - case SC_COMA: - case SC_GRAVITATION: - case SC_NJ_SUITON: - case SC_RICHMANKIM: - case SC_ROKISWEIL: - case SC_FOGWALL: - case SC_FROSTMISTY: - case SC_BURNING: - case SC_MARSHOFABYSS: - case SC_ADORAMUS: - case SC_NEEDLE_OF_PARALYZE: - case SC_DEEP_SLEEP: - case SC_COLD: - - // Exploit prevention - kRO Fix - case SC_PYREXIA: - case SC_DEATHHURT: - case SC_TOXIN: - case SC_PARALYSE: - case SC_VENOMBLEED: - case SC_MAGICMUSHROOM: - case SC_OBLIVIONCURSE: - case SC_LEECHESEND: - - // Ranger Effects - case SC_WUGBITE: - case SC_ELECTRICSHOCKER: - case SC_MAGNETICFIELD: - - // Masquerades - case SC__ENERVATION: - case SC__GROOMY: - case SC__LAZINESS: - case SC__UNLUCKY: - case SC__WEAKNESS: - case SC__IGNORANCE: - - return 0; - } - } - - //Before overlapping fail, one must check for status cured. - switch (type) { - case SC_BLESSING: - //TO-DO Blessing and Agi up should do 1 damage against players on Undead Status, even on PvM - //but cannot be plagiarized (this requires aegis investigation on packets and official behavior) [Brainstorm] - if ((!undead_flag && st->race!=RC_DEMON) || bl->type == BL_PC) { - status_change_end(bl, SC_CURSE, INVALID_TIMER); - if (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE) - status_change_end(bl, SC_STONE, INVALID_TIMER); - } - break; - case SC_INC_AGI: - status_change_end(bl, SC_DEC_AGI, INVALID_TIMER); - break; - case SC_QUAGMIRE: - status_change_end(bl, SC_CONCENTRATION, INVALID_TIMER); - status_change_end(bl, SC_TRUESIGHT, INVALID_TIMER); - status_change_end(bl, SC_WINDWALK, INVALID_TIMER); - //Also blocks the ones below... - case SC_DEC_AGI: - status_change_end(bl, SC_CARTBOOST, INVALID_TIMER); - //Also blocks the ones below... - case SC_DONTFORGETME: - status_change_end(bl, SC_INC_AGI, INVALID_TIMER); - status_change_end(bl, SC_ADRENALINE, INVALID_TIMER); - status_change_end(bl, SC_ADRENALINE2, INVALID_TIMER); - status_change_end(bl, SC_SPEARQUICKEN, INVALID_TIMER); - status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER); - status_change_end(bl, SC_ONEHANDQUICKEN, INVALID_TIMER); - status_change_end(bl, SC_MER_QUICKEN, INVALID_TIMER); - status_change_end(bl, SC_ACCELERATION, INVALID_TIMER); - break; - case SC_ONEHANDQUICKEN: - //Removes the Aspd potion effect, as reported by Vicious. [Skotlex] - status_change_end(bl, SC_ATTHASTE_POTION1, INVALID_TIMER); - status_change_end(bl, SC_ATTHASTE_POTION2, INVALID_TIMER); - status_change_end(bl, SC_ATTHASTE_POTION3, INVALID_TIMER); - status_change_end(bl, SC_ATTHASTE_INFINITY, INVALID_TIMER); - break; - case SC_OVERTHRUSTMAX: - //Cancels Normal Overthrust. [Skotlex] - status_change_end(bl, SC_OVERTHRUST, INVALID_TIMER); - break; - case SC_KYRIE: - //Cancels Assumptio - status_change_end(bl, SC_ASSUMPTIO, INVALID_TIMER); - break; - case SC_DELUGE: - if (sc->data[SC_FOGWALL] && sc->data[SC_BLIND]) - status_change_end(bl, SC_BLIND, INVALID_TIMER); - break; - case SC_SILENCE: - if (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF) - status_change_end(bl, SC_GOSPEL, INVALID_TIMER); - break; - case SC_HIDING: - status_change_end(bl, SC_RG_CCONFINE_M, INVALID_TIMER); - status_change_end(bl, SC_RG_CCONFINE_S, INVALID_TIMER); - break; - case SC_BERSERK: - if( val3 == SC__BLOODYLUST ) break; - if(battle_config.berserk_cancels_buffs) { - status_change_end(bl, SC_ONEHANDQUICKEN, INVALID_TIMER); - status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER); - status_change_end(bl, SC_LKCONCENTRATION, INVALID_TIMER); - status_change_end(bl, SC_PARRYING, INVALID_TIMER); - status_change_end(bl, SC_AURABLADE, INVALID_TIMER); - status_change_end(bl, SC_MER_QUICKEN, INVALID_TIMER); - } -#ifdef RENEWAL - else { - status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER); - } -#endif - break; - case SC_ASSUMPTIO: - status_change_end(bl, SC_KYRIE, INVALID_TIMER); - status_change_end(bl, SC_KAITE, INVALID_TIMER); - break; - case SC_KAITE: - status_change_end(bl, SC_ASSUMPTIO, INVALID_TIMER); - break; - case SC_CARTBOOST: - if(sc->data[SC_DEC_AGI]) - { //Cancel Decrease Agi, but take no further effect [Skotlex] - status_change_end(bl, SC_DEC_AGI, INVALID_TIMER); - return 0; - } - break; - case SC_FUSION: - status_change_end(bl, SC_SOULLINK, INVALID_TIMER); - break; - case SC_GS_ADJUSTMENT: - status_change_end(bl, SC_GS_MADNESSCANCEL, INVALID_TIMER); - break; - case SC_GS_MADNESSCANCEL: - status_change_end(bl, SC_GS_ADJUSTMENT, INVALID_TIMER); - break; - //NPC_CHANGEUNDEAD will debuff Blessing and Agi Up - case SC_PROPERTYUNDEAD: - status_change_end(bl, SC_BLESSING, INVALID_TIMER); - status_change_end(bl, SC_INC_AGI, INVALID_TIMER); - break; - case SC_FOOD_STR: - status_change_end(bl, SC_FOOD_STR_CASH, INVALID_TIMER); - break; - case SC_FOOD_AGI: - status_change_end(bl, SC_FOOD_AGI_CASH, INVALID_TIMER); - break; - case SC_FOOD_VIT: - status_change_end(bl, SC_FOOD_VIT_CASH, INVALID_TIMER); - break; - case SC_FOOD_INT: - status_change_end(bl, SC_FOOD_INT_CASH, INVALID_TIMER); - break; - case SC_FOOD_DEX: - status_change_end(bl, SC_FOOD_DEX_CASH, INVALID_TIMER); - break; - case SC_FOOD_LUK: - status_change_end(bl, SC_FOOD_LUK_CASH, INVALID_TIMER); - break; - case SC_FOOD_STR_CASH: - status_change_end(bl, SC_FOOD_STR, INVALID_TIMER); - break; - case SC_FOOD_AGI_CASH: - status_change_end(bl, SC_FOOD_AGI, INVALID_TIMER); - break; - case SC_FOOD_VIT_CASH: - status_change_end(bl, SC_FOOD_VIT, INVALID_TIMER); - break; - case SC_FOOD_INT_CASH: - status_change_end(bl, SC_FOOD_INT, INVALID_TIMER); - break; - case SC_FOOD_DEX_CASH: - status_change_end(bl, SC_FOOD_DEX, INVALID_TIMER); - break; - case SC_FOOD_LUK_CASH: - status_change_end(bl, SC_FOOD_LUK, INVALID_TIMER); - break; - case SC_ENDURE: - if( val4 ) - status_change_end(bl, SC_LKCONCENTRATION, INVALID_TIMER); - break; - case SC_FIGHTINGSPIRIT: - status_change_end(bl, type, INVALID_TIMER); // Remove previous one. - break; - case SC_MARSHOFABYSS: - status_change_end(bl, SC_INCAGI, INVALID_TIMER); - status_change_end(bl, SC_WINDWALK, INVALID_TIMER); - status_change_end(bl, SC_ATTHASTE_POTION1, INVALID_TIMER); - status_change_end(bl, SC_ATTHASTE_POTION2, INVALID_TIMER); - status_change_end(bl, SC_ATTHASTE_POTION3, INVALID_TIMER); - status_change_end(bl, SC_ATTHASTE_INFINITY, INVALID_TIMER); - break; - case SC_SWING: - case SC_SYMPHONY_LOVE: - case SC_MOONLIT_SERENADE: - case SC_RUSH_WINDMILL: - case SC_ECHOSONG: - case SC_HARMONIZE: //group A doesn't overlap - if (type != SC_SWING) status_change_end(bl, SC_SWING, INVALID_TIMER); - if (type != SC_SYMPHONY_LOVE) status_change_end(bl, SC_SYMPHONY_LOVE, INVALID_TIMER); - if (type != SC_MOONLIT_SERENADE) status_change_end(bl, SC_MOONLIT_SERENADE, INVALID_TIMER); - if (type != SC_RUSH_WINDMILL) status_change_end(bl, SC_RUSH_WINDMILL, INVALID_TIMER); - if (type != SC_ECHOSONG) status_change_end(bl, SC_ECHOSONG, INVALID_TIMER); - if (type != SC_HARMONIZE) status_change_end(bl, SC_HARMONIZE, INVALID_TIMER); - break; - case SC_SIREN: - case SC_DEEP_SLEEP: - case SC_GLOOMYDAY: - case SC_SONG_OF_MANA: - case SC_DANCE_WITH_WUG: - case SC_SATURDAY_NIGHT_FEVER: - case SC_LERADS_DEW: - case SC_MELODYOFSINK: - case SC_BEYOND_OF_WARCRY: - case SC_UNLIMITED_HUMMING_VOICE: //group B - if (type != SC_SIREN) status_change_end(bl, SC_SIREN, INVALID_TIMER); - if (type != SC_DEEP_SLEEP) status_change_end(bl, SC_DEEP_SLEEP, INVALID_TIMER); - if (type != SC_LERADS_DEW) status_change_end(bl, SC_LERADS_DEW, INVALID_TIMER); - if (type != SC_MELODYOFSINK) status_change_end(bl, SC_MELODYOFSINK, INVALID_TIMER); - if (type != SC_BEYOND_OF_WARCRY) status_change_end(bl, SC_BEYOND_OF_WARCRY, INVALID_TIMER); - if (type != SC_UNLIMITED_HUMMING_VOICE) status_change_end(bl, SC_UNLIMITED_HUMMING_VOICE, INVALID_TIMER); - if (type != SC_GLOOMYDAY) { - status_change_end(bl, SC_GLOOMYDAY, INVALID_TIMER); - status_change_end(bl, SC_GLOOMYDAY_SK, INVALID_TIMER); - } - if (type != SC_SONG_OF_MANA) status_change_end(bl, SC_SONG_OF_MANA, INVALID_TIMER); - if (type != SC_DANCE_WITH_WUG) status_change_end(bl, SC_DANCE_WITH_WUG, INVALID_TIMER); - if (type != SC_SATURDAY_NIGHT_FEVER) { - if (sc->data[SC_SATURDAY_NIGHT_FEVER]) { - sc->data[SC_SATURDAY_NIGHT_FEVER]->val2 = 0; //mark to not lose hp - status_change_end(bl, SC_SATURDAY_NIGHT_FEVER, INVALID_TIMER); - } - } - break; - case SC_REFLECTSHIELD: - status_change_end(bl, SC_LG_REFLECTDAMAGE, INVALID_TIMER); - break; - case SC_LG_REFLECTDAMAGE: - status_change_end(bl, SC_REFLECTSHIELD, INVALID_TIMER); - break; - case SC_SHIELDSPELL_DEF: - case SC_SHIELDSPELL_MDEF: - case SC_SHIELDSPELL_REF: - status_change_end(bl, SC_MAGNIFICAT, INVALID_TIMER); - if( type != SC_SHIELDSPELL_DEF ) - status_change_end(bl, SC_SHIELDSPELL_DEF, INVALID_TIMER); - if( type != SC_SHIELDSPELL_MDEF ) - status_change_end(bl, SC_SHIELDSPELL_MDEF, INVALID_TIMER); - if( type != SC_SHIELDSPELL_REF ) - status_change_end(bl, SC_SHIELDSPELL_REF, INVALID_TIMER); - break; - case SC_GENTLETOUCH_ENERGYGAIN: - case SC_GENTLETOUCH_CHANGE: - case SC_GENTLETOUCH_REVITALIZE: - if( type != SC_GENTLETOUCH_REVITALIZE ) - status_change_end(bl, SC_GENTLETOUCH_REVITALIZE, INVALID_TIMER); - if( type != SC_GENTLETOUCH_ENERGYGAIN ) - status_change_end(bl, SC_GENTLETOUCH_ENERGYGAIN, INVALID_TIMER); - if( type != SC_GENTLETOUCH_CHANGE ) - status_change_end(bl, SC_GENTLETOUCH_CHANGE, INVALID_TIMER); - break; - case SC_INVINCIBLE: - status_change_end(bl, SC_INVINCIBLEOFF, INVALID_TIMER); - break; - case SC_INVINCIBLEOFF: - status_change_end(bl, SC_INVINCIBLE, INVALID_TIMER); - break; - case SC_MAGICPOWER: - status_change_end(bl, type, INVALID_TIMER); - break; - } - - //Check for overlapping fails - if( (sce = sc->data[type]) ) { - switch( type ) { - case SC_MER_FLEE: - case SC_MER_ATK: - case SC_MER_HP: - case SC_MER_SP: - case SC_MER_HIT: - if( sce->val1 > val1 ) - val1 = sce->val1; + case SC_FOOD_LUK: + if (sc->data[SC_FOOD_LUK_CASH] && sc->data[SC_FOOD_LUK_CASH]->val1 > val1) + return 0; break; - case SC_ADRENALINE: - case SC_ADRENALINE2: - case SC_WEAPONPERFECT: - case SC_OVERTHRUST: - if (sce->val2 > val2) + case SC_FOOD_STR_CASH: + if (sc->data[SC_FOOD_STR] && sc->data[SC_FOOD_STR]->val1 > val1) return 0; break; - case SC_S_LIFEPOTION: - case SC_L_LIFEPOTION: - case SC_CASH_BOSS_ALARM: - case SC_STUN: - case SC_SLEEP: - case SC_POISON: - case SC_CURSE: - case SC_SILENCE: - case SC_CONFUSION: - case SC_BLIND: - case SC_BLOODING: - case SC_DPOISON: - case SC_RG_CCONFINE_S: //Can't be re-closed in. - case SC_MARIONETTE_MASTER: - case SC_MARIONETTE: - case SC_NOCHAT: - case SC_HLIF_CHANGE: //Otherwise your Hp/Sp would get refilled while still within effect of the last invocation. - case SC__INVISIBILITY: - case SC__ENERVATION: - case SC__GROOMY: - case SC__IGNORANCE: - case SC__LAZINESS: - case SC__WEAKNESS: - case SC__UNLUCKY: - return 0; - case SC_COMBOATTACK: - case SC_DANCING: - case SC_DEVOTION: - case SC_ATTHASTE_POTION1: - case SC_ATTHASTE_POTION2: - case SC_ATTHASTE_POTION3: - case SC_ATTHASTE_INFINITY: - case SC_PLUSATTACKPOWER: - case SC_PLUSMAGICPOWER: - case SC_ENCHANTARMS: - case SC_ARMORPROPERTY: - case SC_ARMOR_RESIST: + case SC_FOOD_AGI_CASH: + if (sc->data[SC_FOOD_AGI] && sc->data[SC_FOOD_AGI]->val1 > val1) + return 0; break; - case SC_GOSPEL: - //Must not override a casting gospel char. - if(sce->val4 == BCT_SELF) + case SC_FOOD_VIT_CASH: + if (sc->data[SC_FOOD_VIT] && sc->data[SC_FOOD_VIT]->val1 > val1) return 0; - if(sce->val1 > val1) - return 1; break; - case SC_ENDURE: - if(sce->val4 && !val4) - return 1; //Don't let you override infinite endure. - if(sce->val1 > val1) - return 1; + case SC_FOOD_INT_CASH: + if (sc->data[SC_FOOD_INT] && sc->data[SC_FOOD_INT]->val1 > val1) + return 0; break; - case SC_KAAHI: - //Kaahi overwrites previous level regardless of existing level. - //Delete timer if it exists. - if (sce->val4 != INVALID_TIMER) { - timer->delete(sce->val4,status->kaahi_heal_timer); - sce->val4 = INVALID_TIMER; + case SC_FOOD_DEX_CASH: + if (sc->data[SC_FOOD_DEX] && sc->data[SC_FOOD_DEX]->val1 > val1) + return 0; + break; + case SC_FOOD_LUK_CASH: + if (sc->data[SC_FOOD_LUK] && sc->data[SC_FOOD_LUK]->val1 > val1) + return 0; + break; + case SC_CAMOUFLAGE: + if( sd && pc->checkskill(sd, RA_CAMOUFLAGE) < 3 && !skill->check_camouflage(bl,NULL) ) + return 0; + break; + case SC__STRIPACCESSARY: + if( sd ) { + int i = -1; + if( !(sd->bonus.unstripable_equip&EQP_ACC_L) ) { + i = sd->equip_index[EQI_ACC_L]; + if( i >= 0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_ARMOR ) + pc->unequipitem(sd,i,3); //L-Accessory + } if( !(sd->bonus.unstripable_equip&EQP_ACC_R) ) { + i = sd->equip_index[EQI_ACC_R]; + if( i >= 0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_ARMOR ) + pc->unequipitem(sd,i,3); //R-Accessory + } + if( i < 0 ) + return 0; } + if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC break; - case SC_JAILED: - //When a player is already jailed, do not edit the jail data. - val2 = sce->val2; - val3 = sce->val3; - val4 = sce->val4; + case SC_TOXIN: + case SC_PARALYSE: + case SC_VENOMBLEED: + case SC_MAGICMUSHROOM: + case SC_DEATHHURT: + case SC_PYREXIA: + case SC_OBLIVIONCURSE: + case SC_LEECHESEND: + { // it doesn't stack or even renewed + int i = SC_TOXIN; + for(; i<= SC_LEECHESEND; i++) + if(sc->data[i]) return 0; + } break; - case SC_LERADS_DEW: - if (sc && sc->data[SC_BERSERK]) + case SC_MAGNETICFIELD: + if(sc->data[SC_HOVERING]) return 0; - case SC_SHAPESHIFT: - case SC_PROPERTYWALK: break; - case SC_LEADERSHIP: - case SC_GLORYWOUNDS: - case SC_SOULCOLD: - case SC_HAWKEYES: - if( sce->val4 && !val4 )//you cannot override master guild aura + case SC_OFFERTORIUM: + if (sc->data[SC_MAGNIFICAT]) return 0; break; - case SC_JOINTBEAT: - val2 |= sce->val2; // stackable ailments - default: - if(sce->val1 > val1) - return 1; //Return true to not mess up skill animations. [Skotlex] + } + + //Check for BOSS resistances + if(st->mode&MD_BOSS && !(flag&1)) { + if (type>=SC_COMMON_MIN && type <= SC_COMMON_MAX) + return 0; + switch (type) { + case SC_BLESSING: + case SC_DEC_AGI: + case SC_PROVOKE: + case SC_COMA: + case SC_GRAVITATION: + case SC_NJ_SUITON: + case SC_RICHMANKIM: + case SC_ROKISWEIL: + case SC_FOGWALL: + case SC_FROSTMISTY: + case SC_BURNING: + case SC_MARSHOFABYSS: + case SC_ADORAMUS: + case SC_NEEDLE_OF_PARALYZE: + case SC_DEEP_SLEEP: + case SC_COLD: + + // Exploit prevention - kRO Fix + case SC_PYREXIA: + case SC_DEATHHURT: + case SC_TOXIN: + case SC_PARALYSE: + case SC_VENOMBLEED: + case SC_MAGICMUSHROOM: + case SC_OBLIVIONCURSE: + case SC_LEECHESEND: + + // Ranger Effects + case SC_WUGBITE: + case SC_ELECTRICSHOCKER: + case SC_MAGNETICFIELD: + + // Masquerades + case SC__ENERVATION: + case SC__GROOMY: + case SC__LAZINESS: + case SC__UNLUCKY: + case SC__WEAKNESS: + case SC__IGNORANCE: + + // Other Effects + case SC_VACUUM_EXTREME: + + return 0; } } - vd = status->get_viewdata(bl); - calc_flag = status->ChangeFlagTable[type]; - if(!(flag&4)) { //&4 - Do not parse val settings when loading SCs - switch(type) { - case SC_DEC_AGI: - case SC_INC_AGI: - val2 = 2 + val1; //Agi change - break; - case SC_ENDURE: - val2 = 7; // Hit-count [Celest] - if( !(flag&1) && (bl->type&(BL_PC|BL_MER)) && !map_flag_gvg(bl->m) && !map->list[bl->m].flag.battleground && !val4 ) { - struct map_session_data *tsd; - if( sd ) { - int i; - for( i = 0; i < 5; i++ ) { - if( sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) ) - status->change_start(&tsd->bl, type, 10000, val1, val2, val3, val4, tick, 1); - } - } else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag && (tsd = ((TBL_MER*)bl)->master) ) - status->change_start(&tsd->bl, type, 10000, val1, val2, val3, val4, tick, 1); + //Before overlapping fail, one must check for status cured. + switch (type) { + case SC_BLESSING: + //TO-DO Blessing and Agi up should do 1 damage against players on Undead Status, even on PvM + //but cannot be plagiarized (this requires aegis investigation on packets and official behavior) [Brainstorm] + if ((!undead_flag && st->race!=RC_DEMON) || bl->type == BL_PC) { + status_change_end(bl, SC_CURSE, INVALID_TIMER); + if (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE) + status_change_end(bl, SC_STONE, INVALID_TIMER); } - //val4 signals infinite endure (if val4 == 2 it is infinite endure from Berserk) - if( val4 ) - tick = -1; break; - case SC_AUTOBERSERK: - if (st->hp < st->max_hp>>2 && - (!sc->data[SC_PROVOKE] || sc->data[SC_PROVOKE]->val2==0)) - sc_start4(bl,SC_PROVOKE,100,10,1,0,0,60000); - tick = -1; - break; - case SC_CRUCIS: - val2 = 10 + 4*val1; //Def reduction - tick = -1; - clif->emotion(bl,E_SWT); - break; - case SC_MAXIMIZEPOWER: - tick_time = val2 = tick>0?tick:60000; - tick = -1; // duration sent to the client should be infinite + case SC_INC_AGI: + status_change_end(bl, SC_DEC_AGI, INVALID_TIMER); break; - case SC_EDP: // [Celest] - val2 = val1 + 2; //Chance to Poison enemies. - val3 = 50*(val1+1); //Damage increase (+50 +50*lv%) -#ifdef RENEWAL_EDP - val4 = 100 * ((val1 + 1)/2 + 2); -#endif - if( sd )//[Ind] - iROwiki says each level increases its duration by 3 seconds - tick += pc->checkskill(sd,GC_RESEARCHNEWPOISON)*3000; + case SC_QUAGMIRE: + status_change_end(bl, SC_CONCENTRATION, INVALID_TIMER); + status_change_end(bl, SC_TRUESIGHT, INVALID_TIMER); + status_change_end(bl, SC_WINDWALK, INVALID_TIMER); + //Also blocks the ones below... + case SC_DEC_AGI: + case SC_ADORAMUS: + status_change_end(bl, SC_CARTBOOST, INVALID_TIMER); + //Also blocks the ones below... + case SC_DONTFORGETME: + status_change_end(bl, SC_INC_AGI, INVALID_TIMER); + status_change_end(bl, SC_ADRENALINE, INVALID_TIMER); + status_change_end(bl, SC_ADRENALINE2, INVALID_TIMER); + status_change_end(bl, SC_SPEARQUICKEN, INVALID_TIMER); + status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER); + status_change_end(bl, SC_ONEHANDQUICKEN, INVALID_TIMER); + status_change_end(bl, SC_MER_QUICKEN, INVALID_TIMER); + status_change_end(bl, SC_ACCELERATION, INVALID_TIMER); break; - case SC_POISONREACT: - val2=(val1+1)/2 + val1/10; // Number of counters [Skotlex] - val3=50; // + 5*val1; //Chance to counter. [Skotlex] + case SC_ONEHANDQUICKEN: + //Removes the Aspd potion effect, as reported by Vicious. [Skotlex] + status_change_end(bl, SC_ATTHASTE_POTION1, INVALID_TIMER); + status_change_end(bl, SC_ATTHASTE_POTION2, INVALID_TIMER); + status_change_end(bl, SC_ATTHASTE_POTION3, INVALID_TIMER); + status_change_end(bl, SC_ATTHASTE_INFINITY, INVALID_TIMER); break; - case SC_MAGICROD: - val2 = val1*20; //SP gained + case SC_OVERTHRUSTMAX: + //Cancels Normal Overthrust. [Skotlex] + status_change_end(bl, SC_OVERTHRUST, INVALID_TIMER); break; case SC_KYRIE: - val2 = (int64)st->max_hp * (val1 * 2 + 10) / 100; //%Max HP to absorb - val3 = (val1 / 2 + 5); //Hits + //Cancels Assumptio + status_change_end(bl, SC_ASSUMPTIO, INVALID_TIMER); break; - case SC_MAGICPOWER: - //val1: Skill lv - val2 = 1; //Lasts 1 invocation - val3 = 5*val1; //Matk% increase - val4 = 0; // 0 = ready to be used, 1 = activated and running - break; - case SC_SACRIFICE: - val2 = 5; //Lasts 5 hits - tick = -1; - break; - case SC_ENCHANTPOISON: - val2= 250+50*val1; //Poisoning Chance (2.5+0.5%) in 1/10000 rate - case SC_ASPERSIO: - case SC_PROPERTYFIRE: - case SC_PROPERTYWATER: - case SC_PROPERTYWIND: - case SC_PROPERTYGROUND: - case SC_PROPERTYDARK: - case SC_PROPERTYTELEKINESIS: - skill->enchant_elemental_end(bl,type); - break; - case SC_ARMOR_PROPERTY: - // val1 : Element Lvl (if called by skill lvl 1, takes random value between 1 and 4) - // val2 : Element (When no element, random one is picked) - // val3 : 0 = called by skill 1 = called by script (fixed level) - if( !val2 ) val2 = rnd()%ELE_MAX; - - if( val1 == 1 && val3 == 0 ) - val1 = 1 + rnd()%4; - else if( val1 > 4 ) - val1 = 4; // Max Level - val3 = 0; // Not need to keep this info. + case SC_DELUGE: + if (sc->data[SC_FOGWALL] && sc->data[SC_BLIND]) + status_change_end(bl, SC_BLIND, INVALID_TIMER); break; - case SC_PROVIDENCE: - val2=val1*5; //Race/Ele resist + case SC_SILENCE: + if (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF) + status_change_end(bl, SC_GOSPEL, INVALID_TIMER); break; - case SC_REFLECTSHIELD: - val2=10+val1*3; // %Dmg reflected - if( !(flag&1) && (bl->type&(BL_PC|BL_MER)) ) { - struct map_session_data *tsd; - if( sd ) { - int i; - for( i = 0; i < 5; i++ ) { - if( sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) ) - status->change_start(&tsd->bl, type, 10000, val1, val2, 0, 0, tick, 1); - } - } else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag && (tsd = ((TBL_MER*)bl)->master) ) - status->change_start(&tsd->bl, type, 10000, val1, val2, 0, 0, tick, 1); + case SC_HIDING: + status_change_end(bl, SC_RG_CCONFINE_M, INVALID_TIMER); + status_change_end(bl, SC_RG_CCONFINE_S, INVALID_TIMER); + break; + case SC_BERSERK: + if( val3 == SC__BLOODYLUST ) + break; + if(battle_config.berserk_cancels_buffs) { + status_change_end(bl, SC_ONEHANDQUICKEN, INVALID_TIMER); + status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER); + status_change_end(bl, SC_LKCONCENTRATION, INVALID_TIMER); + status_change_end(bl, SC_PARRYING, INVALID_TIMER); + status_change_end(bl, SC_AURABLADE, INVALID_TIMER); + status_change_end(bl, SC_MER_QUICKEN, INVALID_TIMER); } + #ifdef RENEWAL + else { + status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER); + } + #endif break; - case SC_NOEQUIPWEAPON: - if (!sd) //Watk reduction - val2 = 25; + case SC_ASSUMPTIO: + status_change_end(bl, SC_KYRIE, INVALID_TIMER); + status_change_end(bl, SC_KAITE, INVALID_TIMER); break; - case SC_NOEQUIPSHIELD: - if (!sd) //Def reduction - val2 = 15; + case SC_KAITE: + status_change_end(bl, SC_ASSUMPTIO, INVALID_TIMER); break; - case SC_NOEQUIPARMOR: - if (!sd) //Vit reduction - val2 = 40; + case SC_CARTBOOST: + if(sc->data[SC_DEC_AGI] || sc->data[SC_ADORAMUS]) + { //Cancel Decrease Agi, but take no further effect [Skotlex] + status_change_end(bl, SC_DEC_AGI, INVALID_TIMER); + status_change_end(bl, SC_ADORAMUS, INVALID_TIMER); + return 0; + } break; - case SC_NOEQUIPHELM: - if (!sd) //Int reduction - val2 = 40; + case SC_FUSION: + status_change_end(bl, SC_SOULLINK, INVALID_TIMER); break; - case SC_AUTOSPELL: - //Val1 Skill LV of Autospell - //Val2 Skill ID to cast - //Val3 Max Lv to cast - val4 = 5 + val1*2; //Chance of casting + case SC_GS_ADJUSTMENT: + status_change_end(bl, SC_GS_MADNESSCANCEL, INVALID_TIMER); break; - case SC_VOLCANO: - val2 = val1*10; //Watk increase -#ifndef RENEWAL - if (st->def_ele != ELE_FIRE) - val2 = 0; -#endif + case SC_GS_MADNESSCANCEL: + status_change_end(bl, SC_GS_ADJUSTMENT, INVALID_TIMER); break; - case SC_VIOLENTGALE: - val2 = val1*3; //Flee increase -#ifndef RENEWAL - if (st->def_ele != ELE_WIND) - val2 = 0; -#endif + //NPC_CHANGEUNDEAD will debuff Blessing and Agi Up + case SC_PROPERTYUNDEAD: + status_change_end(bl, SC_BLESSING, INVALID_TIMER); + status_change_end(bl, SC_INC_AGI, INVALID_TIMER); break; - case SC_DELUGE: - val2 = skill->deluge_eff[val1-1]; //HP increase -#ifndef RENEWAL - if(st->def_ele != ELE_WATER) - val2 = 0; -#endif + case SC_FOOD_STR: + status_change_end(bl, SC_FOOD_STR_CASH, INVALID_TIMER); break; - case SC_NJ_SUITON: - if (!val2 || (sd && (sd->class_&MAPID_BASEMASK) == MAPID_NINJA)) { - //No penalties. - val2 = 0; //Agi penalty - val3 = 0; //Walk speed penalty - break; - } - val3 = 50; - val2 = 3*((val1+1)/3); - if (val1 > 4) val2--; + case SC_FOOD_AGI: + status_change_end(bl, SC_FOOD_AGI_CASH, INVALID_TIMER); break; - case SC_ONEHANDQUICKEN: - case SC_TWOHANDQUICKEN: - val2 = 300; - if (val1 > 10) //For boss casted skills [Skotlex] - val2 += 20*(val1-10); + case SC_FOOD_VIT: + status_change_end(bl, SC_FOOD_VIT_CASH, INVALID_TIMER); break; - case SC_MER_QUICKEN: - val2 = 300; + case SC_FOOD_INT: + status_change_end(bl, SC_FOOD_INT_CASH, INVALID_TIMER); break; -#ifndef RENEWAL_ASPD - case SC_SPEARQUICKEN: - val2 = 200+10*val1; + case SC_FOOD_DEX: + status_change_end(bl, SC_FOOD_DEX_CASH, INVALID_TIMER); break; -#endif - case SC_DANCING: - //val1 : Skill ID + LV - //val2 : Skill Group of the Dance. - //val3 : Brings the skill_lv (merged into val1 here) - //val4 : Partner - if (val1 == CG_MOONLIT) - clif->status_change(bl,SI_MOON,1,tick,0, 0, 0); - val1|= (val3<<16); - val3 = tick/1000; //Tick duration - tick_time = 1000; // [GodLesZ] tick time - break; - case SC_LONGING: -#ifdef RENEWAL - val2 = 50 + 10 * val1; -#else - val2 = 500-100*val1; //Aspd penalty. -#endif + case SC_FOOD_LUK: + status_change_end(bl, SC_FOOD_LUK_CASH, INVALID_TIMER); break; - case SC_EXPLOSIONSPIRITS: - val2 = 75 + 25*val1; //Cri bonus + case SC_FOOD_STR_CASH: + status_change_end(bl, SC_FOOD_STR, INVALID_TIMER); break; - - case SC_ATTHASTE_POTION1: - case SC_ATTHASTE_POTION2: - case SC_ATTHASTE_POTION3: - case SC_ATTHASTE_INFINITY: - val2 = 50*(2+type-SC_ATTHASTE_POTION1); + case SC_FOOD_AGI_CASH: + status_change_end(bl, SC_FOOD_AGI, INVALID_TIMER); break; - - case SC_WEDDING: - case SC_XMAS: - case SC_SUMMER: - case SC_HANBOK: - if (!vd) return 0; - //Store previous values as they could be removed. - unit->stop_attack(bl); + case SC_FOOD_VIT_CASH: + status_change_end(bl, SC_FOOD_VIT, INVALID_TIMER); break; - case SC_NOCHAT: - // [GodLesZ] FIXME: is this correct? a hardcoded interval of 60sec? what about configuration ?_? - tick = 60000; - val1 = battle_config.manner_system; //Mute filters. - if (sd) - { - clif->changestatus(sd,SP_MANNER,sd->status.manner); - clif->updatestatus(sd,SP_MANNER); - } + case SC_FOOD_INT_CASH: + status_change_end(bl, SC_FOOD_INT, INVALID_TIMER); break; - - case SC_STONE: - val3 = tick/1000; //Petrified HP-damage iterations. - if(val3 < 1) val3 = 1; - tick = val4; //Petrifying time. - if(val4 > 500) // not with WL_SIENNAEXECRATE - tick = max(tick, 1000); //Min time - calc_flag = 0; //Actual status changes take effect on petrified state. + case SC_FOOD_DEX_CASH: + status_change_end(bl, SC_FOOD_DEX, INVALID_TIMER); break; - - case SC_DPOISON: - //Lose 10/15% of your life as long as it doesn't brings life below 25% - if (st->hp > st->max_hp>>2) { - int diff = st->max_hp*(bl->type==BL_PC?10:15)/100; - if (st->hp - diff < st->max_hp>>2) - diff = st->hp - (st->max_hp>>2); - if( val2 && bl->type == BL_MOB ) { - struct block_list* src = map->id2bl(val2); - if( src ) - mob->log_damage((TBL_MOB*)bl,src,diff); - } - status_zap(bl, diff, 0); - } - // fall through - case SC_POISON: - val3 = tick/1000; //Damage iterations - if(val3 < 1) val3 = 1; - tick_time = 1000; // [GodLesZ] tick time - //val4: HP damage - if (bl->type == BL_PC) - val4 = (type == SC_DPOISON) ? 3 + st->max_hp/50 : 3 + st->max_hp*3/200; - else - val4 = (type == SC_DPOISON) ? 3 + st->max_hp/100 : 3 + st->max_hp/200; - + case SC_FOOD_LUK_CASH: + status_change_end(bl, SC_FOOD_LUK, INVALID_TIMER); break; - case SC_CONFUSION: - clif->emotion(bl,E_WHAT); + case SC_ENDURE: + if( val4 ) + status_change_end(bl, SC_LKCONCENTRATION, INVALID_TIMER); break; - case SC_BLOODING: - val4 = tick/10000; - if (!val4) val4 = 1; - tick_time = 10000; // [GodLesZ] tick time + case SC_FIGHTINGSPIRIT: + status_change_end(bl, type, INVALID_TIMER); // Remove previous one. break; - case SC_S_LIFEPOTION: - case SC_L_LIFEPOTION: - if( val1 == 0 ) return 0; - // val1 = heal percent/amout - // val2 = seconds between heals - // val4 = total of heals - if( val2 < 1 ) val2 = 1; - if( (val4 = tick/(val2 * 1000)) < 1 ) - val4 = 1; - tick_time = val2 * 1000; // [GodLesZ] tick time + case SC_MARSHOFABYSS: + status_change_end(bl, SC_INCAGI, INVALID_TIMER); + status_change_end(bl, SC_WINDWALK, INVALID_TIMER); + status_change_end(bl, SC_ATTHASTE_POTION1, INVALID_TIMER); + status_change_end(bl, SC_ATTHASTE_POTION2, INVALID_TIMER); + status_change_end(bl, SC_ATTHASTE_POTION3, INVALID_TIMER); + status_change_end(bl, SC_ATTHASTE_INFINITY, INVALID_TIMER); + break; + //Group A Status (doesn't overlap) + case SC_SWING: + case SC_SYMPHONY_LOVE: + case SC_MOONLIT_SERENADE: + case SC_RUSH_WINDMILL: + case SC_ECHOSONG: + case SC_HARMONIZE: + case SC_FRIGG_SONG: + if (type != SC_SWING) status_change_end(bl, SC_SWING, INVALID_TIMER); + if (type != SC_SYMPHONY_LOVE) status_change_end(bl, SC_SYMPHONY_LOVE, INVALID_TIMER); + if (type != SC_MOONLIT_SERENADE) status_change_end(bl, SC_MOONLIT_SERENADE, INVALID_TIMER); + if (type != SC_RUSH_WINDMILL) status_change_end(bl, SC_RUSH_WINDMILL, INVALID_TIMER); + if (type != SC_ECHOSONG) status_change_end(bl, SC_ECHOSONG, INVALID_TIMER); + if (type != SC_HARMONIZE) status_change_end(bl, SC_HARMONIZE, INVALID_TIMER); + if (type != SC_FRIGG_SONG) status_change_end(bl, SC_FRIGG_SONG, INVALID_TIMER); + break; + //Group B Status + case SC_SIREN: + case SC_DEEP_SLEEP: + case SC_SIRCLEOFNATURE: + case SC_LERADS_DEW: + case SC_MELODYOFSINK: + case SC_BEYOND_OF_WARCRY: + case SC_UNLIMITED_HUMMING_VOICE: + case SC_GLOOMYDAY: + case SC_SONG_OF_MANA: + case SC_DANCE_WITH_WUG: + if (type != SC_SIREN) status_change_end(bl, SC_SIREN, INVALID_TIMER); + if (type != SC_DEEP_SLEEP) status_change_end(bl, SC_DEEP_SLEEP, INVALID_TIMER); + if (type != SC_SIRCLEOFNATURE) status_change_end(bl, SC_SIRCLEOFNATURE, INVALID_TIMER); + if (type != SC_LERADS_DEW) status_change_end(bl, SC_LERADS_DEW, INVALID_TIMER); + if (type != SC_MELODYOFSINK) status_change_end(bl, SC_MELODYOFSINK, INVALID_TIMER); + if (type != SC_BEYOND_OF_WARCRY) status_change_end(bl, SC_BEYOND_OF_WARCRY, INVALID_TIMER); + if (type != SC_UNLIMITED_HUMMING_VOICE) status_change_end(bl, SC_UNLIMITED_HUMMING_VOICE, INVALID_TIMER); + if (type != SC_GLOOMYDAY) status_change_end(bl, SC_GLOOMYDAY, INVALID_TIMER); + if (type != SC_SONG_OF_MANA) status_change_end(bl, SC_SONG_OF_MANA, INVALID_TIMER); + if (type != SC_DANCE_WITH_WUG) status_change_end(bl, SC_DANCE_WITH_WUG, INVALID_TIMER); break; - case SC_CASH_BOSS_ALARM: - if( sd != NULL ) { - struct mob_data *boss_md = map->getmob_boss(bl->m); // Search for Boss on this Map - if( boss_md == NULL || boss_md->bl.prev == NULL ) { - // No MVP on this map - MVP is dead - clif->bossmapinfo(sd->fd, boss_md, 1); - return 0; // No need to start SC - } - val1 = boss_md->bl.id; - if( (val4 = tick/1000) < 1 ) - val4 = 1; - tick_time = 1000; // [GodLesZ] tick time - } + case SC_REFLECTSHIELD: + status_change_end(bl, SC_LG_REFLECTDAMAGE, INVALID_TIMER); break; - case SC_HIDING: - val2 = tick/1000; - tick_time = 1000; // [GodLesZ] tick time - val3 = 0; // unused, previously speed adjustment - val4 = val1+3; //Seconds before SP substraction happen. + case SC_LG_REFLECTDAMAGE: + status_change_end(bl, SC_REFLECTSHIELD, INVALID_TIMER); break; - case SC_CHASEWALK: - val2 = tick>0?tick:10000; //Interval at which SP is drained. - val3 = 35 - 5 * val1; //Speed adjustment. - if (sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_ROGUE) - val3 -= 40; - val4 = 10+val1*2; //SP cost. - if (map_flag_gvg(bl->m) || map->list[bl->m].flag.battleground) val4 *= 5; + case SC_SHIELDSPELL_DEF: + case SC_SHIELDSPELL_MDEF: + case SC_SHIELDSPELL_REF: + status_change_end(bl, SC_MAGNIFICAT, INVALID_TIMER); + status_change_end(bl, SC_SHIELDSPELL_DEF, INVALID_TIMER); + status_change_end(bl, SC_SHIELDSPELL_MDEF, INVALID_TIMER); + status_change_end(bl, SC_SHIELDSPELL_REF, INVALID_TIMER); break; - case SC_CLOAKING: - if (!sd) //Monsters should be able to walk with no penalties. [Skotlex] - val1 = 10; - tick_time = val2 = tick>0?tick:60000; //SP consumption rate. - tick = -1; // duration sent to the client should be infinite - val3 = 0; // unused, previously walk speed adjustment - //val4&1 signals the presence of a wall. - //val4&2 makes cloak not end on normal attacks [Skotlex] - //val4&4 makes cloak not end on using skills - if (bl->type == BL_PC || (bl->type == BL_MOB && ((TBL_MOB*)bl)->special_state.clone) ) //Standard cloaking. - val4 |= battle_config.pc_cloak_check_type&7; - else - val4 |= battle_config.monster_cloak_check_type&7; + case SC_GENTLETOUCH_ENERGYGAIN: + case SC_GENTLETOUCH_CHANGE: + case SC_GENTLETOUCH_REVITALIZE: + if( type != SC_GENTLETOUCH_REVITALIZE ) + status_change_end(bl, SC_GENTLETOUCH_REVITALIZE, INVALID_TIMER); + if( type != SC_GENTLETOUCH_ENERGYGAIN ) + status_change_end(bl, SC_GENTLETOUCH_ENERGYGAIN, INVALID_TIMER); + if( type != SC_GENTLETOUCH_CHANGE ) + status_change_end(bl, SC_GENTLETOUCH_CHANGE, INVALID_TIMER); break; - case SC_SIGHT: /* splash status */ - case SC_RUWACH: - case SC_WZ_SIGHTBLASTER: - val3 = skill->get_splash(val2, val1); //Val2 should bring the skill-id. - val2 = tick/250; - tick_time = 10; // [GodLesZ] tick time + case SC_INVINCIBLE: + status_change_end(bl, SC_INVINCIBLEOFF, INVALID_TIMER); break; - - //Permanent effects. - case SC_LEXAETERNA: - case SC_MODECHANGE: - case SC_WEIGHTOVER50: - case SC_WEIGHTOVER90: - case SC_BROKENWEAPON: - case SC_BROKENARMOR: - case SC_STORMKICK_READY: - case SC_DOWNKICK_READY: - case SC_COUNTERKICK_READY: - case SC_TURNKICK_READY: - case SC_DODGE_READY: - case SC_PUSH_CART: - case SC_ALL_RIDING: - tick = -1; + case SC_INVINCIBLEOFF: + status_change_end(bl, SC_INVINCIBLE, INVALID_TIMER); + break; + case SC_MAGICPOWER: + status_change_end(bl, type, INVALID_TIMER); break; + } - case SC_AUTOGUARD: - if( !(flag&1) ) { - struct map_session_data *tsd; - int i,t; - for( i = val2 = 0; i < val1; i++) { - t = 5-(i>>1); - val2 += (t < 0)? 1:t; + //Check for overlapping fails + if( (sce = sc->data[type]) ) { + switch( type ) { + case SC_MER_FLEE: + case SC_MER_ATK: + case SC_MER_HP: + case SC_MER_SP: + case SC_MER_HIT: + if( sce->val1 > val1 ) + val1 = sce->val1; + break; + case SC_ADRENALINE: + case SC_ADRENALINE2: + case SC_WEAPONPERFECT: + case SC_OVERTHRUST: + if (sce->val2 > val2) + return 0; + break; + case SC_S_LIFEPOTION: + case SC_L_LIFEPOTION: + case SC_CASH_BOSS_ALARM: + case SC_STUN: + case SC_SLEEP: + case SC_POISON: + case SC_CURSE: + case SC_SILENCE: + case SC_CONFUSION: + case SC_BLIND: + case SC_BLOODING: + case SC_DPOISON: + case SC_RG_CCONFINE_S: //Can't be re-closed in. + case SC_MARIONETTE_MASTER: + case SC_MARIONETTE: + case SC_NOCHAT: + case SC_HLIF_CHANGE: //Otherwise your Hp/Sp would get refilled while still within effect of the last invocation. + case SC_ABUNDANCE: + case SC_TOXIN: + case SC_PARALYSE: + case SC_VENOMBLEED: + case SC_MAGICMUSHROOM: + case SC_DEATHHURT: + case SC_PYREXIA: + case SC_OBLIVIONCURSE: + case SC_LEECHESEND: + case SC__INVISIBILITY: + case SC__ENERVATION: + case SC__GROOMY: + case SC__IGNORANCE: + case SC__LAZINESS: + case SC__WEAKNESS: + case SC__UNLUCKY: + case SC__CHAOS: + return 0; + case SC_COMBOATTACK: + case SC_DANCING: + case SC_DEVOTION: + case SC_ATTHASTE_POTION1: + case SC_ATTHASTE_POTION2: + case SC_ATTHASTE_POTION3: + case SC_ATTHASTE_INFINITY: + case SC_PLUSATTACKPOWER: + case SC_PLUSMAGICPOWER: + case SC_ENCHANTARMS: + case SC_ARMORPROPERTY: + case SC_ARMOR_RESIST: + break; + case SC_GOSPEL: + //Must not override a casting gospel char. + if(sce->val4 == BCT_SELF) + return 0; + if(sce->val1 > val1) + return 1; + break; + case SC_ENDURE: + if(sce->val4 && !val4) + return 1; //Don't let you override infinite endure. + if(sce->val1 > val1) + return 1; + break; + case SC_KAAHI: + //Kaahi overwrites previous level regardless of existing level. + //Delete timer if it exists. + if (sce->val4 != INVALID_TIMER) { + timer->delete(sce->val4,status->kaahi_heal_timer); + sce->val4 = INVALID_TIMER; } + break; + case SC_JAILED: + //When a player is already jailed, do not edit the jail data. + val2 = sce->val2; + val3 = sce->val3; + val4 = sce->val4; + break; + case SC_LERADS_DEW: + if (sc && sc->data[SC_BERSERK]) + return 0; + case SC_SHAPESHIFT: + case SC_PROPERTYWALK: + break; + case SC_LEADERSHIP: + case SC_GLORYWOUNDS: + case SC_SOULCOLD: + case SC_HAWKEYES: + if( sce->val4 && !val4 )//you cannot override master guild aura + return 0; + break; + case SC_JOINTBEAT: + val2 |= sce->val2; // stackable ailments + default: + if(sce->val1 > val1) + return 1; //Return true to not mess up skill animations. [Skotlex] + } + } - if( bl->type&(BL_PC|BL_MER) ) { + vd = status->get_viewdata(bl); + calc_flag = status->ChangeFlagTable[type]; + if(!(flag&4)) { //&4 - Do not parse val settings when loading SCs + switch(type) { + case SC_ADORAMUS: + sc_start(src,bl,SC_BLIND,100,val1,skill->get_time(status->sc2skill(type),val1)); + // Fall through to SC_INC_AGI + case SC_DEC_AGI: + case SC_INC_AGI: + val2 = 2 + val1; //Agi change + break; + case SC_ENDURE: + val2 = 7; // Hit-count [Celest] + if( !(flag&1) && (bl->type&(BL_PC|BL_MER)) && !map_flag_gvg(bl->m) && !map->list[bl->m].flag.battleground && !val4 ) { + struct map_session_data *tsd; + if( sd ) { + int i; + for( i = 0; i < 5; i++ ) { + if( sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) ) + status->change_start(bl, &tsd->bl, type, 10000, val1, val2, val3, val4, tick, 1); + } + } else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag && (tsd = ((TBL_MER*)bl)->master) ) + status->change_start(bl, &tsd->bl, type, 10000, val1, val2, val3, val4, tick, 1); + } + //val4 signals infinite endure (if val4 == 2 it is infinite endure from Berserk) + if( val4 ) + tick = -1; + break; + case SC_AUTOBERSERK: + if (st->hp < st->max_hp>>2 && + (!sc->data[SC_PROVOKE] || sc->data[SC_PROVOKE]->val2==0)) + sc_start4(src,bl,SC_PROVOKE,100,10,1,0,0,60000); + tick = -1; + break; + case SC_CRUCIS: + val2 = 10 + 4*val1; //Def reduction + tick = -1; + clif->emotion(bl,E_SWT); + break; + case SC_MAXIMIZEPOWER: + tick_time = val2 = tick>0?tick:60000; + tick = -1; // duration sent to the client should be infinite + break; + case SC_EDP: // [Celest] + val2 = val1 + 2; //Chance to Poison enemies. + val3 = 50*(val1+1); //Damage increase (+50 +50*lv%) + #ifdef RENEWAL_EDP + val4 = 100 * ((val1 + 1)/2 + 2); + #endif + if( sd )//[Ind] - iROwiki says each level increases its duration by 3 seconds + tick += pc->checkskill(sd,GC_RESEARCHNEWPOISON)*3000; + break; + case SC_POISONREACT: + val2=(val1+1)/2 + val1/10; // Number of counters [Skotlex] + val3=50; // + 5*val1; //Chance to counter. [Skotlex] + break; + case SC_MAGICROD: + val2 = val1*20; //SP gained + break; + case SC_KYRIE: + val2 = APPLY_RATE(st->max_hp, (val1 * 2 + 10)); //%Max HP to absorb + // val4 holds current about of party memebers when casting AB_PRAEFATIO, + // as Praefatio's barrier has more health and blocks more hits than Kyrie Elesion. + if( val4 < 1 ) //== PR_KYRIE + val3 = (val1 / 2 + 5); // Hits + else { //== AB_PRAEFATIO + val2 += val4 * 2; //Increase barrier strength per party member. + val3 = 6 + val1; + } + if( sd ) + val1 = min(val1,pc->checkskill(sd,PR_KYRIE)); // use skill level to determine barrier health. + break; + case SC_MAGICPOWER: + //val1: Skill lv + val2 = 1; //Lasts 1 invocation + val3 = 5*val1; //Matk% increase + val4 = 0; // 0 = ready to be used, 1 = activated and running + break; + case SC_SACRIFICE: + val2 = 5; //Lasts 5 hits + tick = -1; + break; + case SC_ENCHANTPOISON: + val2= 250+50*val1; //Poisoning Chance (2.5+0.5%) in 1/10000 rate + case SC_ASPERSIO: + case SC_PROPERTYFIRE: + case SC_PROPERTYWATER: + case SC_PROPERTYWIND: + case SC_PROPERTYGROUND: + case SC_PROPERTYDARK: + case SC_PROPERTYTELEKINESIS: + skill->enchant_elemental_end(bl,type); + break; + case SC_ARMOR_PROPERTY: + // val1 : Element Lvl (if called by skill lvl 1, takes random value between 1 and 4) + // val2 : Element (When no element, random one is picked) + // val3 : 0 = called by skill 1 = called by script (fixed level) + if( !val2 ) val2 = rnd()%ELE_MAX; + + if( val1 == 1 && val3 == 0 ) + val1 = 1 + rnd()%4; + else if( val1 > 4 ) + val1 = 4; // Max Level + val3 = 0; // Not need to keep this info. + break; + case SC_PROVIDENCE: + val2=val1*5; //Race/Ele resist + break; + case SC_REFLECTSHIELD: + val2=10+val1*3; // %Dmg reflected + if( !(flag&1) && (bl->type&(BL_PC|BL_MER)) ) { + struct map_session_data *tsd; if( sd ) { + int i; for( i = 0; i < 5; i++ ) { if( sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) ) - status->change_start(&tsd->bl, type, 10000, val1, val2, 0, 0, tick, 1); + status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, 1); } + } else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag && (tsd = ((TBL_MER*)bl)->master) ) + status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, 1); + } + break; + case SC_NOEQUIPWEAPON: + if (!sd) //Watk reduction + val2 = 25; + break; + case SC_NOEQUIPSHIELD: + if (!sd) //Def reduction + val2 = 15; + break; + case SC_NOEQUIPARMOR: + if (!sd) //Vit reduction + val2 = 40; + break; + case SC_NOEQUIPHELM: + if (!sd) //Int reduction + val2 = 40; + break; + case SC_AUTOSPELL: + //Val1 Skill LV of Autospell + //Val2 Skill ID to cast + //Val3 Max Lv to cast + val4 = 5 + val1*2; //Chance of casting + break; + case SC_VOLCANO: + val2 = val1*10; //Watk increase + #ifndef RENEWAL + if (st->def_ele != ELE_FIRE) + val2 = 0; + #endif + break; + case SC_VIOLENTGALE: + val2 = val1*3; //Flee increase + #ifndef RENEWAL + if (st->def_ele != ELE_WIND) + val2 = 0; + #endif + break; + case SC_DELUGE: + val2 = skill->deluge_eff[val1-1]; //HP increase + #ifndef RENEWAL + if(st->def_ele != ELE_WATER) + val2 = 0; + #endif + break; + case SC_NJ_SUITON: + if (!val2 || (sd && (sd->class_&MAPID_BASEMASK) == MAPID_NINJA)) { + //No penalties. + val2 = 0; //Agi penalty + val3 = 0; //Walk speed penalty + break; + } + val3 = 50; + val2 = 3*((val1+1)/3); + if (val1 > 4) val2--; + break; + case SC_ONEHANDQUICKEN: + case SC_TWOHANDQUICKEN: + val2 = 300; + if (val1 > 10) //For boss casted skills [Skotlex] + val2 += 20*(val1-10); + break; + case SC_MER_QUICKEN: + val2 = 300; + break; + #ifndef RENEWAL_ASPD + case SC_SPEARQUICKEN: + val2 = 200+10*val1; + break; + #endif + case SC_DANCING: + //val1 : Skill ID + LV + //val2 : Skill Group of the Dance. + //val3 : Brings the skill_lv (merged into val1 here) + //val4 : Partner + if (val1 == CG_MOONLIT) + clif->status_change(bl,SI_MOON,1,tick,0, 0, 0); + val1|= (val3<<16); + val3 = tick/1000; //Tick duration + tick_time = 1000; // [GodLesZ] tick time + break; + case SC_LONGING: + #ifdef RENEWAL + val2 = 50 + 10 * val1; + #else + val2 = 500-100*val1; //Aspd penalty. + #endif + break; + case SC_EXPLOSIONSPIRITS: + val2 = 75 + 25*val1; //Cri bonus + break; + + case SC_ATTHASTE_POTION1: + case SC_ATTHASTE_POTION2: + case SC_ATTHASTE_POTION3: + case SC_ATTHASTE_INFINITY: + val2 = 50*(2+type-SC_ATTHASTE_POTION1); + break; + + case SC_WEDDING: + case SC_XMAS: + case SC_SUMMER: + case SC_HANBOK: + case SC_OKTOBERFEST: + if (!vd) return 0; + //Store previous values as they could be removed. + unit->stop_attack(bl); + break; + case SC_NOCHAT: + // [GodLesZ] FIXME: is this correct? a hardcoded interval of 60sec? what about configuration ?_? + tick = 60000; + val1 = battle_config.manner_system; //Mute filters. + if (sd) + { + clif->changestatus(sd,SP_MANNER,sd->status.manner); + clif->updatestatus(sd,SP_MANNER); + } + break; + + case SC_STONE: + val3 = tick/1000; //Petrified HP-damage iterations. + if(val3 < 1) val3 = 1; + tick = val4; //Petrifying time. + if(val4 > 500) // not with WL_SIENNAEXECRATE + tick = max(tick, 1000); //Min time + calc_flag = 0; //Actual status changes take effect on petrified state. + break; + + case SC_DPOISON: + //Lose 10/15% of your life as long as it doesn't brings life below 25% + if (st->hp > st->max_hp>>2) { + int diff = st->max_hp*(bl->type==BL_PC?10:15)/100; + if (st->hp - diff < st->max_hp>>2) + diff = st->hp - (st->max_hp>>2); + if( val2 && bl->type == BL_MOB ) { + struct block_list* src2 = map->id2bl(val2); + if( src2 ) + mob->log_damage((TBL_MOB*)bl,src2,diff); } - else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag && (tsd = ((TBL_MER*)bl)->master) ) - status->change_start(&tsd->bl, type, 10000, val1, val2, 0, 0, tick, 1); + status_zap(bl, diff, 0); } - } - break; + // fall through + case SC_POISON: + val3 = tick/1000; //Damage iterations + if(val3 < 1) val3 = 1; + tick_time = 1000; // [GodLesZ] tick time + //val4: HP damage + if (bl->type == BL_PC) + val4 = (type == SC_DPOISON) ? 3 + st->max_hp/50 : 3 + st->max_hp*3/200; + else + val4 = (type == SC_DPOISON) ? 3 + st->max_hp/100 : 3 + st->max_hp/200; - case SC_DEFENDER: - if (!(flag&1)) { - val2 = 5 + 15*val1; //Damage reduction + break; + case SC_CONFUSION: + clif->emotion(bl,E_WHAT); + break; + case SC_BLOODING: + val4 = tick/10000; + if (!val4) val4 = 1; + tick_time = 10000; // [GodLesZ] tick time + break; + case SC_S_LIFEPOTION: + case SC_L_LIFEPOTION: + if( val1 == 0 ) return 0; + // val1 = heal percent/amout + // val2 = seconds between heals + // val4 = total of heals + if( val2 < 1 ) val2 = 1; + if( (val4 = tick/(val2 * 1000)) < 1 ) + val4 = 1; + tick_time = val2 * 1000; // [GodLesZ] tick time + break; + case SC_CASH_BOSS_ALARM: + if( sd != NULL ) { + struct mob_data *boss_md = map->getmob_boss(bl->m); // Search for Boss on this Map + if( boss_md == NULL || boss_md->bl.prev == NULL ) { + // No MVP on this map - MVP is dead + clif->bossmapinfo(sd->fd, boss_md, 1); + return 0; // No need to start SC + } + val1 = boss_md->bl.id; + if( (val4 = tick/1000) < 1 ) + val4 = 1; + tick_time = 1000; // [GodLesZ] tick time + } + break; + case SC_HIDING: + val2 = tick/1000; + tick_time = 1000; // [GodLesZ] tick time val3 = 0; // unused, previously speed adjustment - val4 = 250 - 50*val1; //Aspd adjustment + val4 = val1+3; //Seconds before SP substraction happen. + break; + case SC_CHASEWALK: + val2 = tick>0?tick:10000; //Interval at which SP is drained. + val3 = 35 - 5 * val1; //Speed adjustment. + if (sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_ROGUE) + val3 -= 40; + val4 = 10+val1*2; //SP cost. + if (map_flag_gvg(bl->m) || map->list[bl->m].flag.battleground) val4 *= 5; + break; + case SC_CLOAKING: + if (!sd) //Monsters should be able to walk with no penalties. [Skotlex] + val1 = 10; + tick_time = val2 = tick>0?tick:60000; //SP consumption rate. + tick = -1; // duration sent to the client should be infinite + val3 = 0; // unused, previously walk speed adjustment + //val4&1 signals the presence of a wall. + //val4&2 makes cloak not end on normal attacks [Skotlex] + //val4&4 makes cloak not end on using skills + if (bl->type == BL_PC || (bl->type == BL_MOB && ((TBL_MOB*)bl)->special_state.clone) ) //Standard cloaking. + val4 |= battle_config.pc_cloak_check_type&7; + else + val4 |= battle_config.monster_cloak_check_type&7; + break; + case SC_SIGHT: /* splash status */ + case SC_RUWACH: + case SC_WZ_SIGHTBLASTER: + val3 = skill->get_splash(val2, val1); //Val2 should bring the skill-id. + val2 = tick/250; + tick_time = 10; // [GodLesZ] tick time + break; - if (sd) { + //Permanent effects. + case SC_LEXAETERNA: + case SC_MODECHANGE: + case SC_WEIGHTOVER50: + case SC_WEIGHTOVER90: + case SC_BROKENWEAPON: + case SC_BROKENARMOR: + case SC_STORMKICK_READY: + case SC_DOWNKICK_READY: + case SC_COUNTERKICK_READY: + case SC_TURNKICK_READY: + case SC_DODGE_READY: + case SC_PUSH_CART: + case SC_ALL_RIDING: + tick = -1; + break; + + case SC_AUTOGUARD: + if( !(flag&1) ) { struct map_session_data *tsd; - int i; - for (i = 0; i < 5; i++) { - //See if there are devoted characters, and pass the status to them. [Skotlex] - if (sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i]))) - status->change_start(&tsd->bl,type,10000,val1,5+val1*5,val3,val4,tick,1); + int i,t; + for( i = val2 = 0; i < val1; i++) { + t = 5-(i>>1); + val2 += (t < 0)? 1:t; + } + + if( bl->type&(BL_PC|BL_MER) ) { + if( sd ) { + for( i = 0; i < 5; i++ ) { + if( sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) ) + status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, 1); + } + } + else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag && (tsd = ((TBL_MER*)bl)->master) ) + status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, 1); } } - } - break; + break; - case SC_TENSIONRELAX: - if (sd) { - pc_setsit(sd); - clif->sitting(&sd->bl); - } - val2 = 12; //SP cost - val4 = 10000; //Decrease at 10secs intervals. - val3 = tick/val4; - tick = -1; // duration sent to the client should be infinite - tick_time = val4; // [GodLesZ] tick time - break; - case SC_PARRYING: - val2 = 20 + val1*3; //Block Chance - break; + case SC_DEFENDER: + if (!(flag&1)) { + val2 = 5 + 15*val1; //Damage reduction + val3 = 0; // unused, previously speed adjustment + val4 = 250 - 50*val1; //Aspd adjustment + + if (sd) { + struct map_session_data *tsd; + int i; + for (i = 0; i < 5; i++) { + //See if there are devoted characters, and pass the status to them. [Skotlex] + if (sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i]))) + status->change_start(bl, &tsd->bl,type,10000,val1,5+val1*5,val3,val4,tick,1); + } + } + } + break; - case SC_WINDWALK: - val2 = (val1+1)/2; // Flee bonus is 1/1/2/2/3/3/4/4/5/5 - break; + case SC_TENSIONRELAX: + if (sd) { + pc_setsit(sd); + clif->sitting(&sd->bl); + } + val2 = 12; //SP cost + val4 = 10000; //Decrease at 10secs intervals. + val3 = tick/val4; + tick = -1; // duration sent to the client should be infinite + tick_time = val4; // [GodLesZ] tick time + break; + case SC_PARRYING: + val2 = 20 + val1*3; //Block Chance + break; - case SC_JOINTBEAT: - if( val2&BREAK_NECK ) - sc_start2(bl,SC_BLOODING,100,val1,val3,skill->get_time2(status->sc2skill(type),val1)); - break; + case SC_WINDWALK: + val2 = (val1+1)/2; // Flee bonus is 1/1/2/2/3/3/4/4/5/5 + break; - case SC_BERSERK: - if( val3 == SC__BLOODYLUST ) - sc_start(bl,(sc_type)val3,100,val1,tick); - if( !val3 && !(!sc->data[SC_ENDURE] || !sc->data[SC_ENDURE]->val4) ) - sc_start4(bl, SC_ENDURE, 100,10,0,0,2, tick); - //HP healing is performing after the calc_status call. - //Val2 holds HP penalty - if (!val4) val4 = skill->get_time2(status->sc2skill(type),val1); - if (!val4) val4 = 10000; //Val4 holds damage interval - val3 = tick/val4; //val3 holds skill duration - tick_time = val4; // [GodLesZ] tick time - break; + case SC_JOINTBEAT: + if( val2&BREAK_NECK ) + sc_start2(src,bl,SC_BLOODING,100,val1,val3,skill->get_time2(status->sc2skill(type),val1)); + break; - case SC_GOSPEL: - if(val4 == BCT_SELF) { - // self effect - val2 = tick/10000; - tick_time = 10000; // [GodLesZ] tick time - status->change_clear_buffs(bl,3); //Remove buffs/debuffs - } - break; + case SC_BERSERK: + if( val3 == SC__BLOODYLUST ) + sc_start(src,bl,(sc_type)val3,100,val1,tick); + if( !val3 && !(!sc->data[SC_ENDURE] || !sc->data[SC_ENDURE]->val4) ) + sc_start4(src, bl, SC_ENDURE, 100,10,0,0,2, tick); + //HP healing is performing after the calc_status call. + //Val2 holds HP penalty + if (!val4) val4 = skill->get_time2(status->sc2skill(type),val1); + if (!val4) val4 = 10000; //Val4 holds damage interval + val3 = tick/val4; //val3 holds skill duration + tick_time = val4; // [GodLesZ] tick time + break; - case SC_MARIONETTE_MASTER: - { - int stat; - - val3 = 0; - val4 = 0; - stat = ( sd ? sd->status.str : status->get_base_status(bl)->str ) / 2; val3 |= cap_value(stat,0,0xFF)<<16; - stat = ( sd ? sd->status.agi : status->get_base_status(bl)->agi ) / 2; val3 |= cap_value(stat,0,0xFF)<<8; - stat = ( sd ? sd->status.vit : status->get_base_status(bl)->vit ) / 2; val3 |= cap_value(stat,0,0xFF); - stat = ( sd ? sd->status.int_: status->get_base_status(bl)->int_) / 2; val4 |= cap_value(stat,0,0xFF)<<16; - stat = ( sd ? sd->status.dex : status->get_base_status(bl)->dex ) / 2; val4 |= cap_value(stat,0,0xFF)<<8; - stat = ( sd ? sd->status.luk : status->get_base_status(bl)->luk ) / 2; val4 |= cap_value(stat,0,0xFF); - } - break; - case SC_MARIONETTE: - { - int stat,max_stat; - // fetch caster information - struct block_list *pbl = map->id2bl(val1); - struct status_change *psc = pbl ? status->get_sc(pbl) : NULL; - struct status_change_entry *psce = psc ? psc->data[SC_MARIONETTE_MASTER] : NULL; - // fetch target's stats - struct status_data* tst = status->get_status_data(bl); // battle status - - if (!psce) - return 0; + case SC_GOSPEL: + if(val4 == BCT_SELF) { + // self effect + val2 = tick/10000; + tick_time = 10000; // [GodLesZ] tick time + status->change_clear_buffs(bl,3); //Remove buffs/debuffs + } + break; - val3 = 0; - val4 = 0; - max_stat = battle_config.max_parameter; //Cap to 99 (default) - stat = (psce->val3 >>16)&0xFF; stat = min(stat, max_stat - tst->str ); val3 |= cap_value(stat,0,0xFF)<<16; - stat = (psce->val3 >> 8)&0xFF; stat = min(stat, max_stat - tst->agi ); val3 |= cap_value(stat,0,0xFF)<<8; - stat = (psce->val3 >> 0)&0xFF; stat = min(stat, max_stat - tst->vit ); val3 |= cap_value(stat,0,0xFF); - stat = (psce->val4 >>16)&0xFF; stat = min(stat, max_stat - tst->int_); val4 |= cap_value(stat,0,0xFF)<<16; - stat = (psce->val4 >> 8)&0xFF; stat = min(stat, max_stat - tst->dex ); val4 |= cap_value(stat,0,0xFF)<<8; - stat = (psce->val4 >> 0)&0xFF; stat = min(stat, max_stat - tst->luk ); val4 |= cap_value(stat,0,0xFF); - } - break; - case SC_SWORDREJECT: - val2 = 15*val1; //Reflect chance - val3 = 3; //Reflections - tick = -1; - break; + case SC_MARIONETTE_MASTER: + { + int stat; + + val3 = 0; + val4 = 0; + stat = ( sd ? sd->status.str : status->get_base_status(bl)->str ) / 2; val3 |= cap_value(stat,0,0xFF)<<16; + stat = ( sd ? sd->status.agi : status->get_base_status(bl)->agi ) / 2; val3 |= cap_value(stat,0,0xFF)<<8; + stat = ( sd ? sd->status.vit : status->get_base_status(bl)->vit ) / 2; val3 |= cap_value(stat,0,0xFF); + stat = ( sd ? sd->status.int_: status->get_base_status(bl)->int_) / 2; val4 |= cap_value(stat,0,0xFF)<<16; + stat = ( sd ? sd->status.dex : status->get_base_status(bl)->dex ) / 2; val4 |= cap_value(stat,0,0xFF)<<8; + stat = ( sd ? sd->status.luk : status->get_base_status(bl)->luk ) / 2; val4 |= cap_value(stat,0,0xFF); + } + break; + case SC_MARIONETTE: + { + int stat,max_stat; + // fetch caster information + struct block_list *pbl = map->id2bl(val1); + struct status_change *psc = pbl ? status->get_sc(pbl) : NULL; + struct status_change_entry *psce = psc ? psc->data[SC_MARIONETTE_MASTER] : NULL; + // fetch target's stats + struct status_data* tst = status->get_status_data(bl); // battle status + + if (!psce) + return 0; - case SC_MEMORIZE: - val2 = 5; //Memorized casts. - tick = -1; - break; + val3 = 0; + val4 = 0; + max_stat = battle_config.max_parameter; //Cap to 99 (default) + stat = (psce->val3 >>16)&0xFF; stat = min(stat, max_stat - tst->str ); val3 |= cap_value(stat,0,0xFF)<<16; + stat = (psce->val3 >> 8)&0xFF; stat = min(stat, max_stat - tst->agi ); val3 |= cap_value(stat,0,0xFF)<<8; + stat = (psce->val3 >> 0)&0xFF; stat = min(stat, max_stat - tst->vit ); val3 |= cap_value(stat,0,0xFF); + stat = (psce->val4 >>16)&0xFF; stat = min(stat, max_stat - tst->int_); val4 |= cap_value(stat,0,0xFF)<<16; + stat = (psce->val4 >> 8)&0xFF; stat = min(stat, max_stat - tst->dex ); val4 |= cap_value(stat,0,0xFF)<<8; + stat = (psce->val4 >> 0)&0xFF; stat = min(stat, max_stat - tst->luk ); val4 |= cap_value(stat,0,0xFF); + } + break; + case SC_SWORDREJECT: + val2 = 15*val1; //Reflect chance + val3 = 3; //Reflections + tick = -1; + break; - case SC_GRAVITATION: - val2 = 50*val1; //aspd reduction - break; + case SC_MEMORIZE: + val2 = 5; //Memorized casts. + tick = -1; + break; - case SC_GDSKILL_REGENERATION: - if (val1 == 1) - val2 = 2; - else - val2 = val1; //HP Regerenation rate: 200% 200% 300% - val3 = val1; //SP Regeneration Rate: 100% 200% 300% - //if val4 comes set, this blocks regen rather than increase it. - break; + case SC_GRAVITATION: + val2 = 50*val1; //aspd reduction + break; - case SC_DEVOTION: - { - struct block_list *d_bl; - struct status_change *d_sc; - - if( (d_bl = map->id2bl(val1)) && (d_sc = status->get_sc(d_bl)) && d_sc->count ) { - // Inherits Status From Source - const enum sc_type types[] = { SC_AUTOGUARD, SC_DEFENDER, SC_REFLECTSHIELD, SC_ENDURE }; - enum sc_type type2; - int i = (map_flag_gvg(bl->m) || map->list[bl->m].flag.battleground)?2:3; - while( i >= 0 ) { - type2 = types[i]; - if( d_sc->data[type2] ) - sc_start(bl, type2, 100, d_sc->data[type2]->val1, skill->get_time(status->sc2skill(type2),d_sc->data[type2]->val1)); - i--; + case SC_GDSKILL_REGENERATION: + if (val1 == 1) + val2 = 2; + else + val2 = val1; //HP Regerenation rate: 200% 200% 300% + val3 = val1; //SP Regeneration Rate: 100% 200% 300% + //if val4 comes set, this blocks regen rather than increase it. + break; + + case SC_DEVOTION: + { + struct block_list *d_bl; + struct status_change *d_sc; + + if( (d_bl = map->id2bl(val1)) && (d_sc = status->get_sc(d_bl)) && d_sc->count ) { + // Inherits Status From Source + const enum sc_type types[] = { SC_AUTOGUARD, SC_DEFENDER, SC_REFLECTSHIELD, SC_ENDURE }; + enum sc_type type2; + int i = (map_flag_gvg(bl->m) || map->list[bl->m].flag.battleground)?2:3; + while( i >= 0 ) { + type2 = types[i]; + if( d_sc->data[type2] ) + sc_start(bl, bl, type2, 100, d_sc->data[type2]->val1, skill->get_time(status->sc2skill(type2),d_sc->data[type2]->val1)); + i--; + } } + break; } - break; - } - case SC_COMA: //Coma. Sends a char to 1HP. If val2, do not zap sp - if( val3 && bl->type == BL_MOB ) { - struct block_list* src = map->id2bl(val3); - if( src ) - mob->log_damage((TBL_MOB*)bl,src,st->hp - 1); + case SC_COMA: //Coma. Sends a char to 1HP. If val2, do not zap sp + if( val3 && bl->type == BL_MOB ) { + struct block_list* src2 = map->id2bl(val3); + if( src2 ) + mob->log_damage((TBL_MOB*)bl,src2,st->hp - 1); + } + status_zap(bl, st->hp-1, val2 ? 0 : st->sp); + return 1; + break; + case SC_RG_CCONFINE_S: + { + struct block_list *src2 = val2 ? map->id2bl(val2) : NULL; + struct status_change *sc2 = src ? status->get_sc(src2) : NULL; + struct status_change_entry *sce2 = sc2 ? sc2->data[SC_RG_CCONFINE_M] : NULL; + if (src2 && sc2) { + if (!sce2) //Start lock on caster. + sc_start4(src,src2,SC_RG_CCONFINE_M,100,val1,1,0,0,tick+1000); + else { //Increase count of locked enemies and refresh time. + (sce2->val2)++; + timer->delete(sce2->timer, status->change_timer); + sce2->timer = timer->add(timer->gettick()+tick+1000, status->change_timer, src2->id, SC_RG_CCONFINE_M); + } + } else //Status failed. + return 0; } - status_zap(bl, st->hp-1, val2 ? 0 : st->sp); - return 1; - break; - case SC_RG_CCONFINE_S: - { - struct block_list *src = val2 ? map->id2bl(val2) : NULL; - struct status_change *sc2 = src ? status->get_sc(src) : NULL; - struct status_change_entry *sce2 = sc2 ? sc2->data[SC_RG_CCONFINE_M] : NULL; - if (src && sc2) { - if (!sce2) //Start lock on caster. - sc_start4(src,SC_RG_CCONFINE_M,100,val1,1,0,0,tick+1000); - else { //Increase count of locked enemies and refresh time. - (sce2->val2)++; - timer->delete(sce2->timer, status->change_timer); - sce2->timer = timer->add(timer->gettick()+tick+1000, status->change_timer, src->id, SC_RG_CCONFINE_M); + break; + case SC_KAITE: + val2 = 1+val1/5; //Number of bounces: 1 + skill_lv/5 + break; + case SC_KAUPE: + switch (val1) { + case 3: //33*3 + 1 -> 100% + val2++; + case 1: + case 2: //33, 66% + val2 += 33*val1; + val3 = 1; //Dodge 1 attack total. + break; + default: //Custom. For high level mob usage, higher level means more blocks. [Skotlex] + val2 = 100; + val3 = val1-2; + break; } - } else //Status failed. - return 0; - } - break; - case SC_KAITE: - val2 = 1+val1/5; //Number of bounces: 1 + skill_lv/5 - break; - case SC_KAUPE: - switch (val1) { - case 3: //33*3 + 1 -> 100% - val2++; - case 1: - case 2: //33, 66% - val2 += 33*val1; - val3 = 1; //Dodge 1 attack total. - break; - default: //Custom. For high level mob usage, higher level means more blocks. [Skotlex] - val2 = 100; - val3 = val1-2; - break; - } - break; - - case SC_COMBOATTACK: { - //val1: Skill ID - //val2: When given, target (for autotargetting skills) - //val3: When set, this combo time should NOT delay attack/movement - //val3: TK: Last used kick - //val4: TK: Combo time - struct unit_data *ud = unit->bl2ud(bl); - if (ud && !val3) { - tick += 300 * battle_config.combo_delay_rate/100; - ud->attackabletime = timer->gettick()+tick; - unit->set_walkdelay(bl, timer->gettick(), tick, 1); - } - val3 = 0; - val4 = tick; - } - break; - case SC_EARTHSCROLL: - val2 = 11-val1; //Chance to consume: 11-skill_lv% - break; - case SC_RUN: - val4 = timer->gettick(); //Store time at which you started running. - tick = -1; - break; - case SC_KAAHI: - val2 = 200*val1; //HP heal - val3 = 5*val1; //SP cost - val4 = INVALID_TIMER; //Kaahi Timer. - break; - case SC_BLESSING: - if ((!undead_flag && st->race!=RC_DEMON) || bl->type == BL_PC) - val2 = val1; - else - val2 = 0; //0 -> Half stat. - break; - case SC_TRICKDEAD: - if (vd) vd->dead_sit = 1; - tick = -1; - break; - case SC_CONCENTRATION: - val2 = 2 + val1; - if (sd) { //Store the card-bonus data that should not count in the % - val3 = sd->param_bonus[1]; //Agi - val4 = sd->param_bonus[4]; //Dex - } else { - val3 = val4 = 0; + break; + + case SC_COMBOATTACK: { + //val1: Skill ID + //val2: When given, target (for autotargetting skills) + //val3: When set, this combo time should NOT delay attack/movement + //val3: TK: Last used kick + //val4: TK: Combo time + struct unit_data *ud = unit->bl2ud(bl); + if (ud && !val3) { + tick += 300 * battle_config.combo_delay_rate/100; + ud->attackabletime = timer->gettick()+tick; + unit->set_walkdelay(bl, timer->gettick(), tick, 1); + } + val3 = 0; + val4 = tick; + } + break; + case SC_EARTHSCROLL: + val2 = 11-val1; //Chance to consume: 11-skill_lv% + break; + case SC_RUN: + { + //Store time at which you started running. + int64 currenttick = timer->gettick(); + // Note: this int64 value is stored in two separate int32 variables (FIXME) + val3 = (int)(currenttick&0x00000000ffffffffLL); + val4 = (int)((currenttick&0xffffffff00000000LL)>>32); } - break; - case SC_OVERTHRUSTMAX: - val2 = 20*val1; //Power increase - break; - case SC_OVERTHRUST: - //val2 holds if it was casted on self, or is bonus received from others - val3 = 5*val1; //Power increase - if(sd && pc->checkskill(sd,BS_HILTBINDING)>0) - tick += tick / 10; - break; - case SC_ADRENALINE2: - case SC_ADRENALINE: - val3 = (val2) ? 300 : 200; // aspd increase - case SC_WEAPONPERFECT: - if(sd && pc->checkskill(sd,BS_HILTBINDING)>0) - tick += tick / 10; - break; - case SC_LKCONCENTRATION: - val2 = 5*val1; //Batk/Watk Increase - val3 = 10*val1; //Hit Increase - val4 = 5*val1; //Def reduction - sc_start(bl, SC_ENDURE, 100, 1, tick); //Endure effect - break; - case SC_ANGELUS: - val2 = 5*val1; //def increase - break; - case SC_IMPOSITIO: - val2 = 5*val1; //watk increase - break; - case SC_MELTDOWN: - val2 = 100*val1; //Chance to break weapon - val3 = 70*val1; //Change to break armor - break; - case SC_TRUESIGHT: - val2 = 10*val1; //Critical increase - val3 = 3*val1; //Hit increase - break; - case SC_SUN_COMFORT: - val2 = (status->get_lv(bl) + st->dex + st->luk)/2; //def increase - break; - case SC_MOON_COMFORT: - val2 = (status->get_lv(bl) + st->dex + st->luk)/10; //flee increase - break; - case SC_STAR_COMFORT: - val2 = (status->get_lv(bl) + st->dex + st->luk); //Aspd increase - break; - case SC_QUAGMIRE: - val2 = (sd?5:10)*val1; //Agi/Dex decrease. - break; + tick = -1; + break; + case SC_KAAHI: + val2 = 200*val1; //HP heal + val3 = 5*val1; //SP cost + val4 = INVALID_TIMER; //Kaahi Timer. + break; + case SC_BLESSING: + if ((!undead_flag && st->race!=RC_DEMON) || bl->type == BL_PC) + val2 = val1; + else + val2 = 0; //0 -> Half stat. + break; + case SC_TRICKDEAD: + if (vd) vd->dead_sit = 1; + tick = -1; + break; + case SC_CONCENTRATION: + val2 = 2 + val1; + if (sd) { //Store the card-bonus data that should not count in the % + val3 = sd->param_bonus[1]; //Agi + val4 = sd->param_bonus[4]; //Dex + } else { + val3 = val4 = 0; + } + break; + case SC_OVERTHRUSTMAX: + val2 = 20*val1; //Power increase + break; + case SC_OVERTHRUST: + //val2 holds if it was casted on self, or is bonus received from others + val3 = 5*val1; //Power increase + if(sd && pc->checkskill(sd,BS_HILTBINDING)>0) + tick += tick / 10; + break; + case SC_ADRENALINE2: + case SC_ADRENALINE: + val3 = (val2) ? 300 : 200; // aspd increase + case SC_WEAPONPERFECT: + if(sd && pc->checkskill(sd,BS_HILTBINDING)>0) + tick += tick / 10; + break; + case SC_LKCONCENTRATION: + val2 = 5*val1; //Batk/Watk Increase + val3 = 10*val1; //Hit Increase + val4 = 5*val1; //Def reduction + sc_start(src, bl, SC_ENDURE, 100, 1, tick); //Endure effect + break; + case SC_ANGELUS: + val2 = 5*val1; //def increase + break; + case SC_IMPOSITIO: + val2 = 5*val1; //watk increase + break; + case SC_MELTDOWN: + val2 = 100*val1; //Chance to break weapon + val3 = 70*val1; //Change to break armor + break; + case SC_TRUESIGHT: + val2 = 10*val1; //Critical increase + val3 = 3*val1; //Hit increase + break; + case SC_SUN_COMFORT: + val2 = (status->get_lv(bl) + st->dex + st->luk)/2; //def increase + break; + case SC_MOON_COMFORT: + val2 = (status->get_lv(bl) + st->dex + st->luk)/10; //flee increase + break; + case SC_STAR_COMFORT: + val2 = (status->get_lv(bl) + st->dex + st->luk); //Aspd increase + break; + case SC_QUAGMIRE: + val2 = (sd?5:10)*val1; //Agi/Dex decrease. + break; - // gs_something1 [Vicious] - case SC_GS_GATLINGFEVER: - val2 = 20*val1; //Aspd increase - val4 = 5*val1; //Flee decrease -#ifndef RENEWAL - val3 = 20+10*val1; //Batk increase -#endif - break; + // gs_something1 [Vicious] + case SC_GS_GATLINGFEVER: + val2 = 20*val1; //Aspd increase + val4 = 5*val1; //Flee decrease + #ifndef RENEWAL + val3 = 20+10*val1; //Batk increase + #endif + break; - case SC_FLING: - if (bl->type == BL_PC) - val2 = 0; //No armor reduction to players. - else - val2 = 5*val1; //Def reduction - val3 = 5*val1; //Def2 reduction - break; - case SC_PROVOKE: - //val2 signals autoprovoke. - val3 = 2+3*val1; //Atk increase - val4 = 5+5*val1; //Def reduction. - break; - case SC_HLIF_AVOID: - //val2 = 10*val1; //Speed change rate. - break; - case SC_HAMI_DEFENCE: - val2 = 2*val1; //Def bonus - break; - case SC_HAMI_BLOODLUST: - val2 = 20+10*val1; //Atk rate change. - val3 = 3*val1; //Leech chance - val4 = 20; //Leech percent - break; - case SC_HLIF_FLEET: - val2 = 30*val1; //Aspd change - val3 = 5+5*val1; //bAtk/wAtk rate change - break; - case SC_MINDBREAKER: - val2 = 20*val1; //matk increase. - val3 = 12*val1; //mdef2 reduction. - break; - case SC_SKA: - val2 = tick/1000; - val3 = rnd()%100; //Def changes randomly every second... - tick_time = 1000; // [GodLesZ] tick time - break; - case SC_JAILED: - //Val1 is duration in minutes. Use INT_MAX to specify 'unlimited' time. - tick = val1>0?1000:250; - if (sd) + case SC_FLING: + if (bl->type == BL_PC) + val2 = 0; //No armor reduction to players. + else + val2 = 5*val1; //Def reduction + val3 = 5*val1; //Def2 reduction + break; + case SC_PROVOKE: + //val2 signals autoprovoke. + val3 = 2+3*val1; //Atk increase + val4 = 5+5*val1; //Def reduction. + break; + case SC_HLIF_AVOID: + //val2 = 10*val1; //Speed change rate. + break; + case SC_HAMI_DEFENCE: + val2 = 2*val1; //Def bonus + break; + case SC_HAMI_BLOODLUST: + val2 = 20+10*val1; //Atk rate change. + val3 = 3*val1; //Leech chance + val4 = 20; //Leech percent + break; + case SC_HLIF_FLEET: + val2 = 30*val1; //Aspd change + val3 = 5+5*val1; //bAtk/wAtk rate change + break; + case SC_MINDBREAKER: + val2 = 20*val1; //matk increase. + val3 = 12*val1; //mdef2 reduction. + break; + case SC_SKA: + val2 = tick/1000; + val3 = rnd()%100; //Def changes randomly every second... + tick_time = 1000; // [GodLesZ] tick time + break; + case SC_JAILED: + //Val1 is duration in minutes. Use INT_MAX to specify 'unlimited' time. + tick = val1>0?1000:250; + if (sd) + { + if (sd->mapindex != val2) + { + int pos = (bl->x&0xFFFF)|(bl->y<<16); /// Current Coordinates + int map_index = sd->mapindex; /// Current Map + //1. Place in Jail (val2 -> Jail Map, val3 -> x, val4 -> y + pc->setpos(sd,(unsigned short)val2,val3,val4, CLR_TELEPORT); + //2. Set restore point (val3 -> return map, val4 return coords + val3 = map_index; + val4 = pos; + } else if (!val3 || val3 == sd->mapindex) { //Use save point. + val3 = sd->status.save_point.map; + val4 = (sd->status.save_point.x&0xFFFF) + |(sd->status.save_point.y<<16); + } + } + break; + case SC_NJ_UTSUSEMI: + val2=(val1+1)/2; // number of hits blocked + val3=skill->get_blewcount(NJ_UTSUSEMI, val1); //knockback value. + break; + case SC_NJ_BUNSINJYUTSU: + val2=(val1+1)/2; // number of hits blocked + break; + case SC_HLIF_CHANGE: + val2= 30*val1; //Vit increase + val3= 20*val1; //Int increase + break; + case SC_SWOO: + if(st->mode&MD_BOSS) + tick /= 5; //TODO: Reduce skill's duration. But for how long? + break; + case SC_SPIDERWEB: + if( bl->type == BL_PC ) + tick /= 2; + break; + case SC_ARMOR: + //NPC_DEFENDER: + val2 = 80; //Damage reduction + //Attack requirements to be blocked: + val3 = BF_LONG; //Range + val4 = BF_WEAPON|BF_MISC; //Type + break; + case SC_ENCHANTARMS: + //end previous enchants + skill->enchant_elemental_end(bl,type); + //Make sure the received element is valid. + if (val2 >= ELE_MAX) + val2 = val2%ELE_MAX; + else if (val2 < 0) + val2 = rnd()%ELE_MAX; + break; + case SC_CRITICALWOUND: + val2 = 20*val1; //Heal effectiveness decrease + break; + case SC_MAGICMIRROR: + case SC_SLOWCAST: + val2 = 20*val1; //Magic reflection/cast rate + break; + + case SC_STONESKIN: + if (val2 == NPC_ANTIMAGIC) + { //Boost mdef + val2 =-20; + val3 = 20; + } else { //Boost def + val2 = 20; + val3 =-20; + } + val2*=val1; //20% per level + val3*=val1; + break; + case SC_CASH_PLUSEXP: + case SC_CASH_PLUSONLYJOBEXP: + if (val1 < 0) + val1 = 0; + break; + case SC_PLUSAVOIDVALUE: + case SC_CRITICALPERCENT: + val2 = val1*10; //Actual boost (since 100% = 1000) + break; + case SC_SUFFRAGIUM: + val2 = 15 * val1; //Speed cast decrease + break; + case SC_HEALPLUS: + if (val1 < 1) + val1 = 1; + break; + case SC_ILLUSION: + val2 = 5+val1; //Factor by which displayed damage is increased by + break; + case SC_DOUBLECASTING: + val2 = 30+10*val1; //Trigger rate + break; + case SC_KAIZEL: + val2 = 10*val1; //% of life to be revived with + break; + // case SC_ARMORPROPERTY: + // case SC_ARMOR_RESIST: + // Mod your resistance against elements: + // val1 = water | val2 = earth | val3 = fire | val4 = wind + // break; + //case ????: + //Place here SCs that have no SCB_* data, no skill associated, no ICON + //associated, and yet are not wrong/unknown. [Skotlex] + //break; + + case SC_MER_FLEE: + case SC_MER_ATK: + case SC_MER_HIT: + val2 = 15 * val1; + break; + case SC_MER_HP: + case SC_MER_SP: + val2 = 5 * val1; + break; + case SC_REBIRTH: + val2 = 20*val1; //% of life to be revived with + break; + + case SC_MANU_DEF: + case SC_MANU_ATK: + case SC_MANU_MATK: + val2 = 1; // Manuk group + break; + case SC_SPL_DEF: + case SC_SPL_ATK: + case SC_SPL_MATK: + val2 = 2; // Splendide group + break; + /** + * General + **/ + case SC_FEAR: + val2 = 2; + val4 = tick / 1000; + tick_time = 1000; // [GodLesZ] tick time + break; + case SC_BURNING: + val4 = tick / 3000; // Total Ticks to Burn!! + tick_time = 3000; // [GodLesZ] tick time + break; + /** + * Rune Knight + **/ + case SC_DEATHBOUND: + val2 = 500 + 100 * val1; + break; + case SC_STONEHARDSKIN: + if( sd ) + val1 = sd->status.job_level * pc->checkskill(sd, RK_RUNEMASTERY) / 4; //DEF/MDEF Increase + break; + case SC_ABUNDANCE: + val4 = tick / 10000; + tick_time = 10000; // [GodLesZ] tick time + break; + /** + * Arch Bishop + **/ + case SC_RENOVATIO: + val4 = tick / 5000; + tick_time = 5000; + break; + case SC_SECRAMENT: + val2 = 10 * val1; + break; + case SC_VENOMIMPRESS: + val2 = 10 * val1; + break; + case SC_WEAPONBLOCKING: + val2 = 10 + 2 * val1; // Chance + val4 = tick / 5000; + tick_time = 5000; // [GodLesZ] tick time + break; + case SC_TOXIN: + val4 = tick / 10000; + tick_time = 10000; // [GodLesZ] tick time + break; + case SC_MAGICMUSHROOM: + val4 = tick / 4000; + tick_time = 4000; // [GodLesZ] tick time + break; + case SC_PYREXIA: + status->change_start(src, bl,SC_BLIND,10000,val1,0,0,0,30000,11); // Blind status that last for 30 seconds + val4 = tick / 3000; + tick_time = 3000; // [GodLesZ] tick time + break; + case SC_LEECHESEND: + val4 = tick / 1000; + tick_time = 1000; // [GodLesZ] tick time + break; + case SC_OBLIVIONCURSE: + val4 = tick / 3000; + tick_time = 3000; // [GodLesZ] tick time + break; + case SC_CLOAKINGEXCEED: + val2 = ( val1 + 1 ) / 2; // Hits + val3 = 90 + val1 * 10; // Walk speed + if (bl->type == BL_PC) + val4 |= battle_config.pc_cloak_check_type&7; + else + val4 |= battle_config.monster_cloak_check_type&7; + tick_time = 1000; // [GodLesZ] tick time + break; + case SC_HALLUCINATIONWALK: + val2 = 50 * val1; // Evasion rate of physical attacks. Flee + val3 = 10 * val1; // Evasion rate of magical attacks. + break; + case SC_WHITEIMPRISON: + status_change_end(bl, SC_BURNING, INVALID_TIMER); + status_change_end(bl, SC_FROSTMISTY, INVALID_TIMER); + status_change_end(bl, SC_FREEZE, INVALID_TIMER); + status_change_end(bl, SC_STONE, INVALID_TIMER); + break; + case SC_MARSHOFABYSS: + val2 = 6 * val1; + if( sd ) // half on players + val2 >>= 1; + break; + case SC_FROSTMISTY: + status_change_end(bl, SC_BURNING, INVALID_TIMER); + break; + case SC_READING_SB: + // val2 = sp reduction per second + tick_time = 10000; // [GodLesZ] tick time + break; + case SC_SUMMON1: + case SC_SUMMON2: + case SC_SUMMON3: + case SC_SUMMON4: + case SC_SUMMON5: + val4 = tick / 1000; + if( val4 < 1 ) + val4 = 1; + tick_time = 1000; // [GodLesZ] tick time + break; + case SC_SHAPESHIFT: + switch( val1 ) + { + case 1: val2 = ELE_FIRE; break; + case 2: val2 = ELE_EARTH; break; + case 3: val2 = ELE_WIND; break; + case 4: val2 = ELE_WATER; break; + } + break; + case SC_STEALTHFIELD_MASTER: + val4 = tick / 1000; + tick_time = 2000 + (1000 * val1); + break; + case SC_ELECTRICSHOCKER: + case SC_COLD: + case SC_MEIKYOUSISUI: + val4 = tick / 1000; + if( val4 < 1 ) + val4 = 1; + tick_time = 1000; // [GodLesZ] tick time + break; + case SC_CAMOUFLAGE: + val4 = tick/1000; + tick_time = 1000; // [GodLesZ] tick time + break; + case SC_WUGDASH: + { + //Store time at which you started running. + int64 currenttick = timer->gettick(); + // Note: this int64 value is stored in two separate int32 variables (FIXME) + val3 = (int)(currenttick&0x00000000ffffffffLL); + val4 = (int)((currenttick&0xffffffff00000000LL)>>32); + } + tick = -1; + break; + case SC__REPRODUCE: + val4 = tick / 1000; + tick_time = 1000; + break; + case SC__SHADOWFORM: { + struct map_session_data * s_sd = map->id2sd(val2); + if( s_sd ) + s_sd->shadowform_id = bl->id; + val4 = tick / 1000; + tick_time = 1000; // [GodLesZ] tick time + } + break; + case SC__STRIPACCESSARY: + if (!sd) + val2 = 20; + break; + case SC__INVISIBILITY: + val2 = 50 - 10 * val1; // ASPD + val3 = 200 * val1; // CRITICAL + val4 = tick / 1000; + tick_time = 1000; // [GodLesZ] tick time + break; + case SC__ENERVATION: + val2 = 20 + 10 * val1; // ATK Reduction + if( sd ) pc->delspiritball(sd,sd->spiritball,0); + break; + case SC__GROOMY: + val2 = 20 + 10 * val1; //ASPD. Need to confirm if Movement Speed reduction is the same. [Jobbie] + val3 = 20 * val1; //HIT + if( sd ) { // Removes Animals + if( pc_isriding(sd) ) pc->setriding(sd, 0); + if( pc_isridingdragon(sd) ) pc->setoption(sd, sd->sc.option&~OPTION_DRAGON); + if( pc_iswug(sd) ) pc->setoption(sd, sd->sc.option&~OPTION_WUG); + if( pc_isridingwug(sd) ) pc->setoption(sd, sd->sc.option&~OPTION_WUGRIDER); + if( pc_isfalcon(sd) ) pc->setoption(sd, sd->sc.option&~OPTION_FALCON); + if( sd->status.pet_id > 0 ) pet->menu(sd, 3); + if( homun_alive(sd->hd) ) homun->vaporize(sd,HOM_ST_REST); + if( sd->md ) mercenary->delete(sd->md,3); + } + break; + case SC__LAZINESS: + val2 = 10 + 10 * val1; // Cast reduction + val3 = 10 * val1; // Flee Reduction + break; + case SC__UNLUCKY: + val2 = 10 * val1; // Crit and Flee2 Reduction + break; + case SC__WEAKNESS: + val2 = 10 * val1; + // bypasses coating protection and MADO + sc_start(src, bl,SC_NOEQUIPWEAPON,100,val1,tick); + sc_start(src, bl,SC_NOEQUIPSHIELD,100,val1,tick); + break; + case SC_GN_CARTBOOST: + if( val1 < 3 ) + val2 = 50; + else if( val1 < 5 ) + val2 = 75; + else + val2 = 100; + break; + case SC_PROPERTYWALK: + val3 = 0; + break; + case SC_WARMER: + status_change_end(bl, SC_FREEZE, INVALID_TIMER); + status_change_end(bl, SC_FROSTMISTY, INVALID_TIMER); + status_change_end(bl, SC_COLD, INVALID_TIMER); + break; + case SC_STRIKING: + val1 = 6 - val1;//spcost = 6 - level (lvl1:5 ... lvl 5: 1) + val4 = tick / 1000; + tick_time = 1000; // [GodLesZ] tick time + break; + case SC_BLOOD_SUCKER: { - if (sd->mapindex != val2) + struct block_list *src2 = map->id2bl(val2); + val3 = 1; + if(src2) + val3 = 200 + 100 * val1 + status_get_int(src2); + val4 = tick / 1000; + tick_time = 1000; // [GodLesZ] tick time + } + break; + case SC_SWING: + val3 = 5 * val1 + val2;//Movement Speed And ASPD Increase + break; + case SC_SYMPHONY_LOVE: + val2 = 12 * val1 + val2 + sd->status.job_level / 4;//MDEF Increase In % + case SC_MOONLIT_SERENADE: + case SC_RUSH_WINDMILL: + val2 = 6 * val1 + val2 + sd->status.job_level / 5; + break; + case SC_ECHOSONG: + val3 = 6 * val1 + val2 + sd->status.job_level / 4;//DEF Increase In % + break; + case SC_HARMONIZE: + val2 = 5 + 5 * val1; + break; + case SC_SIREN: + val4 = tick / 2000; + tick_time = 2000; // [GodLesZ] tick time + break; + case SC_DEEP_SLEEP: + val4 = tick / 2000; + tick_time = 2000; // [GodLesZ] tick time + break; + case SC_SIRCLEOFNATURE: + val2 = 40 * val1;//HP recovery + val3 = 4 * val1;//SP drain + val4 = tick / 1000; + tick_time = 1000; // [GodLesZ] tick time + break; + case SC_SONG_OF_MANA: + val3 = 10 + 5 * val2; + val4 = tick/5000; + tick_time = 5000; // [GodLesZ] tick time + break; + case SC_SATURDAY_NIGHT_FEVER: + /*val2 = 12000 - 2000 * val1;//HP/SP Drain Timer + if ( val2 < 1000 ) + val2 = 1000;//Added to prevent val3 from dividing by 0 when using level 6 or higher through commands. [Rytech] + val3 = tick/val2;*/ + val3 = tick / 3000; + tick_time = 3000;// [GodLesZ] tick time + break; + case SC_GLOOMYDAY: + if ( !val2 ) { + val2 = (val4 > 0 ? max(15, rnd()%(val4*5)) : 0) + val1 * 10; + } + if ( rnd()%10000 < val1*100 ) { // 1% per SkillLv chance + if ( !val3 ) + val3 = 50; + if( sd ) { + if( pc_isriding(sd) ) pc->setriding(sd, 0); + if( pc_isridingdragon(sd) ) pc->setoption(sd, sd->sc.option&~OPTION_DRAGON); + } + } + break; + case SC_SITDOWN_FORCE: + case SC_BANANA_BOMB_SITDOWN_POSTDELAY: + if( sd && !pc_issit(sd) ) { - int pos = (bl->x&0xFFFF)|(bl->y<<16); /// Current Coordinates - int mapindex = sd->mapindex; /// Current Map - //1. Place in Jail (val2 -> Jail Map, val3 -> x, val4 -> y - pc->setpos(sd,(unsigned short)val2,val3,val4, CLR_TELEPORT); - //2. Set restore point (val3 -> return map, val4 return coords - val3 = mapindex; - val4 = pos; - } else if (!val3 || val3 == sd->mapindex) { //Use save point. - val3 = sd->status.save_point.map; - val4 = (sd->status.save_point.x&0xFFFF) - |(sd->status.save_point.y<<16); + pc_setsit(sd); + skill->sit(sd,1); + clif->sitting(bl); + } + break; + case SC_DANCE_WITH_WUG: + val3 = 5 + 5 * val2;//ASPD Increase + val4 = 20 + 10 * val2;//Fixed Cast Time Reduction + break; + case SC_LERADS_DEW: + val3 = 200 * val1 + 300 * val2;//MaxHP Increase + break; + case SC_MELODYOFSINK: + val3 = val1 * (2 + val2);//INT Reduction. Formula Includes Caster And 2nd Performer. + val4 = tick/1000; + tick_time = 1000; + break; + case SC_BEYOND_OF_WARCRY: + val3 = val1 * (2 + val2);//STR And Crit Reduction. Formula Includes Caster And 2nd Performer. + val4 = 4 * val1 + 4 * val2;//MaxHP Reduction + break; + case SC_UNLIMITED_HUMMING_VOICE: + { + struct unit_data *ud = unit->bl2ud(bl); + if( ud == NULL ) return 0; + ud->state.skillcastcancel = 0; + val3 = 15 - (3 * val2);//Increased SP Cost. + } + break; + case SC_LG_REFLECTDAMAGE: + val2 = 15 + 5 * val1; + val3 = 25 + 5 * val1; //Number of Reflects + val4 = tick/10000; + tick_time = 10000; // [GodLesZ] tick time + break; + case SC_FORCEOFVANGUARD: + val2 = 8 + 12 * val1; // Chance + val3 = 5 + 2 * val1; // Max rage counters + tick = -1; //endless duration in the client + break; + case SC_EXEEDBREAK: + if( sd ){ + short index = sd->equip_index[EQI_HAND_R]; + val1 = 15 * (sd->status.job_level + val1 * 10); + if( index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_WEAPON ) + val1 += (sd->inventory_data[index]->weight / 10 * sd->inventory_data[index]->wlv) * status->get_lv(bl) / 100; + } + break; + case SC_PRESTIGE: + val2 = (st->int_ + st->luk) * val1 / 20;// Chance to evade magic damage. + val2 = val2 * status->get_lv(bl) / 200; + val2 += val1; + val1 *= 15; // Defence added + if( sd ) + val1 += 10 * pc->checkskill(sd,CR_DEFENDER); + val1 *= status->get_lv(bl) / 100; + break; + case SC_BANDING: + tick_time = 5000; // [GodLesZ] tick time + break; + case SC_MAGNETICFIELD: + val3 = tick / 1000; + tick_time = 1000; // [GodLesZ] tick time + break; + case SC_INSPIRATION: + if( sd ) { + val2 = 40 * val1 + 3 * sd->status.job_level;// ATK bonus + val3 = sd->status.base_level / 10 + sd->status.job_level / 5;// All stat bonus + } + val4 = tick / 5000; + tick_time = 5000; // [GodLesZ] tick time + status->change_clear_buffs(bl,3); //Remove buffs/debuffs + break; + case SC_LIGHTNINGWALK: // [(Job Level / 2) + (40 + 5 * Skill Level)] % + val1 = (sd?sd->status.job_level:2)/2 + 40 + 5 * val1; + break; + case SC_RAISINGDRAGON: + val3 = tick / 5000; + tick_time = 5000; // [GodLesZ] tick time + break; + case SC_GENTLETOUCH_CHANGE: + {// take note there is no def increase as skill desc says. [malufett] + struct block_list * src2; + val3 = st->agi * val1 / 60; // ASPD increase: [(Target AGI x Skill Level) / 60] % + if( (src2 = map->id2bl(val2)) ){ + val4 = ( 200/status_get_int(src2) ) * val1;// MDEF decrease: MDEF [(200 / Caster INT) x Skill Level] + val2 = ( status_get_dex(src2)/4 + status_get_str(src2)/2 ) * val1 / 5; // ATK increase: ATK [{(Caster DEX / 4) + (Caster STR / 2)} x Skill Level / 5] } } - break; - case SC_NJ_UTSUSEMI: - val2=(val1+1)/2; // number of hits blocked - val3=skill->get_blewcount(NJ_UTSUSEMI, val1); //knockback value. - break; - case SC_NJ_BUNSINJYUTSU: - val2=(val1+1)/2; // number of hits blocked - break; - case SC_HLIF_CHANGE: - val2= 30*val1; //Vit increase - val3= 20*val1; //Int increase - break; - case SC_SWOO: - if(st->mode&MD_BOSS) - tick /= 5; //TODO: Reduce skill's duration. But for how long? - break; - case SC_SPIDERWEB: - if( bl->type == BL_PC ) - tick /= 2; - break; - case SC_ARMOR: - //NPC_DEFENDER: - val2 = 80; //Damage reduction - //Attack requirements to be blocked: - val3 = BF_LONG; //Range - val4 = BF_WEAPON|BF_MISC; //Type - break; - case SC_ENCHANTARMS: - //end previous enchants - skill->enchant_elemental_end(bl,type); - //Make sure the received element is valid. - if (val2 >= ELE_MAX) - val2 = val2%ELE_MAX; - else if (val2 < 0) - val2 = rnd()%ELE_MAX; - break; - case SC_CRITICALWOUND: - val2 = 20*val1; //Heal effectiveness decrease - break; - case SC_MAGICMIRROR: - case SC_SLOWCAST: - val2 = 20*val1; //Magic reflection/cast rate - break; - - case SC_STONESKIN: - if (val2 == NPC_ANTIMAGIC) - { //Boost mdef - val2 =-20; - val3 = 20; - } else { //Boost def - val2 = 20; - val3 =-20; - } - val2*=val1; //20% per level - val3*=val1; - break; - case SC_CASH_PLUSEXP: - case SC_CASH_PLUSONLYJOBEXP: - if (val1 < 0) - val1 = 0; - break; - case SC_PLUSAVOIDVALUE: - case SC_CRITICALPERCENT: - val2 = val1*10; //Actual boost (since 100% = 1000) - break; - case SC_SUFFRAGIUM: - val2 = 15 * val1; //Speed cast decrease - break; - case SC_HEALPLUS: - if (val1 < 1) - val1 = 1; - break; - case SC_ILLUSION: - val2 = 5+val1; //Factor by which displayed damage is increased by - break; - case SC_DOUBLECASTING: - val2 = 30+10*val1; //Trigger rate - break; - case SC_KAIZEL: - val2 = 10*val1; //% of life to be revived with - break; - // case SC_ARMORPROPERTY: - // case SC_ARMOR_RESIST: - // Mod your resistance against elements: - // val1 = water | val2 = earth | val3 = fire | val4 = wind - // break; - //case ????: - //Place here SCs that have no SCB_* data, no skill associated, no ICON - //associated, and yet are not wrong/unknown. [Skotlex] - //break; + break; + case SC_GENTLETOUCH_REVITALIZE: + {// take note there is no vit,aspd,speed increase as skill desc says. [malufett] + struct block_list * src2; + val3 = val1 * 30 + 150; // Natural HP recovery increase: [(Skill Level x 30) + 50] % + if( (src2 = map->id2bl(val2)) ) // the stat def is not shown in the status window and it is process differently + val4 = ( status_get_vit(src2)/4 ) * val1; // STAT DEF increase: [(Caster VIT / 4) x Skill Level] + } + break; + case SC_PYROTECHNIC_OPTION: + val2 = 60; + break; + case SC_HEATER_OPTION: + val2 = 120; // Watk. TODO: Renewal (Atk2) + val3 = (sd ? sd->status.job_level : 0); // % Increase damage. + val4 = 3; // Change into fire element. + break; + case SC_TROPIC_OPTION: + val2 = 180; // Watk. TODO: Renewal (Atk2) + val3 = MG_FIREBOLT; + break; + case SC_AQUAPLAY_OPTION: + val2 = 40; + break; + case SC_COOLER_OPTION: + val2 = 80; // Bonus Matk + val3 = (sd ? sd->status.job_level : 0); // % Freezing chance + val4 = 1; // Change into water elemet + break; + case SC_CHILLY_AIR_OPTION: + val2 = 120; // Matk. TODO: Renewal (Matk1) + val3 = MG_COLDBOLT; + break; + case SC_WIND_STEP_OPTION: + val2 = 50; // % Increase speed and flee. + break; + case SC_BLAST_OPTION: + val2 = (sd ? sd->status.job_level : 0); // % Increase damage + val3 = ELE_WIND; + break; + case SC_WILD_STORM_OPTION: + val2 = MG_LIGHTNINGBOLT; + break; + case SC_PETROLOGY_OPTION: + val2 = 5; + val3 = 50; + break; + case SC_SOLID_SKIN_OPTION: + val2 = 33; // % Increase DEF + break; + case SC_CURSED_SOIL_OPTION: + val2 = 10; + val3 = (sd ? sd->status.job_level : 0); // % Increase Damage + val4 = 2; + break; + case SC_UPHEAVAL_OPTION: + val2 = WZ_EARTHSPIKE; + val3 = 15; // Bonus MaxHP + break; + case SC_CIRCLE_OF_FIRE_OPTION: + val2 = 300; + break; + case SC_FIRE_CLOAK_OPTION: + case SC_WATER_DROP_OPTION: + case SC_WIND_CURTAIN_OPTION: + case SC_STONE_SHIELD_OPTION: + val2 = 100; // Elemental modifier. + break; + case SC_CIRCLE_OF_FIRE: + case SC_FIRE_CLOAK: + case SC_WATER_DROP: + case SC_WATER_SCREEN: + case SC_WIND_CURTAIN: + case SC_WIND_STEP: + case SC_STONE_SHIELD: + case SC_SOLID_SKIN: + val2 = 10; + tick_time = 2000; // [GodLesZ] tick time + break; + case SC_WATER_BARRIER: + val2 = 40; // Increasement. Mdef1 ??? + val3 = 30; // Reductions. Atk2, Flee1, Matk1 ???? + break; + case SC_ZEPHYR: + val2 = 25; // Flee. + break; + case SC_TIDAL_WEAPON: + val2 = 20; // Increase Elemental's attack. + break; + case SC_ROCK_CRUSHER: + case SC_ROCK_CRUSHER_ATK: + case SC_POWER_OF_GAIA: + val2 = 33; + break; + case SC_MELON_BOMB: + case SC_BANANA_BOMB: + val1 = 15; + break; + case SC_STOMACHACHE: + val2 = 8; // SP consume. + val4 = tick / 10000; + tick_time = 10000; // [GodLesZ] tick time + break; + case SC_KYOUGAKU: + val2 = 2*val1 + rand()%(3 * val1); + clif->status_change(bl, SI_ACTIVE_MONSTER_TRANSFORM, 1, 0, 1002, 0, 0); // Poring in disguise + break; + case SC_KAGEMUSYA: + val3 = val1 * 2; + case SC_IZAYOI: + val2 = tick/1000; + tick_time = 1000; + break; + case SC_ZANGETSU: + val2 = val4 = status->get_lv(bl) / 3 + 20 * val1; + val3 = status->get_lv(bl) / 2 + 30 * val1; + val2 = (!(status_get_hp(bl)%2) ? val2 : -val3); + val3 = (!(status_get_sp(bl)%2) ? val4 : -val3); + break; + case SC_GENSOU: + +#define PER( a, lvl ) do { \ + int temp__ = (a); \ + if( temp__ <= 15 ) (lvl) = 1; \ + else if( temp__ <= 30 ) (lvl) = 2; \ + else if( temp__ <= 50 ) (lvl) = 3; \ + else if( temp__ <= 75 ) (lvl) = 4; \ + else (lvl) = 5; \ +} while(0) - case SC_MER_FLEE: - case SC_MER_ATK: - case SC_MER_HIT: - val2 = 15 * val1; - break; - case SC_MER_HP: - case SC_MER_SP: - val2 = 5 * val1; - break; - case SC_REBIRTH: - val2 = 20*val1; //% of life to be revived with - break; + { + int hp = status_get_hp(bl), sp = status_get_sp(bl), lv = 5; - case SC_MANU_DEF: - case SC_MANU_ATK: - case SC_MANU_MATK: - val2 = 1; // Manuk group - break; - case SC_SPL_DEF: - case SC_SPL_ATK: - case SC_SPL_MATK: - val2 = 2; // Splendide group - break; - /** - * General - **/ - case SC_FEAR: - val2 = 2; - val4 = tick / 1000; - tick_time = 1000; // [GodLesZ] tick time - break; - case SC_BURNING: - val4 = tick / 3000; // Total Ticks to Burn!! - tick_time = 3000; // [GodLesZ] tick time - break; - /** - * Rune Knight - **/ - case SC_DEATHBOUND: - val2 = 500 + 100 * val1; - break; - case SC_STONEHARDSKIN: - if( sd ) - val1 = sd->status.job_level * pc->checkskill(sd, RK_RUNEMASTERY) / 4; //DEF/MDEF Increase - break; + if( rand()%100 > (25 + 10 * val1) - status_get_int(bl) / 2) + return 0; + + PER( 100 / (status_get_max_hp(bl) / hp), lv ); + status->heal(bl, (!(hp%2) ? (6-lv) *4 / 100 : -(lv*4) / 100), 0, 1); + + PER( 100 / (status_get_max_sp(bl) / sp), lv ); + status->heal(bl, 0,(!(sp%2) ? (6-lv) *3 / 100 : -(lv*3) / 100), 1); + } +#undef PER + break; + case SC_ANGRIFFS_MODUS: + val2 = 50 + 20 * val1; //atk bonus + val3 = 40 + 20 * val1; // Flee reduction. + val4 = tick/1000; // hp/sp reduction timer + tick_time = 1000; + break; + case SC_NEUTRALBARRIER: + tick_time = tick; + tick = -1; + break; + case SC_GOLDENE_FERSE: + val2 = 10 + 10*val1; //max hp bonus + val3 = 6 + 4 * val1; // Aspd Bonus + val4 = 2 + 2 * val1; // Chance of holy attack + break; + case SC_OVERED_BOOST: + val2 = 300 + 40*val1; //flee bonus + val3 = 179 + 2*val1; //aspd bonus + break; + case SC_GRANITIC_ARMOR: + val2 = 2*val1; //dmg reduction + val3 = 6*val1; //dmg on status end + break; + case SC_MAGMA_FLOW: + val2 = 3*val1; //activation chance + break; + case SC_PYROCLASTIC: + val2 += 10*val1; //atk bonus + break; + case SC_NEEDLE_OF_PARALYZE: //[Lighta] need real info + val2 = 2*val1; //def reduction + val3 = 500*val1; //varcast augmentation + break; + case SC_PAIN_KILLER: //[Lighta] need real info + val2 = 2*val1; //aspd reduction % + val3 = 2*val1; //dmg reduction % + if(sc->data[SC_NEEDLE_OF_PARALYZE]) + sc_start(src, bl, SC_ENDURE, 100, val1, tick); //start endure for same duration + break; + case SC_STYLE_CHANGE: //[Lighta] need real info + tick = -1; + if(val2 == MH_MD_FIGHTING) val2 = MH_MD_GRAPPLING; + else val2 = MH_MD_FIGHTING; + break; + case SC_FULL_THROTTLE: + status_percent_heal(bl,100,0); + val2 = 7 - val1; + tick_time = 1000; + val4 = tick / tick_time; + break; + case SC_KINGS_GRACE: + val2 = 3 + val1; + tick_time = 1000; + val4 = tick / tick_time; + break; + case SC_TELEKINESIS_INTENSE: + val2 = 10 * val1; + val3 = 40 * val1; + break; + case SC_OFFERTORIUM: + val2 = 30 * val1; + break; + case SC_FRIGG_SONG: + val2 = 5 * val1; + val3 = (20 * val1) + 80; + tick_time = 1000; + val4 = tick / tick_time; + break; + case SC_DARKCROW: + val2 = 30 * val1; + break; + case SC_MONSTER_TRANSFORM: + if( !mob->db_checkid(val1) ) + val1 = 1002; // default poring + break; + default: + if( calc_flag == SCB_NONE && status->SkillChangeTable[type] == 0 && status->IconChangeTable[type] == 0 ) + { //Status change with no calc, no icon, and no skill associated...? + ShowError("UnknownStatusChange [%d]\n", type); + return 0; + } + } + } else { //Special considerations when loading SC data. + switch( type ) { + case SC_WEDDING: + case SC_XMAS: + case SC_SUMMER: + case SC_HANBOK: + case SC_OKTOBERFEST: + if( !vd ) break; + clif->changelook(bl,LOOK_BASE,vd->class_); + clif->changelook(bl,LOOK_WEAPON,0); + clif->changelook(bl,LOOK_SHIELD,0); + clif->changelook(bl,LOOK_CLOTHES_COLOR,vd->cloth_color); + break; + case SC_KAAHI: + val4 = INVALID_TIMER; + break; + case SC_KYOUGAKU: + clif->status_change(bl, SI_ACTIVE_MONSTER_TRANSFORM, 1, 0, 1002, 0, 0); // Poring in disguise + break; + } + } + + /* values that must be set regardless of flag&4 e.g. val_flag */ + switch(type) { case SC_FIGHTINGSPIRIT: val_flag |= 1|2; break; - case SC_ABUNDANCE: - val4 = tick / 10000; - tick_time = 10000; // [GodLesZ] tick time - break; - /** - * Arch Bishop - **/ - case SC_RENOVATIO: - val4 = tick / 5000; - tick_time = 5000; - break; - case SC_SECRAMENT: - val2 = 10 * val1; - break; case SC_VENOMIMPRESS: - val2 = 10 * val1; val_flag |= 1|2; break; case SC_POISONINGWEAPON: val_flag |= 1|2|4; break; case SC_WEAPONBLOCKING: - val2 = 10 + 2 * val1; // Chance - val4 = tick / 3000; - tick_time = 3000; // [GodLesZ] tick time val_flag |= 1|2; break; - case SC_TOXIN: - val4 = tick / 10000; - tick_time = 10000; // [GodLesZ] tick time - break; - case SC_MAGICMUSHROOM: - val4 = tick / 4000; - tick_time = 4000; // [GodLesZ] tick time - break; - case SC_PYREXIA: - status->change_start(bl,SC_BLIND,10000,val1,0,0,0,30000,11); // Blind status that last for 30 seconds - val4 = tick / 3000; - tick_time = 3000; // [GodLesZ] tick time - break; - case SC_LEECHESEND: - val4 = tick / 1000; - tick_time = 1000; // [GodLesZ] tick time - break; - case SC_OBLIVIONCURSE: - val4 = tick / 3000; - tick_time = 3000; // [GodLesZ] tick time - break; case SC_ROLLINGCUTTER: val_flag |= 1; break; case SC_CLOAKINGEXCEED: - val2 = ( val1 + 1 ) / 2; // Hits - val3 = 90 + val1 * 10; // Walk speed val_flag |= 1|2|4; - if (bl->type == BL_PC) - val4 |= battle_config.pc_cloak_check_type&7; - else - val4 |= battle_config.monster_cloak_check_type&7; - tick_time = 1000; // [GodLesZ] tick time break; case SC_HALLUCINATIONWALK: - val2 = 50 * val1; // Evasion rate of physical attacks. Flee - val3 = 10 * val1; // Evasion rate of magical attacks. val_flag |= 1|2|4; break; - case SC_WHITEIMPRISON: - status_change_end(bl, SC_BURNING, INVALID_TIMER); - status_change_end(bl, SC_FROSTMISTY, INVALID_TIMER); - status_change_end(bl, SC_FREEZE, INVALID_TIMER); - status_change_end(bl, SC_STONE, INVALID_TIMER); - break; - case SC_MARSHOFABYSS: - val2 = 6 * val1; - if( sd ) // half on players - val2 >>= 1; - break; - case SC_FROSTMISTY: - status_change_end(bl, SC_BURNING, INVALID_TIMER); - break; - case SC_READING_SB: - // val2 = sp reduction per second - tick_time = 5000; // [GodLesZ] tick time - break; case SC_SUMMON1: case SC_SUMMON2: case SC_SUMMON3: case SC_SUMMON4: case SC_SUMMON5: - val4 = tick / 1000; - if( val4 < 1 ) - val4 = 1; - tick_time = 1000; // [GodLesZ] tick time val_flag |= 1; break; - case SC_SHAPESHIFT: - switch( val1 ) - { - case 1: val2 = ELE_FIRE; break; - case 2: val2 = ELE_EARTH; break; - case 3: val2 = ELE_WIND; break; - case 4: val2 = ELE_WATER; break; - } - break; - case SC_ELECTRICSHOCKER: - case SC_COLD: - case SC_MEIKYOUSISUI: - val4 = tick / 1000; - if( val4 < 1 ) - val4 = 1; - tick_time = 1000; // [GodLesZ] tick time - break; - case SC_CAMOUFLAGE: - val4 = tick/1000; - tick_time = 1000; // [GodLesZ] tick time - break; - case SC_WUGDASH: - val4 = timer->gettick(); //Store time at which you started running. - tick = -1; - break; - case SC__SHADOWFORM: { - struct map_session_data * s_sd = map->id2sd(val2); - if( s_sd ) - s_sd->shadowform_id = bl->id; - val4 = tick / 1000; + case SC__SHADOWFORM: val_flag |= 1|2|4; - tick_time = 1000; // [GodLesZ] tick time - } - break; - case SC__STRIPACCESSARY: - if (!sd) - val2 = 20; break; case SC__INVISIBILITY: - val2 = 50 - 10 * val1; // ASPD - val3 = 20 * val1; // CRITICAL - val4 = tick / 1000; - tick_time = 1000; // [GodLesZ] tick time val_flag |= 1|2; break; case SC__ENERVATION: - val2 = 20 + 10 * val1; // ATK Reduction val_flag |= 1|2; - if( sd ) pc->delspiritball(sd,sd->spiritball,0); break; case SC__GROOMY: - val2 = 20 + 10 * val1; //ASPD. Need to confirm if Movement Speed reduction is the same. [Jobbie] - val3 = 20 * val1; //HIT val_flag |= 1|2|4; - if( sd ) { // Removes Animals - if( pc_isriding(sd) ) pc->setriding(sd, 0); - if( pc_isridingdragon(sd) ) pc->setoption(sd, sd->sc.option&~OPTION_DRAGON); - if( pc_iswug(sd) ) pc->setoption(sd, sd->sc.option&~OPTION_WUG); - if( pc_isridingwug(sd) ) pc->setoption(sd, sd->sc.option&~OPTION_WUGRIDER); - if( pc_isfalcon(sd) ) pc->setoption(sd, sd->sc.option&~OPTION_FALCON); - if( sd->status.pet_id > 0 ) pet->menu(sd, 3); - if( homun_alive(sd->hd) ) homun->vaporize(sd,1); - if( sd->md ) mercenary->delete(sd->md,3); - } break; case SC__LAZINESS: - val2 = 10 + 10 * val1; // Cast reduction - val3 = 10 * val1; // Flee Reduction val_flag |= 1|2|4; break; case SC__UNLUCKY: - val2 = 10 * val1; // Crit and Flee2 Reduction val_flag |= 1|2|4; break; case SC__WEAKNESS: - val2 = 10 * val1; val_flag |= 1|2; - // bypasses coating protection and MADO - sc_start(bl,SC_NOEQUIPWEAPON,100,val1,tick); - sc_start(bl,SC_NOEQUIPSHIELD,100,val1,tick); - break; - case SC_GN_CARTBOOST: - if( val1 < 3 ) - val2 = 50; - else if( val1 < 5 ) - val2 = 75; - else - val2 = 100; break; case SC_PROPERTYWALK: val_flag |= 1|2; - val3 = 0; - break; - case SC_WARMER: - status_change_end(bl, SC_FREEZE, INVALID_TIMER); - status_change_end(bl, SC_FROSTMISTY, INVALID_TIMER); - status_change_end(bl, SC_COLD, INVALID_TIMER); - break; - case SC_STRIKING: - val1 = 6 - val1;//spcost = 6 - level (lvl1:5 ... lvl 5: 1) - val4 = tick / 1000; - tick_time = 1000; // [GodLesZ] tick time - break; - case SC_BLOOD_SUCKER: - { - struct block_list *src = map->id2bl(val2); - val3 = 1; - if(src) - val3 = 200 + 100 * val1 + status_get_int(src); - val4 = tick / 1000; - tick_time = 1000; // [GodLesZ] tick time - } - break; - case SC_VACUUM_EXTREME: - tick -= (st->str / 20) * 1000; - val4 = val3 = tick / 100; - tick_time = 100; // [GodLesZ] tick time break; - case SC_SWING: - val2 = 4 * val1; // Walk speed and aspd reduction. - break; - case SC_SYMPHONY_LOVE: - case SC_RUSH_WINDMILL: - case SC_ECHOSONG: - val2 = 6 * val1; - val2 += val3; //Adding 1% * Lesson Bonus - val2 += (int)(val4*2/10); //Adding 0.2% per JobLevel - break; - case SC_MOONLIT_SERENADE: - val2 = 10 * val1; - break; - case SC_HARMONIZE: - val2 = 5 + 5 * val1; - break; - case SC_SIREN: - val4 = tick / 2000; - tick_time = 2000; // [GodLesZ] tick time - break; - case SC_DEEP_SLEEP: - val4 = tick / 2000; - tick_time = 2000; // [GodLesZ] tick time - break; - case SC_SIRCLEOFNATURE: - val2 = 1 + val1; //SP consume - val3 = 40 * val1; //HP recovery - val4 = tick / 1000; - tick_time = 1000; // [GodLesZ] tick time - break; - case SC_SONG_OF_MANA: - val3 = 10 + (2 * val2); - val4 = tick/3000; - tick_time = 3000; // [GodLesZ] tick time - break; - case SC_SATURDAY_NIGHT_FEVER: - if (!val4) val4 = skill->get_time2(status->sc2skill(type),val1); - if (!val4) val4 = 3000; - val3 = tick/val4; - tick_time = val4; // [GodLesZ] tick time - break; - case SC_GLOOMYDAY: - val2 = 20 + 5 * val1; // Flee reduction. - val3 = 15 + 5 * val1; // ASPD reduction. - if( sd && rand()%100 < val1 ){ // (Skill Lv) % - val4 = 1; // reduce walk speed by half. - if( pc_isriding(sd) ) pc->setriding(sd, 0); - if( pc_isridingdragon(sd) ) pc->setoption(sd, sd->sc.option&~OPTION_DRAGON); - } - break; - case SC_GLOOMYDAY_SK: - // Random number between [15 ~ (Voice Lesson Skill Level x 5) + (Skill Level x 10)] %. - val2 = 15 + rand()%( (sd?pc->checkskill(sd, WM_LESSON)*5:0) + val1*10 ); - break; - case SC_SITDOWN_FORCE: - case SC_BANANA_BOMB_SITDOWN_POSTDELAY: - if( sd && !pc_issit(sd) ) - { - pc_setsit(sd); - skill->sit(sd,1); - clif->sitting(bl); - } - break; - case SC_DANCE_WITH_WUG: - val3 = (5 * val1) + (1 * val2); //Still need official value. - break; - case SC_LERADS_DEW: - val3 = (5 * val1) + (1 * val2); - break; - case SC_MELODYOFSINK: - val3 = (5 * val1) + (1 * val2); - break; - case SC_BEYOND_OF_WARCRY: - val3 = (5 * val1) + (1 * val2); - break; - case SC_UNLIMITED_HUMMING_VOICE: - { - struct unit_data *ud = unit->bl2ud(bl); - if( ud == NULL ) return 0; - ud->state.skillcastcancel = 0; - val3 = 15 - (2 * val2); - } - break; - case SC_LG_REFLECTDAMAGE: - val2 = 15 + 5 * val1; - val3 = (val1==5)?20:(val1+4)*2; // SP consumption - val4 = tick/10000; - tick_time = 10000; // [GodLesZ] tick time - break; - case SC_FORCEOFVANGUARD: // This is not the official way to handle it but I think we should use it. [pakpil] - val2 = 20 + 12 * (val1 - 1); // Chance - val3 = 5 + (2 * val1); // Max rage counters - tick = -1; //endless duration in the client - tick_time = 6000; // [GodLesZ] tick time + case SC_FORCEOFVANGUARD: val_flag |= 1|2|4; break; - case SC_EXEEDBREAK: - val1 *= 150; // 150 * skill_lv - if( sd && sd->inventory_data[sd->equip_index[EQI_HAND_R]] ) { // Chars. - val1 += (sd->inventory_data[sd->equip_index[EQI_HAND_R]]->weight/10 * sd->inventory_data[sd->equip_index[EQI_HAND_R]]->wlv * status->get_lv(bl) / 100); - val1 += 15 * (sd ? sd->status.job_level:50) + 100; - } else // Mobs - val1 += (400 * status->get_lv(bl) / 100) + (15 * (status->get_lv(bl) / 2)); // About 1138% at mob_lvl 99. Is an aproximation to a standard weapon. [pakpil] - break; - case SC_PRESTIGE: // Based on suggested formula in iRO Wiki and some test, still need more test. [pakpil] - val2 = ((st->int_ + st->luk) / 6) + 5; // Chance to evade magic damage. - val1 *= 15; // Defence added - if( sd ) - val1 += 10 * pc->checkskill(sd,CR_DEFENDER); + case SC_PRESTIGE: val_flag |= 1|2; break; case SC_BANDING: - tick_time = 5000; // [GodLesZ] tick time val_flag |= 1; break; case SC_SHIELDSPELL_DEF: @@ -8407,554 +9063,320 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val case SC_SHIELDSPELL_REF: val_flag |= 1|2; break; - case SC_MAGNETICFIELD: - val3 = tick / 1000; - tick_time = 1000; // [GodLesZ] tick time - break; - case SC_INSPIRATION: - if( sd ) { - val2 = (40 * val1) + (3 * sd->status.job_level); // ATK bonus - val3 = (sd->status.job_level / 10) * 2 + 12; // All stat bonus - } - val4 = tick / 1000; - tick_time = 1000; // [GodLesZ] tick time - status->change_clear_buffs(bl,3); //Remove buffs/debuffs - break; case SC_SPELLFIST: case SC_CURSEDCIRCLE_ATKER: val_flag |= 1|2|4; break; case SC_CRESCENTELBOW: - val2 = 94 + val1; val_flag |= 1|2; break; - case SC_LIGHTNINGWALK: // [(Job Level / 2) + (40 + 5 * Skill Level)] % - val1 = (sd?sd->status.job_level:2)/2 + 40 + 5 * val1; + case SC_LIGHTNINGWALK: val_flag |= 1; break; - case SC_RAISINGDRAGON: - val3 = tick / 5000; - tick_time = 5000; // [GodLesZ] tick time - break; - case SC_GENTLETOUCH_CHANGE: - {// take note there is no def increase as skill desc says. [malufett] - struct block_list * src; - val3 = st->agi * val1 / 60; // ASPD increase: [(Target AGI x Skill Level) / 60] % - if( (src = map->id2bl(val2)) ){ - val4 = ( 200/status_get_int(src) ) * val1;// MDEF decrease: MDEF [(200 / Caster INT) x Skill Level] - val2 = ( status_get_dex(src)/4 + status_get_str(src)/2 ) * val1 / 5; // ATK increase: ATK [{(Caster DEX / 4) + (Caster STR / 2)} x Skill Level / 5] - } - } - break; - case SC_GENTLETOUCH_REVITALIZE: - {// take note there is no vit,aspd,speed increase as skill desc says. [malufett] - struct block_list * src; - val3 = val1 * 30 + 150; // Natural HP recovery increase: [(Skill Level x 30) + 50] % - if( (src = map->id2bl(val2)) ) // the stat def is not shown in the status window and it is process differently - val4 = ( status_get_vit(src)/4 ) * val1; // STAT DEF increase: [(Caster VIT / 4) x Skill Level] - } - break; case SC_PYROTECHNIC_OPTION: val_flag |= 1|2|4; break; case SC_HEATER_OPTION: - val2 = 120; // Watk. TODO: Renewal (Atk2) - val3 = 33; // % Increase effects. - val4 = 3; // Change into fire element. val_flag |= 1|2|4; break; - case SC_TROPIC_OPTION: - val2 = 180; // Watk. TODO: Renewal (Atk2) - val3 = MG_FIREBOLT; - break; case SC_AQUAPLAY_OPTION: - val2 = 40; val_flag |= 1|2|4; break; case SC_COOLER_OPTION: - val2 = 80; // % Freezing chance - val3 = 33; // % increased damage - val4 = 1; // Change into water elemet val_flag |= 1|2|4; break; case SC_CHILLY_AIR_OPTION: - val2 = 120; // Matk. TODO: Renewal (Matk1) - val3 = MG_COLDBOLT; val_flag |= 1|2; break; case SC_GUST_OPTION: val_flag |= 1|2; break; - case SC_WIND_STEP_OPTION: - val2 = 50; // % Increase speed and flee. - break; case SC_BLAST_OPTION: - val2 = 20; - val3 = ELE_WIND; val_flag |= 1|2|4; break; case SC_WILD_STORM_OPTION: - val2 = MG_LIGHTNINGBOLT; val_flag |= 1|2; break; case SC_PETROLOGY_OPTION: - val2 = 5; - val3 = 50; val_flag |= 1|2|4; break; case SC_CURSED_SOIL_OPTION: - val2 = 10; - val3 = 33; - val4 = 2; val_flag |= 1|2|4; break; case SC_UPHEAVAL_OPTION: - val2 = WZ_EARTHSPIKE; val_flag |= 1|2; break; case SC_CIRCLE_OF_FIRE_OPTION: - val2 = 300; val_flag |= 1|2; break; - case SC_FIRE_CLOAK_OPTION: - case SC_WATER_DROP_OPTION: - case SC_WIND_CURTAIN_OPTION: - case SC_STONE_SHIELD_OPTION: - val2 = 20; // Elemental modifier. Not confirmed. - break; - case SC_CIRCLE_OF_FIRE: - case SC_FIRE_CLOAK: - case SC_WATER_DROP: - case SC_WATER_SCREEN: - case SC_WIND_CURTAIN: - case SC_WIND_STEP: - case SC_STONE_SHIELD: - case SC_SOLID_SKIN: - val2 = 10; - tick_time = 2000; // [GodLesZ] tick time - break; case SC_WATER_BARRIER: - val2 = 40; // Increasement. Mdef1 ??? - val3 = 20; // Reductions. Atk2, Flee1, Matk1 ???? val_flag |= 1|2|4; break; - case SC_ZEPHYR: - val2 = 22; // Flee. + case SC_CASH_PLUSEXP: + case SC_CASH_PLUSONLYJOBEXP: + case SC_MONSTER_TRANSFORM: + case SC_CASH_RECEIVEITEM: + val_flag |= 1; break; - case SC_TIDAL_WEAPON: - val2 = 20; // Increase Elemental's attack. + } + + /* [Ind/Hercules] */ + if( sd && status->DisplayType[type] ) { + int dval1 = 0, dval2 = 0, dval3 = 0; + switch( type ) { + case SC_ALL_RIDING: + dval1 = 1; + break; + default: /* all others: just copy val1 */ + dval1 = val1; + break; + } + status->display_add(sd,type,dval1,dval2,dval3); + } + + //Those that make you stop attacking/walking.... + switch (type) { + case SC_VACUUM_EXTREME: + if(!map_flag_gvg(bl->m)) + unit->stop_walking(bl,1); break; - case SC_ROCK_CRUSHER: - case SC_ROCK_CRUSHER_ATK: - case SC_POWER_OF_GAIA: - val2 = 33; + case SC_FREEZE: + case SC_STUN: + case SC_SLEEP: + case SC_STONE: + case SC_DEEP_SLEEP: + if (sd && pc_issit(sd)) //Avoid sprite sync problems. + pc->setstand(sd); + case SC_TRICKDEAD: + status_change_end(bl, SC_DANCING, INVALID_TIMER); + // Cancel cast when get status [LuzZza] + if (battle_config.sc_castcancel&bl->type) + unit->skillcastcancel(bl, 0); + case SC_WHITEIMPRISON: + unit->stop_attack(bl); + case SC_STOP: + case SC_CONFUSION: + case SC_RG_CCONFINE_M: + case SC_RG_CCONFINE_S: + case SC_SPIDERWEB: + case SC_ELECTRICSHOCKER: + case SC_WUGBITE: + case SC_THORNS_TRAP: + case SC__MANHOLE: + case SC__CHAOS: + case SC_COLD: + case SC_CURSEDCIRCLE_ATKER: + case SC_CURSEDCIRCLE_TARGET: + case SC_FEAR: + case SC_MEIKYOUSISUI: + case SC_KYOUGAKU: + case SC_NEEDLE_OF_PARALYZE: + case SC_DEATHBOUND: + unit->stop_walking(bl,1); break; - case SC_MELON_BOMB: - case SC_BANANA_BOMB: - val1 = 15; + case SC_ANKLESNARE: + if( battle_config.skill_trap_type || !map_flag_gvg(bl->m) ) + unit->stop_walking(bl,1); break; - case SC_STOMACHACHE: - val2 = 8; // SP consume. - val4 = tick / 10000; - tick_time = 10000; // [GodLesZ] tick time + case SC_HIDING: + case SC_CLOAKING: + case SC_CLOAKINGEXCEED: + case SC_CHASEWALK: + case SC_WEIGHTOVER90: + case SC_CAMOUFLAGE: + case SC_SIREN: + unit->stop_attack(bl); break; - case SC_KYOUGAKU: - val2 = 2*val1 + rand()%(3 * val1); - clif->status_change(bl, SI_ACTIVE_MONSTER_TRANSFORM, 1, 0, 1002, 0, 0); // Poring in disguise + case SC_SILENCE: + if (battle_config.sc_castcancel&bl->type) + unit->skillcastcancel(bl, 0); break; - case SC_KAGEMUSYA: - val3 = val1 * 2; - case SC_IZAYOI: - val2 = tick/1000; - tick_time = 1000; - break; - case SC_ZANGETSU: - val2 = val4 = status->get_lv(bl) / 3 + 20 * val1; - val3 = status->get_lv(bl) / 2 + 30 * val1; - val2 = (!(status_get_hp(bl)%2) ? val2 : -val3); - val3 = (!(status_get_sp(bl)%2) ? val4 : -val3); - break; - case SC_GENSOU: - -#define PER( a ) do { \ - if( a <= 15 ) lv = 1; \ - else if( a <= 30 ) lv = 2; \ - else if( a <= 50 ) lv = 3; \ - else if( a <= 75 ) lv = 4; \ -} while(0) - - { - int hp = status_get_hp(bl), sp = status_get_sp(bl), lv = 5; + /* */ + case SC_ITEMSCRIPT: + if( sd ) { + switch( val1 ) { + //case ITEMID_PHREEONI_CARD: + //case ITEMID_GHOSTRING_CARD: + case ITEMID_TAO_GUNKA_CARD: + clif->status_change(bl,SI_MVPCARD_TAOGUNKA,1,tick,0,0,0); + break; + case ITEMID_MISTRESS_CARD: + clif->status_change(bl,SI_MVPCARD_MISTRESS,1,tick,0,0,0); + break; + case ITEMID_ORC_HERO_CARD: + clif->status_change(bl,SI_MVPCARD_ORCHERO,1,tick,0,0,0); + break; + case ITEMID_ORC_LOAD_CARD: + clif->status_change(bl,SI_MVPCARD_ORCLORD,1,tick,0,0,0); + break; + } + } + break; + } - if( rand()%100 > (25 + 10 * val1) - status_get_int(bl) / 2) - return 0; + // Set option as needed. + opt_flag = 1; + switch(type) { + //OPT1 + case SC_STONE: sc->opt1 = OPT1_STONEWAIT; break; + case SC_FREEZE: sc->opt1 = OPT1_FREEZE; break; + case SC_STUN: sc->opt1 = OPT1_STUN; break; + case SC_SLEEP: sc->opt1 = OPT1_SLEEP; break; + case SC_BURNING: sc->opt1 = OPT1_BURNING; break; // Burning need this to be showed correctly. [pakpil] + case SC_WHITEIMPRISON: sc->opt1 = OPT1_IMPRISON; break; + case SC_COLD: sc->opt1 = OPT1_CRYSTALIZE; break; + //OPT2 + case SC_POISON: sc->opt2 |= OPT2_POISON; break; + case SC_CURSE: sc->opt2 |= OPT2_CURSE; break; + case SC_SILENCE: sc->opt2 |= OPT2_SILENCE; break; - PER( 100 / (status_get_max_hp(bl) / hp) ); - status->heal(bl, (!(hp%2) ? (6-lv) *4 / 100 : -(lv*4) / 100), 0, 1); + case SC_CRUCIS: + case SC__CHAOS: + sc->opt2 |= OPT2_SIGNUMCRUCIS; + break; - PER( 100 / (status_get_max_sp(bl) / sp) ); - status->heal(bl, 0,(!(sp%2) ? (6-lv) *3 / 100 : -(lv*3) / 100), 1); - } -#undef PER + case SC_BLIND: sc->opt2 |= OPT2_BLIND; break; + case SC_ANGELUS: sc->opt2 |= OPT2_ANGELUS; break; + case SC_BLOODING: sc->opt2 |= OPT2_BLEEDING; break; + case SC_DPOISON: sc->opt2 |= OPT2_DPOISON; break; + //OPT3 + case SC_TWOHANDQUICKEN: + case SC_ONEHANDQUICKEN: + case SC_SPEARQUICKEN: + case SC_LKCONCENTRATION: + case SC_MER_QUICKEN: + sc->opt3 |= OPT3_QUICKEN; + opt_flag = 0; break; - case SC_ANGRIFFS_MODUS: - val2 = 50 + 20 * val1; //atk bonus - val3 = 40 + 20 * val1; // Flee reduction. - val4 = tick/1000; // hp/sp reduction timer - tick_time = 1000; + case SC_OVERTHRUSTMAX: + case SC_OVERTHRUST: + case SC_SWOO: //Why does it shares the same opt as Overthrust? Perhaps we'll never know... + sc->opt3 |= OPT3_OVERTHRUST; + opt_flag = 0; break; - case SC_NEUTRALBARRIER: - tick_time = tick; - tick = -1; + case SC_ENERGYCOAT: + case SC_SKE: + sc->opt3 |= OPT3_ENERGYCOAT; + opt_flag = 0; break; - case SC_GOLDENE_FERSE: - val2 = 10 + 10*val1; //max hp bonus - val3 = 6 + 4 * val1; // Aspd Bonus - val4 = 2 + 2 * val1; // Chance of holy attack + case SC_INCATKRATE: + //Simulate Explosion Spirits effect for NPC_POWERUP [Skotlex] + if (bl->type != BL_MOB) { + opt_flag = 0; + break; + } + case SC_EXPLOSIONSPIRITS: + sc->opt3 |= OPT3_EXPLOSIONSPIRITS; + opt_flag = 0; + break; + case SC_STEELBODY: + case SC_SKA: + sc->opt3 |= OPT3_STEELBODY; + opt_flag = 0; break; - case SC_OVERED_BOOST: - val2 = 300 + 40*val1; //flee bonus - val3 = 179 + 2*val1; //aspd bonus + case SC_BLADESTOP: + sc->opt3 |= OPT3_BLADESTOP; + opt_flag = 0; break; - case SC_GRANITIC_ARMOR: - val2 = 2*val1; //dmg reduction - val3 = 6*val1; //dmg on status end + case SC_AURABLADE: + sc->opt3 |= OPT3_AURABLADE; + opt_flag = 0; break; - case SC_MAGMA_FLOW: - val2 = 3*val1; //activation chance + case SC_BERSERK: + opt_flag = 0; + sc->opt3 |= OPT3_BERSERK; break; - case SC_PYROCLASTIC: - val2 += 10*val1; //atk bonus +// case ???: // doesn't seem to do anything +// sc->opt3 |= OPT3_LIGHTBLADE; +// opt_flag = 0; +// break; + case SC_DANCING: + if ((val1&0xFFFF) == CG_MOONLIT) + sc->opt3 |= OPT3_MOONLIT; + opt_flag = 0; break; - case SC_NEEDLE_OF_PARALYZE: //[Lighta] need real info - val2 = 2*val1; //def reduction - val3 = 500*val1; //varcast augmentation + case SC_MARIONETTE_MASTER: + case SC_MARIONETTE: + sc->opt3 |= OPT3_MARIONETTE; + opt_flag = 0; break; - case SC_PAIN_KILLER: //[Lighta] need real info - val2 = 2*val1; //aspd reduction % - val3 = 2*val1; //dmg reduction % - if(sc->data[SC_NEEDLE_OF_PARALYZE]) - sc_start(bl, SC_ENDURE, 100, val1, tick); //start endure for same duration + case SC_ASSUMPTIO: + sc->opt3 |= OPT3_ASSUMPTIO; + opt_flag = 0; break; - case SC_STYLE_CHANGE: //[Lighta] need real info - tick = -1; - if(val2 == MH_MD_FIGHTING) val2 = MH_MD_GRAPPLING; - else val2 = MH_MD_FIGHTING; + case SC_WARM: //SG skills [Komurka] + sc->opt3 |= OPT3_WARM; + opt_flag = 0; break; - case SC_FULL_THROTTLE: - status_percent_heal(bl,100,0); - val2 = 7 - val1; - tick_time = 1000; - val4 = tick / tick_time; + case SC_KAITE: + sc->opt3 |= OPT3_KAITE; + opt_flag = 0; break; - case SC_KINGS_GRACE: - val2 = 3 + val1; - tick_time = 1000; - val4 = tick / tick_time; + case SC_NJ_BUNSINJYUTSU: + sc->opt3 |= OPT3_BUNSIN; + opt_flag = 0; break; - case SC_TELEKINESIS_INTENSE: - val2 = 10 * val1; - val3 = 40 * val1; + case SC_SOULLINK: + sc->opt3 |= OPT3_SOULLINK; + opt_flag = 0; break; - case SC_OFFERTORIUM: - val2 = 30 * val1; + case SC_PROPERTYUNDEAD: + sc->opt3 |= OPT3_UNDEAD; + opt_flag = 0; break; - case SC_FRIGG_SONG: - val2 = 5 * val1; - val3 = 1000 + 100 * val1; - tick_time = 10000; - val4 = tick / tick_time; +// case ???: // from DA_CONTRACT (looks like biolab mobs aura) +// sc->opt3 |= OPT3_CONTRACT; +// opt_flag = 0; +// break; + //OPTION + case SC_HIDING: + sc->option |= OPTION_HIDE; + opt_flag = 2; break; - case SC_MONSTER_TRANSFORM: - if( !mob->db_checkid(val1) ) - val1 = 1002; // default poring - val_flag |= 1; + case SC_CLOAKING: + case SC_CLOAKINGEXCEED: + sc->option |= OPTION_CLOAK; + opt_flag = 2; + break; + case SC__INVISIBILITY: + case SC_CHASEWALK: + sc->option |= OPTION_CHASEWALK|OPTION_CLOAK; + opt_flag = 2; + break; + case SC_SIGHT: + sc->option |= OPTION_SIGHT; + break; + case SC_RUWACH: + sc->option |= OPTION_RUWACH; break; - default: - if( calc_flag == SCB_NONE && status->SkillChangeTable[type] == 0 && status->IconChangeTable[type] == 0 ) - { //Status change with no calc, no icon, and no skill associated...? - ShowError("UnknownStatusChange [%d]\n", type); - return 0; - } - } - } else { //Special considerations when loading SC data. - switch( type ) { case SC_WEDDING: + sc->option |= OPTION_WEDDING; + opt_flag |= 0x4; + break; case SC_XMAS: - case SC_SUMMER: - case SC_HANBOK: - if( !vd ) break; - clif->changelook(bl,LOOK_BASE,vd->class_); - clif->changelook(bl,LOOK_WEAPON,0); - clif->changelook(bl,LOOK_SHIELD,0); - clif->changelook(bl,LOOK_CLOTHES_COLOR,vd->cloth_color); + sc->option |= OPTION_XMAS; + opt_flag |= 0x4; break; - case SC_KAAHI: - val4 = INVALID_TIMER; + case SC_SUMMER: + sc->option |= OPTION_SUMMER; + opt_flag |= 0x4; break; - case SC_SUMMON1: - case SC_SUMMON2: - case SC_SUMMON3: - case SC_SUMMON4: - case SC_SUMMON5: - case SC_MONSTER_TRANSFORM: - val_flag |= 1; + case SC_HANBOK: + sc->option |= OPTION_HANBOK; + opt_flag |= 0x4; break; - case SC_KYOUGAKU: - clif->status_change(bl, SI_ACTIVE_MONSTER_TRANSFORM, 1, 0, 1002, 0, 0); // Poring in disguise + case SC_ORCISH: + sc->option |= OPTION_ORCISH; break; - } - } - - /* [Ind/Hercules] */ - if( sd && status->DisplayType[type] ) { - int dval1 = 0, dval2 = 0, dval3 = 0; - switch( type ) { - case SC_ALL_RIDING: - dval1 = 1; + case SC_FUSION: + sc->option |= OPTION_FLYING; break; - default: /* all others: just copy val1 */ - dval1 = val1; + case SC_OKTOBERFEST: + sc->option |= OPTION_OKTOBERFEST; + opt_flag |= 0x4; break; - } - status->display_add(sd,type,dval1,dval2,dval3); - } - - //Those that make you stop attacking/walking.... - switch (type) { - case SC_FREEZE: - case SC_STUN: - case SC_SLEEP: - case SC_STONE: - case SC_DEEP_SLEEP: - if (sd && pc_issit(sd)) //Avoid sprite sync problems. - pc->setstand(sd); - case SC_TRICKDEAD: - status_change_end(bl, SC_DANCING, INVALID_TIMER); - // Cancel cast when get status [LuzZza] - if (battle_config.sc_castcancel&bl->type) - unit->skillcastcancel(bl, 0); - case SC_WHITEIMPRISON: - unit->stop_attack(bl); - case SC_STOP: - case SC_CONFUSION: - case SC_RG_CCONFINE_M: - case SC_RG_CCONFINE_S: - case SC_SPIDERWEB: - case SC_ELECTRICSHOCKER: - case SC_WUGBITE: - case SC_THORNS_TRAP: - case SC__MANHOLE: - case SC_COLD: - case SC_CURSEDCIRCLE_ATKER: - case SC_CURSEDCIRCLE_TARGET: - case SC_FEAR: - case SC_NETHERWORLD: - case SC_MEIKYOUSISUI: - case SC_KYOUGAKU: - case SC_NEEDLE_OF_PARALYZE: - case SC_DEATHBOUND: - unit->stop_walking(bl,1); - break; - case SC_ANKLESNARE: - if( battle_config.skill_trap_type || !map_flag_gvg(bl->m) ) - unit->stop_walking(bl,1); - break; - case SC_HIDING: - case SC_CLOAKING: - case SC_CLOAKINGEXCEED: - case SC_CHASEWALK: - case SC_WEIGHTOVER90: - case SC_CAMOUFLAGE: - case SC_SIREN: - unit->stop_attack(bl); - break; - case SC_SILENCE: - if (battle_config.sc_castcancel&bl->type) - unit->skillcastcancel(bl, 0); - break; - /* */ - case SC_ITEMSCRIPT: - if( sd ) { - switch( val1 ) { - //case 4121://Phree - //case 4047://Ghostring - case 4302://Gunka - clif->status_change(bl,SI_MVPCARD_TAOGUNKA,1,tick,0,0,0); - break; - case 4132://Mistress - clif->status_change(bl,SI_MVPCARD_MISTRESS,1,tick,0,0,0); - break; - case 4143://Orc Hero - clif->status_change(bl,SI_MVPCARD_ORCHERO,1,tick,0,0,0); - break; - case 4135://Orc Lord - clif->status_change(bl,SI_MVPCARD_ORCLORD,1,tick,0,0,0); - break; - } - } - break; - } - - // Set option as needed. - opt_flag = 1; - switch(type) { - //OPT1 - case SC_STONE: sc->opt1 = OPT1_STONEWAIT; break; - case SC_FREEZE: sc->opt1 = OPT1_FREEZE; break; - case SC_STUN: sc->opt1 = OPT1_STUN; break; - case SC_DEEP_SLEEP: opt_flag = 0; - case SC_SLEEP: sc->opt1 = OPT1_SLEEP; break; - case SC_BURNING: sc->opt1 = OPT1_BURNING; break; // Burning need this to be showed correctly. [pakpil] - case SC_WHITEIMPRISON: sc->opt1 = OPT1_IMPRISON; break; - case SC_COLD: sc->opt1 = OPT1_CRYSTALIZE; break; - //OPT2 - case SC_POISON: sc->opt2 |= OPT2_POISON; break; - case SC_CURSE: sc->opt2 |= OPT2_CURSE; break; - case SC_SILENCE: sc->opt2 |= OPT2_SILENCE; break; - - case SC_CRUCIS: - sc->opt2 |= OPT2_SIGNUMCRUCIS; - break; - - case SC_BLIND: sc->opt2 |= OPT2_BLIND; break; - case SC_ANGELUS: sc->opt2 |= OPT2_ANGELUS; break; - case SC_BLOODING: sc->opt2 |= OPT2_BLEEDING; break; - case SC_DPOISON: sc->opt2 |= OPT2_DPOISON; break; - //OPT3 - case SC_TWOHANDQUICKEN: - case SC_ONEHANDQUICKEN: - case SC_SPEARQUICKEN: - case SC_LKCONCENTRATION: - case SC_MER_QUICKEN: - sc->opt3 |= OPT3_QUICKEN; - opt_flag = 0; - break; - case SC_OVERTHRUSTMAX: - case SC_OVERTHRUST: - case SC_SWOO: //Why does it shares the same opt as Overthrust? Perhaps we'll never know... - sc->opt3 |= OPT3_OVERTHRUST; - opt_flag = 0; - break; - case SC_ENERGYCOAT: - case SC_SKE: - sc->opt3 |= OPT3_ENERGYCOAT; - opt_flag = 0; - break; - case SC_INCATKRATE: - //Simulate Explosion Spirits effect for NPC_POWERUP [Skotlex] - if (bl->type != BL_MOB) { + default: opt_flag = 0; - break; - } - case SC_EXPLOSIONSPIRITS: - sc->opt3 |= OPT3_EXPLOSIONSPIRITS; - opt_flag = 0; - break; - case SC_STEELBODY: - case SC_SKA: - sc->opt3 |= OPT3_STEELBODY; - opt_flag = 0; - break; - case SC_BLADESTOP: - sc->opt3 |= OPT3_BLADESTOP; - opt_flag = 0; - break; - case SC_AURABLADE: - sc->opt3 |= OPT3_AURABLADE; - opt_flag = 0; - break; - case SC_BERSERK: - opt_flag = 0; - sc->opt3 |= OPT3_BERSERK; - break; - // case ???: // doesn't seem to do anything - // sc->opt3 |= OPT3_LIGHTBLADE; - // opt_flag = 0; - // break; - case SC_DANCING: - if ((val1&0xFFFF) == CG_MOONLIT) - sc->opt3 |= OPT3_MOONLIT; - opt_flag = 0; - break; - case SC_MARIONETTE_MASTER: - case SC_MARIONETTE: - sc->opt3 |= OPT3_MARIONETTE; - opt_flag = 0; - break; - case SC_ASSUMPTIO: - sc->opt3 |= OPT3_ASSUMPTIO; - opt_flag = 0; - break; - case SC_WARM: //SG skills [Komurka] - sc->opt3 |= OPT3_WARM; - opt_flag = 0; - break; - case SC_KAITE: - sc->opt3 |= OPT3_KAITE; - opt_flag = 0; - break; - case SC_NJ_BUNSINJYUTSU: - sc->opt3 |= OPT3_BUNSIN; - opt_flag = 0; - break; - case SC_SOULLINK: - sc->opt3 |= OPT3_SOULLINK; - opt_flag = 0; - break; - case SC_PROPERTYUNDEAD: - sc->opt3 |= OPT3_UNDEAD; - opt_flag = 0; - break; - // case ???: // from DA_CONTRACT (looks like biolab mobs aura) - // sc->opt3 |= OPT3_CONTRACT; - // opt_flag = 0; - // break; - //OPTION - case SC_HIDING: - sc->option |= OPTION_HIDE; - opt_flag = 2; - break; - case SC_CLOAKING: - case SC_CLOAKINGEXCEED: - case SC__INVISIBILITY: - sc->option |= OPTION_CLOAK; - opt_flag = 2; - break; - case SC_CHASEWALK: - sc->option |= OPTION_CHASEWALK|OPTION_CLOAK; - opt_flag = 2; - break; - case SC_SIGHT: - sc->option |= OPTION_SIGHT; - break; - case SC_RUWACH: - sc->option |= OPTION_RUWACH; - break; - case SC_WEDDING: - sc->option |= OPTION_WEDDING; - opt_flag |= 0x4; - break; - case SC_XMAS: - sc->option |= OPTION_XMAS; - opt_flag |= 0x4; - break; - case SC_SUMMER: - sc->option |= OPTION_SUMMER; - opt_flag |= 0x4; - break; - case SC_HANBOK: - sc->option |= OPTION_HANBOK; - opt_flag |= 0x4; - break; - case SC_ORCISH: - sc->option |= OPTION_ORCISH; - break; - case SC_FUSION: - sc->option |= OPTION_FLYING; - break; - default: - opt_flag = 0; } //On Aegis, when turning on a status change, first goes the option packet, then the sc packet. @@ -8998,8 +9420,11 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val sce->val4 = val4; if (tick >= 0) sce->timer = timer->add(timer->gettick() + tick, status->change_timer, bl->id, type); - else + else { sce->timer = INVALID_TIMER; //Infinite duration + if( sd ) + chrif->save_scdata_single(sd->status.account_id,sd->status.char_id,type,sce); + } if (calc_flag) status_calc_bl(bl,calc_flag); @@ -9008,81 +9433,81 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val pet->sc_check(sd, type); //Skotlex: Pet Status Effect Healing switch (type) { - case SC_BERSERK: - if (!(sce->val2)) { //don't heal if already set - status->heal(bl, st->max_hp, 0, 1); //Do not use percent_heal as this healing must override BERSERK's block. - status->set_sp(bl, 0, 0); //Damage all SP - } - sce->val2 = 5 * st->max_hp / 100; - break; - case SC_HLIF_CHANGE: - status_percent_heal(bl, 100, 100); - break; - case SC_RUN: - { - struct unit_data *ud = unit->bl2ud(bl); - if( ud ) - ud->state.running = unit->run(bl); - } - break; - case SC_CASH_BOSS_ALARM: - clif->bossmapinfo(sd->fd, map->id2boss(sce->val1), 0); // First Message - break; - case SC_MER_HP: - status_percent_heal(bl, 100, 0); // Recover Full HP - break; - case SC_MER_SP: - status_percent_heal(bl, 0, 100); // Recover Full SP - break; - /** - * Ranger - **/ - case SC_WUGDASH: - { - struct unit_data *ud = unit->bl2ud(bl); - if( ud ) - ud->state.running = unit->wugdash(bl, sd); - } - break; - case SC_COMBOATTACK: - switch (sce->val1) { - case TK_STORMKICK: - clif->skill_nodamage(bl,bl,TK_READYSTORM,1,1); + case SC_BERSERK: + if (!(sce->val2)) { //don't heal if already set + status->heal(bl, st->max_hp, 0, 1); //Do not use percent_heal as this healing must override BERSERK's block. + status->set_sp(bl, 0, 0); //Damage all SP + } + sce->val2 = 5 * st->max_hp / 100; break; - case TK_DOWNKICK: - clif->skill_nodamage(bl,bl,TK_READYDOWN,1,1); + case SC_HLIF_CHANGE: + status_percent_heal(bl, 100, 100); break; - case TK_TURNKICK: - clif->skill_nodamage(bl,bl,TK_READYTURN,1,1); + case SC_RUN: + { + struct unit_data *ud = unit->bl2ud(bl); + if( ud ) + ud->state.running = unit->run(bl); + } break; - case TK_COUNTER: - clif->skill_nodamage(bl,bl,TK_READYCOUNTER,1,1); + case SC_CASH_BOSS_ALARM: + clif->bossmapinfo(sd->fd, map->id2boss(sce->val1), 0); // First Message break; - case MO_COMBOFINISH: - case CH_TIGERFIST: - case CH_CHAINCRUSH: - if (sd) - clif->skillinfo(sd,MO_EXTREMITYFIST, INF_SELF_SKILL); + case SC_MER_HP: + status_percent_heal(bl, 100, 0); // Recover Full HP break; - case TK_JUMPKICK: - if (sd) - clif->skillinfo(sd,TK_JUMPKICK, INF_SELF_SKILL); + case SC_MER_SP: + status_percent_heal(bl, 0, 100); // Recover Full SP break; - case MO_TRIPLEATTACK: - if (sd && pc->checkskill(sd, SR_DRAGONCOMBO) > 0) - clif->skillinfo(sd,SR_DRAGONCOMBO, INF_SELF_SKILL); + /** + * Ranger + **/ + case SC_WUGDASH: + { + struct unit_data *ud = unit->bl2ud(bl); + if( ud ) + ud->state.running = unit->wugdash(bl, sd); + } break; - case SR_FALLENEMPIRE: - if (sd){ - clif->skillinfo(sd,SR_GATEOFHELL, INF_SELF_SKILL); - clif->skillinfo(sd,SR_TIGERCANNON, INF_SELF_SKILL); + case SC_COMBOATTACK: + switch (sce->val1) { + case TK_STORMKICK: + clif->skill_nodamage(bl,bl,TK_READYSTORM,1,1); + break; + case TK_DOWNKICK: + clif->skill_nodamage(bl,bl,TK_READYDOWN,1,1); + break; + case TK_TURNKICK: + clif->skill_nodamage(bl,bl,TK_READYTURN,1,1); + break; + case TK_COUNTER: + clif->skill_nodamage(bl,bl,TK_READYCOUNTER,1,1); + break; + case MO_COMBOFINISH: + case CH_TIGERFIST: + case CH_CHAINCRUSH: + if (sd) + clif->skillinfo(sd,MO_EXTREMITYFIST, INF_SELF_SKILL); + break; + case TK_JUMPKICK: + if (sd) + clif->skillinfo(sd,TK_JUMPKICK, INF_SELF_SKILL); + break; + case MO_TRIPLEATTACK: + if (sd && pc->checkskill(sd, SR_DRAGONCOMBO) > 0) + clif->skillinfo(sd,SR_DRAGONCOMBO, INF_SELF_SKILL); + break; + case SR_FALLENEMPIRE: + if (sd){ + clif->skillinfo(sd,SR_GATEOFHELL, INF_SELF_SKILL); + clif->skillinfo(sd,SR_TIGERCANNON, INF_SELF_SKILL); + } + break; } break; - } - break; - case SC_RAISINGDRAGON: - sce->val2 = st->max_hp / 100;// Officially tested its 1%hp drain. [Jobbie] - break; + case SC_RAISINGDRAGON: + sce->val2 = st->max_hp / 100;// Officially tested its 1%hp drain. [Jobbie] + break; } if( opt_flag&2 && sd && sd->touching_id ) @@ -9090,7 +9515,6 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val return 1; } - /*========================================== * Ending all status except those listed. * @TODO maybe usefull for dispel instead reseting a liste there. @@ -9116,25 +9540,16 @@ int status_change_clear(struct block_list* bl, int type) { if(type == 0){ if( status->get_sc_type(i)&SC_NO_REM_DEATH ) { switch (i) { - case SC_ARMOR_PROPERTY://Only when its Holy or Dark that it doesn't dispell on death - if( sc->data[i]->val2 != ELE_HOLY && sc->data[i]->val2 != ELE_DARK ) - break; - default: - continue; + case SC_ARMOR_PROPERTY://Only when its Holy or Dark that it doesn't dispell on death + if( sc->data[i]->val2 != ELE_HOLY && sc->data[i]->val2 != ELE_DARK ) + break; + default: + continue; } } } - if( type == 3 ) { - switch (i) {// TODO: This list may be incomplete - case SC_WEIGHTOVER50: - case SC_WEIGHTOVER90: - case SC_NOCHAT: - case SC_PUSH_CART: - case SC_JAILED: - case SC_ALL_RIDING: - continue; - } - } + if( type == 3 && status->get_sc_type(i)&SC_NO_CLEAR ) + continue; status_change_end(bl, (sc_type)i, INVALID_TIMER); @@ -9152,6 +9567,7 @@ int status_change_clear(struct block_list* bl, int type) { sc->opt2 = 0; sc->opt3 = 0; sc->bs_counter = 0; + sc->fv_counter = 0; #ifndef RENEWAL sc->sg_counter = 0; #endif @@ -9172,7 +9588,10 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const struct status_data *st; struct view_data *vd; int opt_flag=0, calc_flag; - +#ifdef ANTI_MAYAP_CHEAT + bool invisible = false; +#endif + nullpo_ret(bl); sc = status->get_sc(bl); @@ -9186,6 +9605,9 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const if (sce->timer != tid && tid != INVALID_TIMER) return 0; + if( sd && sce->timer == INVALID_TIMER ) + chrif->del_scdata_single(sd->status.account_id,sd->status.char_id,type); + if (tid == INVALID_TIMER) { if (type == SC_ENDURE && sce->val4) //Do not end infinite endure. @@ -9197,19 +9619,19 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const //"Ugly workaround" [Skotlex] //delays status change ending so that a skill that sets opt1 fails to //trigger when it also removed one - case SC_STONE: - sce->val3 = 0; //Petrify time counter. - case SC_FREEZE: - case SC_STUN: - case SC_SLEEP: - if (sce->val1) { - //Removing the 'level' shouldn't affect anything in the code - //since these SC are not affected by it, and it lets us know - //if we have already delayed this attack or not. - sce->val1 = 0; - sce->timer = timer->add(timer->gettick()+10, status->change_timer, bl->id, type); - return 1; - } + case SC_STONE: + sce->val3 = 0; //Petrify time counter. + case SC_FREEZE: + case SC_STUN: + case SC_SLEEP: + if (sce->val1) { + //Removing the 'level' shouldn't affect anything in the code + //since these SC are not affected by it, and it lets us know + //if we have already delayed this attack or not. + sce->val1 = 0; + sce->timer = timer->add(timer->gettick()+10, status->change_timer, bl->id, type); + return 1; + } } } @@ -9221,602 +9643,625 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const status->display_remove(sd,type); } +#ifdef ANTI_MAYAP_CHEAT + if (sc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_INVISIBLE)) + invisible = true; +#endif + vd = status->get_viewdata(bl); calc_flag = status->ChangeFlagTable[type]; switch(type) { - case SC_GRANITIC_ARMOR: - { - int damage = st->max_hp*sce->val3/100; - if(st->hp < damage) //to not kill him - damage = st->hp-1; - status->damage(NULL, bl, damage,0,0,1); - } - break; - case SC_PYROCLASTIC: - if(bl->type == BL_PC) - skill->break_equip(bl,EQP_WEAPON,10000,BCT_SELF); - break; - case SC_RUN: + case SC_GRANITIC_ARMOR: { - struct unit_data *ud = unit->bl2ud(bl); - bool begin_spurt = true; - if (ud) { - if(!ud->state.running) - begin_spurt = false; - ud->state.running = 0; - if (ud->walktimer != INVALID_TIMER) - unit->stop_walking(bl,1); - } - if (begin_spurt && sce->val1 >= 7 - && DIFF_TICK(timer->gettick(), sce->val4) <= 1000 - && (!sd || (sd->weapontype1 == 0 && sd->weapontype2 == 0)) - ) - sc_start(bl,SC_STRUP,100,sce->val1,skill->get_time2(status->sc2skill(type), sce->val1)); + int damage = st->max_hp*sce->val3/100; + if(st->hp < damage) //to not kill him + damage = st->hp-1; + status->damage(NULL, bl, damage,0,0,1); } - break; - case SC_AUTOBERSERK: - if (sc->data[SC_PROVOKE] && sc->data[SC_PROVOKE]->val2 == 1) - status_change_end(bl, SC_PROVOKE, INVALID_TIMER); - break; + break; + case SC_PYROCLASTIC: + if(bl->type == BL_PC) + skill->break_equip(bl,EQP_WEAPON,10000,BCT_SELF); + break; + case SC_RUN: + { + struct unit_data *ud = unit->bl2ud(bl); + bool begin_spurt = true; + // Note: this int64 value is stored in two separate int32 variables (FIXME) + int64 starttick = (int64)sce->val3&0x00000000ffffffffLL; + starttick |= ((int64)sce->val4<<32)&0xffffffff00000000LL; + + if (ud) { + if(!ud->state.running) + begin_spurt = false; + ud->state.running = 0; + if (ud->walktimer != INVALID_TIMER) + unit->stop_walking(bl,1); + } + if (begin_spurt && sce->val1 >= 7 + && DIFF_TICK(timer->gettick(), starttick) <= 1000 + && (!sd || (sd->weapontype1 == 0 && sd->weapontype2 == 0)) + ) + sc_start(bl, bl,SC_STRUP,100,sce->val1,skill->get_time2(status->sc2skill(type), sce->val1)); + } + break; + case SC_AUTOBERSERK: + if (sc->data[SC_PROVOKE] && sc->data[SC_PROVOKE]->val2 == 1) + status_change_end(bl, SC_PROVOKE, INVALID_TIMER); + break; - case SC_ENDURE: - case SC_DEFENDER: - case SC_REFLECTSHIELD: - case SC_AUTOGUARD: - { - struct map_session_data *tsd; - if( bl->type == BL_PC ) { - // Clear Status from others - int i; - for( i = 0; i < 5; i++ ) { - if( sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) && tsd->sc.data[type] ) + case SC_ENDURE: + case SC_DEFENDER: + case SC_REFLECTSHIELD: + case SC_AUTOGUARD: + { + struct map_session_data *tsd; + if( bl->type == BL_PC ) { + // Clear Status from others + int i; + for( i = 0; i < 5; i++ ) { + if( sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) && tsd->sc.data[type] ) + status_change_end(&tsd->bl, type, INVALID_TIMER); + } + } else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag ) { + // Clear Status from Master + tsd = ((TBL_MER*)bl)->master; + if( tsd && tsd->sc.data[type] ) status_change_end(&tsd->bl, type, INVALID_TIMER); } - } else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag ) { - // Clear Status from Master - tsd = ((TBL_MER*)bl)->master; - if( tsd && tsd->sc.data[type] ) - status_change_end(&tsd->bl, type, INVALID_TIMER); } - } - break; - case SC_DEVOTION: - { - struct block_list *d_bl = map->id2bl(sce->val1); - if( d_bl ) { - if( d_bl->type == BL_PC ) - ((TBL_PC*)d_bl)->devotion[sce->val2] = 0; - else if( d_bl->type == BL_MER ) - ((TBL_MER*)d_bl)->devotion_flag = 0; - clif->devotion(d_bl, NULL); - } - - status_change_end(bl, SC_AUTOGUARD, INVALID_TIMER); - status_change_end(bl, SC_DEFENDER, INVALID_TIMER); - status_change_end(bl, SC_REFLECTSHIELD, INVALID_TIMER); - status_change_end(bl, SC_ENDURE, INVALID_TIMER); - } - break; + break; + case SC_DEVOTION: + { + struct block_list *d_bl = map->id2bl(sce->val1); + if( d_bl ) { + if( d_bl->type == BL_PC ) + ((TBL_PC*)d_bl)->devotion[sce->val2] = 0; + else if( d_bl->type == BL_MER ) + ((TBL_MER*)d_bl)->devotion_flag = 0; + clif->devotion(d_bl, NULL); + } - case SC_BLADESTOP: - if(sce->val4) { - int tid = sce->val4; - struct block_list *tbl = map->id2bl(tid); - struct status_change *tsc = status->get_sc(tbl); - sce->val4 = 0; - if(tbl && tsc && tsc->data[SC_BLADESTOP]) { - tsc->data[SC_BLADESTOP]->val4 = 0; - status_change_end(tbl, SC_BLADESTOP, INVALID_TIMER); - } - clif->bladestop(bl, tid, 0); - } - break; - case SC_DANCING: - { - const char* prevfile = "<unknown>"; - int prevline = 0; - struct map_session_data *dsd; - struct status_change_entry *dsc; - struct skill_unit_group *group; + status_change_end(bl, SC_AUTOGUARD, INVALID_TIMER); + status_change_end(bl, SC_DEFENDER, INVALID_TIMER); + status_change_end(bl, SC_REFLECTSHIELD, INVALID_TIMER); + status_change_end(bl, SC_ENDURE, INVALID_TIMER); + } + break; - if( sd ) - { - if( sd->delunit_prevfile ) - {// initially this is NULL, when a character logs in - prevfile = sd->delunit_prevfile; - prevline = sd->delunit_prevline; + case SC_BLADESTOP: + if(sce->val4) { + int target_id = sce->val4; + struct block_list *tbl = map->id2bl(target_id); + struct status_change *tsc = status->get_sc(tbl); + sce->val4 = 0; + if(tbl && tsc && tsc->data[SC_BLADESTOP]) { + tsc->data[SC_BLADESTOP]->val4 = 0; + status_change_end(tbl, SC_BLADESTOP, INVALID_TIMER); } - else + clif->bladestop(bl, target_id, 0); + } + break; + case SC_DANCING: + { + const char* prevfile = "<unknown>"; + int prevline = 0; + struct map_session_data *dsd; + struct status_change_entry *dsc; + struct skill_unit_group *group; + + if( sd ) { - prevfile = "<none>"; + if( sd->delunit_prevfile ) + {// initially this is NULL, when a character logs in + prevfile = sd->delunit_prevfile; + prevline = sd->delunit_prevline; + } + else + { + prevfile = "<none>"; + } + sd->delunit_prevfile = file; + sd->delunit_prevline = line; } - sd->delunit_prevfile = file; - sd->delunit_prevline = line; - } - if(sce->val4 && sce->val4 != BCT_SELF && (dsd=map->id2sd(sce->val4))) - {// end status on partner as well - dsc = dsd->sc.data[SC_DANCING]; - if(dsc) { + if(sce->val4 && sce->val4 != BCT_SELF && (dsd=map->id2sd(sce->val4))) + {// end status on partner as well + dsc = dsd->sc.data[SC_DANCING]; + if(dsc) { - //This will prevent recursive loops. - dsc->val2 = dsc->val4 = 0; + //This will prevent recursive loops. + dsc->val2 = dsc->val4 = 0; - status_change_end(&dsd->bl, SC_DANCING, INVALID_TIMER); + status_change_end(&dsd->bl, SC_DANCING, INVALID_TIMER); + } } - } - if(sce->val2) - {// erase associated land skill - group = skill->id2group(sce->val2); + if(sce->val2) + {// erase associated land skill + group = skill->id2group(sce->val2); + + if( group == NULL ) + { + ShowDebug("status_change_end: SC_DANCING is missing skill unit group (val1=%d, val2=%d, val3=%d, val4=%d, timer=%d, tid=%d, char_id=%d, map=%s, x=%d, y=%d, prev=%s:%d, from=%s:%d). Please report this! (#3504)\n", + sce->val1, sce->val2, sce->val3, sce->val4, sce->timer, tid, + sd ? sd->status.char_id : 0, + mapindex_id2name(map_id2index(bl->m)), bl->x, bl->y, + prevfile, prevline, + file, line); + } - if( group == NULL ) - { - ShowDebug("status_change_end: SC_DANCING is missing skill unit group (val1=%d, val2=%d, val3=%d, val4=%d, timer=%d, tid=%d, char_id=%d, map=%s, x=%d, y=%d, prev=%s:%d, from=%s:%d). Please report this! (#3504)\n", - sce->val1, sce->val2, sce->val3, sce->val4, sce->timer, tid, - sd ? sd->status.char_id : 0, - mapindex_id2name(map_id2index(bl->m)), bl->x, bl->y, - prevfile, prevline, - file, line); + sce->val2 = 0; + skill->del_unitgroup(group,ALC_MARK); } - sce->val2 = 0; - skill->del_unitgroup(group,ALC_MARK); + if((sce->val1&0xFFFF) == CG_MOONLIT) + clif->sc_end(bl,bl->id,AREA,SI_MOON); + + status_change_end(bl, SC_LONGING, INVALID_TIMER); + } + break; + case SC_NOCHAT: + if (sd && sd->status.manner < 0 && tid != INVALID_TIMER) + sd->status.manner = 0; + if (sd && tid == INVALID_TIMER) + { + clif->changestatus(sd,SP_MANNER,sd->status.manner); + clif->updatestatus(sd,SP_MANNER); + } + break; + case SC_SPLASHER: + { + struct block_list *src=map->id2bl(sce->val3); + if(src && tid != INVALID_TIMER) + skill->castend_damage_id(src, bl, sce->val2, sce->val1, timer->gettick(), SD_LEVEL ); + } + break; + case SC_RG_CCONFINE_S: + { + struct block_list *src = sce->val2 ? map->id2bl(sce->val2) : NULL; + struct status_change *sc2 = src ? status->get_sc(src) : NULL; + if (src && sc2 && sc2->data[SC_RG_CCONFINE_M]) { + //If status was already ended, do nothing. + //Decrease count + if (--(sc2->data[SC_RG_CCONFINE_M]->val1) <= 0) //No more holds, free him up. + status_change_end(src, SC_RG_CCONFINE_M, INVALID_TIMER); + } + } + case SC_RG_CCONFINE_M: + if (sce->val2 > 0) { + //Caster has been unlocked... nearby chars need to be unlocked. + int range = 1 + +skill->get_range2(bl, status->sc2skill(type), sce->val1) + +skill->get_range2(bl, TF_BACKSLIDING, 1); //Since most people use this to escape the hold.... + map->foreachinarea(status->change_timer_sub, + bl->m, bl->x-range, bl->y-range, bl->x+range,bl->y+range,BL_CHAR,bl,sce,type,timer->gettick()); } + break; + case SC_COMBOATTACK: + if( sd ) + switch (sce->val1) { + case MO_COMBOFINISH: + case CH_TIGERFIST: + case CH_CHAINCRUSH: + clif->skillinfo(sd, MO_EXTREMITYFIST, 0); + break; + case TK_JUMPKICK: + clif->skillinfo(sd, TK_JUMPKICK, 0); + break; + case MO_TRIPLEATTACK: + if (pc->checkskill(sd, SR_DRAGONCOMBO) > 0) + clif->skillinfo(sd, SR_DRAGONCOMBO, 0); + break; + case SR_FALLENEMPIRE: + clif->skillinfo(sd, SR_GATEOFHELL, 0); + clif->skillinfo(sd, SR_TIGERCANNON, 0); + break; + } + break; - if((sce->val1&0xFFFF) == CG_MOONLIT) - clif->sc_end(bl,bl->id,AREA,SI_MOON); + case SC_MARIONETTE_MASTER: + case SC_MARIONETTE: /// Marionette target + if (sce->val1) { + // check for partner and end their marionette status as well + enum sc_type type2 = (type == SC_MARIONETTE_MASTER) ? SC_MARIONETTE : SC_MARIONETTE_MASTER; + struct block_list *pbl = map->id2bl(sce->val1); + struct status_change* sc2 = pbl ? status->get_sc(pbl) : NULL; + + if (sc2 && sc2->data[type2]) + { + sc2->data[type2]->val1 = 0; + status_change_end(pbl, type2, INVALID_TIMER); + } + } + break; - status_change_end(bl, SC_LONGING, INVALID_TIMER); - } - break; - case SC_NOCHAT: - if (sd && sd->status.manner < 0 && tid != INVALID_TIMER) - sd->status.manner = 0; - if (sd && tid == INVALID_TIMER) - { - clif->changestatus(sd,SP_MANNER,sd->status.manner); - clif->updatestatus(sd,SP_MANNER); - } - break; - case SC_SPLASHER: - { - struct block_list *src=map->id2bl(sce->val3); - if(src && tid != INVALID_TIMER) - skill->castend_damage_id(src, bl, sce->val2, sce->val1, timer->gettick(), SD_LEVEL ); - } - break; - case SC_RG_CCONFINE_S: - { - struct block_list *src = sce->val2 ? map->id2bl(sce->val2) : NULL; - struct status_change *sc2 = src ? status->get_sc(src) : NULL; - if (src && sc2 && sc2->data[SC_RG_CCONFINE_M]) { - //If status was already ended, do nothing. - //Decrease count - if (--(sc2->data[SC_RG_CCONFINE_M]->val1) <= 0) //No more holds, free him up. - status_change_end(src, SC_RG_CCONFINE_M, INVALID_TIMER); + case SC_BERSERK: + if(st->hp > 200 && sc && sc->data[SC__BLOODYLUST]) { + status_percent_heal(bl, 100, 0); + status_change_end(bl, SC__BLOODYLUST, INVALID_TIMER); + } else if(st->hp > 100 && sce->val2) //If val2 is removed, no HP penalty (dispelled?) [Skotlex] + status->set_hp(bl, 100, 0); + if(sc->data[SC_ENDURE] && sc->data[SC_ENDURE]->val4 == 2) { + sc->data[SC_ENDURE]->val4 = 0; + status_change_end(bl, SC_ENDURE, INVALID_TIMER); } - } - case SC_RG_CCONFINE_M: - if (sce->val2 > 0) { - //Caster has been unlocked... nearby chars need to be unlocked. - int range = 1 - +skill->get_range2(bl, status->sc2skill(type), sce->val1) - +skill->get_range2(bl, TF_BACKSLIDING, 1); //Since most people use this to escape the hold.... - map->foreachinarea(status->change_timer_sub, - bl->m, bl->x-range, bl->y-range, bl->x+range,bl->y+range,BL_CHAR,bl,sce,type,timer->gettick()); - } - break; - case SC_COMBOATTACK: - if( sd ) - switch (sce->val1) { - case MO_COMBOFINISH: - case CH_TIGERFIST: - case CH_CHAINCRUSH: - clif->skillinfo(sd, MO_EXTREMITYFIST, 0); - break; - case TK_JUMPKICK: - clif->skillinfo(sd, TK_JUMPKICK, 0); + sc_start4(bl, bl, SC_GDSKILL_REGENERATION, 100, 10,0,0,(RGN_HP|RGN_SP), skill->get_time(LK_BERSERK, sce->val1)); + if( type == SC_SATURDAY_NIGHT_FEVER ) //Sit down force of Saturday Night Fever has the duration of only 3 seconds. + sc_start(bl,bl,SC_SITDOWN_FORCE,100,sce->val1,skill->get_time2(WM_SATURDAY_NIGHT_FEVER,sce->val1)); + break; + case SC_GOSPEL: + if (sce->val3) { //Clear the group. + struct skill_unit_group* group = skill->id2group(sce->val3); + sce->val3 = 0; + skill->del_unitgroup(group,ALC_MARK); + } + break; + case SC_HERMODE: + if(sce->val3 == BCT_SELF) + skill->clear_unitgroup(bl); + break; + case SC_BASILICA: //Clear the skill area. [Skotlex] + skill->clear_unitgroup(bl); + break; + case SC_TRICKDEAD: + if (vd) vd->dead_sit = 0; + break; + case SC_WARM: + case SC__MANHOLE: + if (sce->val4) { //Clear the group. + struct skill_unit_group* group = skill->id2group(sce->val4); + sce->val4 = 0; + if( group ) /* might have been cleared before status ended, e.g. land protector */ + skill->del_unitgroup(group,ALC_MARK); + } + break; + case SC_KAAHI: + //Delete timer if it exists. + if (sce->val4 != INVALID_TIMER) + timer->delete(sce->val4,status->kaahi_heal_timer); + break; + case SC_JAILED: + if(tid == INVALID_TIMER) break; - case MO_TRIPLEATTACK: - if (pc->checkskill(sd, SR_DRAGONCOMBO) > 0) - clif->skillinfo(sd, SR_DRAGONCOMBO, 0); + //natural expiration. + if(sd && sd->mapindex == sce->val2) + pc->setpos(sd,(unsigned short)sce->val3,sce->val4&0xFFFF, sce->val4>>16, CLR_TELEPORT); + break; //guess hes not in jail :P + case SC_HLIF_CHANGE: + if (tid == INVALID_TIMER) break; - case SR_FALLENEMPIRE: - clif->skillinfo(sd, SR_GATEOFHELL, 0); - clif->skillinfo(sd, SR_TIGERCANNON, 0); + // "lose almost all their HP and SP" on natural expiration. + status->set_hp(bl, 10, 0); + status->set_sp(bl, 10, 0); + break; + case SC_AUTOTRADE: + if (tid == INVALID_TIMER) break; - } - break; - - case SC_MARIONETTE_MASTER: - case SC_MARIONETTE: /// Marionette target - if (sce->val1) { - // check for partner and end their marionette status as well - enum sc_type type2 = (type == SC_MARIONETTE_MASTER) ? SC_MARIONETTE : SC_MARIONETTE_MASTER; - struct block_list *pbl = map->id2bl(sce->val1); - struct status_change* sc2 = pbl ? status->get_sc(pbl) : NULL; - - if (sc2 && sc2->data[type2]) - { - sc2->data[type2]->val1 = 0; - status_change_end(pbl, type2, INVALID_TIMER); + // Note: vending/buying is closed by unit_remove_map, no + // need to do it here. + map->quit(sd); + // Because map->quit calls status_change_end with tid -1 + // from here it's not neccesary to continue + return 1; + break; + case SC_STOP: + if( sce->val2 ) { + struct block_list *tbl = map->id2bl(sce->val2); + struct status_change *tsc = NULL; + sce->val2 = 0; + if( tbl && (tsc = status->get_sc(tbl)) && tsc->data[SC_STOP] && tsc->data[SC_STOP]->val2 == bl->id ) + status_change_end(tbl, SC_STOP, INVALID_TIMER); } - } - break; - - case SC_BERSERK: - case SC_SATURDAY_NIGHT_FEVER: - if(st->hp > 200 && sc && sc->data[SC__BLOODYLUST]) { - status_percent_heal(bl, 100, 0); - status_change_end(bl, SC__BLOODYLUST, INVALID_TIMER); - } else if(st->hp > 100 && sce->val2) //If val2 is removed, no HP penalty (dispelled?) [Skotlex] - status->set_hp(bl, 100, 0); - if(sc->data[SC_ENDURE] && sc->data[SC_ENDURE]->val4 == 2) { - sc->data[SC_ENDURE]->val4 = 0; + break; + case SC_LKCONCENTRATION: status_change_end(bl, SC_ENDURE, INVALID_TIMER); - } - sc_start4(bl, SC_GDSKILL_REGENERATION, 100, 10,0,0,(RGN_HP|RGN_SP), skill->get_time(LK_BERSERK, sce->val1)); - if( type == SC_SATURDAY_NIGHT_FEVER ) //Sit down force of Saturday Night Fever has the duration of only 3 seconds. - sc_start(bl,SC_SITDOWN_FORCE,100,sce->val1,skill->get_time2(WM_SATURDAY_NIGHT_FEVER,sce->val1)); - break; - case SC_GOSPEL: - if (sce->val3) { //Clear the group. - struct skill_unit_group* group = skill->id2group(sce->val3); - sce->val3 = 0; - skill->del_unitgroup(group,ALC_MARK); - } - break; - case SC_HERMODE: - if(sce->val3 == BCT_SELF) - skill->clear_unitgroup(bl); - break; - case SC_BASILICA: //Clear the skill area. [Skotlex] - skill->clear_unitgroup(bl); - break; - case SC_TRICKDEAD: - if (vd) vd->dead_sit = 0; - break; - case SC_WARM: - case SC__MANHOLE: - if (sce->val4) { //Clear the group. - struct skill_unit_group* group = skill->id2group(sce->val4); - sce->val4 = 0; - if( group ) /* might have been cleared before status ended, e.g. land protector */ - skill->del_unitgroup(group,ALC_MARK); - } - break; - case SC_KAAHI: - //Delete timer if it exists. - if (sce->val4 != INVALID_TIMER) - timer->delete(sce->val4,status->kaahi_heal_timer); - break; - case SC_JAILED: - if(tid == INVALID_TIMER) - break; - //natural expiration. - if(sd && sd->mapindex == sce->val2) - pc->setpos(sd,(unsigned short)sce->val3,sce->val4&0xFFFF, sce->val4>>16, CLR_TELEPORT); - break; //guess hes not in jail :P - case SC_HLIF_CHANGE: - if (tid == INVALID_TIMER) - break; - // "lose almost all their HP and SP" on natural expiration. - status->set_hp(bl, 10, 0); - status->set_sp(bl, 10, 0); - break; - case SC_AUTOTRADE: - if (tid == INVALID_TIMER) - break; - // Note: vending/buying is closed by unit_remove_map, no - // need to do it here. - map->quit(sd); - // Because map->quit calls status_change_end with tid -1 - // from here it's not neccesary to continue - return 1; - break; - case SC_STOP: - if( sce->val2 ) { - struct block_list* tbl = map->id2bl(sce->val2); - sce->val2 = 0; - if( tbl && (sc = status->get_sc(tbl)) && sc->data[SC_STOP] && sc->data[SC_STOP]->val2 == bl->id ) - status_change_end(tbl, SC_STOP, INVALID_TIMER); - } - break; - case SC_LKCONCENTRATION: - status_change_end(bl, SC_ENDURE, INVALID_TIMER); - break; - /** - * 3rd Stuff - **/ - case SC_MILLENNIUMSHIELD: - clif->millenniumshield(sd,0); - break; - case SC_HALLUCINATIONWALK: - sc_start(bl,SC_HALLUCINATIONWALK_POSTDELAY,100,sce->val1,skill->get_time2(GC_HALLUCINATIONWALK,sce->val1)); - break; - case SC_WHITEIMPRISON: - { - struct block_list* src = map->id2bl(sce->val2); - if( tid == -1 || !src) - break; // Terminated by Damage - status_fix_damage(src,bl,400*sce->val1,clif->damage(bl,bl,timer->gettick(),0,0,400*sce->val1,0,0,0)); - } - break; - case SC_WUGDASH: - { - struct unit_data *ud = unit->bl2ud(bl); - if (ud) { - ud->state.running = 0; - if (ud->walktimer != -1) - unit->stop_walking(bl,1); + break; + /** + * 3rd Stuff + **/ + case SC_MILLENNIUMSHIELD: + clif->millenniumshield(bl,0); + break; + case SC_HALLUCINATIONWALK: + sc_start(bl,bl,SC_HALLUCINATIONWALK_POSTDELAY,100,sce->val1,skill->get_time2(GC_HALLUCINATIONWALK,sce->val1)); + break; + case SC_WHITEIMPRISON: + { + struct block_list* src = map->id2bl(sce->val2); + if( tid == -1 || !src) + break; // Terminated by Damage + status_fix_damage(src,bl,400*sce->val1,clif->damage(bl,bl,0,0,400*sce->val1,0,0,0)); } - } - break; - case SC_ADORAMUS: - status_change_end(bl, SC_BLIND, INVALID_TIMER); - break; - case SC__SHADOWFORM: - { - struct map_session_data *s_sd = map->id2sd(sce->val2); - if( !s_sd ) - break; - s_sd->shadowform_id = 0; - } - break; - case SC_SITDOWN_FORCE: - if( sd && pc_issit(sd) ) { - pc->setstand(sd); - clif->standing(bl); - } - break; - case SC_NEUTRALBARRIER_MASTER: - case SC_STEALTHFIELD_MASTER: - if( sce->val2 ) { - struct skill_unit_group* group = skill->id2group(sce->val2); - sce->val2 = 0; - if( group ) /* might have been cleared before status ended, e.g. land protector */ - skill->del_unitgroup(group,ALC_MARK); - } - break; - case SC_BANDING: - if(sce->val4) { - struct skill_unit_group *group = skill->id2group(sce->val4); - sce->val4 = 0; - if( group ) /* might have been cleared before status ended, e.g. land protector */ - skill->del_unitgroup(group,ALC_MARK); - } - break; - case SC_CURSEDCIRCLE_ATKER: - if( sce->val2 ) // used the default area size cause there is a chance the caster could knock back and can't clear the target. - map->foreachinrange(status->change_timer_sub, bl, battle_config.area_size,BL_CHAR, bl, sce, SC_CURSEDCIRCLE_TARGET, timer->gettick()); - break; - case SC_RAISINGDRAGON: - if( sd && sce->val2 && !pc_isdead(sd) ) { - int i; - i = min(sd->spiritball,5); - pc->delspiritball(sd, sd->spiritball, 0); - status_change_end(bl, SC_EXPLOSIONSPIRITS, INVALID_TIMER); - while( i > 0 ) { - pc->addspiritball(sd, skill->get_time(MO_CALLSPIRITS, pc->checkskill(sd,MO_CALLSPIRITS)), 5); - --i; + break; + case SC_WUGDASH: + { + struct unit_data *ud = unit->bl2ud(bl); + if (ud) { + ud->state.running = 0; + if (ud->walktimer != -1) + unit->stop_walking(bl,1); + } } - } - break; - case SC_CURSEDCIRCLE_TARGET: - { - struct block_list *src = map->id2bl(sce->val2); - struct status_change *sc = status->get_sc(src); - if( sc && sc->data[SC_CURSEDCIRCLE_ATKER] && --(sc->data[SC_CURSEDCIRCLE_ATKER]->val2) == 0 ){ - status_change_end(src, SC_CURSEDCIRCLE_ATKER, INVALID_TIMER); - clif->bladestop(bl, sce->val2, 0); - } - } - break; - case SC_BLOOD_SUCKER: - if( sce->val2 ){ + break; + case SC_ADORAMUS: + status_change_end(bl, SC_BLIND, INVALID_TIMER); + break; + case SC__SHADOWFORM: + { + struct map_session_data *s_sd = map->id2sd(sce->val2); + if( !s_sd ) + break; + s_sd->shadowform_id = 0; + } + break; + case SC_SITDOWN_FORCE: + if( sd && pc_issit(sd) ) { + pc->setstand(sd); + clif->standing(bl); + } + break; + case SC_NEUTRALBARRIER_MASTER: + case SC_STEALTHFIELD_MASTER: + if( sce->val2 ) { + struct skill_unit_group* group = skill->id2group(sce->val2); + sce->val2 = 0; + if( group ) /* might have been cleared before status ended, e.g. land protector */ + skill->del_unitgroup(group,ALC_MARK); + } + break; + case SC_BANDING: + if(sce->val4) { + struct skill_unit_group *group = skill->id2group(sce->val4); + sce->val4 = 0; + if( group ) /* might have been cleared before status ended, e.g. land protector */ + skill->del_unitgroup(group,ALC_MARK); + } + break; + case SC_CURSEDCIRCLE_ATKER: + if( sce->val2 ) // used the default area size cause there is a chance the caster could knock back and can't clear the target. + map->foreachinrange(status->change_timer_sub, bl, battle_config.area_size,BL_CHAR, bl, sce, SC_CURSEDCIRCLE_TARGET, timer->gettick()); + break; + case SC_RAISINGDRAGON: + if( sd && sce->val2 && !pc_isdead(sd) ) { + int i; + i = min(sd->spiritball,5); + pc->delspiritball(sd, sd->spiritball, 0); + status_change_end(bl, SC_EXPLOSIONSPIRITS, INVALID_TIMER); + while( i > 0 ) { + pc->addspiritball(sd, skill->get_time(MO_CALLSPIRITS, pc->checkskill(sd,MO_CALLSPIRITS)), 5); + --i; + } + } + break; + case SC_CURSEDCIRCLE_TARGET: + { struct block_list *src = map->id2bl(sce->val2); - if(src) { - struct status_change *sc = status->get_sc(src); - sc->bs_counter--; + struct status_change *ssc = status->get_sc(src); + if( ssc && ssc->data[SC_CURSEDCIRCLE_ATKER] && --(ssc->data[SC_CURSEDCIRCLE_ATKER]->val2) == 0 ){ + status_change_end(src, SC_CURSEDCIRCLE_ATKER, INVALID_TIMER); + clif->bladestop(bl, sce->val2, 0); } } - break; - case SC_KYOUGAKU: - clif->sc_end(&sd->bl,sd->bl.id,AREA,SI_ACTIVE_MONSTER_TRANSFORM); - break; - case SC_CLAIRVOYANCE: - calc_flag = SCB_ALL;/* required for overlapping */ - break; - case SC_FULL_THROTTLE: - sc_start(bl,SC_REBOUND,100,sce->val1,skill->get_time2(ALL_FULL_THROTTLE,sce->val1)); - break; - case SC_ITEMSCRIPT: - if( sd ) { - switch( sce->val1 ) { - //case 4121://Phree - //case 4047://Ghostring - case 4302://Gunka - clif->sc_end(&sd->bl, sd->bl.id, SELF, SI_MVPCARD_TAOGUNKA); - break; - case 4132://Mistress - clif->sc_end(&sd->bl, sd->bl.id, SELF, SI_MVPCARD_MISTRESS); - break; - case 4143://Orc Hero - clif->sc_end(&sd->bl, sd->bl.id, SELF, SI_MVPCARD_ORCHERO); - break; - case 4135://Orc Lord - clif->sc_end(&sd->bl, sd->bl.id, SELF, SI_MVPCARD_ORCLORD); - break; + break; + case SC_BLOOD_SUCKER: + if( sce->val2 ){ + struct block_list *src = map->id2bl(sce->val2); + if(src) { + struct status_change *ssc = status->get_sc(src); + ssc->bs_counter--; + } } - } - break; + break; + case SC_KYOUGAKU: + clif->sc_end(&sd->bl,sd->bl.id,AREA,SI_ACTIVE_MONSTER_TRANSFORM); + break; + case SC_CLAIRVOYANCE: + calc_flag = SCB_ALL;/* required for overlapping */ + break; + case SC_FULL_THROTTLE: + sc_start(bl,bl,SC_REBOUND,100,sce->val1,skill->get_time2(ALL_FULL_THROTTLE,sce->val1)); + break; + case SC_MONSTER_TRANSFORM: + if( sce->val2 ) + status_change_end(bl, (sc_type)sce->val2, INVALID_TIMER); + break; + case SC_ITEMSCRIPT: + if( sd ) { + switch( sce->val1 ) { + //case ITEMID_PHREEONI_CARD: + //case ITEMID_GHOSTRING_CARD: + case ITEMID_TAO_GUNKA_CARD: + clif->sc_end(&sd->bl, sd->bl.id, SELF, SI_MVPCARD_TAOGUNKA); + break; + case ITEMID_MISTRESS_CARD: + clif->sc_end(&sd->bl, sd->bl.id, SELF, SI_MVPCARD_MISTRESS); + break; + case ITEMID_ORC_HERO_CARD: + clif->sc_end(&sd->bl, sd->bl.id, SELF, SI_MVPCARD_ORCHERO); + break; + case ITEMID_ORC_LOAD_CARD: + clif->sc_end(&sd->bl, sd->bl.id, SELF, SI_MVPCARD_ORCLORD); + break; + } + } + break; } opt_flag = 1; - switch(type){ - case SC_STONE: - case SC_FREEZE: - case SC_STUN: - case SC_SLEEP: - case SC_DEEP_SLEEP: - case SC_BURNING: - case SC_WHITEIMPRISON: - case SC_COLD: - sc->opt1 = 0; - break; + switch(type) { + case SC_STONE: + case SC_FREEZE: + case SC_STUN: + case SC_SLEEP: + case SC_BURNING: + case SC_WHITEIMPRISON: + case SC_COLD: + sc->opt1 = 0; + break; - case SC_POISON: - case SC_CURSE: - case SC_SILENCE: - case SC_BLIND: - sc->opt2 &= ~(1<<(type-SC_POISON)); - break; - case SC_DPOISON: - sc->opt2 &= ~OPT2_DPOISON; - break; - case SC_CRUCIS: - sc->opt2 &= ~OPT2_SIGNUMCRUCIS; - break; + case SC_POISON: + case SC_CURSE: + case SC_SILENCE: + case SC_BLIND: + sc->opt2 &= ~(1<<(type-SC_POISON)); + break; + case SC_DPOISON: + sc->opt2 &= ~OPT2_DPOISON; + break; + case SC_CRUCIS: + case SC__CHAOS: + sc->opt2 &= ~OPT2_SIGNUMCRUCIS; + break; - case SC_HIDING: - sc->option &= ~OPTION_HIDE; - opt_flag|= 2|4; //Check for warp trigger + AoE trigger - break; - case SC_CLOAKING: - case SC_CLOAKINGEXCEED: - case SC__INVISIBILITY: - sc->option &= ~OPTION_CLOAK; - case SC_CAMOUFLAGE: - opt_flag|= 2; - break; - case SC_CHASEWALK: - sc->option &= ~(OPTION_CHASEWALK|OPTION_CLOAK); - opt_flag|= 2; - break; - case SC_SIGHT: - sc->option &= ~OPTION_SIGHT; - break; - case SC_WEDDING: - sc->option &= ~OPTION_WEDDING; - opt_flag |= 0x4; - break; - case SC_XMAS: - sc->option &= ~OPTION_XMAS; - opt_flag |= 0x4; - break; - case SC_SUMMER: - sc->option &= ~OPTION_SUMMER; - opt_flag |= 0x4; - break; - case SC_HANBOK: - sc->option &= ~OPTION_HANBOK; - opt_flag |= 0x4; - break; - case SC_ORCISH: - sc->option &= ~OPTION_ORCISH; - break; - case SC_RUWACH: - sc->option &= ~OPTION_RUWACH; - break; - case SC_FUSION: - sc->option &= ~OPTION_FLYING; - break; - //opt3 - case SC_TWOHANDQUICKEN: - case SC_ONEHANDQUICKEN: - case SC_SPEARQUICKEN: - case SC_CONCENTRATION: - case SC_MER_QUICKEN: - sc->opt3 &= ~OPT3_QUICKEN; - opt_flag = 0; - break; - case SC_OVERTHRUST: - case SC_OVERTHRUSTMAX: - case SC_SWOO: - sc->opt3 &= ~OPT3_OVERTHRUST; - if( type == SC_SWOO ) - opt_flag = 8; - else + case SC_HIDING: + sc->option &= ~OPTION_HIDE; + opt_flag|= 2|4; //Check for warp trigger + AoE trigger + break; + case SC_CLOAKING: + case SC_CLOAKINGEXCEED: + sc->option &= ~OPTION_CLOAK; + case SC_CAMOUFLAGE: + opt_flag|= 2; + break; + case SC__INVISIBILITY: + case SC_CHASEWALK: + sc->option &= ~(OPTION_CHASEWALK|OPTION_CLOAK); + opt_flag|= 2; + break; + case SC_SIGHT: + sc->option &= ~OPTION_SIGHT; + break; + case SC_WEDDING: + sc->option &= ~OPTION_WEDDING; + opt_flag |= 0x4; + break; + case SC_XMAS: + sc->option &= ~OPTION_XMAS; + opt_flag |= 0x4; + break; + case SC_SUMMER: + sc->option &= ~OPTION_SUMMER; + opt_flag |= 0x4; + break; + case SC_HANBOK: + sc->option &= ~OPTION_HANBOK; + opt_flag |= 0x4; + break; + case SC_OKTOBERFEST: + sc->option &= ~OPTION_OKTOBERFEST; + opt_flag |= 0x4; + break; + case SC_ORCISH: + sc->option &= ~OPTION_ORCISH; + break; + case SC_RUWACH: + sc->option &= ~OPTION_RUWACH; + break; + case SC_FUSION: + sc->option &= ~OPTION_FLYING; + break; + //opt3 + case SC_TWOHANDQUICKEN: + case SC_ONEHANDQUICKEN: + case SC_SPEARQUICKEN: + case SC_CONCENTRATION: + case SC_MER_QUICKEN: + sc->opt3 &= ~OPT3_QUICKEN; opt_flag = 0; - break; - case SC_ENERGYCOAT: - case SC_SKE: - sc->opt3 &= ~OPT3_ENERGYCOAT; - opt_flag = 0; - break; - case SC_INCATKRATE: //Simulated Explosion spirits effect. - if (bl->type != BL_MOB) - { + break; + case SC_OVERTHRUST: + case SC_OVERTHRUSTMAX: + case SC_SWOO: + sc->opt3 &= ~OPT3_OVERTHRUST; + if( type == SC_SWOO ) + opt_flag = 8; + else + opt_flag = 0; + break; + case SC_ENERGYCOAT: + case SC_SKE: + sc->opt3 &= ~OPT3_ENERGYCOAT; opt_flag = 0; break; - } - case SC_EXPLOSIONSPIRITS: - sc->opt3 &= ~OPT3_EXPLOSIONSPIRITS; - opt_flag = 0; - break; - case SC_STEELBODY: - case SC_SKA: - sc->opt3 &= ~OPT3_STEELBODY; - opt_flag = 0; - break; - case SC_BLADESTOP: - sc->opt3 &= ~OPT3_BLADESTOP; - opt_flag = 0; - break; - case SC_AURABLADE: - sc->opt3 &= ~OPT3_AURABLADE; - opt_flag = 0; - break; - case SC_BERSERK: - opt_flag = 0; - sc->opt3 &= ~OPT3_BERSERK; - break; - // case ???: // doesn't seem to do anything - // sc->opt3 &= ~OPT3_LIGHTBLADE; - // opt_flag = 0; - // break; - case SC_DANCING: - if ((sce->val1&0xFFFF) == CG_MOONLIT) - sc->opt3 &= ~OPT3_MOONLIT; - opt_flag = 0; - break; - case SC_MARIONETTE: - case SC_MARIONETTE_MASTER: - sc->opt3 &= ~OPT3_MARIONETTE; - opt_flag = 0; - break; - case SC_ASSUMPTIO: - sc->opt3 &= ~OPT3_ASSUMPTIO; - opt_flag = 0; - break; - case SC_WARM: //SG skills [Komurka] - sc->opt3 &= ~OPT3_WARM; - opt_flag = 0; - break; - case SC_KAITE: - sc->opt3 &= ~OPT3_KAITE; - opt_flag = 0; - break; - case SC_NJ_BUNSINJYUTSU: - sc->opt3 &= ~OPT3_BUNSIN; - opt_flag = 0; - break; - case SC_SOULLINK: - sc->opt3 &= ~OPT3_SOULLINK; - opt_flag = 0; - break; - case SC_PROPERTYUNDEAD: - sc->opt3 &= ~OPT3_UNDEAD; - opt_flag = 0; - break; - // case ???: // from DA_CONTRACT (looks like biolab mobs aura) - // sc->opt3 &= ~OPT3_CONTRACT; - // opt_flag = 0; - // break; - default: - opt_flag = 0; + case SC_INCATKRATE: //Simulated Explosion spirits effect. + if (bl->type != BL_MOB) + { + opt_flag = 0; + break; + } + case SC_EXPLOSIONSPIRITS: + sc->opt3 &= ~OPT3_EXPLOSIONSPIRITS; + opt_flag = 0; + break; + case SC_STEELBODY: + case SC_SKA: + sc->opt3 &= ~OPT3_STEELBODY; + opt_flag = 0; + break; + case SC_BLADESTOP: + sc->opt3 &= ~OPT3_BLADESTOP; + opt_flag = 0; + break; + case SC_AURABLADE: + sc->opt3 &= ~OPT3_AURABLADE; + opt_flag = 0; + break; + case SC_BERSERK: + opt_flag = 0; + sc->opt3 &= ~OPT3_BERSERK; + break; + // case ???: // doesn't seem to do anything + // sc->opt3 &= ~OPT3_LIGHTBLADE; + // opt_flag = 0; + // break; + case SC_DANCING: + if ((sce->val1&0xFFFF) == CG_MOONLIT) + sc->opt3 &= ~OPT3_MOONLIT; + opt_flag = 0; + break; + case SC_MARIONETTE: + case SC_MARIONETTE_MASTER: + sc->opt3 &= ~OPT3_MARIONETTE; + opt_flag = 0; + break; + case SC_ASSUMPTIO: + sc->opt3 &= ~OPT3_ASSUMPTIO; + opt_flag = 0; + break; + case SC_WARM: //SG skills [Komurka] + sc->opt3 &= ~OPT3_WARM; + opt_flag = 0; + break; + case SC_KAITE: + sc->opt3 &= ~OPT3_KAITE; + opt_flag = 0; + break; + case SC_NJ_BUNSINJYUTSU: + sc->opt3 &= ~OPT3_BUNSIN; + opt_flag = 0; + break; + case SC_SOULLINK: + sc->opt3 &= ~OPT3_SOULLINK; + opt_flag = 0; + break; + case SC_PROPERTYUNDEAD: + sc->opt3 &= ~OPT3_UNDEAD; + opt_flag = 0; + break; + // case ???: // from DA_CONTRACT (looks like biolab mobs aura) + // sc->opt3 &= ~OPT3_CONTRACT; + // opt_flag = 0; + // break; + default: + opt_flag = 0; + } + +#ifdef ANTI_MAYAP_CHEAT + if (invisible && !(sc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_INVISIBLE))) { + clif->fixpos(bl); } +#endif if (calc_flag&SCB_DYE) { //Restore DYE color if (vd && !vd->cloth_color && sce->val4) @@ -9832,7 +10277,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const else if(opt_flag) { clif->changeoption(bl); if( sd && opt_flag&0x4 ) { - clif->changelook(bl,LOOK_BASE,vd->class_); + clif->changelook(bl,LOOK_BASE,sd->vd.class_); clif->get_weapon_view(sd, &sd->vd.weapon, &sd->vd.shield); clif->changelook(bl,LOOK_WEAPON,sd->vd.weapon); clif->changelook(bl,LOOK_SHIELD,sd->vd.shield); @@ -9853,7 +10298,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const return 1; } -int kaahi_heal_timer(int tid, unsigned int tick, int id, intptr_t data) { +int kaahi_heal_timer(int tid, int64 tick, int id, intptr_t data) { struct block_list *bl; struct status_change *sc; struct status_change_entry *sce; @@ -9891,7 +10336,7 @@ int kaahi_heal_timer(int tid, unsigned int tick, int id, intptr_t data) { * For recusive status, like for each 5s we drop sp etc. * Reseting the end timer. *------------------------------------------*/ -int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) { +int status_change_timer(int tid, int64 tick, int id, intptr_t data) { enum sc_type type = (sc_type)data; struct block_list *bl; struct map_session_data *sd; @@ -9924,773 +10369,794 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data) { // set the next timer of the sce (don't assume the status still exists) #define sc_timer_next(t,f,i,d) do { \ if( (sce=sc->data[type]) ) \ - sce->timer = timer->add(t,f,i,d); \ + sce->timer = timer->add((t),(f),(i),(d)); \ else \ ShowError("status_change_timer: Unexpected NULL status change id: %d data: %d\n", id, data); \ } while(0) switch(type) { - case SC_MAXIMIZEPOWER: - case SC_CLOAKING: - if(!status->charge(bl, 0, 1)) - break; //Not enough SP to continue. - sc_timer_next(sce->val2+tick, status->change_timer, bl->id, data); - return 0; - - case SC_CHASEWALK: - if(!status->charge(bl, 0, sce->val4)) - break; //Not enough SP to continue. + case SC_MAXIMIZEPOWER: + case SC_CLOAKING: + if(!status->charge(bl, 0, 1)) + break; //Not enough SP to continue. + sc_timer_next(sce->val2+tick, status->change_timer, bl->id, data); + return 0; - if (!sc->data[SC_CHASEWALK2]) { - sc_start(bl, SC_CHASEWALK2,100,1<<(sce->val1-1), - (sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_ROGUE?10:1) //SL bonus -> x10 duration - * skill->get_time2(status->sc2skill(type),sce->val1)); - } - sc_timer_next(sce->val2+tick, status->change_timer, bl->id, data); - return 0; - break; + case SC_CHASEWALK: + if(!status->charge(bl, 0, sce->val4)) + break; //Not enough SP to continue. - case SC_SKA: - if(--(sce->val2)>0) { - sce->val3 = rnd()%100; //Random defense. - sc_timer_next(1000+tick, status->change_timer,bl->id, data); + if (!sc->data[SC_CHASEWALK2]) { + sc_start(bl,bl, SC_CHASEWALK2,100,1<<(sce->val1-1), + (sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_ROGUE?10:1) //SL bonus -> x10 duration + * skill->get_time2(status->sc2skill(type),sce->val1)); + } + sc_timer_next(sce->val2+tick, status->change_timer, bl->id, data); return 0; - } - break; + break; - case SC_HIDING: - if(--(sce->val2)>0) { - if(sce->val2 % sce->val4 == 0 && !status->charge(bl, 0, 1)) - break; //Fail if it's time to substract SP and there isn't. + case SC_SKA: + if(--(sce->val2)>0) { + sce->val3 = rnd()%100; //Random defense. + sc_timer_next(1000+tick, status->change_timer,bl->id, data); + return 0; + } + break; - sc_timer_next(1000+tick, status->change_timer,bl->id, data); - return 0; - } - break; + case SC_HIDING: + if(--(sce->val2)>0) { + if(sce->val2 % sce->val4 == 0 && !status->charge(bl, 0, 1)) + break; //Fail if it's time to substract SP and there isn't. - case SC_SIGHT: - case SC_RUWACH: - case SC_WZ_SIGHTBLASTER: - if(type == SC_WZ_SIGHTBLASTER) - map->foreachinrange(status->change_timer_sub, bl, sce->val3, BL_CHAR|BL_SKILL, bl, sce, type, tick); - else - map->foreachinrange(status->change_timer_sub, bl, sce->val3, BL_CHAR, bl, sce, type, tick); + sc_timer_next(1000+tick, status->change_timer,bl->id, data); + return 0; + } + break; - if( --(sce->val2)>0 ){ - sce->val4 += 250; // use for Shadow Form 2 seconds checking. - sc_timer_next(250+tick, status->change_timer, bl->id, data); - return 0; - } - break; + case SC_SIGHT: + case SC_RUWACH: + case SC_WZ_SIGHTBLASTER: + if(type == SC_WZ_SIGHTBLASTER) + map->foreachinrange(status->change_timer_sub, bl, sce->val3, BL_CHAR|BL_SKILL, bl, sce, type, tick); + else + map->foreachinrange(status->change_timer_sub, bl, sce->val3, BL_CHAR, bl, sce, type, tick); - case SC_PROVOKE: - if(sce->val2) { //Auto-provoke (it is ended in status->heal) - sc_timer_next(1000*60+tick, status->change_timer, bl->id, data ); - return 0; - } - break; + if( --(sce->val2)>0 ){ + sce->val4 += 250; // use for Shadow Form 2 seconds checking. + sc_timer_next(250+tick, status->change_timer, bl->id, data); + return 0; + } + break; - case SC_STONE: - if(sc->opt1 == OPT1_STONEWAIT && sce->val3) { - sce->val4 = 0; - unit->stop_walking(bl,1); - unit->stop_attack(bl); - sc->opt1 = OPT1_STONE; - clif->changeoption(bl); - sc_timer_next(1000+tick, status->change_timer, bl->id, data ); - status_calc_bl(bl, status->ChangeFlagTable[type]); - return 0; - } - if(--(sce->val3) > 0) { - if(++(sce->val4)%5 == 0 && st->hp > st->max_hp/4) - status_percent_damage(NULL, bl, 1, 0, false); - sc_timer_next(1000+tick, status->change_timer, bl->id, data ); - return 0; - } - break; + case SC_PROVOKE: + if(sce->val2) { //Auto-provoke (it is ended in status->heal) + sc_timer_next(1000*60+tick, status->change_timer, bl->id, data ); + return 0; + } + break; - case SC_POISON: - if(st->hp <= max(st->max_hp>>2, sce->val4)) //Stop damaging after 25% HP left. + case SC_STONE: + if(sc->opt1 == OPT1_STONEWAIT && sce->val3) { + sce->val4 = 0; + unit->stop_walking(bl,1); + unit->stop_attack(bl); + sc->opt1 = OPT1_STONE; + clif->changeoption(bl); + sc_timer_next(1000+tick, status->change_timer, bl->id, data ); + status_calc_bl(bl, status->ChangeFlagTable[type]); + return 0; + } + if(--(sce->val3) > 0) { + if(++(sce->val4)%5 == 0 && st->hp > st->max_hp/4) + status_percent_damage(NULL, bl, 1, 0, false); + sc_timer_next(1000+tick, status->change_timer, bl->id, data ); + return 0; + } break; - case SC_DPOISON: - if (--(sce->val3) > 0) { - if (!sc->data[SC_SLOWPOISON]) { - if( sce->val2 && bl->type == BL_MOB ) { - struct block_list* src = map->id2bl(sce->val2); - if( src ) - mob->log_damage((TBL_MOB*)bl,src,sce->val4); + + case SC_POISON: + if(st->hp <= max(st->max_hp>>2, sce->val4)) //Stop damaging after 25% HP left. + break; + case SC_DPOISON: + if (--(sce->val3) > 0) { + if (!sc->data[SC_SLOWPOISON]) { + if( sce->val2 && bl->type == BL_MOB ) { + struct block_list* src = map->id2bl(sce->val2); + if( src ) + mob->log_damage((TBL_MOB*)bl,src,sce->val4); + } + map->freeblock_lock(); + status_zap(bl, sce->val4, 0); + if (sc->data[type]) { // Check if the status still last ( can be dead since then ). + sc_timer_next(1000 + tick, status->change_timer, bl->id, data ); + } + map->freeblock_unlock(); + } + return 0; + } + break; + + case SC_TENSIONRELAX: + if(st->max_hp > st->hp && --(sce->val3) > 0) { + sc_timer_next(sce->val4+tick, status->change_timer, bl->id, data); + return 0; + } + break; + + case SC_KNOWLEDGE: + if (!sd) break; + if(bl->m == sd->feel_map[0].m || + bl->m == sd->feel_map[1].m || + bl->m == sd->feel_map[2].m) + { //Timeout will be handled by pc->setpos + sce->timer = INVALID_TIMER; + return 0; + } + break; + + case SC_BLOODING: + if (--(sce->val4) >= 0) { + int hp = rnd()%600 + 200; + struct block_list* src = map->id2bl(sce->val2); + if( src && bl && bl->type == BL_MOB ) { + mob->log_damage((TBL_MOB*)bl,src,sd||hp<st->hp?hp:st->hp-1); } map->freeblock_lock(); - status_zap(bl, sce->val4, 0); - if (sc->data[type]) { // Check if the status still last ( can be dead since then ). - sc_timer_next(1000 + tick, status->change_timer, bl->id, data ); + status_fix_damage(src, bl, sd||hp<st->hp?hp:st->hp-1, 1); + if( sc->data[type] ) { + if( st->hp == 1 ) { + map->freeblock_unlock(); + break; + } + sc_timer_next(10000 + tick, status->change_timer, bl->id, data); } map->freeblock_unlock(); + return 0; } - return 0; - } - break; + break; - case SC_TENSIONRELAX: - if(st->max_hp > st->hp && --(sce->val3) > 0) { - sc_timer_next(sce->val4+tick, status->change_timer, bl->id, data); - return 0; - } - break; + case SC_S_LIFEPOTION: + case SC_L_LIFEPOTION: + if( sd && --(sce->val4) >= 0 ) { + // val1 < 0 = per max% | val1 > 0 = exact amount + int hp = 0; + if( st->hp < st->max_hp ) + hp = (sce->val1 < 0) ? (int)(sd->status.max_hp * -1 * sce->val1 / 100.) : sce->val1 ; + status->heal(bl, hp, 0, 2); + sc_timer_next((sce->val2 * 1000) + tick, status->change_timer, bl->id, data); + return 0; + } + break; - case SC_KNOWLEDGE: - if (!sd) break; - if(bl->m == sd->feel_map[0].m || - bl->m == sd->feel_map[1].m || - bl->m == sd->feel_map[2].m) - { //Timeout will be handled by pc->setpos - sce->timer = INVALID_TIMER; - return 0; - } - break; + case SC_CASH_BOSS_ALARM: + if( sd && --(sce->val4) >= 0 ) { + struct mob_data *boss_md = map->id2boss(sce->val1); + if( boss_md && sd->bl.m == boss_md->bl.m ) { + clif->bossmapinfo(sd->fd, boss_md, 1); // Update X - Y on minimap + if (boss_md->bl.prev != NULL) { + sc_timer_next(5000 + tick, status->change_timer, bl->id, data); + return 0; + } + } + } + break; - case SC_BLOODING: - if (--(sce->val4) >= 0) { - int hp = rnd()%600 + 200; - struct block_list* src = map->id2bl(sce->val2); - if( src && bl && bl->type == BL_MOB ) { - mob->log_damage((TBL_MOB*)bl,src,sd||hp<st->hp?hp:st->hp-1); - } - map->freeblock_lock(); - status_fix_damage(src, bl, sd||hp<st->hp?hp:st->hp-1, 1); - if( sc->data[type] ) { - if( st->hp == 1 ) { - map->freeblock_unlock(); + case SC_DANCING: //SP consumption by time of dancing skills + { + int s = 0; + int sp = 1; + if (--sce->val3 <= 0) + break; + switch(sce->val1&0xFFFF){ + case BD_RICHMANKIM: + case BD_DRUMBATTLEFIELD: + case BD_RINGNIBELUNGEN: + case BD_SIEGFRIED: + case BA_DISSONANCE: + case BA_ASSASSINCROSS: + case DC_UGLYDANCE: + s=3; + break; + case BD_LULLABY: + case BD_ETERNALCHAOS: + case BD_ROKISWEIL: + case DC_FORTUNEKISS: + s=4; + break; + case CG_HERMODE: + case BD_INTOABYSS: + case BA_WHISTLE: + case DC_HUMMING: + case BA_POEMBRAGI: + case DC_SERVICEFORYOU: + s=5; + break; + case BA_APPLEIDUN: + #ifdef RENEWAL + s=5; + #else + s=6; + #endif + break; + case CG_MOONLIT: + //Moonlit's cost is 4sp*skill_lv [Skotlex] + sp= 4*(sce->val1>>16); + //Upkeep is also every 10 secs. + case DC_DONTFORGETME: + s=10; break; } - sc_timer_next(10000 + tick, status->change_timer, bl->id, data); + if( s != 0 && sce->val3 % s == 0 ) { + if (sc->data[SC_LONGING]) + sp*= 3; + if (!status->charge(bl, 0, sp)) + break; + } + sc_timer_next(1000+tick, status->change_timer, bl->id, data); + return 0; } - map->freeblock_unlock(); - return 0; - } - break; - - case SC_S_LIFEPOTION: - case SC_L_LIFEPOTION: - if( sd && --(sce->val4) >= 0 ) { - // val1 < 0 = per max% | val1 > 0 = exact amount - int hp = 0; - if( st->hp < st->max_hp ) - hp = (sce->val1 < 0) ? (int)(sd->status.max_hp * -1 * sce->val1 / 100.) : sce->val1 ; - status->heal(bl, hp, 0, 2); - sc_timer_next((sce->val2 * 1000) + tick, status->change_timer, bl->id, data); - return 0; - } - break; + break; + case SC_BERSERK: + // 5% every 10 seconds [DracoRPG] + if( --( sce->val3 ) > 0 && status->charge(bl, sce->val2, 0) && st->hp > 100 ) { + sc_timer_next(sce->val4+tick, status->change_timer, bl->id, data); + return 0; + } + break; - case SC_CASH_BOSS_ALARM: - if( sd && --(sce->val4) >= 0 ) { - struct mob_data *boss_md = map->id2boss(sce->val1); - if( boss_md && sd->bl.m == boss_md->bl.m ) { - clif->bossmapinfo(sd->fd, boss_md, 1); // Update X - Y on minimap - if (boss_md->bl.prev != NULL) { - sc_timer_next(5000 + tick, status->change_timer, bl->id, data); + case SC_NOCHAT: + if(sd) { + sd->status.manner++; + clif->changestatus(sd,SP_MANNER,sd->status.manner); + clif->updatestatus(sd,SP_MANNER); + if (sd->status.manner < 0) { + //Every 60 seconds your manner goes up by 1 until it gets back to 0. + sc_timer_next(60000+tick, status->change_timer, bl->id, data); return 0; } } - } - break; + break; - case SC_DANCING: //SP consumption by time of dancing skills - { - int s = 0; - int sp = 1; - if (--sce->val3 <= 0) - break; - switch(sce->val1&0xFFFF){ - case BD_RICHMANKIM: - case BD_DRUMBATTLEFIELD: - case BD_RINGNIBELUNGEN: - case BD_SIEGFRIED: - case BA_DISSONANCE: - case BA_ASSASSINCROSS: - case DC_UGLYDANCE: - s=3; - break; - case BD_LULLABY: - case BD_ETERNALCHAOS: - case BD_ROKISWEIL: - case DC_FORTUNEKISS: - s=4; - break; - case CG_HERMODE: - case BD_INTOABYSS: - case BA_WHISTLE: - case DC_HUMMING: - case BA_POEMBRAGI: - case DC_SERVICEFORYOU: - s=5; - break; - case BA_APPLEIDUN: -#ifdef RENEWAL - s=5; -#else - s=6; -#endif - break; - case CG_MOONLIT: - //Moonlit's cost is 4sp*skill_lv [Skotlex] - sp= 4*(sce->val1>>16); - //Upkeep is also every 10 secs. - case DC_DONTFORGETME: - s=10; - break; + case SC_SPLASHER: + // custom Venom Splasher countdown timer + //if (sce->val4 % 1000 == 0) { + // char counter[10]; + // snprintf (counter, 10, "%d", sce->val4/1000); + // clif->message(bl, counter); + //} + if((sce->val4 -= 500) > 0) { + sc_timer_next(500 + tick, status->change_timer, bl->id, data); + return 0; } - if( s != 0 && sce->val3 % s == 0 ) { - if (sc->data[SC_LONGING]) - sp*= 3; - if (!status->charge(bl, 0, sp)) - break; + break; + + case SC_MARIONETTE_MASTER: + case SC_MARIONETTE: + { + struct block_list *pbl = map->id2bl(sce->val1); + if( pbl && check_distance_bl(bl, pbl, 7) ) { + sc_timer_next(1000 + tick, status->change_timer, bl->id, data); + return 0; + } } - sc_timer_next(1000+tick, status->change_timer, bl->id, data); - return 0; - } - break; - case SC_BERSERK: - // 5% every 10 seconds [DracoRPG] - if( --( sce->val3 ) > 0 && status->charge(bl, sce->val2, 0) && st->hp > 100 ) { - sc_timer_next(sce->val4+tick, status->change_timer, bl->id, data); - return 0; - } - break; + break; - case SC_NOCHAT: - if(sd) { - sd->status.manner++; - clif->changestatus(sd,SP_MANNER,sd->status.manner); - clif->updatestatus(sd,SP_MANNER); - if (sd->status.manner < 0) { - //Every 60 seconds your manner goes up by 1 until it gets back to 0. - sc_timer_next(60000+tick, status->change_timer, bl->id, data); + case SC_GOSPEL: + if(sce->val4 == BCT_SELF && --(sce->val2) > 0) { + int hp, sp; + hp = (sce->val1 > 5) ? 45 : 30; + sp = (sce->val1 > 5) ? 35 : 20; + if(!status->charge(bl, hp, sp)) + break; + sc_timer_next(10000+tick, status->change_timer, bl->id, data); return 0; } - } - break; - - case SC_SPLASHER: - // custom Venom Splasher countdown timer - //if (sce->val4 % 1000 == 0) { - // char counter[10]; - // snprintf (counter, 10, "%d", sce->val4/1000); - // clif->message(bl, counter); - //} - if((sce->val4 -= 500) > 0) { - sc_timer_next(500 + tick, status->change_timer, bl->id, data); - return 0; - } - break; + break; - case SC_MARIONETTE_MASTER: - case SC_MARIONETTE: - { - struct block_list *pbl = map->id2bl(sce->val1); - if( pbl && check_distance_bl(bl, pbl, 7) ) { - sc_timer_next(1000 + tick, status->change_timer, bl->id, data); + case SC_JAILED: + if(sce->val1 == INT_MAX || --(sce->val1) > 0) { + sc_timer_next(60000+tick, status->change_timer, bl->id,data); return 0; } - } - break; - - case SC_GOSPEL: - if(sce->val4 == BCT_SELF && --(sce->val2) > 0) { - int hp, sp; - hp = (sce->val1 > 5) ? 45 : 30; - sp = (sce->val1 > 5) ? 35 : 20; - if(!status->charge(bl, hp, sp)) - break; - sc_timer_next(10000+tick, status->change_timer, bl->id, data); - return 0; - } - break; - - case SC_JAILED: - if(sce->val1 == INT_MAX || --(sce->val1) > 0) { - sc_timer_next(60000+tick, status->change_timer, bl->id,data); - return 0; - } - break; - - case SC_BLIND: - if(sc->data[SC_FOGWALL]) { - //Blind lasts forever while you are standing on the fog. - sc_timer_next(5000+tick, status->change_timer, bl->id, data); - return 0; - } - break; - case SC_ABUNDANCE: - if(--(sce->val4) > 0) { - status->heal(bl,0,60,0); - sc_timer_next(10000+tick, status->change_timer, bl->id, data); - } - break; - - case SC_PYREXIA: - if( --(sce->val4) > 0 ) { - map->freeblock_lock(); - clif->damage(bl,bl,tick,status_get_amotion(bl),status_get_dmotion(bl)+500,100,0,0,0); - status_fix_damage(NULL,bl,100,0); - if( sc->data[type] ) { - sc_timer_next(3000+tick,status->change_timer,bl->id,data); - } - map->freeblock_unlock(); - return 0; - } - break; + break; - case SC_LEECHESEND: - if( --(sce->val4) > 0 ) { - int damage = st->max_hp/100; // {Target VIT x (New Poison Research Skill Level - 3)} + (Target HP/100) - damage += st->vit * (sce->val1 - 3); - unit->skillcastcancel(bl,2); - map->freeblock_lock(); - status->damage(bl, bl, damage, 0, clif->damage(bl,bl,tick,status_get_amotion(bl),status_get_dmotion(bl)+500,damage,1,0,0), 1); - if( sc->data[type] ) { - sc_timer_next(1000 + tick, status->change_timer, bl->id, data ); - } - map->freeblock_unlock(); - return 0; - } - break; + case SC_BLIND: + if(sc->data[SC_FOGWALL]) { + //Blind lasts forever while you are standing on the fog. + sc_timer_next(5000+tick, status->change_timer, bl->id, data); + return 0; + } + break; + case SC_ABUNDANCE: + if(--(sce->val4) > 0) { + status->heal(bl,0,60,0); + sc_timer_next(10000+tick, status->change_timer, bl->id, data); + } + break; - case SC_MAGICMUSHROOM: - if( --(sce->val4) > 0 ) { - bool flag = 0; - int damage = st->max_hp * 3 / 100; - if( st->hp <= damage ) - damage = st->hp - 1; // Cannot Kill + case SC_PYREXIA: + if( --(sce->val4) > 0 ) { + map->freeblock_lock(); + clif->damage(bl,bl,status_get_amotion(bl),status_get_dmotion(bl)+500,100,0,0,0); + status_fix_damage(NULL,bl,100,0); + if( sc->data[type] ) { + sc_timer_next(3000+tick,status->change_timer,bl->id,data); + } + map->freeblock_unlock(); + return 0; + } + break; - if( damage > 0 ) { // 3% Damage each 4 seconds + case SC_LEECHESEND: + if( --(sce->val4) > 0 ) { + int damage = st->max_hp/100; // {Target VIT x (New Poison Research Skill Level - 3)} + (Target HP/100) + damage += st->vit * (sce->val1 - 3); + unit->skillcastcancel(bl,2); map->freeblock_lock(); - status_zap(bl,damage,0); - flag = !sc->data[type]; // Killed? Should not + status->damage(bl, bl, damage, 0, clif->damage(bl,bl,status_get_amotion(bl),status_get_dmotion(bl)+500,damage,1,0,0), 1); + if( sc->data[type] ) { + sc_timer_next(1000 + tick, status->change_timer, bl->id, data ); + } map->freeblock_unlock(); + return 0; } + break; - if( !flag ) { // Random Skill Cast - if (sd && !pc_issit(sd)) { //can't cast if sit - int mushroom_skill_id = 0, i; - unit->stop_attack(bl); - unit->skillcastcancel(bl,1); - do { - i = rnd() % MAX_SKILL_MAGICMUSHROOM_DB; - mushroom_skill_id = skill->magicmushroom_db[i].skill_id; - } - while( mushroom_skill_id == 0 ); + case SC_MAGICMUSHROOM: + if( --(sce->val4) > 0 ) { + bool flag = 0; + int damage = st->max_hp * 3 / 100; + if( st->hp <= damage ) + damage = st->hp - 1; // Cannot Kill + + if( damage > 0 ) { // 3% Damage each 4 seconds + map->freeblock_lock(); + status_zap(bl,damage,0); + flag = !sc->data[type]; // Killed? Should not + map->freeblock_unlock(); + } - switch( skill->get_casttype(mushroom_skill_id) ) { // Magic Mushroom skills are buffs or area damage - case CAST_GROUND: - skill->castend_pos2(bl,bl->x,bl->y,mushroom_skill_id,1,tick,0); - break; - case CAST_NODAMAGE: - skill->castend_nodamage_id(bl,bl,mushroom_skill_id,1,tick,0); - break; - case CAST_DAMAGE: - skill->castend_damage_id(bl,bl,mushroom_skill_id,1,tick,0); - break; + if( !flag ) { // Random Skill Cast + if (sd && !pc_issit(sd)) { //can't cast if sit + int mushroom_skill_id = 0, i; + unit->stop_attack(bl); + unit->skillcastcancel(bl,0); + do { + i = rnd() % MAX_SKILL_MAGICMUSHROOM_DB; + mushroom_skill_id = skill->magicmushroom_db[i].skill_id; + } + while( mushroom_skill_id == 0 ); + + switch( skill->get_casttype(mushroom_skill_id) ) { // Magic Mushroom skills are buffs or area damage + case CAST_GROUND: + skill->castend_pos2(bl,bl->x,bl->y,mushroom_skill_id,1,tick,0); + break; + case CAST_NODAMAGE: + skill->castend_nodamage_id(bl,bl,mushroom_skill_id,1,tick,0); + break; + case CAST_DAMAGE: + skill->castend_damage_id(bl,bl,mushroom_skill_id,1,tick,0); + break; + } } + + clif->emotion(bl,E_HEH); + sc_timer_next(4000+tick,status->change_timer,bl->id,data); } + return 0; + } + break; - clif->emotion(bl,E_HEH); - sc_timer_next(4000+tick,status->change_timer,bl->id,data); + case SC_TOXIN: + if( --(sce->val4) > 0 ) { + //Damage is every 10 seconds including 3%sp drain. + map->freeblock_lock(); + clif->damage(bl,bl,status_get_amotion(bl),1,1,0,0,0); + status->damage(NULL, bl, 1, st->max_sp * 3 / 100, 0, 0); //cancel dmg only if cancelable + if( sc->data[type] ) { + sc_timer_next(10000 + tick, status->change_timer, bl->id, data ); + } + map->freeblock_unlock(); + return 0; } - return 0; - } - break; + break; - case SC_TOXIN: - if( --(sce->val4) > 0 ) { - //Damage is every 10 seconds including 3%sp drain. - map->freeblock_lock(); - clif->damage(bl,bl,tick,status_get_amotion(bl),1,1,0,0,0); - status->damage(NULL, bl, 1, st->max_sp * 3 / 100, 0, 0); //cancel dmg only if cancelable - if( sc->data[type] ) { - sc_timer_next(10000 + tick, status->change_timer, bl->id, data ); - } - map->freeblock_unlock(); - return 0; - } - break; + case SC_OBLIVIONCURSE: + if( --(sce->val4) > 0 ) { + clif->emotion(bl,E_WHAT); + sc_timer_next(3000 + tick, status->change_timer, bl->id, data ); + return 0; + } + break; - case SC_OBLIVIONCURSE: - if( --(sce->val4) > 0 ) { - clif->emotion(bl,E_WHAT); - sc_timer_next(3000 + tick, status->change_timer, bl->id, data ); - return 0; - } - break; + case SC_WEAPONBLOCKING: + if( --(sce->val4) > 0 ) { + if( !status->charge(bl,0,3) ) + break; + sc_timer_next(5000+tick,status->change_timer,bl->id,data); + return 0; + } + break; - case SC_WEAPONBLOCKING: - if( --(sce->val4) > 0 ) { - if( !status->charge(bl,0,3) ) + case SC_CLOAKINGEXCEED: + if(!status->charge(bl,0,10-sce->val1)) break; - sc_timer_next(3000+tick,status->change_timer,bl->id,data); + sc_timer_next(1000 + tick, status->change_timer, bl->id, data); return 0; - } - break; - case SC_CLOAKINGEXCEED: - if(!status->charge(bl,0,10-sce->val1)) + case SC_RENOVATIO: + if( --(sce->val4) > 0 ) { + int heal = st->max_hp * 3 / 100; + if( sc && sc->data[SC_AKAITSUKI] && heal ) + heal = ~heal + 1; + status->heal(bl, heal, 0, 2); + sc_timer_next(5000 + tick, status->change_timer, bl->id, data); + return 0; + } break; - sc_timer_next(1000 + tick, status->change_timer, bl->id, data); - return 0; - case SC_RENOVATIO: - if( --(sce->val4) > 0 ) { - int heal = st->max_hp * 3 / 100; - if( sc && sc->data[SC_AKAITSUKI] && heal ) - heal = ~heal + 1; - status->heal(bl, heal, 0, 2); - sc_timer_next(5000 + tick, status->change_timer, bl->id, data); - return 0; - } - break; + case SC_BURNING: + if( --(sce->val4) > 0 ) { + struct block_list *src = map->id2bl(sce->val3); + int damage = 1000 + 3 * status_get_max_hp(bl) / 100; // Deals fixed (1000 + 3%*MaxHP) - case SC_BURNING: - if( --(sce->val4) > 0 ) { - struct block_list *src = map->id2bl(sce->val3); - int damage = 1000 + 3 * status_get_max_hp(bl) / 100; // Deals fixed (1000 + 3%*MaxHP) + map->freeblock_lock(); + clif->damage(bl,bl,0,0,damage,1,9,0); //damage is like endure effect with no walk delay + status->damage(src, bl, damage, 0, 0, 1); - map->freeblock_lock(); - clif->damage(bl,bl,tick,0,0,damage,1,9,0); //damage is like endure effect with no walk delay - status->damage(src, bl, damage, 0, 0, 1); + if( sc->data[type]){ // Target still lives. [LimitLine] + sc_timer_next(3000 + tick, status->change_timer, bl->id, data); + } + map->freeblock_unlock(); + return 0; + } + break; - if( sc->data[type]){ // Target still lives. [LimitLine] - sc_timer_next(3000 + tick, status->change_timer, bl->id, data); + case SC_FEAR: + if( --(sce->val4) > 0 ) { + if( sce->val2 > 0 ) + sce->val2--; + sc_timer_next(1000 + tick, status->change_timer, bl->id, data); + return 0; } - map->freeblock_unlock(); - return 0; - } - break; + break; - case SC_FEAR: - if( --(sce->val4) > 0 ) { - if( sce->val2 > 0 ) - sce->val2--; - sc_timer_next(1000 + tick, status->change_timer, bl->id, data); - return 0; - } - break; + case SC_SUMMON1: + case SC_SUMMON2: + case SC_SUMMON3: + case SC_SUMMON4: + case SC_SUMMON5: + if( --(sce->val4) > 0 ) { + if( !status->charge(bl, 0, 1) ) + break; + sc_timer_next(1000 + tick, status->change_timer, bl->id, data); + return 0; + } + break; - case SC_SUMMON1: - case SC_SUMMON2: - case SC_SUMMON3: - case SC_SUMMON4: - case SC_SUMMON5: - if( --(sce->val4) > 0 ) { - if( !status->charge(bl, 0, 1) ) + case SC_READING_SB: + if( !status->charge(bl, 0, sce->val2) ) { + int i; + for(i = SC_SPELLBOOK1; i <= SC_SPELLBOOK7; i++) // Also remove stored spell as well. + status_change_end(bl, (sc_type)i, INVALID_TIMER); break; - sc_timer_next(1000 + tick, status->change_timer, bl->id, data); + } + sc_timer_next(10000 + tick, status->change_timer, bl->id, data); return 0; - } - break; - case SC_READING_SB: - if( !status->charge(bl, 0, sce->val2) ) { - int i; - for(i = SC_SPELLBOOK1; i <= SC_SPELLBOOK7; i++) // Also remove stored spell as well. - status_change_end(bl, (sc_type)i, INVALID_TIMER); + case SC_ELECTRICSHOCKER: + if( --(sce->val4) > 0 ) { + status->charge(bl, 0, st->max_sp / 100 * sce->val1 ); + sc_timer_next(1000 + tick, status->change_timer, bl->id, data); + return 0; + } break; - } - sc_timer_next(5000 + tick, status->change_timer, bl->id, data); - return 0; - case SC_ELECTRICSHOCKER: - if( --(sce->val4) > 0 ) { - status->charge(bl, 0, st->max_sp / 100 * sce->val1 ); - sc_timer_next(1000 + tick, status->change_timer, bl->id, data); - return 0; - } - break; - - case SC_CAMOUFLAGE: - if(--(sce->val4) > 0) { - status->charge(bl,0,7 - sce->val1); - sc_timer_next(1000 + tick, status->change_timer, bl->id, data); - return 0; - } - break; + case SC_CAMOUFLAGE: + if(--(sce->val4) > 0) { + status->charge(bl,0,7 - sce->val1); + sc_timer_next(1000 + tick, status->change_timer, bl->id, data); + return 0; + } + break; - case SC__REPRODUCE: - if(!status->charge(bl, 0, 1)) + case SC__REPRODUCE: + if( --(sce->val4) >= 0 ) { + if( !status_charge(bl, 0, 9 - (1 + sce->val1) / 2) ) + break; + sc_timer_next(1000 + tick, status->change_timer, bl->id, data); + return 0; + } break; - sc_timer_next(1000+tick, status->change_timer, bl->id, data); - return 0; - case SC__SHADOWFORM: - if( --(sce->val4) > 0 ) { - if( !status->charge(bl, 0, sce->val1 - (sce->val1 - 1)) ) - break; - sc_timer_next(1000 + tick, status->change_timer, bl->id, data); - return 0; - } - break; + case SC__SHADOWFORM: + if( --(sce->val4) > 0 ) { + if( !status->charge(bl, 0, sce->val1 - (sce->val1 - 1)) ) + break; + sc_timer_next(1000 + tick, status->change_timer, bl->id, data); + return 0; + } + break; - case SC__INVISIBILITY: - if( --(sce->val4) > 0 ) { - if( !status->charge(bl, 0, (st->sp * 6 - sce->val1) / 100) )// 6% - skill_lv. - break; - sc_timer_next(1000 + tick, status->change_timer, bl->id, data); - return 0; - } - break; + case SC__INVISIBILITY: + if( --(sce->val4) >= 0 ) { + if( !status->charge(bl, 0, status_get_max_sp(bl) * (12 - sce->val1*2) / 100) ) + break; + sc_timer_next(1000 + tick, status->change_timer, bl->id, data); + return 0; + } + break; - case SC_STRIKING: - if( --(sce->val4) > 0 ) { - if( !status->charge(bl,0, sce->val1 ) ) - break; - sc_timer_next(1000 + tick, status->change_timer, bl->id, data); - return 0; - } - break; - case SC_VACUUM_EXTREME: - if( --(sce->val4) > 0 ) { - sc_timer_next(100 + tick, status->change_timer, bl->id, data); - return 0; - } - break; - case SC_BLOOD_SUCKER: - if( --(sce->val4) > 0 ) { - struct block_list *src = map->id2bl(sce->val2); - int damage; - if( !src || (src && (status->isdead(src) || src->m != bl->m || distance_bl(src, bl) >= 12)) ) - break; - map->freeblock_lock(); - damage = sce->val3; - status->damage(src, bl, damage, 0, clif->damage(bl,bl,tick,st->amotion,st->dmotion+200,damage,1,0,0), 1); - unit->skillcastcancel(bl,1); - if ( sc->data[type] ) { + case SC_STRIKING: + if( --(sce->val4) > 0 ) { + if( !status->charge(bl,0, sce->val1 ) ) + break; sc_timer_next(1000 + tick, status->change_timer, bl->id, data); + return 0; } - map->freeblock_unlock(); - status->heal(src, damage*(5 + 5 * sce->val1)/100, 0, 0); // 5 + 5% per level - return 0; - } - break; + break; + case SC_BLOOD_SUCKER: + if( --(sce->val4) > 0 ) { + struct block_list *src = map->id2bl(sce->val2); + int damage; + if( !src || (src && (status->isdead(src) || src->m != bl->m || distance_bl(src, bl) >= 12)) ) + break; + map->freeblock_lock(); + damage = sce->val3; + status->damage(src, bl, damage, 0, clif->damage(bl,bl,st->amotion,st->dmotion+200,damage,1,0,0), 1); + unit->skillcastcancel(bl,1); + if ( sc->data[type] ) { + sc_timer_next(1000 + tick, status->change_timer, bl->id, data); + } + map->freeblock_unlock(); + status->heal(src, damage*(5 + 5 * sce->val1)/100, 0, 0); // 5 + 5% per level + return 0; + } + break; - case SC_SIREN: - if( --(sce->val4) > 0 ) { - clif->emotion(bl,E_LV); - sc_timer_next(2000 + tick, status->change_timer, bl->id, data); - return 0; - } - break; + case SC_SIREN: + if( --(sce->val4) > 0 ) { + clif->emotion(bl,E_LV); + sc_timer_next(2000 + tick, status->change_timer, bl->id, data); + return 0; + } + break; - case SC_DEEP_SLEEP: - if( --(sce->val4) > 0 ) { - // Recovers 1% HP/SP every 2 seconds. - status->heal(bl, st->max_hp / 100, st->max_sp / 100, 2); - sc_timer_next(2000 + tick, status->change_timer, bl->id, data); - return 0; - } - break; + case SC_DEEP_SLEEP: + if( --(sce->val4) >= 0 ) + {// Recovers 3% of the player's MaxHP/MaxSP every 2 seconds. + status->heal(bl, st->max_hp * 3 / 100, st->max_sp * 3 / 100, 2); + sc_timer_next(2000 + tick, status->change_timer, bl->id, data); + return 0; + } + break; - case SC_SIRCLEOFNATURE: - if( --(sce->val4) > 0 ) { - if( !status->charge(bl,0,sce->val2) ) - break; - status->heal(bl, sce->val3, 0, 1); - sc_timer_next(1000 + tick, status->change_timer, bl->id, data); - return 0; - } - break; + case SC_SIRCLEOFNATURE: + if( --(sce->val4) >= 0 ) { + if( !status_charge(bl,0,sce->val3) ) + break; + status->heal(bl, sce->val2, 0, 1); + sc_timer_next(1000 + tick, status_change_timer, bl->id, data); + return 0; + } + break; - case SC_SONG_OF_MANA: - if( --(sce->val4) > 0 ) { - status->heal(bl,0,sce->val3,3); - sc_timer_next(3000 + tick, status->change_timer, bl->id, data); - return 0; - } - break; + case SC_SONG_OF_MANA: + if( --(sce->val4) >= 0 ) { + status->heal(bl,0,sce->val3,3); + sc_timer_next(5000 + tick, status->change_timer, bl->id, data); + return 0; + } + break; - case SC_SATURDAY_NIGHT_FEVER: - // 1% HP/SP drain every val4 seconds [Jobbie] - if( --(sce->val3) > 0 ) { - int hp = st->hp / 100; - int sp = st->sp / 100; - if( !status->charge(bl, hp, sp) ) + case SC_SATURDAY_NIGHT_FEVER: + if( --(sce->val3) >= 0 ) { + if( !status_charge(bl, st->max_hp * 1 / 100, st->max_sp * 1 / 100) ) break; - sc_timer_next(sce->val4+tick, status->change_timer, bl->id, data); - return 0; - } - break; - - case SC_COLD: - if( --(sce->val4) > 0 ) { - // Drains 2% of HP and 1% of SP every seconds. - if( bl->type != BL_MOB) // doesn't work on mobs - status->charge(bl, st->max_hp * 2 / 100, st->max_sp / 100); - sc_timer_next(1000 + tick, status->change_timer, bl->id, data); - return 0; - } - break; + sc_timer_next(3000+tick, status->change_timer, bl->id, data); + return 0; + } + break; - case SC_FORCEOFVANGUARD: - if( !status->charge(bl,0,20) ) + case SC_MELODYOFSINK: + if( --(sce->val4) >= 0 ) { + status_charge(bl, 0, st->max_sp * ( 2 * sce->val1 + 2 * sce->val2 ) / 100); + sc_timer_next(1000+tick, status->change_timer, bl->id, data); + return 0; + } break; - sc_timer_next(6000 + tick, status->change_timer, bl->id, data); - return 0; - case SC_BANDING: - if( status->charge(bl, 0, 7 - sce->val1) ) { - if( sd ) pc->banding(sd, sce->val1); - sc_timer_next(5000 + tick, status->change_timer, bl->id, data); - return 0; - } - break; + case SC_COLD: + if( --(sce->val4) > 0 ) { + // Drains 2% of HP and 1% of SP every seconds. + if( bl->type != BL_MOB) // doesn't work on mobs + status->charge(bl, st->max_hp * 2 / 100, st->max_sp / 100); + sc_timer_next(1000 + tick, status->change_timer, bl->id, data); + return 0; + } + break; - case SC_LG_REFLECTDAMAGE: - if( --(sce->val4) > 0 ) { - if( !status->charge(bl,0,sce->val3) ) + case SC_FORCEOFVANGUARD: + if( !status->charge(bl, 0, (24 - 4 * sce->val1)) ) break; sc_timer_next(10000 + tick, status->change_timer, bl->id, data); return 0; - } - break; - case SC_OVERHEAT_LIMITPOINT: - if( --(sce->val1) > 0 ) { // Cooling - sc_timer_next(30000 + tick, status->change_timer, bl->id, data); - } - break; + case SC_BANDING: + if( status->charge(bl, 0, 7 - sce->val1) ) { + if( sd ) pc->banding(sd, sce->val1); + sc_timer_next(5000 + tick, status->change_timer, bl->id, data); + return 0; + } + break; - case SC_OVERHEAT: - { - int damage = st->max_hp / 100; // Suggestion 1% each second - if( damage >= st->hp ) damage = st->hp - 1; // Do not kill, just keep you with 1 hp minimum - map->freeblock_lock(); - status_fix_damage(NULL,bl,damage,clif->damage(bl,bl,tick,0,0,damage,0,0,0)); - if( sc->data[type] ) { + case SC_LG_REFLECTDAMAGE: + if( --(sce->val4) >= 0 ) { + if( !status->charge(bl,0,10) ) + break; sc_timer_next(1000 + tick, status->change_timer, bl->id, data); + return 0; } - map->freeblock_unlock(); - } - break; + break; - case SC_MAGNETICFIELD: - { - if( --(sce->val3) <= 0 ) - break; // Time out - if( sce->val2 == bl->id ) { - if( !status->charge(bl,0,14 + (3 * sce->val1)) ) - break; // No more SP status should end, and in the next second will end for the other affected players - } else { - struct block_list *src = map->id2bl(sce->val2); - struct status_change *ssc; - if( !src || (ssc = status->get_sc(src)) == NULL || !ssc->data[SC_MAGNETICFIELD] ) - break; // Source no more under Magnetic Field + case SC_OVERHEAT_LIMITPOINT: + if( --(sce->val1) > 0 ) { // Cooling + sc_timer_next(30000 + tick, status->change_timer, bl->id, data); } - sc_timer_next(1000 + tick, status->change_timer, bl->id, data); - } - break; + break; + + case SC_OVERHEAT: + { + int damage = st->max_hp / 100; // Suggestion 1% each second + if( damage >= st->hp ) damage = st->hp - 1; // Do not kill, just keep you with 1 hp minimum + map->freeblock_lock(); + status_fix_damage(NULL,bl,damage,clif->damage(bl,bl,0,0,damage,0,0,0)); + if( sc->data[type] ) { + sc_timer_next(1000 + tick, status->change_timer, bl->id, data); + } + map->freeblock_unlock(); + } + break; - case SC_INSPIRATION: - if(--(sce->val4) > 0) { - int hp = st->max_hp * (7-sce->val1) / 100; - int sp = st->max_sp * (9-sce->val1) / 100; + case SC_MAGNETICFIELD: + { + if( --(sce->val3) <= 0 ) + break; // Time out + if( sce->val2 == bl->id ) { + if( !status->charge(bl,0,50) ) + break; // No more SP status should end, and in the next second will end for the other affected players + } else { + struct block_list *src = map->id2bl(sce->val2); + struct status_change *ssc; + if( !src || (ssc = status->get_sc(src)) == NULL || !ssc->data[SC_MAGNETICFIELD] ) + break; // Source no more under Magnetic Field + } + sc_timer_next(1000 + tick, status->change_timer, bl->id, data); + } + break; - if( !status->charge(bl,hp,sp) ) break; + case SC_STEALTHFIELD_MASTER: + if(--(sce->val4) >= 0) { + // 1% SP Upkeep Cost + int sp = st->max_sp / 100; + + if( st->sp <= sp ) + status_change_end(bl,SC_STEALTHFIELD_MASTER,INVALID_TIMER); - sc_timer_next(1000+tick,status->change_timer,bl->id, data); - return 0; - } - break; + if( !status_charge(bl,0,sp) ) + break; - case SC_RAISINGDRAGON: - // 1% every 5 seconds [Jobbie] - if( --(sce->val3)>0 && status->charge(bl, sce->val2, 0) ) { - if( !sc->data[type] ) return 0; - sc_timer_next(5000 + tick, status->change_timer, bl->id, data); - return 0; - } - break; + if( !sc->data[SC_STEALTHFIELD_MASTER] ) + break; - case SC_CIRCLE_OF_FIRE: - case SC_FIRE_CLOAK: - case SC_WATER_DROP: - case SC_WATER_SCREEN: - case SC_WIND_CURTAIN: - case SC_WIND_STEP: - case SC_STONE_SHIELD: - case SC_SOLID_SKIN: - if( !status->charge(bl,0,sce->val2) ){ - struct block_list *s_bl = battle->get_master(bl); - if( s_bl ) - status_change_end(s_bl,type+1,INVALID_TIMER); - status_change_end(bl,type,INVALID_TIMER); + sc_timer_next((2000 + 1000 * sce->val1)+tick,status->change_timer,bl->id, data); + return 0; + } break; - } - sc_timer_next(2000 + tick, status->change_timer, bl->id, data); - return 0; - case SC_STOMACHACHE: - if( --(sce->val4) > 0 ) { - status->charge(bl,0,sce->val2); // Reduce 8 every 10 seconds. - if( sd && !pc_issit(sd) ) { // Force to sit every 10 seconds. - pc_stop_walking(sd,1|4); - pc_stop_attack(sd); - pc_setsit(sd); - clif->sitting(bl); + case SC_INSPIRATION: + if(--(sce->val4) >= 0) { + int hp = st->max_hp * (35 - 5 * sce->val1) / 1000; + int sp = st->max_sp * (45 - 5 * sce->val1) / 1000; + + if( !status->charge(bl,hp,sp) ) break; + + sc_timer_next(5000+tick,status->change_timer,bl->id, data); + return 0; } - sc_timer_next(10000 + tick, status->change_timer, bl->id, data); - return 0; - } - break; - case SC_LEADERSHIP: - case SC_GLORYWOUNDS: - case SC_SOULCOLD: - case SC_HAWKEYES: - /* they only end by status_change_end */ - sc_timer_next(600000 + tick, status->change_timer, bl->id, data); - return 0; - case SC_MEIKYOUSISUI: - if( --(sce->val4) > 0 ) { - status->heal(bl, st->max_hp * (sce->val1+1) / 100, st->max_sp * sce->val1 / 100, 0); - sc_timer_next(1000 + tick, status->change_timer, bl->id, data); - return 0; - } - break; - case SC_IZAYOI: - case SC_KAGEMUSYA: - if( --(sce->val2) > 0 ) { - if(!status->charge(bl, 0, 1)) break; - sc_timer_next(1000+tick, status->change_timer, bl->id, data); - return 0; - } - break; - case SC_ANGRIFFS_MODUS: - if(--(sce->val4) > 0) { //drain hp/sp - if( !status->charge(bl,100,20) ) break; - sc_timer_next(1000+tick,status->change_timer,bl->id, data); - return 0; - } - break; - case SC_FULL_THROTTLE: - if( --(sce->val4) > 0 ) { - status_percent_damage(bl, bl, sce->val2, 0, false); - sc_timer_next(1000 + tick, status->change_timer, bl->id, data); - return 0; - } - break; - case SC_KINGS_GRACE: - if( --(sce->val4) > 0 ) { - status_percent_heal(bl, sce->val2, 0); - sc_timer_next(1000 + tick, status->change_timer, bl->id, data); + break; + + case SC_RAISINGDRAGON: + // 1% every 5 seconds [Jobbie] + if( --(sce->val3)>0 && status->charge(bl, sce->val2, 0) ) { + if( !sc->data[type] ) return 0; + sc_timer_next(5000 + tick, status->change_timer, bl->id, data); + return 0; + } + break; + + case SC_CIRCLE_OF_FIRE: + case SC_FIRE_CLOAK: + case SC_WATER_DROP: + case SC_WATER_SCREEN: + case SC_WIND_CURTAIN: + case SC_WIND_STEP: + case SC_STONE_SHIELD: + case SC_SOLID_SKIN: + if( !status->charge(bl,0,sce->val2) ){ + struct block_list *s_bl = battle->get_master(bl); + if( s_bl ) + status_change_end(s_bl,type+1,INVALID_TIMER); + status_change_end(bl,type,INVALID_TIMER); + break; + } + sc_timer_next(2000 + tick, status->change_timer, bl->id, data); return 0; - } - break; - case SC_FRIGG_SONG: - if( --(sce->val4) > 0 ) { - status->heal(bl, sce->val3, 0, 0); - sc_timer_next(10000 + tick, status->change_timer, bl->id, data); + + case SC_STOMACHACHE: + if( --(sce->val4) > 0 ) { + status->charge(bl,0,sce->val2); // Reduce 8 every 10 seconds. + if( sd && !pc_issit(sd) ) { // Force to sit every 10 seconds. + pc_stop_walking(sd,1|4); + pc_stop_attack(sd); + pc_setsit(sd); + clif->sitting(bl); + } + sc_timer_next(10000 + tick, status->change_timer, bl->id, data); + return 0; + } + break; + case SC_LEADERSHIP: + case SC_GLORYWOUNDS: + case SC_SOULCOLD: + case SC_HAWKEYES: + /* they only end by status_change_end */ + sc_timer_next(600000 + tick, status->change_timer, bl->id, data); return 0; - } - break; + case SC_MEIKYOUSISUI: + if( --(sce->val4) > 0 ) { + status->heal(bl, st->max_hp * (sce->val1+1) / 100, st->max_sp * sce->val1 / 100, 0); + sc_timer_next(1000 + tick, status->change_timer, bl->id, data); + return 0; + } + break; + case SC_IZAYOI: + case SC_KAGEMUSYA: + if( --(sce->val2) > 0 ) { + if(!status->charge(bl, 0, 1)) break; + sc_timer_next(1000+tick, status->change_timer, bl->id, data); + return 0; + } + break; + case SC_ANGRIFFS_MODUS: + if(--(sce->val4) > 0) { //drain hp/sp + if( !status->charge(bl,100,20) ) break; + sc_timer_next(1000+tick,status->change_timer,bl->id, data); + return 0; + } + break; + case SC_FULL_THROTTLE: + if( --(sce->val4) > 0 ) { + status_percent_damage(bl, bl, sce->val2, 0, false); + sc_timer_next(1000 + tick, status->change_timer, bl->id, data); + return 0; + } + break; + case SC_KINGS_GRACE: + if( --(sce->val4) > 0 ) { + status_percent_heal(bl, sce->val2, 0); + sc_timer_next(1000 + tick, status->change_timer, bl->id, data); + return 0; + } + break; + case SC_FRIGG_SONG: + if( --(sce->val4) > 0 ) { + status->heal(bl, sce->val3, 0, 0); + sc_timer_next(1000 + tick, status->change_timer, bl->id, data); + return 0; + } + break; } // default for all non-handled control paths is to end the status @@ -10707,7 +11173,7 @@ int status_change_timer_sub(struct block_list* bl, va_list ap) { struct block_list* src = va_arg(ap,struct block_list*); struct status_change_entry* sce = va_arg(ap,struct status_change_entry*); enum sc_type type = (sc_type)va_arg(ap,int); //gcc: enum args get promoted to int - unsigned int tick = va_arg(ap,unsigned int); + int64 tick = va_arg(ap, int64); if (status->isdead(bl)) return 0; @@ -10715,57 +11181,54 @@ int status_change_timer_sub(struct block_list* bl, va_list ap) { tsc = status->get_sc(bl); switch( type ) { - case SC_SIGHT: /* Reveal hidden ennemy on 3*3 range */ - if( tsc && tsc->data[SC__SHADOWFORM] && (sce && sce->val4 >0 && sce->val4%2000 == 0) && // for every 2 seconds do the checking - rnd()%100 < 100-tsc->data[SC__SHADOWFORM]->val1*10 ) // [100 - (Skill Level x 10)] % - status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER); - case SC_CONCENTRATION: - status_change_end(bl, SC_HIDING, INVALID_TIMER); - status_change_end(bl, SC_CLOAKING, INVALID_TIMER); - status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER); - status_change_end(bl, SC_CAMOUFLAGE, INVALID_TIMER); - status_change_end(bl, SC__INVISIBILITY, INVALID_TIMER); - break; - case SC_RUWACH: /* Reveal hidden target and deal little dammages if ennemy */ - if (tsc && (tsc->data[SC_HIDING] || tsc->data[SC_CLOAKING] || - tsc->data[SC_CAMOUFLAGE] || tsc->data[SC_CLOAKINGEXCEED] || - tsc->data[SC__INVISIBILITY])) { - status_change_end(bl, SC_HIDING, INVALID_TIMER); - status_change_end(bl, SC_CLOAKING, INVALID_TIMER); - status_change_end(bl, SC_CAMOUFLAGE, INVALID_TIMER); - status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER); - status_change_end(bl, SC__INVISIBILITY, INVALID_TIMER); - if(battle->check_target( src, bl, BCT_ENEMY ) > 0) - skill->attack(BF_MAGIC,src,src,bl,AL_RUWACH,1,tick,0); - } - if( tsc && tsc->data[SC__SHADOWFORM] && (sce && sce->val4 >0 && sce->val4%2000 == 0) && // for every 2 seconds do the checking - rnd()%100 < 100-tsc->data[SC__SHADOWFORM]->val1*10 ) // [100 - (Skill Level x 10)] % - status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER); - break; - case SC_WZ_SIGHTBLASTER: - if (battle->check_target( src, bl, BCT_ENEMY ) > 0 - && status->check_skilluse(src, bl, WZ_SIGHTBLASTER, 2) - ) { - if (sce && !(bl->type&BL_SKILL) //The hit is not counted if it's against a trap - && skill->attack(BF_MAGIC,src,src,bl,WZ_SIGHTBLASTER,1,tick,0) - ){ - sce->val2 = 0; //This signals it to end. + case SC_SIGHT: /* Reveal hidden ennemy on 3*3 range */ + if( tsc && tsc->data[SC__SHADOWFORM] && (sce && sce->val4 >0 && sce->val4%2000 == 0) && // for every 2 seconds do the checking + rnd()%100 < 100-tsc->data[SC__SHADOWFORM]->val1*10 ) // [100 - (Skill Level x 10)] % + status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER); + case SC_CONCENTRATION: + status_change_end(bl, SC_HIDING, INVALID_TIMER); + status_change_end(bl, SC_CLOAKING, INVALID_TIMER); + status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER); + status_change_end(bl, SC_CAMOUFLAGE, INVALID_TIMER); + break; + case SC_RUWACH: /* Reveal hidden target and deal little dammages if ennemy */ + if (tsc && (tsc->data[SC_HIDING] || tsc->data[SC_CLOAKING] || + tsc->data[SC_CAMOUFLAGE] || tsc->data[SC_CLOAKINGEXCEED])) { + status_change_end(bl, SC_HIDING, INVALID_TIMER); + status_change_end(bl, SC_CLOAKING, INVALID_TIMER); + status_change_end(bl, SC_CAMOUFLAGE, INVALID_TIMER); + status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER); + if(battle->check_target( src, bl, BCT_ENEMY ) > 0) + skill->attack(BF_MAGIC,src,src,bl,AL_RUWACH,1,tick,0); } - } - break; - case SC_RG_CCONFINE_M: - //Lock char has released the hold on everyone... - if (tsc && tsc->data[SC_RG_CCONFINE_S] && tsc->data[SC_RG_CCONFINE_S]->val2 == src->id) { - tsc->data[SC_RG_CCONFINE_S]->val2 = 0; - status_change_end(bl, SC_RG_CCONFINE_S, INVALID_TIMER); - } - break; - case SC_CURSEDCIRCLE_TARGET: - if( tsc && tsc->data[SC_CURSEDCIRCLE_TARGET] && tsc->data[SC_CURSEDCIRCLE_TARGET]->val2 == src->id ) { - clif->bladestop(bl, tsc->data[SC_CURSEDCIRCLE_TARGET]->val2, 0); - status_change_end(bl, type, INVALID_TIMER); - } - break; + if( tsc && tsc->data[SC__SHADOWFORM] && (sce && sce->val4 >0 && sce->val4%2000 == 0) && // for every 2 seconds do the checking + rnd()%100 < 100-tsc->data[SC__SHADOWFORM]->val1*10 ) // [100 - (Skill Level x 10)] % + status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER); + break; + case SC_WZ_SIGHTBLASTER: + if (battle->check_target( src, bl, BCT_ENEMY ) > 0 + && status->check_skilluse(src, bl, WZ_SIGHTBLASTER, 2) + ) { + if (sce && !(bl->type&BL_SKILL) //The hit is not counted if it's against a trap + && skill->attack(BF_MAGIC,src,src,bl,WZ_SIGHTBLASTER,1,tick,0) + ){ + sce->val2 = 0; //This signals it to end. + } + } + break; + case SC_RG_CCONFINE_M: + //Lock char has released the hold on everyone... + if (tsc && tsc->data[SC_RG_CCONFINE_S] && tsc->data[SC_RG_CCONFINE_S]->val2 == src->id) { + tsc->data[SC_RG_CCONFINE_S]->val2 = 0; + status_change_end(bl, SC_RG_CCONFINE_S, INVALID_TIMER); + } + break; + case SC_CURSEDCIRCLE_TARGET: + if( tsc && tsc->data[SC_CURSEDCIRCLE_TARGET] && tsc->data[SC_CURSEDCIRCLE_TARGET]->val2 == src->id ) { + clif->bladestop(bl, tsc->data[SC_CURSEDCIRCLE_TARGET]->val2, 0); + status_change_end(bl, type, INVALID_TIMER); + } + break; } return 0; } @@ -10871,7 +11334,7 @@ int status_get_matk(struct block_list *bl, int flag) { st->matk_min = status_base_matk_min(st) + (sd?sd->bonus.ematk:0); st->matk_max = status_base_matk_max(st) + (sd?sd->bonus.ematk:0); #endif - if (bl->type&BL_PC && sd->matk_rate != 100) { + if (sd && sd->matk_rate != 100) { st->matk_max = st->matk_max * sd->matk_rate/100; st->matk_min = st->matk_min * sd->matk_rate/100; } @@ -10943,7 +11406,6 @@ int status_change_clear_buffs (struct block_list* bl, int type) { continue; break; case SC_BERSERK: - case SC_SATURDAY_NIGHT_FEVER: if(type&4) continue; sc->data[i]->val2 = 0; @@ -10961,7 +11423,7 @@ int status_change_clear_buffs (struct block_list* bl, int type) { int status_change_spread( struct block_list *src, struct block_list *bl ) { int i, flag = 0; struct status_change *sc = status->get_sc(src); - unsigned int tick; + int64 tick; struct status_change_data data; if( !sc || !sc->count ) @@ -11003,7 +11465,7 @@ int status_change_spread( struct block_list *src, struct block_list *bl ) { const struct TimerData *td = timer->get(sc->data[i]->timer); if (td == NULL || td->func != status->change_timer || DIFF_TICK(td->tick,tick) < 0) continue; - data.tick = DIFF_TICK(td->tick,tick); + data.tick = DIFF_TICK32(td->tick,tick); } else data.tick = INVALID_TIMER; break; @@ -11038,7 +11500,7 @@ int status_change_spread( struct block_list *src, struct block_list *bl ) { data.val2 = sc->data[i]->val2; data.val3 = sc->data[i]->val3; data.val4 = sc->data[i]->val4; - status->change_start(bl,(sc_type)i,10000,data.val1,data.val2,data.val3,data.val4,data.tick,1|2|8); + status->change_start(src,bl,(sc_type)i,10000,data.val1,data.val2,data.val3,data.val4,data.tick,1|2|8); flag = 1; } } @@ -11211,7 +11673,7 @@ int status_natural_heal(struct block_list* bl, va_list args) { val*=2; sd->state.doridori = 0; if ((rate = pc->checkskill(sd,TK_SPTIME))) - sc_start(bl,status->skill2sc(TK_SPTIME), + sc_start(bl,bl,status->skill2sc(TK_SPTIME), 100,rate,skill->get_time(TK_SPTIME, rate)); if ((sd->class_&MAPID_UPPERMASK) == MAPID_STAR_GLADIATOR &&rnd()%10000 < battle_config.sg_angel_skill_ratio @@ -11231,8 +11693,9 @@ int status_natural_heal(struct block_list* bl, va_list args) { } //Natural heal main timer. -int status_natural_heal_timer(int tid, unsigned int tick, int id, intptr_t data) { - status->natural_heal_diff_tick = DIFF_TICK(tick,status->natural_heal_prev_tick); +int status_natural_heal_timer(int tid, int64 tick, int id, intptr_t data) { + // This difference is always positive and lower than UINT_MAX (~24 days) + status->natural_heal_diff_tick = (unsigned int)cap_value(DIFF_TICK(tick,status->natural_heal_prev_tick), 0, UINT_MAX); map->foreachregen(status->natural_heal); status->natural_heal_prev_tick = tick; return 0; @@ -11431,7 +11894,10 @@ int status_readdb(void) /*========================================== * Status db init and destroy. *------------------------------------------*/ -int do_init_status(void) { +int do_init_status(bool minimal) { + if (minimal) + return 0; + timer->add_func_list(status->change_timer,"status_change_timer"); timer->add_func_list(status->kaahi_heal_timer,"status_kaahi_heal_timer"); timer->add_func_list(status->natural_heal_timer,"status_natural_heal_timer"); @@ -11502,7 +11968,7 @@ void status_defaults(void) { status->set_sp = status_set_sp; status->heal = status_heal; status->revive = status_revive; - + status->fixed_revive = status_fixed_revive; status->get_regen_data = status_get_regen_data; status->get_status_data = status_get_status_data; status->get_base_status = status_get_base_status; diff --git a/src/map/status.h b/src/map/status.h index c7518a213..06bea3908 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -2,8 +2,8 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _STATUS_H_ -#define _STATUS_H_ +#ifndef _MAP_STATUS_H_ +#define _MAP_STATUS_H_ #include "../common/mmo.h" @@ -14,6 +14,21 @@ struct homun_data; struct mercenary_data; struct status_change; +//Change the equation when the values are high enough to discard the +//imprecision in exchange of overflow protection [Skotlex] +//Also add 100% checks since those are the most used cases where we don't +//want aproximation errors. +#define APPLY_RATE(value, rate) ( \ + (rate) == 100 ? \ + (value) \ + : ( \ + (value) > 100000 ? \ + (rate) * ( (value) / 100 ) \ + : \ + (value) * (rate) / 100 \ + ) \ +) + /** * Max Refine available to your server * Changing this limit requires edits to refine_db.txt @@ -34,13 +49,14 @@ enum refine_type { }; typedef enum sc_conf_type { - SC_NO_REM_DEATH = 0x1, - SC_NO_SAVE = 0x2, - SC_NO_DISPELL = 0x4, - SC_NO_CLEARANCE = 0x8, - SC_BUFF = 0x10, - SC_DEBUFF = 0x20, - SC_MADO_NO_RESET = 0x40 + SC_NO_REM_DEATH = 0x01, + SC_NO_SAVE = 0x02, + SC_NO_DISPELL = 0x04, + SC_NO_CLEARANCE = 0x08, + SC_BUFF = 0x10, + SC_DEBUFF = 0x20, + SC_MADO_NO_RESET = 0x40, + SC_NO_CLEAR = 0x80, } sc_conf_type; // Status changes listing. These code are for use by the server. @@ -357,7 +373,7 @@ typedef enum sc_type { /** * 3rd **/ - SC_FEAR, + SC_FEAR, // 310 SC_FROSTMISTY, /** * Rune Knight @@ -370,20 +386,20 @@ typedef enum sc_type { SC_REUSE_REFRESH, SC_GIANTGROWTH, SC_STONEHARDSKIN, - SC_VITALITYACTIVATION, + SC_VITALITYACTIVATION, // 320 SC_STORMBLAST, SC_FIGHTINGSPIRIT, SC_ABUNDANCE, /** * Arch Bishop - **/ + **/ SC_ADORAMUS, SC_EPICLESIS, SC_ORATIO, SC_LAUDAAGNUS, SC_LAUDARAMUS, SC_RENOVATIO, - SC_EXPIATIO, + SC_EXPIATIO, // 330 SC_DUPLELIGHT, SC_SECRAMENT, /** @@ -396,7 +412,7 @@ typedef enum sc_type { SC_SUMMON1, SC_SUMMON2, SC_SUMMON3, - SC_SUMMON4, + SC_SUMMON4, // 340 SC_SUMMON5, SC_READING_SB, SC_FREEZINGSP, @@ -412,7 +428,7 @@ typedef enum sc_type { * Mechanic **/ SC_ACCELERATION, - SC_HOVERING, + SC_HOVERING, // 350 SC_SHAPESHIFT, SC_INFRAREDSCAN, SC_ANALYZE, @@ -422,7 +438,7 @@ typedef enum sc_type { SC_STEALTHFIELD, SC_STEALTHFIELD_MASTER, SC_OVERHEAT, - SC_OVERHEAT_LIMITPOINT, + SC_OVERHEAT_LIMITPOINT, // 360 /** * Guillotine Cross **/ @@ -435,7 +451,7 @@ typedef enum sc_type { SC_ROLLINGCUTTER, SC_TOXIN, SC_PARALYSE, - SC_VENOMBLEED, + SC_VENOMBLEED, // 370 SC_MAGICMUSHROOM, SC_DEATHHURT, SC_PYREXIA, @@ -448,7 +464,7 @@ typedef enum sc_type { SC_FORCEOFVANGUARD, SC_SHIELDSPELL_DEF, SC_SHIELDSPELL_MDEF, - SC_SHIELDSPELL_REF, + SC_SHIELDSPELL_REF, // 380 SC_EXEEDBREAK, SC_PRESTIGE, SC_BANDING, @@ -461,7 +477,7 @@ typedef enum sc_type { SC_SPELLFIST, SC_COLD, SC_STRIKING, - SC_WARMER, + SC_WARMER, // 390 SC_VACUUM_EXTREME, SC_PROPERTYWALK, /** @@ -474,30 +490,30 @@ typedef enum sc_type { SC_ECHOSONG, SC_HARMONIZE, SC_SIREN, - SC_DEEP_SLEEP, + SC_DEEP_SLEEP, // 400 SC_SIRCLEOFNATURE, SC_GLOOMYDAY, - SC_GLOOMYDAY_SK, - SC_SONG_OF_MANA, + //SC_GLOOMYDAY_SK, + SC_SONG_OF_MANA = 404, SC_DANCE_WITH_WUG, SC_SATURDAY_NIGHT_FEVER, SC_LERADS_DEW, SC_MELODYOFSINK, SC_BEYOND_OF_WARCRY, - SC_UNLIMITED_HUMMING_VOICE, + SC_UNLIMITED_HUMMING_VOICE, // 410 SC_SITDOWN_FORCE, - SC_NETHERWORLD, + //SC_NETHERWORLD, /** * Sura **/ - SC_CRESCENTELBOW, + SC_CRESCENTELBOW = 413, SC_CURSEDCIRCLE_ATKER, SC_CURSEDCIRCLE_TARGET, SC_LIGHTNINGWALK, SC_RAISINGDRAGON, SC_GENTLETOUCH_ENERGYGAIN, SC_GENTLETOUCH_CHANGE, - SC_GENTLETOUCH_REVITALIZE, + SC_GENTLETOUCH_REVITALIZE, // 420 /** * Genetic **/ @@ -510,7 +526,7 @@ typedef enum sc_type { SC_STOMACHACHE, SC_MYSTERIOUS_POWDER, SC_MELON_BOMB, - SC_BANANA_BOMB, + SC_BANANA_BOMB, // 430 SC_BANANA_BOMB_SITDOWN_POSTDELAY, SC_SAVAGE_STEAK, SC_COCKTAIL_WARG_BLOOD, @@ -520,7 +536,7 @@ typedef enum sc_type { SC_PUTTI_TAILS_NOODLES, SC_BOOST500, SC_FULL_SWING_K, - SC_MANA_PLUS, + SC_MANA_PLUS, // 440 SC_MUSTLE_M, SC_LIFE_FORCE_F, SC_EXTRACT_WHITE_POTION_Z, @@ -533,7 +549,7 @@ typedef enum sc_type { SC__AUTOSHADOWSPELL, SC__SHADOWFORM, SC__BODYPAINT, - SC__INVISIBILITY, + SC__INVISIBILITY, // 450 SC__DEADLYINFECT, SC__ENERVATION, SC__GROOMY, @@ -543,7 +559,7 @@ typedef enum sc_type { SC__WEAKNESS, SC__STRIPACCESSARY, SC__MANHOLE, - SC__BLOODYLUST, + SC__BLOODYLUST, // 460 /** * Elemental Spirits **/ @@ -556,7 +572,7 @@ typedef enum sc_type { SC_WATER_DROP, SC_WATER_DROP_OPTION, SC_WATER_BARRIER, - SC_WIND_STEP, + SC_WIND_STEP, // 470 SC_WIND_STEP_OPTION, SC_WIND_CURTAIN, SC_WIND_CURTAIN_OPTION, @@ -566,7 +582,7 @@ typedef enum sc_type { SC_STONE_SHIELD, SC_STONE_SHIELD_OPTION, SC_POWER_OF_GAIA, - SC_PYROTECHNIC, + SC_PYROTECHNIC, // 480 SC_PYROTECHNIC_OPTION, SC_HEATER, SC_HEATER_OPTION, @@ -576,7 +592,7 @@ typedef enum sc_type { SC_AQUAPLAY_OPTION, SC_COOLER, SC_COOLER_OPTION, - SC_CHILLY_AIR, + SC_CHILLY_AIR, // 490 SC_CHILLY_AIR_OPTION, SC_GUST, SC_GUST_OPTION, @@ -586,7 +602,7 @@ typedef enum sc_type { SC_WILD_STORM_OPTION, SC_PETROLOGY, SC_PETROLOGY_OPTION, - SC_CURSED_SOIL, + SC_CURSED_SOIL, // 500 SC_CURSED_SOIL_OPTION, SC_UPHEAVAL, SC_UPHEAVAL_OPTION, @@ -597,21 +613,21 @@ typedef enum sc_type { /* Guild Aura */ SC_LEADERSHIP, SC_GLORYWOUNDS, - SC_SOULCOLD, + SC_SOULCOLD, // 510 SC_HAWKEYES, /* ... */ SC_ODINS_POWER, /* Sorcerer .extra */ SC_FIRE_INSIGNIA, SC_WATER_INSIGNIA, - SC_WIND_INSIGNIA, + SC_WIND_INSIGNIA, SC_EARTH_INSIGNIA, /* new pushcart */ SC_PUSH_CART, /* Warlock Spell books */ SC_SPELLBOOK1, SC_SPELLBOOK2, - SC_SPELLBOOK3, + SC_SPELLBOOK3, // 520 SC_SPELLBOOK4, SC_SPELLBOOK5, SC_SPELLBOOK6, @@ -623,13 +639,13 @@ typedef enum sc_type { /* Max HP & SP */ SC_INCMHP, SC_INCMSP, - SC_PARTYFLEE, + SC_PARTYFLEE, /** * Kagerou & Oboro [malufett] **/ SC_MEIKYOUSISUI, SC_KO_JYUMONJIKIRI, - SC_KYOUGAKU, + SC_KYOUGAKU, // 530 SC_IZAYOI, SC_ZENKAI, SC_KG_KAGEHUMI, @@ -640,19 +656,19 @@ typedef enum sc_type { SC_AKAITSUKI, //homon S - SC_STYLE_CHANGE, - SC_GOLDENE_FERSE, - SC_ANGRIFFS_MODUS, - SC_ERASER_CUTTER, - SC_OVERED_BOOST, - SC_LIGHT_OF_REGENE, - SC_VOLCANIC_ASH, - SC_GRANITIC_ARMOR, - SC_MAGMA_FLOW, - SC_PYROCLASTIC, - SC_NEEDLE_OF_PARALYZE, - SC_PAIN_KILLER, -#ifdef RENEWAL + SC_STYLE_CHANGE, + SC_GOLDENE_FERSE, // 540 + SC_ANGRIFFS_MODUS, + SC_ERASER_CUTTER, + SC_OVERED_BOOST, + SC_LIGHT_OF_REGENE, + SC_VOLCANIC_ASH, + SC_GRANITIC_ARMOR, + SC_MAGMA_FLOW, + SC_PYROCLASTIC, + SC_NEEDLE_OF_PARALYZE, + SC_PAIN_KILLER, // 550 +#ifdef RENEWAL SC_EXTREMITYFIST2, SC_RAID, #endif @@ -663,7 +679,7 @@ typedef enum sc_type { SC_KINGS_GRACE, SC_TELEKINESIS_INTENSE, SC_OFFERTORIUM, - SC_FRIGG_SONG, + SC_FRIGG_SONG, // 560 SC_ALL_RIDING, SC_HANBOK, @@ -671,6 +687,21 @@ typedef enum sc_type { SC_ANGEL_PROTECT, SC_ILLUSIONDOPING, + SC_MTF_ASPD, + SC_MTF_RANGEATK, + SC_MTF_MATK, + SC_MTF_MLEATKED, + SC_MTF_CRIDAMAGE, // 570 + + SC_MOONSTAR, + SC_SUPER_STAR, + + SC_OKTOBERFEST, + SC_STRANGELIGHTS, + SC_DECORATION_OF_MUSIC, + + SC__MAELSTROM, + SC__CHAOS, SC_MAX, //Automatically updated max, used in for's to check we are within bounds. } sc_type; // Official status change ids, used to display status icons on the client. @@ -1405,6 +1436,34 @@ enum si_type { //SI_ = 735, SI_CHILL = 736, SI_BURNT = 737, + SI_FLASHCOMBO = 740, + SI_B_TRAP = 752, + SI_E_CHAIN = 753, + SI_E_QD_SHOT_READY = 754, + SI_C_MARKER = 755, + SI_H_MINE = 756, + SI_H_MINE_SPLASH = 757, + SI_P_ALTER = 758, + SI_HEAT_BARREL = 759, + SI_ANTI_M_BLAST = 760, + SI_SLUGSHOT = 761, + SI_SWORDCLAN = 762, + SI_ARCWANDCLAN = 763, + SI_GOLDENMACECLAN = 764, + SI_CROSSBOWCLAN = 765, + SI_PACKING_ENVELOPE1 = 766, + SI_PACKING_ENVELOPE2 = 767, + SI_PACKING_ENVELOPE3 = 768, + SI_PACKING_ENVELOPE4 = 769, + SI_PACKING_ENVELOPE5 = 770, + SI_PACKING_ENVELOPE6 = 771, + SI_PACKING_ENVELOPE7 = 772, + SI_PACKING_ENVELOPE8 = 773, + SI_PACKING_ENVELOPE9 = 774, + SI_PACKING_ENVELOPE10 = 775, + SI_GLASTHEIM_TRANS = 776, + SI_HEAT_BARREL_AFTER = 778, + SI_DECORATION_OF_MUSIC = 779, SI_MAX, }; // JOINTBEAT stackable ailments @@ -1494,30 +1553,31 @@ enum { }; enum { - OPTION_NOTHING = 0x00000000, - OPTION_SIGHT = 0x00000001, - OPTION_HIDE = 0x00000002, - OPTION_CLOAK = 0x00000004, - OPTION_FALCON = 0x00000010, - OPTION_RIDING = 0x00000020, - OPTION_INVISIBLE = 0x00000040, - OPTION_ORCISH = 0x00000800, - OPTION_WEDDING = 0x00001000, - OPTION_RUWACH = 0x00002000, - OPTION_CHASEWALK = 0x00004000, - OPTION_FLYING = 0x00008000, //Note that clientside Flying and Xmas are 0x8000 for clients prior to 2007. - OPTION_XMAS = 0x00010000, - OPTION_TRANSFORM = 0x00020000, - OPTION_SUMMER = 0x00040000, - OPTION_DRAGON1 = 0x00080000, - OPTION_WUG = 0x00100000, - OPTION_WUGRIDER = 0x00200000, - OPTION_MADOGEAR = 0x00400000, - OPTION_DRAGON2 = 0x00800000, - OPTION_DRAGON3 = 0x01000000, - OPTION_DRAGON4 = 0x02000000, - OPTION_DRAGON5 = 0x04000000, - OPTION_HANBOK = 0x08000000, + OPTION_NOTHING = 0x00000000, + OPTION_SIGHT = 0x00000001, + OPTION_HIDE = 0x00000002, + OPTION_CLOAK = 0x00000004, + OPTION_FALCON = 0x00000010, + OPTION_RIDING = 0x00000020, + OPTION_INVISIBLE = 0x00000040, + OPTION_ORCISH = 0x00000800, + OPTION_WEDDING = 0x00001000, + OPTION_RUWACH = 0x00002000, + OPTION_CHASEWALK = 0x00004000, + OPTION_FLYING = 0x00008000, //Note that clientside Flying and Xmas are 0x8000 for clients prior to 2007. + OPTION_XMAS = 0x00010000, + OPTION_TRANSFORM = 0x00020000, + OPTION_SUMMER = 0x00040000, + OPTION_DRAGON1 = 0x00080000, + OPTION_WUG = 0x00100000, + OPTION_WUGRIDER = 0x00200000, + OPTION_MADOGEAR = 0x00400000, + OPTION_DRAGON2 = 0x00800000, + OPTION_DRAGON3 = 0x01000000, + OPTION_DRAGON4 = 0x02000000, + OPTION_DRAGON5 = 0x04000000, + OPTION_HANBOK = 0x08000000, + OPTION_OKTOBERFEST = 0x10000000, #ifndef NEW_CARTS OPTION_CART1 = 0x00000008, @@ -1592,6 +1652,12 @@ enum e_regen { RGN_SSP = 0x08, }; +enum e_status_calc_opt { + SCO_NONE = 0x0, + SCO_FIRST = 0x1, /* trigger the calculations that should take place only onspawn/once */ + SCO_FORCE = 0x2, /* only relevant to BL_PC types, ensures call bypasses the queue caused by delayed damage */ +}; + //Define to determine who gets HP/SP consumed on doing skills/etc. [Skotlex] #define BL_CONSUME (BL_PC|BL_HOM|BL_MER|BL_ELEM) //Define to determine who has regen @@ -1717,72 +1783,73 @@ struct status_change { unsigned char sg_counter; //Storm gust counter (previous hits from storm gust) #endif unsigned char bs_counter; // Blood Sucker counter + unsigned char fv_counter; // Force of vanguard counter struct status_change_entry *data[SC_MAX]; }; //Define for standard HP damage attacks. -#define status_fix_damage(src, target, hp, walkdelay) status->damage(src, target, hp, 0, walkdelay, 0) +#define status_fix_damage(src, target, hp, walkdelay) (status->damage((src), (target), (hp), 0, (walkdelay), 0)) //Define for standard HP/SP damage triggers. -#define status_zap(bl, hp, sp) status->damage(NULL, bl, hp, sp, 0, 1) +#define status_zap(bl, hp, sp) (status->damage(NULL, (bl), (hp), (sp), 0, 1)) //Easier handling of status->percent_change -#define status_percent_heal(bl, hp_rate, sp_rate) status->percent_change(NULL, bl, -(hp_rate), -(sp_rate), 0) -#define status_percent_damage(src, target, hp_rate, sp_rate, kill) status->percent_change(src, target, hp_rate, sp_rate, (kill)?1:2) +#define status_percent_heal(bl, hp_rate, sp_rate) (status->percent_change(NULL, (bl), -(hp_rate), -(sp_rate), 0)) +#define status_percent_damage(src, target, hp_rate, sp_rate, kill) (status->percent_change((src), (target), (hp_rate), (sp_rate), (kill)?1:2)) //Instant kill with no drops/exp/etc -#define status_kill(bl) status_percent_damage(NULL, bl, 100, 0, true) +#define status_kill(bl) status_percent_damage(NULL, (bl), 100, 0, true) -#define status_get_range(bl) status->get_status_data(bl)->rhw.range -#define status_get_hp(bl) status->get_status_data(bl)->hp -#define status_get_max_hp(bl) status->get_status_data(bl)->max_hp -#define status_get_sp(bl) status->get_status_data(bl)->sp -#define status_get_max_sp(bl) status->get_status_data(bl)->max_sp -#define status_get_str(bl) status->get_status_data(bl)->str -#define status_get_agi(bl) status->get_status_data(bl)->agi -#define status_get_vit(bl) status->get_status_data(bl)->vit -#define status_get_int(bl) status->get_status_data(bl)->int_ -#define status_get_dex(bl) status->get_status_data(bl)->dex -#define status_get_luk(bl) status->get_status_data(bl)->luk -#define status_get_hit(bl) status->get_status_data(bl)->hit -#define status_get_flee(bl) status->get_status_data(bl)->flee -#define status_get_mdef(bl) status->get_status_data(bl)->mdef -#define status_get_flee2(bl) status->get_status_data(bl)->flee2 -#define status_get_def2(bl) status->get_status_data(bl)->def2 -#define status_get_mdef2(bl) status->get_status_data(bl)->mdef2 -#define status_get_critical(bl) status->get_status_data(bl)->cri -#define status_get_batk(bl) status->get_status_data(bl)->batk -#define status_get_watk(bl) status->get_status_data(bl)->rhw.atk -#define status_get_watk2(bl) status->get_status_data(bl)->rhw.atk2 -#define status_get_matk_max(bl) status->get_status_data(bl)->matk_max -#define status_get_matk_min(bl) status->get_status_data(bl)->matk_min -#define status_get_lwatk(bl) status->get_status_data(bl)->lhw.atk -#define status_get_lwatk2(bl) status->get_status_data(bl)->lhw.atk2 -#define status_get_adelay(bl) status->get_status_data(bl)->adelay -#define status_get_amotion(bl) status->get_status_data(bl)->amotion -#define status_get_dmotion(bl) status->get_status_data(bl)->dmotion -#define status_get_element(bl) status->get_status_data(bl)->def_ele -#define status_get_element_level(bl) status->get_status_data(bl)->ele_lv -#define status_get_attack_sc_element(bl, sc) status->calc_attack_element(bl, sc, 0) -#define status_get_attack_element(bl) status->get_status_data(bl)->rhw.ele -#define status_get_attack_lelement(bl) status->get_status_data(bl)->lhw.ele -#define status_get_race(bl) status->get_status_data(bl)->race -#define status_get_size(bl) status->get_status_data(bl)->size -#define status_get_mode(bl) status->get_status_data(bl)->mode +#define status_get_range(bl) (status->get_status_data(bl)->rhw.range) +#define status_get_hp(bl) (status->get_status_data(bl)->hp) +#define status_get_max_hp(bl) (status->get_status_data(bl)->max_hp) +#define status_get_sp(bl) (status->get_status_data(bl)->sp) +#define status_get_max_sp(bl) (status->get_status_data(bl)->max_sp) +#define status_get_str(bl) (status->get_status_data(bl)->str) +#define status_get_agi(bl) (status->get_status_data(bl)->agi) +#define status_get_vit(bl) (status->get_status_data(bl)->vit) +#define status_get_int(bl) (status->get_status_data(bl)->int_) +#define status_get_dex(bl) (status->get_status_data(bl)->dex) +#define status_get_luk(bl) (status->get_status_data(bl)->luk) +#define status_get_hit(bl) (status->get_status_data(bl)->hit) +#define status_get_flee(bl) (status->get_status_data(bl)->flee) +#define status_get_mdef(bl) (status->get_status_data(bl)->mdef) +#define status_get_flee2(bl) (status->get_status_data(bl)->flee2) +#define status_get_def2(bl) (status->get_status_data(bl)->def2) +#define status_get_mdef2(bl) (status->get_status_data(bl)->mdef2) +#define status_get_critical(bl) (status->get_status_data(bl)->cri) +#define status_get_batk(bl) (status->get_status_data(bl)->batk) +#define status_get_watk(bl) (status->get_status_data(bl)->rhw.atk) +#define status_get_watk2(bl) (status->get_status_data(bl)->rhw.atk2) +#define status_get_matk_max(bl) (status->get_status_data(bl)->matk_max) +#define status_get_matk_min(bl) (status->get_status_data(bl)->matk_min) +#define status_get_lwatk(bl) (status->get_status_data(bl)->lhw.atk) +#define status_get_lwatk2(bl) (status->get_status_data(bl)->lhw.atk2) +#define status_get_adelay(bl) (status->get_status_data(bl)->adelay) +#define status_get_amotion(bl) (status->get_status_data(bl)->amotion) +#define status_get_dmotion(bl) (status->get_status_data(bl)->dmotion) +#define status_get_element(bl) (status->get_status_data(bl)->def_ele) +#define status_get_element_level(bl) (status->get_status_data(bl)->ele_lv) +#define status_get_attack_sc_element(bl, sc) (status->calc_attack_element((bl), (sc), 0)) +#define status_get_attack_element(bl) (status->get_status_data(bl)->rhw.ele) +#define status_get_attack_lelement(bl) (status->get_status_data(bl)->lhw.ele) +#define status_get_race(bl) (status->get_status_data(bl)->race) +#define status_get_size(bl) (status->get_status_data(bl)->size) +#define status_get_mode(bl) (status->get_status_data(bl)->mode) //Short version, receives rate in 1->100 range, and does not uses a flag setting. -#define sc_start(bl, type, rate, val1, tick) status->change_start(bl,type,100*(rate),val1,0,0,0,tick,0) -#define sc_start2(bl, type, rate, val1, val2, tick) status->change_start(bl,type,100*(rate),val1,val2,0,0,tick,0) -#define sc_start4(bl, type, rate, val1, val2, val3, val4, tick) status->change_start(bl,type,100*(rate),val1,val2,val3,val4,tick,0) +#define sc_start(src, bl, type, rate, val1, tick) (status->change_start((src),(bl),(type),100*(rate),(val1),0,0,0,(tick),0)) +#define sc_start2(src, bl, type, rate, val1, val2, tick) (status->change_start((src),(bl),(type),100*(rate),(val1),(val2),0,0,(tick),0)) +#define sc_start4(src, bl, type, rate, val1, val2, val3, val4, tick) (status->change_start((src),(bl),(type),100*(rate),(val1),(val2),(val3),(val4),(tick),0)) -#define status_change_end(bl,type,tid) status->change_end_(bl,type,tid,__FILE__,__LINE__) +#define status_change_end(bl,type,tid) (status->change_end_((bl),(type),(tid),__FILE__,__LINE__)) -#define status_calc_bl(bl, flag) status->calc_bl_(bl, (enum scb_flag)(flag), false) -#define status_calc_mob(md, first) status->calc_bl_(&(md)->bl, SCB_ALL, first) -#define status_calc_pet(pd, first) status->calc_bl_(&(pd)->bl, SCB_ALL, first) -#define status_calc_pc(sd, first) status->calc_bl_(&(sd)->bl, SCB_ALL, first) -#define status_calc_homunculus(hd, first) status->calc_bl_(&(hd)->bl, SCB_ALL, first) -#define status_calc_mercenary(md, first) status->calc_bl_(&(md)->bl, SCB_ALL, first) -#define status_calc_elemental(ed, first) status->calc_bl_(&(ed)->bl, SCB_ALL, first) -#define status_calc_npc(nd, first) status->calc_bl_(&(nd)->bl, SCB_ALL, first) +#define status_calc_bl(bl, flag) (status->calc_bl_((bl), (enum scb_flag)(flag), SCO_NONE)) +#define status_calc_mob(md, opt) (status->calc_bl_(&(md)->bl, SCB_ALL, (opt))) +#define status_calc_pet(pd, opt) (status->calc_bl_(&(pd)->bl, SCB_ALL, (opt))) +#define status_calc_pc(sd, opt) (status->calc_bl_(&(sd)->bl, SCB_ALL, (opt))) +#define status_calc_homunculus(hd, opt) (status->calc_bl_(&(hd)->bl, SCB_ALL, (opt))) +#define status_calc_mercenary(md, opt) (status->calc_bl_(&(md)->bl, SCB_ALL, (opt))) +#define status_calc_elemental(ed, opt) (status->calc_bl_(&(ed)->bl, SCB_ALL, (opt))) +#define status_calc_npc(nd, opt) (status->calc_bl_(&(nd)->bl, SCB_ALL, (opt))) // bonus values and upgrade chances for refining equipment struct s_refine_info { @@ -1826,9 +1893,10 @@ struct status_interface { sc_conf_type sc_conf[SC_MAX]; struct eri *data_ers; //For sc_data entries struct status_data dummy; - unsigned int natural_heal_prev_tick,natural_heal_diff_tick; + int64 natural_heal_prev_tick; + unsigned int natural_heal_diff_tick; /* */ - int (*init) (void); + int (*init) (bool minimal); void (*final) (void); /* funcs */ int (*get_refine_chance) (enum refine_type wlv, int refine); @@ -1847,6 +1915,7 @@ struct status_interface { int (*set_sp) (struct block_list *bl, unsigned int sp, int flag); int (*heal) (struct block_list *bl,int64 hp,int64 sp, int flag); int (*revive) (struct block_list *bl, unsigned char per_hp, unsigned char per_sp); + int (*fixed_revive) (struct block_list *bl, unsigned int per_hp, unsigned int per_sp); struct regen_data * (*get_regen_data) (struct block_list *bl); struct status_data * (*get_status_data) (struct block_list *bl); struct status_data * (*get_base_status) (struct block_list *bl); @@ -1867,22 +1936,22 @@ struct status_interface { struct status_change * (*get_sc) (struct block_list *bl); int (*isdead) (struct block_list *bl); int (*isimmune) (struct block_list *bl); - int (*get_sc_def) (struct block_list *bl, enum sc_type type, int rate, int tick, int flag); - int (*change_start) (struct block_list* bl,enum sc_type type,int rate,int val1,int val2,int val3,int val4,int tick,int flag); + int (*get_sc_def) (struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int tick, int flag); + int (*change_start) (struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int val1, int val2, int val3, int val4, int tick, int flag); int (*change_end_) (struct block_list* bl, enum sc_type type, int tid, const char* file, int line); - int (*kaahi_heal_timer) (int tid, unsigned int tick, int id, intptr_t data); - int (*change_timer) (int tid, unsigned int tick, int id, intptr_t data); + int (*kaahi_heal_timer) (int tid, int64 tick, int id, intptr_t data); + int (*change_timer) (int tid, int64 tick, int id, intptr_t data); int (*change_timer_sub) (struct block_list* bl, va_list ap); int (*change_clear) (struct block_list* bl, int type); int (*change_clear_buffs) (struct block_list* bl, int type); - void (*calc_bl_) (struct block_list *bl, enum scb_flag flag, bool first); - int (*calc_mob_) (struct mob_data* md, bool first); - int (*calc_pet_) (struct pet_data* pd, bool first); - int (*calc_pc_) (struct map_session_data* sd, bool first); - int (*calc_homunculus_) (struct homun_data *hd, bool first); - int (*calc_mercenary_) (struct mercenary_data *md, bool first); - int (*calc_elemental_) (struct elemental_data *ed, bool first); - void (*calc_misc) (struct block_list *bl, struct status_data *status, int level); + void (*calc_bl_) (struct block_list *bl, enum scb_flag flag, enum e_status_calc_opt opt); + int (*calc_mob_) (struct mob_data* md, enum e_status_calc_opt opt); + int (*calc_pet_) (struct pet_data* pd, enum e_status_calc_opt opt); + int (*calc_pc_) (struct map_session_data* sd, enum e_status_calc_opt opt); + int (*calc_homunculus_) (struct homun_data *hd, enum e_status_calc_opt opt); + int (*calc_mercenary_) (struct mercenary_data *md, enum e_status_calc_opt opt); + int (*calc_elemental_) (struct elemental_data *ed, enum e_status_calc_opt opt); + void (*calc_misc) (struct block_list *bl, struct status_data *st, int level); void (*calc_regen) (struct block_list *bl, struct status_data *st, struct regen_data *regen); void (*calc_regen_rate) (struct block_list *bl, struct regen_data *regen, struct status_change *sc); int (*check_skilluse) (struct block_list *src, struct block_list *target, uint16 skill_id, int flag); // [Skotlex] @@ -1907,7 +1976,7 @@ struct status_interface { void (*calc_sigma) (void); unsigned int (*base_pc_maxhp) (struct map_session_data *sd, struct status_data *st); unsigned int (*base_pc_maxsp) (struct map_session_data *sd, struct status_data *st); - int (*calc_npc_) (struct npc_data *nd, bool first); + int (*calc_npc_) (struct npc_data *nd, enum e_status_calc_opt opt); unsigned short (*calc_str) (struct block_list *bl, struct status_change *sc, int str); unsigned short (*calc_agi) (struct block_list *bl, struct status_change *sc, int agi); unsigned short (*calc_vit) (struct block_list *bl, struct status_change *sc, int vit); @@ -1935,7 +2004,7 @@ struct status_interface { void (*display_add) (struct map_session_data *sd, enum sc_type type, int dval1, int dval2, int dval3); void (*display_remove) (struct map_session_data *sd, enum sc_type type); int (*natural_heal) (struct block_list *bl, va_list args); - int (*natural_heal_timer) (int tid, unsigned int tick, int id, intptr_t data); + int (*natural_heal_timer) (int tid, int64 tick, int id, intptr_t data); bool (*readdb_job1) (char *fields[], int columns, int current); bool (*readdb_job2) (char *fields[], int columns, int current); bool (*readdb_sizefix) (char *fields[], int columns, int current); @@ -1947,4 +2016,4 @@ struct status_interface *status; void status_defaults(void); -#endif /* _STATUS_H_ */ +#endif /* _MAP_STATUS_H_ */ diff --git a/src/map/storage.c b/src/map/storage.c index cc1100d28..e65ed7b80 100644 --- a/src/map/storage.c +++ b/src/map/storage.c @@ -85,7 +85,7 @@ int storage_storageopen(struct map_session_data *sd) if(sd->state.storage_flag) return 1; //Already open? - if( !pc->can_give_items(sd) ) + if( !pc_can_give_items(sd) ) { //check is this GM level is allowed to put items to storage clif->message(sd->fd, msg_txt(246)); return 1; @@ -107,7 +107,8 @@ int compare_item(struct item *a, struct item *b) a->identify == b->identify && a->refine == b->refine && a->attribute == b->attribute && - a->expire_time == b->expire_time ) + a->expire_time == b->expire_time && + a->bound == b->bound ) { int i; for (i = 0; i < MAX_SLOTS && (a->card[i] == b->card[i]); i++); @@ -134,12 +135,17 @@ int storage_additem(struct map_session_data* sd, struct item* item_data, int amo return 1; } - if( !itemdb_canstore(item_data, pc->get_group_level(sd)) ) + if( !itemdb_canstore(item_data, pc_get_group_level(sd)) ) { //Check if item is storable. [Skotlex] clif->message (sd->fd, msg_txt(264)); return 1; } + if( item_data->bound > IBT_ACCOUNT && !pc_can_give_bound_items(sd) ) { + clif->message(sd->fd, msg_txt(294)); + return 1; + } + if( itemdb->isstackable2(data) ) {//Stackable for( i = 0; i < MAX_STORAGE; i++ ) @@ -381,7 +387,7 @@ int storage_guild_storageopen(struct map_session_data* sd) if(sd->state.storage_flag) return 1; //Can't open both storages at a time. - if( !pc->can_give_items(sd) ) { //check is this GM level can open guild storage and store items [Lupus] + if( !pc_can_give_items(sd) ) { //check is this GM level can open guild storage and store items [Lupus] clif->message(sd->fd, msg_txt(246)); return 1; } @@ -429,12 +435,17 @@ int guild_storage_additem(struct map_session_data* sd, struct guild_storage* sto return 1; } - if( !itemdb_canguildstore(item_data, pc->get_group_level(sd)) || item_data->expire_time ) - { //Check if item is storable. [Skotlex] + if( !itemdb_canguildstore(item_data, pc_get_group_level(sd)) || item_data->expire_time ) + { //Check if item is storable. [Skotlex] clif->message (sd->fd, msg_txt(264)); return 1; } + if( item_data->bound && item_data->bound != IBT_GUILD && !pc_can_give_bound_items(sd) ) { + clif->message(sd->fd, msg_txt(294)); + return 1; + } + if(itemdb->isstackable2(data)){ //Stackable for(i=0;i<MAX_GUILD_STORAGE;i++){ if(compare_item(&stor->items[i], item_data)) { @@ -520,6 +531,8 @@ int storage_guild_storageadd(struct map_session_data* sd, int index, int amount) if(gstorage->additem(sd,stor,&sd->status.inventory[index],amount)==0) pc->delitem(sd,index,amount,0,4,LOG_TYPE_GSTORAGE); + else + clif->dropitem(sd, index,0); return 1; } @@ -717,7 +730,9 @@ int storage_guild_storage_quit(struct map_session_data* sd, int flag) { return 0; } -void do_init_gstorage(void) { +void do_init_gstorage(bool minimal) { + if (minimal) + return; gstorage->db = idb_alloc(DB_OPT_RELEASE_DATA); } void do_final_gstorage(void) { diff --git a/src/map/storage.h b/src/map/storage.h index 9258e0265..8f9f904f6 100644 --- a/src/map/storage.h +++ b/src/map/storage.h @@ -2,8 +2,8 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _STORAGE_H_ -#define _STORAGE_H_ +#ifndef _MAP_STORAGE_H_ +#define _MAP_STORAGE_H_ struct storage_data; struct guild_storage; @@ -36,7 +36,7 @@ struct guild_storage_interface { struct guild_storage *(*id2storage) (int guild_id); struct guild_storage *(*id2storage2) (int guild_id); /* */ - void (*init) (void); + void (*init) (bool minimal); void (*final) (void); /* */ int (*delete) (int guild_id); @@ -59,4 +59,4 @@ struct guild_storage_interface *gstorage; void storage_defaults(void); void gstorage_defaults(void); -#endif /* _STORAGE_H_ */ +#endif /* _MAP_STORAGE_H_ */ diff --git a/src/map/trade.c b/src/map/trade.c index 8dd30371b..44b669ebd 100644 --- a/src/map/trade.c +++ b/src/map/trade.c @@ -69,7 +69,7 @@ void trade_traderequest(struct map_session_data *sd, struct map_session_data *ta return; } - if (!pc->can_give_items(sd) || !pc->can_give_items(target_sd)) //check if both GMs are allowed to trade + if (!pc_can_give_items(sd) || !pc_can_give_items(target_sd)) //check if both GMs are allowed to trade { clif->message(sd->fd, msg_txt(246)); clif->tradestart(sd, 2); // GM is not allowed to trade @@ -178,7 +178,7 @@ int impossible_trade_check(struct map_session_data *sd) nullpo_retr(1, sd); if(sd->deal.zeny > sd->status.zeny) { - pc_setglobalreg(sd,"ZENY_HACKER",1); + pc_setglobalreg(sd,script->add_str("ZENY_HACKER"),1); return -1; } @@ -335,7 +335,7 @@ void trade_tradeadditem(struct map_session_data *sd, short index, short amount) if( amount == 0 ) { //Why do this.. ~.~ just send an ack, the item won't display on the trade window. - clif->tradeitemok(sd, index, 0); + clif->tradeitemok(sd, index, TIO_SUCCESS); return; } @@ -348,35 +348,44 @@ void trade_tradeadditem(struct map_session_data *sd, short index, short amount) return; item = &sd->status.inventory[index]; - src_lv = pc->get_group_level(sd); - dst_lv = pc->get_group_level(target_sd); + src_lv = pc_get_group_level(sd); + dst_lv = pc_get_group_level(target_sd); if( !itemdb_cantrade(item, src_lv, dst_lv) && //Can't trade (pc->get_partner(sd) != target_sd || !itemdb_canpartnertrade(item, src_lv, dst_lv)) ) //Can't partner-trade { clif->message (sd->fd, msg_txt(260)); - clif->tradeitemok(sd, index+2, 1); + clif->tradeitemok(sd, index+2, TIO_INDROCKS); return; } if( item->expire_time ) { // Rental System clif->message (sd->fd, msg_txt(260)); - clif->tradeitemok(sd, index+2, 1); + clif->tradeitemok(sd, index+2, TIO_INDROCKS); return; } + if( item->bound && + !( item->bound == IBT_GUILD && sd->status.guild_id == target_sd->status.guild_id ) && + !( item->bound == IBT_PARTY && sd->status.party_id == target_sd->status.party_id ) + && !pc_can_give_bound_items(sd) ) { + clif->message(sd->fd, msg_txt(293)); + clif->tradeitemok(sd, index+2, TIO_INDROCKS); + return; + } + //Locate a trade position ARR_FIND( 0, 10, trade_i, sd->deal.item[trade_i].index == index || sd->deal.item[trade_i].amount == 0 ); if( trade_i == 10 ) //No space left { - clif->tradeitemok(sd, index+2, 1); + clif->tradeitemok(sd, index+2, TIO_OVERWEIGHT); return; } trade_weight = sd->inventory_data[index]->weight * amount; if( target_sd->weight + sd->deal.weight + trade_weight > target_sd->max_weight ) { //fail to add item -- the player was over weighted. - clif->tradeitemok(sd, index+2, 1); + clif->tradeitemok(sd, index+2, TIO_OVERWEIGHT); return; } @@ -396,7 +405,7 @@ void trade_tradeadditem(struct map_session_data *sd, short index, short amount) } sd->deal.weight += trade_weight; - clif->tradeitemok(sd, index+2, 0); // Return the index as it was received + clif->tradeitemok(sd, index+2, TIO_SUCCESS); // Return the index as it was received clif->tradeadditem(sd, target_sd, index+2, amount); } @@ -440,7 +449,7 @@ void trade_tradeok(struct map_session_data *sd) { return; } sd->state.deal_locked = 1; - clif->tradeitemok(sd, 0, 0); + clif->tradeitemok(sd, 0, TIO_SUCCESS); clif->tradedeal_lock(sd, 0); clif->tradedeal_lock(target_sd, 1); } diff --git a/src/map/trade.h b/src/map/trade.h index d0b900504..f2c0d4622 100644 --- a/src/map/trade.h +++ b/src/map/trade.h @@ -2,10 +2,11 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _TRADE_H_ -#define _TRADE_H_ +#ifndef _MAP_TRADE_H_ +#define _MAP_TRADE_H_ //Max distance from traders to enable a trade to take place. +//TODO: battle_config candidate? #define TRADE_DISTANCE 2 struct map_session_data; @@ -26,4 +27,4 @@ struct trade_interface *trade; void trade_defaults(void); -#endif /* _TRADE_H_ */ +#endif /* _MAP_TRADE_H_ */ diff --git a/src/map/unit.c b/src/map/unit.c index b195d3c91..47cf07ef6 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -82,9 +82,6 @@ struct unit_data* unit_bl2ud2(struct block_list *bl) { return unit->bl2ud(bl); } -int unit_attack_timer(int tid, unsigned int tick, int id, intptr_t data); -int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data); - int unit_walktoxy_sub(struct block_list *bl) { int i; @@ -137,7 +134,7 @@ int unit_walktoxy_sub(struct block_list *bl) return 1; } -int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data) { +int unit_walktoxy_timer(int tid, int64 tick, int id, intptr_t data) { int i; int x,y,dx,dy; uint8 dir; @@ -207,23 +204,28 @@ int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data) { } else sd->areanpc_id=0; - if( sd->md && !check_distance_bl(&sd->bl, &sd->md->bl, MAX_MER_DISTANCE) ) - { - // mercenary should be warped after being 3 seconds too far from the master [greenbox] - if (sd->md->masterteleport_timer == 0) - { - sd->md->masterteleport_timer = timer->gettick(); - } - else if (DIFF_TICK(timer->gettick(), sd->md->masterteleport_timer) > 3000) - { + if( sd->md ) { // mercenary should be warped after being 3 seconds too far from the master [greenbox] + if( !check_distance_bl(&sd->bl, &sd->md->bl, MAX_MER_DISTANCE) ) { + if (sd->md->masterteleport_timer == 0) + sd->md->masterteleport_timer = timer->gettick(); + else if (DIFF_TICK(timer->gettick(), sd->md->masterteleport_timer) > 3000) { + sd->md->masterteleport_timer = 0; + unit->warp( &sd->md->bl, sd->bl.m, sd->bl.x, sd->bl.y, CLR_TELEPORT ); + } + } else // reset the tick, he is not far anymore sd->md->masterteleport_timer = 0; - unit->warp( &sd->md->bl, sd->bl.m, sd->bl.x, sd->bl.y, CLR_TELEPORT ); - } + } - else if( sd->md ) - { - // reset the tick, he is not far anymore - sd->md->masterteleport_timer = 0; + if( sd->hd ) { + if( homun_alive(sd->hd) && !check_distance_bl(&sd->bl, &sd->hd->bl, MAX_MER_DISTANCE) ) { + if (sd->hd->masterteleport_timer == 0) + sd->hd->masterteleport_timer = timer->gettick(); + else if (DIFF_TICK(timer->gettick(), sd->hd->masterteleport_timer) > 3000) { + sd->hd->masterteleport_timer = 0; + unit->warp( &sd->hd->bl, sd->bl.m, sd->bl.x, sd->bl.y, CLR_TELEPORT ); + } + } else + sd->hd->masterteleport_timer = 0; } } else if (md) { if( map->getcell(bl->m,x,y,CELL_CHKNPC) ) { @@ -322,7 +324,7 @@ int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data) { return 0; } -int unit_delay_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data) { +int unit_delay_walktoxy_timer(int tid, int64 tick, int id, intptr_t data) { struct block_list *bl = map->id2bl(id); if (!bl || bl->prev == NULL) @@ -375,7 +377,7 @@ int unit_walktoxy( struct block_list *bl, short x, short y, int flag) unit->set_target(ud, 0); sc = status->get_sc(bl); - if (sc && sc->data[SC_CONFUSION]) //Randomize the target position + if (sc && (sc->data[SC_CONFUSION] || sc->data[SC__CHAOS])) //Randomize the target position map->random_dir(bl, &ud->to_x, &ud->to_y); if(ud->walktimer != INVALID_TIMER) { @@ -402,7 +404,7 @@ static inline void set_mobstate(struct block_list* bl, int flag) md->state.skillstate = md->state.aggressive ? MSS_FOLLOW : MSS_RUSH; } -int unit_walktobl_sub(int tid, unsigned int tick, int id, intptr_t data) { +int unit_walktobl_sub(int tid, int64 tick, int id, intptr_t data) { struct block_list *bl = map->id2bl(id); struct unit_data *ud = bl?unit->bl2ud(bl):NULL; @@ -447,7 +449,7 @@ int unit_walktobl(struct block_list *bl, struct block_list *tbl, int range, int unit->set_target(ud, 0); sc = status->get_sc(bl); - if (sc && sc->data[SC_CONFUSION]) //Randomize the target position + if (sc && (sc->data[SC_CONFUSION] || sc->data[SC__CHAOS])) //Randomize the target position map->random_dir(bl, &ud->to_x, &ud->to_y); if(ud->walktimer != INVALID_TIMER) { @@ -668,15 +670,15 @@ int unit_movepos(struct block_list *bl, short dst_x, short dst_y, int easy, bool if( sd->status.pet_id > 0 && sd->pd && sd->pd->pet.intimate > 0 ) { // Check if pet needs to be teleported. [Skotlex] int flag = 0; - struct block_list* bl = &sd->pd->bl; - if( !checkpath && !path->search(NULL,bl->m,bl->x,bl->y,dst_x,dst_y,0,CELL_CHKNOPASS) ) + struct block_list* pbl = &sd->pd->bl; + if( !checkpath && !path->search(NULL,pbl->m,pbl->x,pbl->y,dst_x,dst_y,0,CELL_CHKNOPASS) ) flag = 1; - else if (!check_distance_bl(&sd->bl, bl, AREA_SIZE)) //Too far, teleport. + else if (!check_distance_bl(&sd->bl, pbl, AREA_SIZE)) //Too far, teleport. flag = 2; if( flag ) { - unit->movepos(bl,sd->bl.x,sd->bl.y, 0, 0); - clif->slide(bl,bl->x,bl->y); + unit->movepos(pbl,sd->bl.x,sd->bl.y, 0, 0); + clif->slide(pbl,pbl->x,pbl->y); } } } @@ -718,6 +720,8 @@ int unit_blown(struct block_list* bl, int dx, int dy, int count, int flag) struct skill_unit* su = NULL; int nx, ny, result; + nullpo_ret(bl); + sd = BL_CAST(BL_PC, bl); su = BL_CAST(BL_SKILL, bl); @@ -854,7 +858,7 @@ int unit_stop_walking(struct block_list *bl,int type) { struct unit_data *ud; const struct TimerData* td; - unsigned int tick; + int64 tick; nullpo_ret(bl); ud = unit->bl2ud(bl); @@ -964,7 +968,7 @@ int unit_can_move(struct block_list *bl) { || sc->data[SC_CURSEDCIRCLE_ATKER] || sc->data[SC_CURSEDCIRCLE_TARGET] || (sc->data[SC_COLD] && bl->type != BL_MOB) - || sc->data[SC_NETHERWORLD] + || sc->data[SC_DEEP_SLEEP] || (sc->data[SC_CAMOUFLAGE] && sc->data[SC_CAMOUFLAGE]->val1 < 3 && !(sc->data[SC_CAMOUFLAGE]->val3&1)) || sc->data[SC_MEIKYOUSISUI] || sc->data[SC_KG_KAGEHUMI] @@ -1001,17 +1005,17 @@ int unit_can_move(struct block_list *bl) { * Resume running after a walk delay *------------------------------------------*/ -int unit_resume_running(int tid, unsigned int tick, int id, intptr_t data) { +int unit_resume_running(int tid, int64 tick, int id, intptr_t data) { struct unit_data *ud = (struct unit_data *)data; TBL_PC * sd = map->id2sd(id); if(sd && pc_isridingwug(sd)) clif->skill_nodamage(ud->bl,ud->bl,RA_WUGDASH,ud->skill_lv, - sc_start4(ud->bl,status->skill2sc(RA_WUGDASH),100,ud->skill_lv,unit->getdir(ud->bl),0,0,1)); + sc_start4(ud->bl,ud->bl,status->skill2sc(RA_WUGDASH),100,ud->skill_lv,unit->getdir(ud->bl),0,0,1)); else clif->skill_nodamage(ud->bl,ud->bl,TK_RUN,ud->skill_lv, - sc_start4(ud->bl,status->skill2sc(TK_RUN),100,ud->skill_lv,unit->getdir(ud->bl),0,0,0)); + sc_start4(ud->bl,ud->bl,status->skill2sc(TK_RUN),100,ud->skill_lv,unit->getdir(ud->bl),0,0,0)); if (sd) clif->walkok(sd); @@ -1025,8 +1029,7 @@ int unit_resume_running(int tid, unsigned int tick, int id, intptr_t data) { * if type is 0, this is a damage induced delay: if previous delay is active, do not change it. * if type is 1, this is a skill induced delay: walk-delay may only be increased, not decreased. *------------------------------------------*/ -int unit_set_walkdelay(struct block_list *bl, unsigned int tick, int delay, int type) -{ +int unit_set_walkdelay(struct block_list *bl, int64 tick, int delay, int type) { struct unit_data *ud = unit->bl2ud(bl); if (delay <= 0 || !ud) return 0; @@ -1073,7 +1076,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui struct status_change *sc; struct map_session_data *sd = NULL; struct block_list * target = NULL; - unsigned int tick = timer->gettick(); + int64 tick = timer->gettick(); int temp = 0, range; nullpo_ret(src); @@ -1342,6 +1345,19 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui casttime = 0; } + if( sc ) { + /** + * why the if else chain: these 3 status do not stack, so its efficient that way. + **/ + if( sc->data[SC_CLOAKING] && !(sc->data[SC_CLOAKING]->val4&4) && skill_id != AS_CLOAKING ) { + status_change_end(src, SC_CLOAKING, INVALID_TIMER); + if (!src->prev) return 0; //Warped away! + } else if( sc->data[SC_CLOAKINGEXCEED] && !(sc->data[SC_CLOAKINGEXCEED]->val4&4) && skill_id != GC_CLOAKINGEXCEED ) { + status_change_end(src,SC_CLOAKINGEXCEED, INVALID_TIMER); + if (!src->prev) return 0; + } + } + if(!ud->state.running) //need TK_RUN or WUGDASH handler to be done before that, see bugreport:6026 unit->stop_walking(src,1);// eventhough this is not how official works but this will do the trick. bugreport:6829 @@ -1398,20 +1414,6 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui ud->skill_id = skill_id; ud->skill_lv = skill_lv; - if( sc ) { - /** - * why the if else chain: these 3 status do not stack, so its efficient that way. - **/ - if( sc->data[SC_CLOAKING] && !(sc->data[SC_CLOAKING]->val4&4) && skill_id != AS_CLOAKING ) { - status_change_end(src, SC_CLOAKING, INVALID_TIMER); - if (!src->prev) return 0; //Warped away! - } else if( sc->data[SC_CLOAKINGEXCEED] && !(sc->data[SC_CLOAKINGEXCEED]->val4&4) && skill_id != GC_CLOAKINGEXCEED ) { - status_change_end(src,SC_CLOAKINGEXCEED, INVALID_TIMER); - if (!src->prev) return 0; - } - } - - if( casttime > 0 ) { ud->skilltimer = timer->add( tick+casttime, skill->castend_id, src->id, 0 ); if( sd && (pc->checkskill(sd,SA_FREECAST) > 0 || skill_id == LG_EXEEDBREAK) ) @@ -1437,7 +1439,7 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui struct unit_data *ud = NULL; struct status_change *sc; struct block_list bl; - unsigned int tick = timer->gettick(); + int64 tick = timer->gettick(); int range; nullpo_ret(src); @@ -1468,10 +1470,6 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); return 0; } - if( (skill_id >= SC_MANHOLE && skill_id <= SC_FEINTBOMB) && map->getcell(src->m, skill_x, skill_y, CELL_CHKMAELSTROM) ) { - clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); - return 0; - } } if (!status->check_skilluse(src, NULL, skill_id, 0)) @@ -1795,8 +1793,7 @@ int unit_calc_pos(struct block_list *bl, int tx, int ty, uint8 dir) /*========================================== * Continuous Attack (function timer) *------------------------------------------*/ -int unit_attack_timer_sub(struct block_list* src, int tid, unsigned int tick) -{ +int unit_attack_timer_sub(struct block_list* src, int tid, int64 tick) { struct block_list *target; struct unit_data *ud; struct status_data *sstatus; @@ -1915,15 +1912,15 @@ int unit_attack_timer_sub(struct block_list* src, int tid, unsigned int tick) } if(ud->state.attack_continue) { - if( src->type == BL_PC ) - ((TBL_PC*)src)->idletime = last_tick; + if( src->type == BL_PC && battle_config.idletime_criteria & BCIDLE_ATTACK ) + ((TBL_PC*)src)->idletime = sockt->last_tick; ud->attacktimer = timer->add(ud->attackabletime,unit->attack_timer,src->id,0); } return 1; } -int unit_attack_timer(int tid, unsigned int tick, int id, intptr_t data) { +int unit_attack_timer(int tid, int64 tick, int id, intptr_t data) { struct block_list *bl; bl = map->id2bl(id); if(bl && unit->attack_timer_sub(bl, tid, tick) == 0) @@ -1940,7 +1937,7 @@ int unit_skillcastcancel(struct block_list *bl,int type) { struct map_session_data *sd = NULL; struct unit_data *ud = unit->bl2ud( bl); - unsigned int tick=timer->gettick(); + int64 tick = timer->gettick(); int ret=0, skill_id; nullpo_ret(bl); @@ -1955,7 +1952,7 @@ int unit_skillcastcancel(struct block_list *bl,int type) return 0; if (sd && (sd->special_state.no_castcancel2 || - ((sd->sc.data[SC_UNLIMITED_HUMMING_VOICE] || sd->special_state.no_castcancel) && !map_flag_gvg(bl->m) && !map->list[bl->m].flag.battleground))) //fixed flags being read the wrong way around [blackhole89] + ( sd->special_state.no_castcancel && !map_flag_gvg(bl->m) && !map->list[bl->m].flag.battleground))) //fixed flags being read the wrong way around [blackhole89] return 0; } @@ -1971,7 +1968,7 @@ int unit_skillcastcancel(struct block_list *bl,int type) else ret = timer->delete( ud->skilltimer, skill->castend_id ); if( ret < 0 ) - ShowError("delete timer error : skill_id : %d\n",ret); + ShowError("delete timer error %d : skill %d (%s)\n",ret,skill_id,skill->get_name(skill_id)); ud->skilltimer = INVALID_TIMER; @@ -2021,14 +2018,13 @@ int unit_counttargeted(struct block_list* bl) /*========================================== * *------------------------------------------*/ -int unit_fixdamage(struct block_list *src,struct block_list *target,unsigned int tick,int sdelay,int ddelay,int64 damage,int div,int type,int64 damage2) -{ +int unit_fixdamage(struct block_list *src, struct block_list *target, int sdelay, int ddelay, int64 damage, short div, unsigned char type, int64 damage2) { nullpo_ret(target); if(damage+damage2 <= 0) return 0; - return status_fix_damage(src,target,damage+damage2,clif->damage(target,target,tick,sdelay,ddelay,damage,div,type,damage2)); + return status_fix_damage(src,target,damage+damage2,clif->damage(target,target,sdelay,ddelay,damage,div,type,damage2)); } /*========================================== @@ -2106,6 +2102,11 @@ int unit_remove_map(struct block_list *bl, clr_type clrtype, const char* file, i status_change_end(bl, SC_STOP, INVALID_TIMER); status_change_end(bl, SC_WUGDASH, INVALID_TIMER); status_change_end(bl, SC_CAMOUFLAGE, INVALID_TIMER); + status_change_end(bl, SC_MAGNETICFIELD, INVALID_TIMER); + status_change_end(bl, SC_NEUTRALBARRIER_MASTER, INVALID_TIMER); + status_change_end(bl, SC_NEUTRALBARRIER, INVALID_TIMER); + status_change_end(bl, SC_STEALTHFIELD_MASTER, INVALID_TIMER); + status_change_end(bl, SC_STEALTHFIELD, INVALID_TIMER); status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER); status_change_end(bl, SC__MANHOLE, INVALID_TIMER); status_change_end(bl, SC_VACUUM_EXTREME, INVALID_TIMER); @@ -2200,6 +2201,10 @@ int unit_remove_map(struct block_list *bl, clr_type clrtype, const char* file, i instance->list[map->list[bl->m].instance_id].users--; instance->check_idle(map->list[bl->m].instance_id); } + if( sd->state.hpmeter_visible ) { + map->list[bl->m].hpmeter_visible--; + sd->state.hpmeter_visible = 0; + } sd->state.debug_remove_map = 1; // temporary state to track double remove_map's [FlavioJS] sd->debug_file = file; sd->debug_line = line; @@ -2233,7 +2238,6 @@ int unit_remove_map(struct block_list *bl, clr_type clrtype, const char* file, i } case BL_HOM: { struct homun_data *hd = (struct homun_data *)bl; - ud->canact_tick = ud->canmove_tick; //It appears HOM do reset the can-act tick. if( !hd->homunculus.intimacy && !(hd->master && !hd->master->state.active) ) { //If logging out, this is deleted on unit->free clif->emotion(bl, E_SOB); @@ -2350,29 +2354,16 @@ int unit_free(struct block_list *bl, clr_type clrtype) { for(i = 1; i < 5; i++) pc->del_charm(sd, sd->charm[i], i); - if( sd->reg ) { //Double logout already freed pointer fix... [Skotlex] - aFree(sd->reg); - sd->reg = NULL; - sd->reg_num = 0; - } - if( sd->regstr ) { - for( i = 0; i < sd->regstr_num; ++i ) - if( sd->regstr[i].data ) - aFree(sd->regstr[i].data); - aFree(sd->regstr); - sd->regstr = NULL; - sd->regstr_num = 0; - } if( sd->st && sd->st->state != RUN ) {// free attached scripts that are waiting script->free_state(sd->st); sd->st = NULL; sd->npc_id = 0; } - if( sd->combos.count ) { - aFree(sd->combos.bonus); - aFree(sd->combos.id); - sd->combos.count = 0; + if( sd->combos ) { + aFree(sd->combos); + sd->combos = NULL; } + sd->combo_count = 0; /* [Ind/Hercules] */ if( sd->sc_display_count ) { for(i = 0; i < sd->sc_display_count; i++) { @@ -2392,12 +2383,17 @@ int unit_free(struct block_list *bl, clr_type clrtype) { aFree(sd->queues); sd->queues = NULL; } + if( sd->quest_log != NULL ) { + aFree(sd->quest_log); + sd->quest_log = NULL; + sd->num_quests = sd->avail_quests = 0; + } for( k = 0; k < sd->hdatac; k++ ) { if( sd->hdata[k]->flag.free ) { aFree(sd->hdata[k]->data); - aFree(sd->hdata[k]); } + aFree(sd->hdata[k]); } if( sd->hdata ) aFree(sd->hdata); @@ -2576,7 +2572,10 @@ int unit_free(struct block_list *bl, clr_type clrtype) { return 0; } -int do_init_unit(void) { +int do_init_unit(bool minimal) { + if (minimal) + return 0; + timer->add_func_list(unit->attack_timer, "unit_attack_timer"); timer->add_func_list(unit->walktoxy_timer,"unit_walktoxy_timer"); timer->add_func_list(unit->walktobl_sub, "unit_walktobl_sub"); diff --git a/src/map/unit.h b/src/map/unit.h index be7b789d9..33fa4e052 100644 --- a/src/map/unit.h +++ b/src/map/unit.h @@ -1,8 +1,9 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena Dev Teams -#ifndef _UNIT_H_ -#define _UNIT_H_ +#ifndef _MAP_UNIT_H_ +#define _MAP_UNIT_H_ //#include "map.h" struct block_list; @@ -30,10 +31,10 @@ struct unit_data { int target_to; int attacktimer; int walktimer; - int chaserange; - unsigned int attackabletime; - unsigned int canact_tick; - unsigned int canmove_tick; + int chaserange; + int64 attackabletime; + int64 canact_tick; + int64 canmove_tick; uint8 dir; unsigned char walk_count; unsigned char target_count; @@ -72,17 +73,17 @@ extern const short dirx[8]; extern const short diry[8]; struct unit_interface { - int (*init) (void); + int (*init) (bool minimal); int (*final) (void); /* */ struct unit_data* (*bl2ud) (struct block_list *bl); struct unit_data* (*bl2ud2) (struct block_list *bl); - int (*attack_timer) (int tid, unsigned int tick, int id, intptr_t data); - int (*walktoxy_timer) (int tid, unsigned int tick, int id, intptr_t data); + int (*attack_timer) (int tid, int64 tick, int id, intptr_t data); + int (*walktoxy_timer) (int tid, int64 tick, int id, intptr_t data); int (*walktoxy_sub) (struct block_list *bl); - int (*delay_walktoxy_timer) (int tid, unsigned int tick, int id, intptr_t data); + int (*delay_walktoxy_timer) (int tid, int64 tick, int id, intptr_t data); int (*walktoxy) (struct block_list *bl, short x, short y, int flag); - int (*walktobl_sub) (int tid, unsigned int tick, int id, intptr_t data); + int (*walktobl_sub) (int tid, int64 tick, int id, intptr_t data); int (*walktobl) (struct block_list *bl, struct block_list *tbl, int range, int flag); int (*run) (struct block_list *bl); int (*wugdash) (struct block_list *bl, struct map_session_data *sd); @@ -96,8 +97,8 @@ struct unit_interface { int (*skilluse_id) (struct block_list *src, int target_id, uint16 skill_id, uint16 skill_lv); int (*is_walking) (struct block_list *bl); int (*can_move) (struct block_list *bl); - int (*resume_running) (int tid, unsigned int tick, int id, intptr_t data); - int (*set_walkdelay) (struct block_list *bl, unsigned int tick, int delay, int type); + int (*resume_running) (int tid, int64 tick, int id, intptr_t data); + int (*set_walkdelay) (struct block_list *bl, int64 tick, int delay, int type); int (*skilluse_id2) (struct block_list *src, int target_id, uint16 skill_id, uint16 skill_lv, int casttime, int castcancel); int (*skilluse_pos) (struct block_list *src, short skill_x, short skill_y, uint16 skill_id, uint16 skill_lv); int (*skilluse_pos2) (struct block_list *src, short skill_x, short skill_y, uint16 skill_id, uint16 skill_lv, int casttime, int castcancel); @@ -109,11 +110,11 @@ struct unit_interface { bool (*can_reach_pos) (struct block_list *bl, int x, int y, int easy); bool (*can_reach_bl) (struct block_list *bl, struct block_list *tbl, int range, int easy, short *x, short *y); int (*calc_pos) (struct block_list *bl, int tx, int ty, uint8 dir); - int (*attack_timer_sub) (struct block_list *src, int tid, unsigned int tick); + int (*attack_timer_sub) (struct block_list *src, int tid, int64 tick); int (*skillcastcancel) (struct block_list *bl, int type); void (*dataset) (struct block_list *bl); int (*counttargeted) (struct block_list *bl); - int (*fixdamage) (struct block_list *src, struct block_list *target, unsigned int tick, int sdelay, int ddelay, int64 damage, int div, int type, int64 damage2); + int (*fixdamage) (struct block_list *src, struct block_list *target, int sdelay, int ddelay, int64 damage, short div, unsigned char type, int64 damage2); int (*changeviewsize) (struct block_list *bl, short size); int (*remove_map) (struct block_list *bl, clr_type clrtype, const char *file, int line, const char *func); void (*remove_map_pc) (struct map_session_data *sd, clr_type clrtype); @@ -125,4 +126,4 @@ struct unit_interface *unit; void unit_defaults(void); -#endif /* _UNIT_H_ */ +#endif /* _MAP_UNIT_H_ */ diff --git a/src/map/vending.c b/src/map/vending.c index 7d6d02cfb..9462975b3 100644 --- a/src/map/vending.c +++ b/src/map/vending.c @@ -53,7 +53,7 @@ void vending_vendinglistreq(struct map_session_data* sd, unsigned int id) { if( !vsd->state.vending ) return; // not vending - if (!pc->can_give_items(sd) || !pc->can_give_items(vsd)) { //check if both GMs are allowed to trade + if (!pc_can_give_items(sd) || !pc_can_give_items(vsd)) { //check if both GMs are allowed to trade // GM is not allowed to trade clif->message(sd->fd, msg_txt(246)); return; @@ -179,7 +179,7 @@ void vending_purchasereq(struct map_session_data* sd, int aid, unsigned int uid, if( battle_config.buyer_name ) { char temp[256]; sprintf(temp, msg_txt(265), sd->status.name); - clif->disp_onlyself(vsd,temp,strlen(temp)); + clif_disp_onlyself(vsd,temp,strlen(temp)); } } @@ -212,7 +212,8 @@ void vending_purchasereq(struct map_session_data* sd, int aid, unsigned int uid, //Close Vending (this was automatically done by the client, we have to do it manually for autovenders) [Skotlex] vending->close(vsd); map->quit(vsd); //They have no reason to stay around anymore, do they? - } + } else + pc->autotrade_update(vsd,PAUC_REFRESH); } } @@ -257,7 +258,8 @@ void vending_openvending(struct map_session_data* sd, const char* message, const || !sd->status.cart[index].identify // unidentified item || sd->status.cart[index].attribute == 1 // broken item || sd->status.cart[index].expire_time // It should not be in the cart but just in case - || !itemdb_cantrade(&sd->status.cart[index], pc->get_group_level(sd), pc->get_group_level(sd)) ) // untradeable item + || (sd->status.cart[index].bound && !pc_can_give_bound_items(sd)) // can't trade bound items w/o permission + || !itemdb_cantrade(&sd->status.cart[index], pc_get_group_level(sd), pc_get_group_level(sd)) ) // untradeable item continue; sd->vending[i].index = index; @@ -360,7 +362,7 @@ void final(void) { db_destroy(vending->db); } -void init(void) { +void init(bool minimal) { vending->db = idb_alloc(DB_OPT_BASE); vending->next_id = 0; } diff --git a/src/map/vending.h b/src/map/vending.h index 968811ecd..b2ba22955 100644 --- a/src/map/vending.h +++ b/src/map/vending.h @@ -2,8 +2,8 @@ // See the LICENSE file // Portions Copyright (c) Athena Dev Teams -#ifndef _VENDING_H_ -#define _VENDING_H_ +#ifndef _MAP_VENDING_H_ +#define _MAP_VENDING_H_ #include "../common/cbasetypes.h" #include "../common/db.h" @@ -20,7 +20,7 @@ struct vending_interface { unsigned int next_id;/* next vender id */ DBMap *db; /* */ - void (*init) (void); + void (*init) (bool minimal); void (*final) (void); /* */ void (*close) (struct map_session_data* sd); @@ -35,4 +35,4 @@ struct vending_interface *vending; void vending_defaults(void); -#endif /* _VENDING_H_ */ +#endif /* _MAP_VENDING_H_ */ diff --git a/src/plugins/HPMHooking.c b/src/plugins/HPMHooking.c index 8b4f06ae0..e6e698383 100644 --- a/src/plugins/HPMHooking.c +++ b/src/plugins/HPMHooking.c @@ -46,6 +46,8 @@ #include "../map/mail.h" #include "../map/irc-bot.h" +#include "../common/HPMDataCheck.h" + HPExport struct hplugin_info pinfo = { "HPMHooking", // Plugin name SERVER_TYPE_MAP,// Which server types this plugin works with? @@ -53,8 +55,7 @@ HPExport struct hplugin_info pinfo = { HPM_VERSION, // HPM Version (don't change, macro is automatically updated) }; -#define HP_POP(x) #x , (void**)(&x) -#define HP_POP2(x) (void*)x +#define HP_POP(x,y) #x , (void**)(&x) , (void*)y , 0 DBMap *hp_db;/* hooking points db -- for quick lookup */ struct HookingPointData { @@ -150,7 +151,7 @@ void HPM_HP_final(void) { void HPM_HP_load(void) { #include "../plugins/HPMHooking/HPMHooking.HookingPoints.inc" - int i, len = ARRAYLENGTH(HookingPoints); + int i, len = ARRAYLENGTH(HookingPoints), idx = 0; memset(&HPMHooks,0,sizeof(struct HPMHooksCore)); @@ -163,6 +164,9 @@ void HPM_HP_load(void) { memcpy(hpd, &HookingPoints[i], sizeof(struct HookingPointData)); + hpd->idx = idx; + idx += 2; + strdb_put(hp_db, HookingPoints[i].name, hpd); HPMHooks.data.total++; diff --git a/src/plugins/HPMHooking/HPMHooking.GetSymbol.inc b/src/plugins/HPMHooking/HPMHooking.GetSymbol.inc index c3845675c..8482b9f80 100644 --- a/src/plugins/HPMHooking/HPMHooking.GetSymbol.inc +++ b/src/plugins/HPMHooking/HPMHooking.GetSymbol.inc @@ -30,6 +30,7 @@ if( !(mob = GET_SYMBOL("mob") ) ) return false; if( !(npc = GET_SYMBOL("npc") ) ) return false; if( !(party = GET_SYMBOL("party") ) ) return false; if( !(path = GET_SYMBOL("path") ) ) return false; +if( !(pcg = GET_SYMBOL("pc_groups") ) ) return false; if( !(pc = GET_SYMBOL("pc") ) ) return false; if( !(pet = GET_SYMBOL("pet") ) ) return false; if( !(quest = GET_SYMBOL("quest") ) ) return false; diff --git a/src/plugins/HPMHooking/HPMHooking.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking.HPMHooksCore.inc index ea5e2405f..5bc9f7da0 100644 --- a/src/plugins/HPMHooking/HPMHooking.HPMHooksCore.inc +++ b/src/plugins/HPMHooking/HPMHooking.HPMHooksCore.inc @@ -9,8 +9,8 @@ struct { struct HPMHookPoint *HP_atcommand_init_post; struct HPMHookPoint *HP_atcommand_final_pre; struct HPMHookPoint *HP_atcommand_final_post; - struct HPMHookPoint *HP_atcommand_parse_pre; - struct HPMHookPoint *HP_atcommand_parse_post; + struct HPMHookPoint *HP_atcommand_exec_pre; + struct HPMHookPoint *HP_atcommand_exec_post; struct HPMHookPoint *HP_atcommand_create_pre; struct HPMHookPoint *HP_atcommand_create_post; struct HPMHookPoint *HP_atcommand_can_use_pre; @@ -61,6 +61,10 @@ struct { struct HPMHookPoint *HP_atcommand_doload_post; struct HPMHookPoint *HP_atcommand_base_commands_pre; struct HPMHookPoint *HP_atcommand_base_commands_post; + struct HPMHookPoint *HP_atcommand_add_pre; + struct HPMHookPoint *HP_atcommand_add_post; + struct HPMHookPoint *HP_atcommand_msg_pre; + struct HPMHookPoint *HP_atcommand_msg_post; struct HPMHookPoint *HP_battle_init_pre; struct HPMHookPoint *HP_battle_init_post; struct HPMHookPoint *HP_battle_final_pre; @@ -81,8 +85,8 @@ struct { struct HPMHookPoint *HP_battle_delay_damage_post; struct HPMHookPoint *HP_battle_drain_pre; struct HPMHookPoint *HP_battle_drain_post; - struct HPMHookPoint *HP_battle_calc_return_damage_pre; - struct HPMHookPoint *HP_battle_calc_return_damage_post; + struct HPMHookPoint *HP_battle_reflect_damage_pre; + struct HPMHookPoint *HP_battle_reflect_damage_post; struct HPMHookPoint *HP_battle_attr_ratio_pre; struct HPMHookPoint *HP_battle_attr_ratio_post; struct HPMHookPoint *HP_battle_attr_fix_pre; @@ -93,6 +97,8 @@ struct { struct HPMHookPoint *HP_battle_calc_elefix_post; struct HPMHookPoint *HP_battle_calc_masteryfix_pre; struct HPMHookPoint *HP_battle_calc_masteryfix_post; + struct HPMHookPoint *HP_battle_calc_chorusbonus_pre; + struct HPMHookPoint *HP_battle_calc_chorusbonus_post; struct HPMHookPoint *HP_battle_calc_skillratio_pre; struct HPMHookPoint *HP_battle_calc_skillratio_post; struct HPMHookPoint *HP_battle_calc_sizefix_pre; @@ -257,10 +263,10 @@ struct { struct HPMHookPoint *HP_chat_trigger_event_post; struct HPMHookPoint *HP_chat_create_pre; struct HPMHookPoint *HP_chat_create_post; - struct HPMHookPoint *HP_chrif_final_pre; - struct HPMHookPoint *HP_chrif_final_post; struct HPMHookPoint *HP_chrif_init_pre; struct HPMHookPoint *HP_chrif_init_post; + struct HPMHookPoint *HP_chrif_final_pre; + struct HPMHookPoint *HP_chrif_final_post; struct HPMHookPoint *HP_chrif_setuserid_pre; struct HPMHookPoint *HP_chrif_setuserid_post; struct HPMHookPoint *HP_chrif_setpasswd_pre; @@ -309,8 +315,6 @@ struct { struct HPMHookPoint *HP_chrif_save_scdata_post; struct HPMHookPoint *HP_chrif_ragsrvinfo_pre; struct HPMHookPoint *HP_chrif_ragsrvinfo_post; - struct HPMHookPoint *HP_chrif_char_offline_pre; - struct HPMHookPoint *HP_chrif_char_offline_post; struct HPMHookPoint *HP_chrif_char_offline_nsd_pre; struct HPMHookPoint *HP_chrif_char_offline_nsd_post; struct HPMHookPoint *HP_chrif_char_reset_offline_pre; @@ -327,8 +331,8 @@ struct { struct HPMHookPoint *HP_chrif_removefriend_post; struct HPMHookPoint *HP_chrif_send_report_pre; struct HPMHookPoint *HP_chrif_send_report_post; - struct HPMHookPoint *HP_chrif_flush_fifo_pre; - struct HPMHookPoint *HP_chrif_flush_fifo_post; + struct HPMHookPoint *HP_chrif_flush_pre; + struct HPMHookPoint *HP_chrif_flush_post; struct HPMHookPoint *HP_chrif_skillid2idx_pre; struct HPMHookPoint *HP_chrif_skillid2idx_post; struct HPMHookPoint *HP_chrif_sd_to_auth_pre; @@ -367,8 +371,8 @@ struct { struct HPMHookPoint *HP_chrif_changedsex_post; struct HPMHookPoint *HP_chrif_divorceack_pre; struct HPMHookPoint *HP_chrif_divorceack_post; - struct HPMHookPoint *HP_chrif_accountban_pre; - struct HPMHookPoint *HP_chrif_accountban_post; + struct HPMHookPoint *HP_chrif_idbanned_pre; + struct HPMHookPoint *HP_chrif_idbanned_post; struct HPMHookPoint *HP_chrif_recvfamelist_pre; struct HPMHookPoint *HP_chrif_recvfamelist_post; struct HPMHookPoint *HP_chrif_load_scdata_pre; @@ -395,6 +399,10 @@ struct { struct HPMHookPoint *HP_chrif_on_disconnect_post; struct HPMHookPoint *HP_chrif_parse_pre; struct HPMHookPoint *HP_chrif_parse_post; + struct HPMHookPoint *HP_chrif_save_scdata_single_pre; + struct HPMHookPoint *HP_chrif_save_scdata_single_post; + struct HPMHookPoint *HP_chrif_del_scdata_single_pre; + struct HPMHookPoint *HP_chrif_del_scdata_single_post; struct HPMHookPoint *HP_clif_init_pre; struct HPMHookPoint *HP_clif_init_post; struct HPMHookPoint *HP_clif_final_pre; @@ -467,6 +475,8 @@ struct { struct HPMHookPoint *HP_clif_cashshop_load_post; struct HPMHookPoint *HP_clif_package_announce_pre; struct HPMHookPoint *HP_clif_package_announce_post; + struct HPMHookPoint *HP_clif_item_drop_announce_pre; + struct HPMHookPoint *HP_clif_item_drop_announce_post; struct HPMHookPoint *HP_clif_clearunit_single_pre; struct HPMHookPoint *HP_clif_clearunit_single_post; struct HPMHookPoint *HP_clif_clearunit_area_pre; @@ -493,8 +503,6 @@ struct { struct HPMHookPoint *HP_clif_refreshlook_post; struct HPMHookPoint *HP_clif_class_change_pre; struct HPMHookPoint *HP_clif_class_change_post; - struct HPMHookPoint *HP_clif_skill_setunit_pre; - struct HPMHookPoint *HP_clif_skill_setunit_post; struct HPMHookPoint *HP_clif_skill_delunit_pre; struct HPMHookPoint *HP_clif_skill_delunit_post; struct HPMHookPoint *HP_clif_skillunit_update_pre; @@ -521,6 +529,8 @@ struct { struct HPMHookPoint *HP_clif_clearchar_skillunit_post; struct HPMHookPoint *HP_clif_getareachar_pre; struct HPMHookPoint *HP_clif_getareachar_post; + struct HPMHookPoint *HP_clif_graffiti_entry_pre; + struct HPMHookPoint *HP_clif_graffiti_entry_post; struct HPMHookPoint *HP_clif_spawn_pre; struct HPMHookPoint *HP_clif_spawn_post; struct HPMHookPoint *HP_clif_changemap_pre; @@ -691,8 +701,6 @@ struct { struct HPMHookPoint *HP_clif_equiptickack_post; struct HPMHookPoint *HP_clif_viewequip_ack_pre; struct HPMHookPoint *HP_clif_viewequip_ack_post; - struct HPMHookPoint *HP_clif_viewequip_fail_pre; - struct HPMHookPoint *HP_clif_viewequip_fail_post; struct HPMHookPoint *HP_clif_equpcheckbox_pre; struct HPMHookPoint *HP_clif_equpcheckbox_post; struct HPMHookPoint *HP_clif_displayexp_pre; @@ -849,8 +857,6 @@ struct { struct HPMHookPoint *HP_clif_wis_message_post; struct HPMHookPoint *HP_clif_wis_end_pre; struct HPMHookPoint *HP_clif_wis_end_post; - struct HPMHookPoint *HP_clif_disp_onlyself_pre; - struct HPMHookPoint *HP_clif_disp_onlyself_post; struct HPMHookPoint *HP_clif_disp_message_pre; struct HPMHookPoint *HP_clif_disp_message_post; struct HPMHookPoint *HP_clif_broadcast_pre; @@ -885,6 +891,8 @@ struct { struct HPMHookPoint *HP_clif_wisall_post; struct HPMHookPoint *HP_clif_PMIgnoreList_pre; struct HPMHookPoint *HP_clif_PMIgnoreList_post; + struct HPMHookPoint *HP_clif_ShowScript_pre; + struct HPMHookPoint *HP_clif_ShowScript_post; struct HPMHookPoint *HP_clif_traderequest_pre; struct HPMHookPoint *HP_clif_traderequest_post; struct HPMHookPoint *HP_clif_tradestart_pre; @@ -1001,8 +1009,6 @@ struct { struct HPMHookPoint *HP_clif_guild_notice_post; struct HPMHookPoint *HP_clif_guild_message_pre; struct HPMHookPoint *HP_clif_guild_message_post; - struct HPMHookPoint *HP_clif_guild_skillup_pre; - struct HPMHookPoint *HP_clif_guild_skillup_post; struct HPMHookPoint *HP_clif_guild_reqalliance_pre; struct HPMHookPoint *HP_clif_guild_reqalliance_post; struct HPMHookPoint *HP_clif_guild_allianceack_pre; @@ -1271,6 +1277,22 @@ struct { struct HPMHookPoint *HP_clif_chsys_gjoin_post; struct HPMHookPoint *HP_clif_chsys_gleave_pre; struct HPMHookPoint *HP_clif_chsys_gleave_post; + struct HPMHookPoint *HP_clif_bank_deposit_pre; + struct HPMHookPoint *HP_clif_bank_deposit_post; + struct HPMHookPoint *HP_clif_bank_withdraw_pre; + struct HPMHookPoint *HP_clif_bank_withdraw_post; + struct HPMHookPoint *HP_clif_show_modifiers_pre; + struct HPMHookPoint *HP_clif_show_modifiers_post; + struct HPMHookPoint *HP_clif_notify_bounditem_pre; + struct HPMHookPoint *HP_clif_notify_bounditem_post; + struct HPMHookPoint *HP_clif_delay_damage_pre; + struct HPMHookPoint *HP_clif_delay_damage_post; + struct HPMHookPoint *HP_clif_delay_damage_sub_pre; + struct HPMHookPoint *HP_clif_delay_damage_sub_post; + struct HPMHookPoint *HP_clif_npc_market_open_pre; + struct HPMHookPoint *HP_clif_npc_market_open_post; + struct HPMHookPoint *HP_clif_npc_market_purchase_ack_pre; + struct HPMHookPoint *HP_clif_npc_market_purchase_ack_post; struct HPMHookPoint *HP_clif_pWantToConnection_pre; struct HPMHookPoint *HP_clif_pWantToConnection_post; struct HPMHookPoint *HP_clif_pLoadEndAck_pre; @@ -1549,6 +1571,8 @@ struct { struct HPMHookPoint *HP_clif_pGMReqAccountName_post; struct HPMHookPoint *HP_clif_pGMChangeMapType_pre; struct HPMHookPoint *HP_clif_pGMChangeMapType_post; + struct HPMHookPoint *HP_clif_pGMFullStrip_pre; + struct HPMHookPoint *HP_clif_pGMFullStrip_post; struct HPMHookPoint *HP_clif_pPMIgnore_pre; struct HPMHookPoint *HP_clif_pPMIgnore_post; struct HPMHookPoint *HP_clif_pPMIgnoreAll_pre; @@ -1699,6 +1723,22 @@ struct { struct HPMHookPoint *HP_clif_pPartyBookingRefuseVolunteer_post; struct HPMHookPoint *HP_clif_pPartyBookingCancelVolunteer_pre; struct HPMHookPoint *HP_clif_pPartyBookingCancelVolunteer_post; + struct HPMHookPoint *HP_clif_pBankDeposit_pre; + struct HPMHookPoint *HP_clif_pBankDeposit_post; + struct HPMHookPoint *HP_clif_pBankWithdraw_pre; + struct HPMHookPoint *HP_clif_pBankWithdraw_post; + struct HPMHookPoint *HP_clif_pBankCheck_pre; + struct HPMHookPoint *HP_clif_pBankCheck_post; + struct HPMHookPoint *HP_clif_pBankOpen_pre; + struct HPMHookPoint *HP_clif_pBankOpen_post; + struct HPMHookPoint *HP_clif_pBankClose_pre; + struct HPMHookPoint *HP_clif_pBankClose_post; + struct HPMHookPoint *HP_clif_pNPCShopClosed_pre; + struct HPMHookPoint *HP_clif_pNPCShopClosed_post; + struct HPMHookPoint *HP_clif_pNPCMarketClosed_pre; + struct HPMHookPoint *HP_clif_pNPCMarketClosed_post; + struct HPMHookPoint *HP_clif_pNPCMarketPurchase_pre; + struct HPMHookPoint *HP_clif_pNPCMarketPurchase_post; struct HPMHookPoint *HP_duel_create_pre; struct HPMHookPoint *HP_duel_create_post; struct HPMHookPoint *HP_duel_invite_pre; @@ -1917,6 +1957,8 @@ struct { struct HPMHookPoint *HP_guild_flags_clear_post; struct HPMHookPoint *HP_guild_aura_refresh_pre; struct HPMHookPoint *HP_guild_aura_refresh_post; + struct HPMHookPoint *HP_guild_retrieveitembound_pre; + struct HPMHookPoint *HP_guild_retrieveitembound_post; struct HPMHookPoint *HP_guild_payexp_timer_pre; struct HPMHookPoint *HP_guild_payexp_timer_post; struct HPMHookPoint *HP_guild_sd_check_pre; @@ -2081,6 +2123,8 @@ struct { struct HPMHookPoint *HP_instance_init_post; struct HPMHookPoint *HP_instance_final_pre; struct HPMHookPoint *HP_instance_final_post; + struct HPMHookPoint *HP_instance_reload_pre; + struct HPMHookPoint *HP_instance_reload_post; struct HPMHookPoint *HP_instance_create_pre; struct HPMHookPoint *HP_instance_create_post; struct HPMHookPoint *HP_instance_add_map_pre; @@ -2091,6 +2135,12 @@ struct { struct HPMHookPoint *HP_instance_map2imap_post; struct HPMHookPoint *HP_instance_mapid2imapid_pre; struct HPMHookPoint *HP_instance_mapid2imapid_post; + struct HPMHookPoint *HP_instance_mapname2imap_pre; + struct HPMHookPoint *HP_instance_mapname2imap_post; + struct HPMHookPoint *HP_instance_map_npcsub_pre; + struct HPMHookPoint *HP_instance_map_npcsub_post; + struct HPMHookPoint *HP_instance_init_npc_pre; + struct HPMHookPoint *HP_instance_init_npc_post; struct HPMHookPoint *HP_instance_destroy_pre; struct HPMHookPoint *HP_instance_destroy_post; struct HPMHookPoint *HP_instance_start_pre; @@ -2179,6 +2229,8 @@ struct { struct HPMHookPoint *HP_intif_guild_castle_dataload_post; struct HPMHookPoint *HP_intif_guild_castle_datasave_pre; struct HPMHookPoint *HP_intif_guild_castle_datasave_post; + struct HPMHookPoint *HP_intif_itembound_req_pre; + struct HPMHookPoint *HP_intif_itembound_req_post; struct HPMHookPoint *HP_intif_request_petdata_pre; struct HPMHookPoint *HP_intif_request_petdata_post; struct HPMHookPoint *HP_intif_save_petdata_pre; @@ -2335,6 +2387,8 @@ struct { struct HPMHookPoint *HP_intif_pAuctionMessage_post; struct HPMHookPoint *HP_intif_pAuctionBid_pre; struct HPMHookPoint *HP_intif_pAuctionBid_post; + struct HPMHookPoint *HP_intif_pItembound_ack_pre; + struct HPMHookPoint *HP_intif_pItembound_ack_post; struct HPMHookPoint *HP_intif_pMercenaryReceived_pre; struct HPMHookPoint *HP_intif_pMercenaryReceived_post; struct HPMHookPoint *HP_intif_pMercenaryDeleted_pre; @@ -2403,8 +2457,6 @@ struct { struct HPMHookPoint *HP_itemdb_reload_post; struct HPMHookPoint *HP_itemdb_name_constants_pre; struct HPMHookPoint *HP_itemdb_name_constants_post; - struct HPMHookPoint *HP_itemdb_force_name_constants_pre; - struct HPMHookPoint *HP_itemdb_force_name_constants_post; struct HPMHookPoint *HP_itemdb_read_groups_pre; struct HPMHookPoint *HP_itemdb_read_groups_post; struct HPMHookPoint *HP_itemdb_read_chains_pre; @@ -2425,8 +2477,6 @@ struct { struct HPMHookPoint *HP_itemdb_load_post; struct HPMHookPoint *HP_itemdb_search_pre; struct HPMHookPoint *HP_itemdb_search_post; - struct HPMHookPoint *HP_itemdb_parse_dbrow_pre; - struct HPMHookPoint *HP_itemdb_parse_dbrow_post; struct HPMHookPoint *HP_itemdb_exists_pre; struct HPMHookPoint *HP_itemdb_exists_post; struct HPMHookPoint *HP_itemdb_in_group_pre; @@ -2501,12 +2551,16 @@ struct { struct HPMHookPoint *HP_itemdb_read_combos_post; struct HPMHookPoint *HP_itemdb_gendercheck_pre; struct HPMHookPoint *HP_itemdb_gendercheck_post; - struct HPMHookPoint *HP_itemdb_re_split_atoi_pre; - struct HPMHookPoint *HP_itemdb_re_split_atoi_post; - struct HPMHookPoint *HP_itemdb_readdb_pre; - struct HPMHookPoint *HP_itemdb_readdb_post; - struct HPMHookPoint *HP_itemdb_read_sqldb_pre; - struct HPMHookPoint *HP_itemdb_read_sqldb_post; + struct HPMHookPoint *HP_itemdb_validate_entry_pre; + struct HPMHookPoint *HP_itemdb_validate_entry_post; + struct HPMHookPoint *HP_itemdb_readdb_sql_sub_pre; + struct HPMHookPoint *HP_itemdb_readdb_sql_sub_post; + struct HPMHookPoint *HP_itemdb_readdb_libconfig_sub_pre; + struct HPMHookPoint *HP_itemdb_readdb_libconfig_sub_post; + struct HPMHookPoint *HP_itemdb_readdb_libconfig_pre; + struct HPMHookPoint *HP_itemdb_readdb_libconfig_post; + struct HPMHookPoint *HP_itemdb_readdb_sql_pre; + struct HPMHookPoint *HP_itemdb_readdb_sql_post; struct HPMHookPoint *HP_itemdb_unique_id_pre; struct HPMHookPoint *HP_itemdb_unique_id_post; struct HPMHookPoint *HP_itemdb_uid_load_pre; @@ -2517,6 +2571,10 @@ struct { struct HPMHookPoint *HP_itemdb_destroy_item_data_post; struct HPMHookPoint *HP_itemdb_final_sub_pre; struct HPMHookPoint *HP_itemdb_final_sub_post; + struct HPMHookPoint *HP_itemdb_clear_pre; + struct HPMHookPoint *HP_itemdb_clear_post; + struct HPMHookPoint *HP_itemdb_id2combo_pre; + struct HPMHookPoint *HP_itemdb_id2combo_post; struct HPMHookPoint *HP_logs_pick_pc_pre; struct HPMHookPoint *HP_logs_pick_pc_post; struct HPMHookPoint *HP_logs_pick_mob_pre; @@ -2831,6 +2889,14 @@ struct { struct HPMHookPoint *HP_map_addblcell_post; struct HPMHookPoint *HP_map_delblcell_pre; struct HPMHookPoint *HP_map_delblcell_post; + struct HPMHookPoint *HP_map_get_new_bonus_id_pre; + struct HPMHookPoint *HP_map_get_new_bonus_id_post; + struct HPMHookPoint *HP_map_add_questinfo_pre; + struct HPMHookPoint *HP_map_add_questinfo_post; + struct HPMHookPoint *HP_map_remove_questinfo_pre; + struct HPMHookPoint *HP_map_remove_questinfo_post; + struct HPMHookPoint *HP_map_merge_zone_pre; + struct HPMHookPoint *HP_map_merge_zone_post; struct HPMHookPoint *HP_mapit_alloc_pre; struct HPMHookPoint *HP_mapit_alloc_post; struct HPMHookPoint *HP_mapit_free_pre; @@ -3085,6 +3151,8 @@ struct { struct HPMHookPoint *HP_mob_readdb_post; struct HPMHookPoint *HP_mob_read_sqldb_pre; struct HPMHookPoint *HP_mob_read_sqldb_post; + struct HPMHookPoint *HP_mob_name_constants_pre; + struct HPMHookPoint *HP_mob_name_constants_post; struct HPMHookPoint *HP_mob_readdb_mobavail_pre; struct HPMHookPoint *HP_mob_readdb_mobavail_post; struct HPMHookPoint *HP_mob_read_randommonster_pre; @@ -3219,6 +3287,10 @@ struct { struct HPMHookPoint *HP_npc_delsrcfile_post; struct HPMHookPoint *HP_npc_parsename_pre; struct HPMHookPoint *HP_npc_parsename_post; + struct HPMHookPoint *HP_npc_parseview_pre; + struct HPMHookPoint *HP_npc_parseview_post; + struct HPMHookPoint *HP_npc_viewisid_pre; + struct HPMHookPoint *HP_npc_viewisid_post; struct HPMHookPoint *HP_npc_add_warp_pre; struct HPMHookPoint *HP_npc_add_warp_post; struct HPMHookPoint *HP_npc_parse_warp_pre; @@ -3277,6 +3349,24 @@ struct { struct HPMHookPoint *HP_npc_debug_warps_sub_post; struct HPMHookPoint *HP_npc_debug_warps_pre; struct HPMHookPoint *HP_npc_debug_warps_post; + struct HPMHookPoint *HP_npc_trader_count_funds_pre; + struct HPMHookPoint *HP_npc_trader_count_funds_post; + struct HPMHookPoint *HP_npc_trader_pay_pre; + struct HPMHookPoint *HP_npc_trader_pay_post; + struct HPMHookPoint *HP_npc_trader_update_pre; + struct HPMHookPoint *HP_npc_trader_update_post; + struct HPMHookPoint *HP_npc_market_buylist_pre; + struct HPMHookPoint *HP_npc_market_buylist_post; + struct HPMHookPoint *HP_npc_trader_open_pre; + struct HPMHookPoint *HP_npc_trader_open_post; + struct HPMHookPoint *HP_npc_market_fromsql_pre; + struct HPMHookPoint *HP_npc_market_fromsql_post; + struct HPMHookPoint *HP_npc_market_tosql_pre; + struct HPMHookPoint *HP_npc_market_tosql_post; + struct HPMHookPoint *HP_npc_market_delfromsql_pre; + struct HPMHookPoint *HP_npc_market_delfromsql_post; + struct HPMHookPoint *HP_npc_market_delfromsql_sub_pre; + struct HPMHookPoint *HP_npc_market_delfromsql_sub_post; struct HPMHookPoint *HP_npc_secure_timeout_timer_pre; struct HPMHookPoint *HP_npc_secure_timeout_timer_post; struct HPMHookPoint *HP_party_init_pre; @@ -3347,6 +3437,8 @@ struct { struct HPMHookPoint *HP_party_send_dot_remove_post; struct HPMHookPoint *HP_party_sub_count_pre; struct HPMHookPoint *HP_party_sub_count_post; + struct HPMHookPoint *HP_party_sub_count_chorus_pre; + struct HPMHookPoint *HP_party_sub_count_chorus_post; struct HPMHookPoint *HP_party_booking_register_pre; struct HPMHookPoint *HP_party_booking_register_post; struct HPMHookPoint *HP_party_booking_update_pre; @@ -3385,6 +3477,28 @@ struct { struct HPMHookPoint *HP_path_check_distance_post; struct HPMHookPoint *HP_path_distance_pre; struct HPMHookPoint *HP_path_distance_post; + struct HPMHookPoint *HP_pcg_init_pre; + struct HPMHookPoint *HP_pcg_init_post; + struct HPMHookPoint *HP_pcg_final_pre; + struct HPMHookPoint *HP_pcg_final_post; + struct HPMHookPoint *HP_pcg_reload_pre; + struct HPMHookPoint *HP_pcg_reload_post; + struct HPMHookPoint *HP_pcg_get_dummy_group_pre; + struct HPMHookPoint *HP_pcg_get_dummy_group_post; + struct HPMHookPoint *HP_pcg_exists_pre; + struct HPMHookPoint *HP_pcg_exists_post; + struct HPMHookPoint *HP_pcg_id2group_pre; + struct HPMHookPoint *HP_pcg_id2group_post; + struct HPMHookPoint *HP_pcg_has_permission_pre; + struct HPMHookPoint *HP_pcg_has_permission_post; + struct HPMHookPoint *HP_pcg_should_log_commands_pre; + struct HPMHookPoint *HP_pcg_should_log_commands_post; + struct HPMHookPoint *HP_pcg_get_name_pre; + struct HPMHookPoint *HP_pcg_get_name_post; + struct HPMHookPoint *HP_pcg_get_level_pre; + struct HPMHookPoint *HP_pcg_get_level_post; + struct HPMHookPoint *HP_pcg_get_idx_pre; + struct HPMHookPoint *HP_pcg_get_idx_post; struct HPMHookPoint *HP_pc_init_pre; struct HPMHookPoint *HP_pc_init_post; struct HPMHookPoint *HP_pc_final_pre; @@ -3393,14 +3507,12 @@ struct { struct HPMHookPoint *HP_pc_get_dummy_sd_post; struct HPMHookPoint *HP_pc_class2idx_pre; struct HPMHookPoint *HP_pc_class2idx_post; - struct HPMHookPoint *HP_pc_get_group_level_pre; - struct HPMHookPoint *HP_pc_get_group_level_post; struct HPMHookPoint *HP_pc_can_give_items_pre; struct HPMHookPoint *HP_pc_can_give_items_post; + struct HPMHookPoint *HP_pc_can_give_bound_items_pre; + struct HPMHookPoint *HP_pc_can_give_bound_items_post; struct HPMHookPoint *HP_pc_can_use_command_pre; struct HPMHookPoint *HP_pc_can_use_command_post; - struct HPMHookPoint *HP_pc_has_permission_pre; - struct HPMHookPoint *HP_pc_has_permission_post; struct HPMHookPoint *HP_pc_set_group_pre; struct HPMHookPoint *HP_pc_set_group_post; struct HPMHookPoint *HP_pc_should_log_commands_pre; @@ -3543,6 +3655,8 @@ struct { struct HPMHookPoint *HP_pc_gets_status_point_post; struct HPMHookPoint *HP_pc_need_status_point_pre; struct HPMHookPoint *HP_pc_need_status_point_post; + struct HPMHookPoint *HP_pc_maxparameterincrease_pre; + struct HPMHookPoint *HP_pc_maxparameterincrease_post; struct HPMHookPoint *HP_pc_statusup_pre; struct HPMHookPoint *HP_pc_statusup_post; struct HPMHookPoint *HP_pc_statusup2_pre; @@ -3765,6 +3879,32 @@ struct { struct HPMHookPoint *HP_pc_calcweapontype_post; struct HPMHookPoint *HP_pc_removecombo_pre; struct HPMHookPoint *HP_pc_removecombo_post; + struct HPMHookPoint *HP_pc_bank_deposit_pre; + struct HPMHookPoint *HP_pc_bank_deposit_post; + struct HPMHookPoint *HP_pc_bank_withdraw_pre; + struct HPMHookPoint *HP_pc_bank_withdraw_post; + struct HPMHookPoint *HP_pc_rental_expire_pre; + struct HPMHookPoint *HP_pc_rental_expire_post; + struct HPMHookPoint *HP_pc_scdata_received_pre; + struct HPMHookPoint *HP_pc_scdata_received_post; + struct HPMHookPoint *HP_pc_bound_clear_pre; + struct HPMHookPoint *HP_pc_bound_clear_post; + struct HPMHookPoint *HP_pc_expiration_timer_pre; + struct HPMHookPoint *HP_pc_expiration_timer_post; + struct HPMHookPoint *HP_pc_global_expiration_timer_pre; + struct HPMHookPoint *HP_pc_global_expiration_timer_post; + struct HPMHookPoint *HP_pc_expire_check_pre; + struct HPMHookPoint *HP_pc_expire_check_post; + struct HPMHookPoint *HP_pc_autotrade_load_pre; + struct HPMHookPoint *HP_pc_autotrade_load_post; + struct HPMHookPoint *HP_pc_autotrade_update_pre; + struct HPMHookPoint *HP_pc_autotrade_update_post; + struct HPMHookPoint *HP_pc_autotrade_start_pre; + struct HPMHookPoint *HP_pc_autotrade_start_post; + struct HPMHookPoint *HP_pc_autotrade_prepare_pre; + struct HPMHookPoint *HP_pc_autotrade_prepare_post; + struct HPMHookPoint *HP_pc_autotrade_populate_pre; + struct HPMHookPoint *HP_pc_autotrade_populate_post; struct HPMHookPoint *HP_pet_init_pre; struct HPMHookPoint *HP_pet_init_post; struct HPMHookPoint *HP_pet_final_pre; @@ -3845,10 +3985,12 @@ struct { struct HPMHookPoint *HP_pet_read_db_post; struct HPMHookPoint *HP_quest_init_pre; struct HPMHookPoint *HP_quest_init_post; + struct HPMHookPoint *HP_quest_final_pre; + struct HPMHookPoint *HP_quest_final_post; struct HPMHookPoint *HP_quest_reload_pre; struct HPMHookPoint *HP_quest_reload_post; - struct HPMHookPoint *HP_quest_search_db_pre; - struct HPMHookPoint *HP_quest_search_db_post; + struct HPMHookPoint *HP_quest_db_pre; + struct HPMHookPoint *HP_quest_db_post; struct HPMHookPoint *HP_quest_pc_login_pre; struct HPMHookPoint *HP_quest_pc_login_post; struct HPMHookPoint *HP_quest_add_pre; @@ -3865,6 +4007,8 @@ struct { struct HPMHookPoint *HP_quest_update_status_post; struct HPMHookPoint *HP_quest_check_pre; struct HPMHookPoint *HP_quest_check_post; + struct HPMHookPoint *HP_quest_clear_pre; + struct HPMHookPoint *HP_quest_clear_post; struct HPMHookPoint *HP_quest_read_db_pre; struct HPMHookPoint *HP_quest_read_db_post; struct HPMHookPoint *HP_script_init_pre; @@ -3875,6 +4019,8 @@ struct { struct HPMHookPoint *HP_script_reload_post; struct HPMHookPoint *HP_script_parse_pre; struct HPMHookPoint *HP_script_parse_post; + struct HPMHookPoint *HP_script_add_builtin_pre; + struct HPMHookPoint *HP_script_add_builtin_post; struct HPMHookPoint *HP_script_parse_builtin_pre; struct HPMHookPoint *HP_script_parse_builtin_post; struct HPMHookPoint *HP_script_parse_subexpr_pre; @@ -3911,8 +4057,6 @@ struct { struct HPMHookPoint *HP_script_set_constant_post; struct HPMHookPoint *HP_script_set_constant2_pre; struct HPMHookPoint *HP_script_set_constant2_post; - struct HPMHookPoint *HP_script_set_constant_force_pre; - struct HPMHookPoint *HP_script_set_constant_force_post; struct HPMHookPoint *HP_script_get_constant_pre; struct HPMHookPoint *HP_script_get_constant_post; struct HPMHookPoint *HP_script_label_add_pre; @@ -3985,8 +4129,6 @@ struct { struct HPMHookPoint *HP_script_reportdata_post; struct HPMHookPoint *HP_script_reportfunc_pre; struct HPMHookPoint *HP_script_reportfunc_post; - struct HPMHookPoint *HP_script_disp_error_message2_pre; - struct HPMHookPoint *HP_script_disp_error_message2_post; struct HPMHookPoint *HP_script_disp_warning_message_pre; struct HPMHookPoint *HP_script_disp_warning_message_post; struct HPMHookPoint *HP_script_check_event_pre; @@ -4031,8 +4173,6 @@ struct { struct HPMHookPoint *HP_script_stack_expand_post; struct HPMHookPoint *HP_script_push_retinfo_pre; struct HPMHookPoint *HP_script_push_retinfo_post; - struct HPMHookPoint *HP_script_pop_val_pre; - struct HPMHookPoint *HP_script_pop_val_post; struct HPMHookPoint *HP_script_op_3_pre; struct HPMHookPoint *HP_script_op_3_post; struct HPMHookPoint *HP_script_op_2str_pre; @@ -4057,8 +4197,6 @@ struct { struct HPMHookPoint *HP_script_buildin_areawarp_sub_post; struct HPMHookPoint *HP_script_buildin_areapercentheal_sub_pre; struct HPMHookPoint *HP_script_buildin_areapercentheal_sub_post; - struct HPMHookPoint *HP_script_getarraysize_pre; - struct HPMHookPoint *HP_script_getarraysize_post; struct HPMHookPoint *HP_script_buildin_delitem_delete_pre; struct HPMHookPoint *HP_script_buildin_delitem_delete_post; struct HPMHookPoint *HP_script_buildin_delitem_search_pre; @@ -4087,16 +4225,14 @@ struct { struct HPMHookPoint *HP_script_buildin_maprespawnguildid_sub_mob_post; struct HPMHookPoint *HP_script_buildin_mobcount_sub_pre; struct HPMHookPoint *HP_script_buildin_mobcount_sub_post; - struct HPMHookPoint *HP_script_playBGM_sub_pre; - struct HPMHookPoint *HP_script_playBGM_sub_post; - struct HPMHookPoint *HP_script_playBGM_foreachpc_sub_pre; - struct HPMHookPoint *HP_script_playBGM_foreachpc_sub_post; + struct HPMHookPoint *HP_script_playbgm_sub_pre; + struct HPMHookPoint *HP_script_playbgm_sub_post; + struct HPMHookPoint *HP_script_playbgm_foreachpc_sub_pre; + struct HPMHookPoint *HP_script_playbgm_foreachpc_sub_post; struct HPMHookPoint *HP_script_soundeffect_sub_pre; struct HPMHookPoint *HP_script_soundeffect_sub_post; struct HPMHookPoint *HP_script_buildin_query_sql_sub_pre; struct HPMHookPoint *HP_script_buildin_query_sql_sub_post; - struct HPMHookPoint *HP_script_axtoi_pre; - struct HPMHookPoint *HP_script_axtoi_post; struct HPMHookPoint *HP_script_buildin_instance_warpall_sub_pre; struct HPMHookPoint *HP_script_buildin_instance_warpall_sub_post; struct HPMHookPoint *HP_script_buildin_mobuseskill_sub_pre; @@ -4105,6 +4241,36 @@ struct { struct HPMHookPoint *HP_script_cleanfloor_sub_post; struct HPMHookPoint *HP_script_run_func_pre; struct HPMHookPoint *HP_script_run_func_post; + struct HPMHookPoint *HP_script_getfuncname_pre; + struct HPMHookPoint *HP_script_getfuncname_post; + struct HPMHookPoint *HP_script_calc_hash_ci_pre; + struct HPMHookPoint *HP_script_calc_hash_ci_post; + struct HPMHookPoint *HP_script_array_src_pre; + struct HPMHookPoint *HP_script_array_src_post; + struct HPMHookPoint *HP_script_array_update_pre; + struct HPMHookPoint *HP_script_array_update_post; + struct HPMHookPoint *HP_script_array_delete_pre; + struct HPMHookPoint *HP_script_array_delete_post; + struct HPMHookPoint *HP_script_array_remove_member_pre; + struct HPMHookPoint *HP_script_array_remove_member_post; + struct HPMHookPoint *HP_script_array_add_member_pre; + struct HPMHookPoint *HP_script_array_add_member_post; + struct HPMHookPoint *HP_script_array_size_pre; + struct HPMHookPoint *HP_script_array_size_post; + struct HPMHookPoint *HP_script_array_highest_key_pre; + struct HPMHookPoint *HP_script_array_highest_key_post; + struct HPMHookPoint *HP_script_array_free_db_pre; + struct HPMHookPoint *HP_script_array_free_db_post; + struct HPMHookPoint *HP_script_array_ensure_zero_pre; + struct HPMHookPoint *HP_script_array_ensure_zero_post; + struct HPMHookPoint *HP_script_reg_destroy_single_pre; + struct HPMHookPoint *HP_script_reg_destroy_single_post; + struct HPMHookPoint *HP_script_reg_destroy_pre; + struct HPMHookPoint *HP_script_reg_destroy_post; + struct HPMHookPoint *HP_script_generic_ui_array_expand_pre; + struct HPMHookPoint *HP_script_generic_ui_array_expand_post; + struct HPMHookPoint *HP_script_array_cpy_list_pre; + struct HPMHookPoint *HP_script_array_cpy_list_post; struct HPMHookPoint *HP_searchstore_open_pre; struct HPMHookPoint *HP_searchstore_open_post; struct HPMHookPoint *HP_searchstore_query_pre; @@ -4487,10 +4653,10 @@ struct { struct HPMHookPoint *HP_skill_get_elemental_type_post; struct HPMHookPoint *HP_skill_cooldown_save_pre; struct HPMHookPoint *HP_skill_cooldown_save_post; - struct HPMHookPoint *HP_skill_maelstrom_suction_pre; - struct HPMHookPoint *HP_skill_maelstrom_suction_post; struct HPMHookPoint *HP_skill_get_new_group_id_pre; struct HPMHookPoint *HP_skill_get_new_group_id_post; + struct HPMHookPoint *HP_skill_check_shadowform_pre; + struct HPMHookPoint *HP_skill_check_shadowform_post; struct HPMHookPoint *HP_status_init_pre; struct HPMHookPoint *HP_status_init_post; struct HPMHookPoint *HP_status_final_pre; @@ -4521,6 +4687,8 @@ struct { struct HPMHookPoint *HP_status_heal_post; struct HPMHookPoint *HP_status_revive_pre; struct HPMHookPoint *HP_status_revive_post; + struct HPMHookPoint *HP_status_fixed_revive_pre; + struct HPMHookPoint *HP_status_fixed_revive_post; struct HPMHookPoint *HP_status_get_regen_data_pre; struct HPMHookPoint *HP_status_get_regen_data_post; struct HPMHookPoint *HP_status_get_status_data_pre; @@ -4866,8 +5034,8 @@ struct { int HP_atcommand_init_post; int HP_atcommand_final_pre; int HP_atcommand_final_post; - int HP_atcommand_parse_pre; - int HP_atcommand_parse_post; + int HP_atcommand_exec_pre; + int HP_atcommand_exec_post; int HP_atcommand_create_pre; int HP_atcommand_create_post; int HP_atcommand_can_use_pre; @@ -4918,6 +5086,10 @@ struct { int HP_atcommand_doload_post; int HP_atcommand_base_commands_pre; int HP_atcommand_base_commands_post; + int HP_atcommand_add_pre; + int HP_atcommand_add_post; + int HP_atcommand_msg_pre; + int HP_atcommand_msg_post; int HP_battle_init_pre; int HP_battle_init_post; int HP_battle_final_pre; @@ -4938,8 +5110,8 @@ struct { int HP_battle_delay_damage_post; int HP_battle_drain_pre; int HP_battle_drain_post; - int HP_battle_calc_return_damage_pre; - int HP_battle_calc_return_damage_post; + int HP_battle_reflect_damage_pre; + int HP_battle_reflect_damage_post; int HP_battle_attr_ratio_pre; int HP_battle_attr_ratio_post; int HP_battle_attr_fix_pre; @@ -4950,6 +5122,8 @@ struct { int HP_battle_calc_elefix_post; int HP_battle_calc_masteryfix_pre; int HP_battle_calc_masteryfix_post; + int HP_battle_calc_chorusbonus_pre; + int HP_battle_calc_chorusbonus_post; int HP_battle_calc_skillratio_pre; int HP_battle_calc_skillratio_post; int HP_battle_calc_sizefix_pre; @@ -5114,10 +5288,10 @@ struct { int HP_chat_trigger_event_post; int HP_chat_create_pre; int HP_chat_create_post; - int HP_chrif_final_pre; - int HP_chrif_final_post; int HP_chrif_init_pre; int HP_chrif_init_post; + int HP_chrif_final_pre; + int HP_chrif_final_post; int HP_chrif_setuserid_pre; int HP_chrif_setuserid_post; int HP_chrif_setpasswd_pre; @@ -5166,8 +5340,6 @@ struct { int HP_chrif_save_scdata_post; int HP_chrif_ragsrvinfo_pre; int HP_chrif_ragsrvinfo_post; - int HP_chrif_char_offline_pre; - int HP_chrif_char_offline_post; int HP_chrif_char_offline_nsd_pre; int HP_chrif_char_offline_nsd_post; int HP_chrif_char_reset_offline_pre; @@ -5184,8 +5356,8 @@ struct { int HP_chrif_removefriend_post; int HP_chrif_send_report_pre; int HP_chrif_send_report_post; - int HP_chrif_flush_fifo_pre; - int HP_chrif_flush_fifo_post; + int HP_chrif_flush_pre; + int HP_chrif_flush_post; int HP_chrif_skillid2idx_pre; int HP_chrif_skillid2idx_post; int HP_chrif_sd_to_auth_pre; @@ -5224,8 +5396,8 @@ struct { int HP_chrif_changedsex_post; int HP_chrif_divorceack_pre; int HP_chrif_divorceack_post; - int HP_chrif_accountban_pre; - int HP_chrif_accountban_post; + int HP_chrif_idbanned_pre; + int HP_chrif_idbanned_post; int HP_chrif_recvfamelist_pre; int HP_chrif_recvfamelist_post; int HP_chrif_load_scdata_pre; @@ -5252,6 +5424,10 @@ struct { int HP_chrif_on_disconnect_post; int HP_chrif_parse_pre; int HP_chrif_parse_post; + int HP_chrif_save_scdata_single_pre; + int HP_chrif_save_scdata_single_post; + int HP_chrif_del_scdata_single_pre; + int HP_chrif_del_scdata_single_post; int HP_clif_init_pre; int HP_clif_init_post; int HP_clif_final_pre; @@ -5324,6 +5500,8 @@ struct { int HP_clif_cashshop_load_post; int HP_clif_package_announce_pre; int HP_clif_package_announce_post; + int HP_clif_item_drop_announce_pre; + int HP_clif_item_drop_announce_post; int HP_clif_clearunit_single_pre; int HP_clif_clearunit_single_post; int HP_clif_clearunit_area_pre; @@ -5350,8 +5528,6 @@ struct { int HP_clif_refreshlook_post; int HP_clif_class_change_pre; int HP_clif_class_change_post; - int HP_clif_skill_setunit_pre; - int HP_clif_skill_setunit_post; int HP_clif_skill_delunit_pre; int HP_clif_skill_delunit_post; int HP_clif_skillunit_update_pre; @@ -5378,6 +5554,8 @@ struct { int HP_clif_clearchar_skillunit_post; int HP_clif_getareachar_pre; int HP_clif_getareachar_post; + int HP_clif_graffiti_entry_pre; + int HP_clif_graffiti_entry_post; int HP_clif_spawn_pre; int HP_clif_spawn_post; int HP_clif_changemap_pre; @@ -5548,8 +5726,6 @@ struct { int HP_clif_equiptickack_post; int HP_clif_viewequip_ack_pre; int HP_clif_viewequip_ack_post; - int HP_clif_viewequip_fail_pre; - int HP_clif_viewequip_fail_post; int HP_clif_equpcheckbox_pre; int HP_clif_equpcheckbox_post; int HP_clif_displayexp_pre; @@ -5706,8 +5882,6 @@ struct { int HP_clif_wis_message_post; int HP_clif_wis_end_pre; int HP_clif_wis_end_post; - int HP_clif_disp_onlyself_pre; - int HP_clif_disp_onlyself_post; int HP_clif_disp_message_pre; int HP_clif_disp_message_post; int HP_clif_broadcast_pre; @@ -5742,6 +5916,8 @@ struct { int HP_clif_wisall_post; int HP_clif_PMIgnoreList_pre; int HP_clif_PMIgnoreList_post; + int HP_clif_ShowScript_pre; + int HP_clif_ShowScript_post; int HP_clif_traderequest_pre; int HP_clif_traderequest_post; int HP_clif_tradestart_pre; @@ -5858,8 +6034,6 @@ struct { int HP_clif_guild_notice_post; int HP_clif_guild_message_pre; int HP_clif_guild_message_post; - int HP_clif_guild_skillup_pre; - int HP_clif_guild_skillup_post; int HP_clif_guild_reqalliance_pre; int HP_clif_guild_reqalliance_post; int HP_clif_guild_allianceack_pre; @@ -6128,6 +6302,22 @@ struct { int HP_clif_chsys_gjoin_post; int HP_clif_chsys_gleave_pre; int HP_clif_chsys_gleave_post; + int HP_clif_bank_deposit_pre; + int HP_clif_bank_deposit_post; + int HP_clif_bank_withdraw_pre; + int HP_clif_bank_withdraw_post; + int HP_clif_show_modifiers_pre; + int HP_clif_show_modifiers_post; + int HP_clif_notify_bounditem_pre; + int HP_clif_notify_bounditem_post; + int HP_clif_delay_damage_pre; + int HP_clif_delay_damage_post; + int HP_clif_delay_damage_sub_pre; + int HP_clif_delay_damage_sub_post; + int HP_clif_npc_market_open_pre; + int HP_clif_npc_market_open_post; + int HP_clif_npc_market_purchase_ack_pre; + int HP_clif_npc_market_purchase_ack_post; int HP_clif_pWantToConnection_pre; int HP_clif_pWantToConnection_post; int HP_clif_pLoadEndAck_pre; @@ -6406,6 +6596,8 @@ struct { int HP_clif_pGMReqAccountName_post; int HP_clif_pGMChangeMapType_pre; int HP_clif_pGMChangeMapType_post; + int HP_clif_pGMFullStrip_pre; + int HP_clif_pGMFullStrip_post; int HP_clif_pPMIgnore_pre; int HP_clif_pPMIgnore_post; int HP_clif_pPMIgnoreAll_pre; @@ -6556,6 +6748,22 @@ struct { int HP_clif_pPartyBookingRefuseVolunteer_post; int HP_clif_pPartyBookingCancelVolunteer_pre; int HP_clif_pPartyBookingCancelVolunteer_post; + int HP_clif_pBankDeposit_pre; + int HP_clif_pBankDeposit_post; + int HP_clif_pBankWithdraw_pre; + int HP_clif_pBankWithdraw_post; + int HP_clif_pBankCheck_pre; + int HP_clif_pBankCheck_post; + int HP_clif_pBankOpen_pre; + int HP_clif_pBankOpen_post; + int HP_clif_pBankClose_pre; + int HP_clif_pBankClose_post; + int HP_clif_pNPCShopClosed_pre; + int HP_clif_pNPCShopClosed_post; + int HP_clif_pNPCMarketClosed_pre; + int HP_clif_pNPCMarketClosed_post; + int HP_clif_pNPCMarketPurchase_pre; + int HP_clif_pNPCMarketPurchase_post; int HP_duel_create_pre; int HP_duel_create_post; int HP_duel_invite_pre; @@ -6774,6 +6982,8 @@ struct { int HP_guild_flags_clear_post; int HP_guild_aura_refresh_pre; int HP_guild_aura_refresh_post; + int HP_guild_retrieveitembound_pre; + int HP_guild_retrieveitembound_post; int HP_guild_payexp_timer_pre; int HP_guild_payexp_timer_post; int HP_guild_sd_check_pre; @@ -6938,6 +7148,8 @@ struct { int HP_instance_init_post; int HP_instance_final_pre; int HP_instance_final_post; + int HP_instance_reload_pre; + int HP_instance_reload_post; int HP_instance_create_pre; int HP_instance_create_post; int HP_instance_add_map_pre; @@ -6948,6 +7160,12 @@ struct { int HP_instance_map2imap_post; int HP_instance_mapid2imapid_pre; int HP_instance_mapid2imapid_post; + int HP_instance_mapname2imap_pre; + int HP_instance_mapname2imap_post; + int HP_instance_map_npcsub_pre; + int HP_instance_map_npcsub_post; + int HP_instance_init_npc_pre; + int HP_instance_init_npc_post; int HP_instance_destroy_pre; int HP_instance_destroy_post; int HP_instance_start_pre; @@ -7036,6 +7254,8 @@ struct { int HP_intif_guild_castle_dataload_post; int HP_intif_guild_castle_datasave_pre; int HP_intif_guild_castle_datasave_post; + int HP_intif_itembound_req_pre; + int HP_intif_itembound_req_post; int HP_intif_request_petdata_pre; int HP_intif_request_petdata_post; int HP_intif_save_petdata_pre; @@ -7192,6 +7412,8 @@ struct { int HP_intif_pAuctionMessage_post; int HP_intif_pAuctionBid_pre; int HP_intif_pAuctionBid_post; + int HP_intif_pItembound_ack_pre; + int HP_intif_pItembound_ack_post; int HP_intif_pMercenaryReceived_pre; int HP_intif_pMercenaryReceived_post; int HP_intif_pMercenaryDeleted_pre; @@ -7260,8 +7482,6 @@ struct { int HP_itemdb_reload_post; int HP_itemdb_name_constants_pre; int HP_itemdb_name_constants_post; - int HP_itemdb_force_name_constants_pre; - int HP_itemdb_force_name_constants_post; int HP_itemdb_read_groups_pre; int HP_itemdb_read_groups_post; int HP_itemdb_read_chains_pre; @@ -7282,8 +7502,6 @@ struct { int HP_itemdb_load_post; int HP_itemdb_search_pre; int HP_itemdb_search_post; - int HP_itemdb_parse_dbrow_pre; - int HP_itemdb_parse_dbrow_post; int HP_itemdb_exists_pre; int HP_itemdb_exists_post; int HP_itemdb_in_group_pre; @@ -7358,12 +7576,16 @@ struct { int HP_itemdb_read_combos_post; int HP_itemdb_gendercheck_pre; int HP_itemdb_gendercheck_post; - int HP_itemdb_re_split_atoi_pre; - int HP_itemdb_re_split_atoi_post; - int HP_itemdb_readdb_pre; - int HP_itemdb_readdb_post; - int HP_itemdb_read_sqldb_pre; - int HP_itemdb_read_sqldb_post; + int HP_itemdb_validate_entry_pre; + int HP_itemdb_validate_entry_post; + int HP_itemdb_readdb_sql_sub_pre; + int HP_itemdb_readdb_sql_sub_post; + int HP_itemdb_readdb_libconfig_sub_pre; + int HP_itemdb_readdb_libconfig_sub_post; + int HP_itemdb_readdb_libconfig_pre; + int HP_itemdb_readdb_libconfig_post; + int HP_itemdb_readdb_sql_pre; + int HP_itemdb_readdb_sql_post; int HP_itemdb_unique_id_pre; int HP_itemdb_unique_id_post; int HP_itemdb_uid_load_pre; @@ -7374,6 +7596,10 @@ struct { int HP_itemdb_destroy_item_data_post; int HP_itemdb_final_sub_pre; int HP_itemdb_final_sub_post; + int HP_itemdb_clear_pre; + int HP_itemdb_clear_post; + int HP_itemdb_id2combo_pre; + int HP_itemdb_id2combo_post; int HP_logs_pick_pc_pre; int HP_logs_pick_pc_post; int HP_logs_pick_mob_pre; @@ -7688,6 +7914,14 @@ struct { int HP_map_addblcell_post; int HP_map_delblcell_pre; int HP_map_delblcell_post; + int HP_map_get_new_bonus_id_pre; + int HP_map_get_new_bonus_id_post; + int HP_map_add_questinfo_pre; + int HP_map_add_questinfo_post; + int HP_map_remove_questinfo_pre; + int HP_map_remove_questinfo_post; + int HP_map_merge_zone_pre; + int HP_map_merge_zone_post; int HP_mapit_alloc_pre; int HP_mapit_alloc_post; int HP_mapit_free_pre; @@ -7942,6 +8176,8 @@ struct { int HP_mob_readdb_post; int HP_mob_read_sqldb_pre; int HP_mob_read_sqldb_post; + int HP_mob_name_constants_pre; + int HP_mob_name_constants_post; int HP_mob_readdb_mobavail_pre; int HP_mob_readdb_mobavail_post; int HP_mob_read_randommonster_pre; @@ -8076,6 +8312,10 @@ struct { int HP_npc_delsrcfile_post; int HP_npc_parsename_pre; int HP_npc_parsename_post; + int HP_npc_parseview_pre; + int HP_npc_parseview_post; + int HP_npc_viewisid_pre; + int HP_npc_viewisid_post; int HP_npc_add_warp_pre; int HP_npc_add_warp_post; int HP_npc_parse_warp_pre; @@ -8134,6 +8374,24 @@ struct { int HP_npc_debug_warps_sub_post; int HP_npc_debug_warps_pre; int HP_npc_debug_warps_post; + int HP_npc_trader_count_funds_pre; + int HP_npc_trader_count_funds_post; + int HP_npc_trader_pay_pre; + int HP_npc_trader_pay_post; + int HP_npc_trader_update_pre; + int HP_npc_trader_update_post; + int HP_npc_market_buylist_pre; + int HP_npc_market_buylist_post; + int HP_npc_trader_open_pre; + int HP_npc_trader_open_post; + int HP_npc_market_fromsql_pre; + int HP_npc_market_fromsql_post; + int HP_npc_market_tosql_pre; + int HP_npc_market_tosql_post; + int HP_npc_market_delfromsql_pre; + int HP_npc_market_delfromsql_post; + int HP_npc_market_delfromsql_sub_pre; + int HP_npc_market_delfromsql_sub_post; int HP_npc_secure_timeout_timer_pre; int HP_npc_secure_timeout_timer_post; int HP_party_init_pre; @@ -8204,6 +8462,8 @@ struct { int HP_party_send_dot_remove_post; int HP_party_sub_count_pre; int HP_party_sub_count_post; + int HP_party_sub_count_chorus_pre; + int HP_party_sub_count_chorus_post; int HP_party_booking_register_pre; int HP_party_booking_register_post; int HP_party_booking_update_pre; @@ -8242,6 +8502,28 @@ struct { int HP_path_check_distance_post; int HP_path_distance_pre; int HP_path_distance_post; + int HP_pcg_init_pre; + int HP_pcg_init_post; + int HP_pcg_final_pre; + int HP_pcg_final_post; + int HP_pcg_reload_pre; + int HP_pcg_reload_post; + int HP_pcg_get_dummy_group_pre; + int HP_pcg_get_dummy_group_post; + int HP_pcg_exists_pre; + int HP_pcg_exists_post; + int HP_pcg_id2group_pre; + int HP_pcg_id2group_post; + int HP_pcg_has_permission_pre; + int HP_pcg_has_permission_post; + int HP_pcg_should_log_commands_pre; + int HP_pcg_should_log_commands_post; + int HP_pcg_get_name_pre; + int HP_pcg_get_name_post; + int HP_pcg_get_level_pre; + int HP_pcg_get_level_post; + int HP_pcg_get_idx_pre; + int HP_pcg_get_idx_post; int HP_pc_init_pre; int HP_pc_init_post; int HP_pc_final_pre; @@ -8250,14 +8532,12 @@ struct { int HP_pc_get_dummy_sd_post; int HP_pc_class2idx_pre; int HP_pc_class2idx_post; - int HP_pc_get_group_level_pre; - int HP_pc_get_group_level_post; int HP_pc_can_give_items_pre; int HP_pc_can_give_items_post; + int HP_pc_can_give_bound_items_pre; + int HP_pc_can_give_bound_items_post; int HP_pc_can_use_command_pre; int HP_pc_can_use_command_post; - int HP_pc_has_permission_pre; - int HP_pc_has_permission_post; int HP_pc_set_group_pre; int HP_pc_set_group_post; int HP_pc_should_log_commands_pre; @@ -8400,6 +8680,8 @@ struct { int HP_pc_gets_status_point_post; int HP_pc_need_status_point_pre; int HP_pc_need_status_point_post; + int HP_pc_maxparameterincrease_pre; + int HP_pc_maxparameterincrease_post; int HP_pc_statusup_pre; int HP_pc_statusup_post; int HP_pc_statusup2_pre; @@ -8622,6 +8904,32 @@ struct { int HP_pc_calcweapontype_post; int HP_pc_removecombo_pre; int HP_pc_removecombo_post; + int HP_pc_bank_deposit_pre; + int HP_pc_bank_deposit_post; + int HP_pc_bank_withdraw_pre; + int HP_pc_bank_withdraw_post; + int HP_pc_rental_expire_pre; + int HP_pc_rental_expire_post; + int HP_pc_scdata_received_pre; + int HP_pc_scdata_received_post; + int HP_pc_bound_clear_pre; + int HP_pc_bound_clear_post; + int HP_pc_expiration_timer_pre; + int HP_pc_expiration_timer_post; + int HP_pc_global_expiration_timer_pre; + int HP_pc_global_expiration_timer_post; + int HP_pc_expire_check_pre; + int HP_pc_expire_check_post; + int HP_pc_autotrade_load_pre; + int HP_pc_autotrade_load_post; + int HP_pc_autotrade_update_pre; + int HP_pc_autotrade_update_post; + int HP_pc_autotrade_start_pre; + int HP_pc_autotrade_start_post; + int HP_pc_autotrade_prepare_pre; + int HP_pc_autotrade_prepare_post; + int HP_pc_autotrade_populate_pre; + int HP_pc_autotrade_populate_post; int HP_pet_init_pre; int HP_pet_init_post; int HP_pet_final_pre; @@ -8702,10 +9010,12 @@ struct { int HP_pet_read_db_post; int HP_quest_init_pre; int HP_quest_init_post; + int HP_quest_final_pre; + int HP_quest_final_post; int HP_quest_reload_pre; int HP_quest_reload_post; - int HP_quest_search_db_pre; - int HP_quest_search_db_post; + int HP_quest_db_pre; + int HP_quest_db_post; int HP_quest_pc_login_pre; int HP_quest_pc_login_post; int HP_quest_add_pre; @@ -8722,6 +9032,8 @@ struct { int HP_quest_update_status_post; int HP_quest_check_pre; int HP_quest_check_post; + int HP_quest_clear_pre; + int HP_quest_clear_post; int HP_quest_read_db_pre; int HP_quest_read_db_post; int HP_script_init_pre; @@ -8732,6 +9044,8 @@ struct { int HP_script_reload_post; int HP_script_parse_pre; int HP_script_parse_post; + int HP_script_add_builtin_pre; + int HP_script_add_builtin_post; int HP_script_parse_builtin_pre; int HP_script_parse_builtin_post; int HP_script_parse_subexpr_pre; @@ -8768,8 +9082,6 @@ struct { int HP_script_set_constant_post; int HP_script_set_constant2_pre; int HP_script_set_constant2_post; - int HP_script_set_constant_force_pre; - int HP_script_set_constant_force_post; int HP_script_get_constant_pre; int HP_script_get_constant_post; int HP_script_label_add_pre; @@ -8842,8 +9154,6 @@ struct { int HP_script_reportdata_post; int HP_script_reportfunc_pre; int HP_script_reportfunc_post; - int HP_script_disp_error_message2_pre; - int HP_script_disp_error_message2_post; int HP_script_disp_warning_message_pre; int HP_script_disp_warning_message_post; int HP_script_check_event_pre; @@ -8888,8 +9198,6 @@ struct { int HP_script_stack_expand_post; int HP_script_push_retinfo_pre; int HP_script_push_retinfo_post; - int HP_script_pop_val_pre; - int HP_script_pop_val_post; int HP_script_op_3_pre; int HP_script_op_3_post; int HP_script_op_2str_pre; @@ -8914,8 +9222,6 @@ struct { int HP_script_buildin_areawarp_sub_post; int HP_script_buildin_areapercentheal_sub_pre; int HP_script_buildin_areapercentheal_sub_post; - int HP_script_getarraysize_pre; - int HP_script_getarraysize_post; int HP_script_buildin_delitem_delete_pre; int HP_script_buildin_delitem_delete_post; int HP_script_buildin_delitem_search_pre; @@ -8944,16 +9250,14 @@ struct { int HP_script_buildin_maprespawnguildid_sub_mob_post; int HP_script_buildin_mobcount_sub_pre; int HP_script_buildin_mobcount_sub_post; - int HP_script_playBGM_sub_pre; - int HP_script_playBGM_sub_post; - int HP_script_playBGM_foreachpc_sub_pre; - int HP_script_playBGM_foreachpc_sub_post; + int HP_script_playbgm_sub_pre; + int HP_script_playbgm_sub_post; + int HP_script_playbgm_foreachpc_sub_pre; + int HP_script_playbgm_foreachpc_sub_post; int HP_script_soundeffect_sub_pre; int HP_script_soundeffect_sub_post; int HP_script_buildin_query_sql_sub_pre; int HP_script_buildin_query_sql_sub_post; - int HP_script_axtoi_pre; - int HP_script_axtoi_post; int HP_script_buildin_instance_warpall_sub_pre; int HP_script_buildin_instance_warpall_sub_post; int HP_script_buildin_mobuseskill_sub_pre; @@ -8962,6 +9266,36 @@ struct { int HP_script_cleanfloor_sub_post; int HP_script_run_func_pre; int HP_script_run_func_post; + int HP_script_getfuncname_pre; + int HP_script_getfuncname_post; + int HP_script_calc_hash_ci_pre; + int HP_script_calc_hash_ci_post; + int HP_script_array_src_pre; + int HP_script_array_src_post; + int HP_script_array_update_pre; + int HP_script_array_update_post; + int HP_script_array_delete_pre; + int HP_script_array_delete_post; + int HP_script_array_remove_member_pre; + int HP_script_array_remove_member_post; + int HP_script_array_add_member_pre; + int HP_script_array_add_member_post; + int HP_script_array_size_pre; + int HP_script_array_size_post; + int HP_script_array_highest_key_pre; + int HP_script_array_highest_key_post; + int HP_script_array_free_db_pre; + int HP_script_array_free_db_post; + int HP_script_array_ensure_zero_pre; + int HP_script_array_ensure_zero_post; + int HP_script_reg_destroy_single_pre; + int HP_script_reg_destroy_single_post; + int HP_script_reg_destroy_pre; + int HP_script_reg_destroy_post; + int HP_script_generic_ui_array_expand_pre; + int HP_script_generic_ui_array_expand_post; + int HP_script_array_cpy_list_pre; + int HP_script_array_cpy_list_post; int HP_searchstore_open_pre; int HP_searchstore_open_post; int HP_searchstore_query_pre; @@ -9344,10 +9678,10 @@ struct { int HP_skill_get_elemental_type_post; int HP_skill_cooldown_save_pre; int HP_skill_cooldown_save_post; - int HP_skill_maelstrom_suction_pre; - int HP_skill_maelstrom_suction_post; int HP_skill_get_new_group_id_pre; int HP_skill_get_new_group_id_post; + int HP_skill_check_shadowform_pre; + int HP_skill_check_shadowform_post; int HP_status_init_pre; int HP_status_init_post; int HP_status_final_pre; @@ -9378,6 +9712,8 @@ struct { int HP_status_heal_post; int HP_status_revive_pre; int HP_status_revive_post; + int HP_status_fixed_revive_pre; + int HP_status_fixed_revive_post; int HP_status_get_regen_data_pre; int HP_status_get_regen_data_post; int HP_status_get_status_data_pre; @@ -9745,6 +10081,7 @@ struct { struct npc_interface npc; struct party_interface party; struct path_interface path; + struct pc_groups_interface pcg; struct pc_interface pc; struct pet_interface pet; struct quest_interface quest; diff --git a/src/plugins/HPMHooking/HPMHooking.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking.HookingPoints.inc index 0eaaf4b93..9cd73bce8 100644 --- a/src/plugins/HPMHooking/HPMHooking.HookingPoints.inc +++ b/src/plugins/HPMHooking/HPMHooking.HookingPoints.inc @@ -6,2469 +6,2554 @@ struct HookingPointData HookingPoints[] = { /* atcommand */ - { HP_POP(atcommand->init), HP_POP2(HP_atcommand_init), 0 }, - { HP_POP(atcommand->final), HP_POP2(HP_atcommand_final), 2 }, - { HP_POP(atcommand->parse), HP_POP2(HP_atcommand_parse), 4 }, - { HP_POP(atcommand->create), HP_POP2(HP_atcommand_create), 6 }, - { HP_POP(atcommand->can_use), HP_POP2(HP_atcommand_can_use), 8 }, - { HP_POP(atcommand->can_use2), HP_POP2(HP_atcommand_can_use2), 10 }, - { HP_POP(atcommand->load_groups), HP_POP2(HP_atcommand_load_groups), 12 }, - { HP_POP(atcommand->exists), HP_POP2(HP_atcommand_exists), 14 }, - { HP_POP(atcommand->msg_read), HP_POP2(HP_atcommand_msg_read), 16 }, - { HP_POP(atcommand->final_msg), HP_POP2(HP_atcommand_final_msg), 18 }, - { HP_POP(atcommand->get_bind_byname), HP_POP2(HP_atcommand_get_bind_byname), 20 }, - { HP_POP(atcommand->get_info_byname), HP_POP2(HP_atcommand_get_info_byname), 22 }, - { HP_POP(atcommand->check_alias), HP_POP2(HP_atcommand_check_alias), 24 }, - { HP_POP(atcommand->get_suggestions), HP_POP2(HP_atcommand_get_suggestions), 26 }, - { HP_POP(atcommand->config_read), HP_POP2(HP_atcommand_config_read), 28 }, - { HP_POP(atcommand->stopattack), HP_POP2(HP_atcommand_stopattack), 30 }, - { HP_POP(atcommand->pvpoff_sub), HP_POP2(HP_atcommand_pvpoff_sub), 32 }, - { HP_POP(atcommand->pvpon_sub), HP_POP2(HP_atcommand_pvpon_sub), 34 }, - { HP_POP(atcommand->atkillmonster_sub), HP_POP2(HP_atcommand_atkillmonster_sub), 36 }, - { HP_POP(atcommand->raise_sub), HP_POP2(HP_atcommand_raise_sub), 38 }, - { HP_POP(atcommand->get_jail_time), HP_POP2(HP_atcommand_get_jail_time), 40 }, - { HP_POP(atcommand->cleanfloor_sub), HP_POP2(HP_atcommand_cleanfloor_sub), 42 }, - { HP_POP(atcommand->mutearea_sub), HP_POP2(HP_atcommand_mutearea_sub), 44 }, - { HP_POP(atcommand->commands_sub), HP_POP2(HP_atcommand_commands_sub), 46 }, - { HP_POP(atcommand->cmd_db_clear), HP_POP2(HP_atcommand_cmd_db_clear), 48 }, - { HP_POP(atcommand->cmd_db_clear_sub), HP_POP2(HP_atcommand_cmd_db_clear_sub), 50 }, - { HP_POP(atcommand->doload), HP_POP2(HP_atcommand_doload), 52 }, - { HP_POP(atcommand->base_commands), HP_POP2(HP_atcommand_base_commands), 54 }, + { HP_POP(atcommand->init, HP_atcommand_init) }, + { HP_POP(atcommand->final, HP_atcommand_final) }, + { HP_POP(atcommand->exec, HP_atcommand_exec) }, + { HP_POP(atcommand->create, HP_atcommand_create) }, + { HP_POP(atcommand->can_use, HP_atcommand_can_use) }, + { HP_POP(atcommand->can_use2, HP_atcommand_can_use2) }, + { HP_POP(atcommand->load_groups, HP_atcommand_load_groups) }, + { HP_POP(atcommand->exists, HP_atcommand_exists) }, + { HP_POP(atcommand->msg_read, HP_atcommand_msg_read) }, + { HP_POP(atcommand->final_msg, HP_atcommand_final_msg) }, + { HP_POP(atcommand->get_bind_byname, HP_atcommand_get_bind_byname) }, + { HP_POP(atcommand->get_info_byname, HP_atcommand_get_info_byname) }, + { HP_POP(atcommand->check_alias, HP_atcommand_check_alias) }, + { HP_POP(atcommand->get_suggestions, HP_atcommand_get_suggestions) }, + { HP_POP(atcommand->config_read, HP_atcommand_config_read) }, + { HP_POP(atcommand->stopattack, HP_atcommand_stopattack) }, + { HP_POP(atcommand->pvpoff_sub, HP_atcommand_pvpoff_sub) }, + { HP_POP(atcommand->pvpon_sub, HP_atcommand_pvpon_sub) }, + { HP_POP(atcommand->atkillmonster_sub, HP_atcommand_atkillmonster_sub) }, + { HP_POP(atcommand->raise_sub, HP_atcommand_raise_sub) }, + { HP_POP(atcommand->get_jail_time, HP_atcommand_get_jail_time) }, + { HP_POP(atcommand->cleanfloor_sub, HP_atcommand_cleanfloor_sub) }, + { HP_POP(atcommand->mutearea_sub, HP_atcommand_mutearea_sub) }, + { HP_POP(atcommand->commands_sub, HP_atcommand_commands_sub) }, + { HP_POP(atcommand->cmd_db_clear, HP_atcommand_cmd_db_clear) }, + { HP_POP(atcommand->cmd_db_clear_sub, HP_atcommand_cmd_db_clear_sub) }, + { HP_POP(atcommand->doload, HP_atcommand_doload) }, + { HP_POP(atcommand->base_commands, HP_atcommand_base_commands) }, + { HP_POP(atcommand->add, HP_atcommand_add) }, + { HP_POP(atcommand->msg, HP_atcommand_msg) }, /* battle */ - { HP_POP(battle->init), HP_POP2(HP_battle_init), 56 }, - { HP_POP(battle->final), HP_POP2(HP_battle_final), 58 }, - { HP_POP(battle->calc_attack), HP_POP2(HP_battle_calc_attack), 60 }, - { HP_POP(battle->calc_damage), HP_POP2(HP_battle_calc_damage), 62 }, - { HP_POP(battle->calc_gvg_damage), HP_POP2(HP_battle_calc_gvg_damage), 64 }, - { HP_POP(battle->calc_bg_damage), HP_POP2(HP_battle_calc_bg_damage), 66 }, - { HP_POP(battle->weapon_attack), HP_POP2(HP_battle_weapon_attack), 68 }, - { HP_POP(battle->calc_weapon_attack), HP_POP2(HP_battle_calc_weapon_attack), 70 }, - { HP_POP(battle->delay_damage), HP_POP2(HP_battle_delay_damage), 72 }, - { HP_POP(battle->drain), HP_POP2(HP_battle_drain), 74 }, - { HP_POP(battle->calc_return_damage), HP_POP2(HP_battle_calc_return_damage), 76 }, - { HP_POP(battle->attr_ratio), HP_POP2(HP_battle_attr_ratio), 78 }, - { HP_POP(battle->attr_fix), HP_POP2(HP_battle_attr_fix), 80 }, - { HP_POP(battle->calc_cardfix), HP_POP2(HP_battle_calc_cardfix), 82 }, - { HP_POP(battle->calc_elefix), HP_POP2(HP_battle_calc_elefix), 84 }, - { HP_POP(battle->calc_masteryfix), HP_POP2(HP_battle_calc_masteryfix), 86 }, - { HP_POP(battle->calc_skillratio), HP_POP2(HP_battle_calc_skillratio), 88 }, - { HP_POP(battle->calc_sizefix), HP_POP2(HP_battle_calc_sizefix), 90 }, - { HP_POP(battle->calc_weapon_damage), HP_POP2(HP_battle_calc_weapon_damage), 92 }, - { HP_POP(battle->calc_defense), HP_POP2(HP_battle_calc_defense), 94 }, - { HP_POP(battle->get_master), HP_POP2(HP_battle_get_master), 96 }, - { HP_POP(battle->get_targeted), HP_POP2(HP_battle_get_targeted), 98 }, - { HP_POP(battle->get_enemy), HP_POP2(HP_battle_get_enemy), 100 }, - { HP_POP(battle->get_target), HP_POP2(HP_battle_get_target), 102 }, - { HP_POP(battle->get_current_skill), HP_POP2(HP_battle_get_current_skill), 104 }, - { HP_POP(battle->check_undead), HP_POP2(HP_battle_check_undead), 106 }, - { HP_POP(battle->check_target), HP_POP2(HP_battle_check_target), 108 }, - { HP_POP(battle->check_range), HP_POP2(HP_battle_check_range), 110 }, - { HP_POP(battle->consume_ammo), HP_POP2(HP_battle_consume_ammo), 112 }, - { HP_POP(battle->get_targeted_sub), HP_POP2(HP_battle_get_targeted_sub), 114 }, - { HP_POP(battle->get_enemy_sub), HP_POP2(HP_battle_get_enemy_sub), 116 }, - { HP_POP(battle->get_enemy_area_sub), HP_POP2(HP_battle_get_enemy_area_sub), 118 }, - { HP_POP(battle->delay_damage_sub), HP_POP2(HP_battle_delay_damage_sub), 120 }, - { HP_POP(battle->blewcount_bonus), HP_POP2(HP_battle_blewcount_bonus), 122 }, - { HP_POP(battle->range_type), HP_POP2(HP_battle_range_type), 124 }, - { HP_POP(battle->calc_base_damage), HP_POP2(HP_battle_calc_base_damage), 126 }, - { HP_POP(battle->calc_base_damage2), HP_POP2(HP_battle_calc_base_damage2), 128 }, - { HP_POP(battle->calc_misc_attack), HP_POP2(HP_battle_calc_misc_attack), 130 }, - { HP_POP(battle->calc_magic_attack), HP_POP2(HP_battle_calc_magic_attack), 132 }, - { HP_POP(battle->adjust_skill_damage), HP_POP2(HP_battle_adjust_skill_damage), 134 }, - { HP_POP(battle->add_mastery), HP_POP2(HP_battle_add_mastery), 136 }, - { HP_POP(battle->calc_drain), HP_POP2(HP_battle_calc_drain), 138 }, - { HP_POP(battle->config_read), HP_POP2(HP_battle_config_read), 140 }, - { HP_POP(battle->config_set_defaults), HP_POP2(HP_battle_config_set_defaults), 142 }, - { HP_POP(battle->config_set_value), HP_POP2(HP_battle_config_set_value), 144 }, - { HP_POP(battle->config_get_value), HP_POP2(HP_battle_config_get_value), 146 }, - { HP_POP(battle->config_adjust), HP_POP2(HP_battle_config_adjust), 148 }, - { HP_POP(battle->get_enemy_area), HP_POP2(HP_battle_get_enemy_area), 150 }, - { HP_POP(battle->damage_area), HP_POP2(HP_battle_damage_area), 152 }, + { HP_POP(battle->init, HP_battle_init) }, + { HP_POP(battle->final, HP_battle_final) }, + { HP_POP(battle->calc_attack, HP_battle_calc_attack) }, + { HP_POP(battle->calc_damage, HP_battle_calc_damage) }, + { HP_POP(battle->calc_gvg_damage, HP_battle_calc_gvg_damage) }, + { HP_POP(battle->calc_bg_damage, HP_battle_calc_bg_damage) }, + { HP_POP(battle->weapon_attack, HP_battle_weapon_attack) }, + { HP_POP(battle->calc_weapon_attack, HP_battle_calc_weapon_attack) }, + { HP_POP(battle->delay_damage, HP_battle_delay_damage) }, + { HP_POP(battle->drain, HP_battle_drain) }, + { HP_POP(battle->reflect_damage, HP_battle_reflect_damage) }, + { HP_POP(battle->attr_ratio, HP_battle_attr_ratio) }, + { HP_POP(battle->attr_fix, HP_battle_attr_fix) }, + { HP_POP(battle->calc_cardfix, HP_battle_calc_cardfix) }, + { HP_POP(battle->calc_elefix, HP_battle_calc_elefix) }, + { HP_POP(battle->calc_masteryfix, HP_battle_calc_masteryfix) }, + { HP_POP(battle->calc_chorusbonus, HP_battle_calc_chorusbonus) }, + { HP_POP(battle->calc_skillratio, HP_battle_calc_skillratio) }, + { HP_POP(battle->calc_sizefix, HP_battle_calc_sizefix) }, + { HP_POP(battle->calc_weapon_damage, HP_battle_calc_weapon_damage) }, + { HP_POP(battle->calc_defense, HP_battle_calc_defense) }, + { HP_POP(battle->get_master, HP_battle_get_master) }, + { HP_POP(battle->get_targeted, HP_battle_get_targeted) }, + { HP_POP(battle->get_enemy, HP_battle_get_enemy) }, + { HP_POP(battle->get_target, HP_battle_get_target) }, + { HP_POP(battle->get_current_skill, HP_battle_get_current_skill) }, + { HP_POP(battle->check_undead, HP_battle_check_undead) }, + { HP_POP(battle->check_target, HP_battle_check_target) }, + { HP_POP(battle->check_range, HP_battle_check_range) }, + { HP_POP(battle->consume_ammo, HP_battle_consume_ammo) }, + { HP_POP(battle->get_targeted_sub, HP_battle_get_targeted_sub) }, + { HP_POP(battle->get_enemy_sub, HP_battle_get_enemy_sub) }, + { HP_POP(battle->get_enemy_area_sub, HP_battle_get_enemy_area_sub) }, + { HP_POP(battle->delay_damage_sub, HP_battle_delay_damage_sub) }, + { HP_POP(battle->blewcount_bonus, HP_battle_blewcount_bonus) }, + { HP_POP(battle->range_type, HP_battle_range_type) }, + { HP_POP(battle->calc_base_damage, HP_battle_calc_base_damage) }, + { HP_POP(battle->calc_base_damage2, HP_battle_calc_base_damage2) }, + { HP_POP(battle->calc_misc_attack, HP_battle_calc_misc_attack) }, + { HP_POP(battle->calc_magic_attack, HP_battle_calc_magic_attack) }, + { HP_POP(battle->adjust_skill_damage, HP_battle_adjust_skill_damage) }, + { HP_POP(battle->add_mastery, HP_battle_add_mastery) }, + { HP_POP(battle->calc_drain, HP_battle_calc_drain) }, + { HP_POP(battle->config_read, HP_battle_config_read) }, + { HP_POP(battle->config_set_defaults, HP_battle_config_set_defaults) }, + { HP_POP(battle->config_set_value, HP_battle_config_set_value) }, + { HP_POP(battle->config_get_value, HP_battle_config_get_value) }, + { HP_POP(battle->config_adjust, HP_battle_config_adjust) }, + { HP_POP(battle->get_enemy_area, HP_battle_get_enemy_area) }, + { HP_POP(battle->damage_area, HP_battle_damage_area) }, /* bg */ - { HP_POP(bg->init), HP_POP2(HP_bg_init), 154 }, - { HP_POP(bg->final), HP_POP2(HP_bg_final), 156 }, - { HP_POP(bg->name2arena), HP_POP2(HP_bg_name2arena), 158 }, - { HP_POP(bg->queue_add), HP_POP2(HP_bg_queue_add), 160 }, - { HP_POP(bg->can_queue), HP_POP2(HP_bg_can_queue), 162 }, - { HP_POP(bg->id2pos), HP_POP2(HP_bg_id2pos), 164 }, - { HP_POP(bg->queue_pc_cleanup), HP_POP2(HP_bg_queue_pc_cleanup), 166 }, - { HP_POP(bg->begin), HP_POP2(HP_bg_begin), 168 }, - { HP_POP(bg->begin_timer), HP_POP2(HP_bg_begin_timer), 170 }, - { HP_POP(bg->queue_pregame), HP_POP2(HP_bg_queue_pregame), 172 }, - { HP_POP(bg->fillup_timer), HP_POP2(HP_bg_fillup_timer), 174 }, - { HP_POP(bg->queue_ready_ack), HP_POP2(HP_bg_queue_ready_ack), 176 }, - { HP_POP(bg->match_over), HP_POP2(HP_bg_match_over), 178 }, - { HP_POP(bg->queue_check), HP_POP2(HP_bg_queue_check), 180 }, - { HP_POP(bg->team_search), HP_POP2(HP_bg_team_search), 182 }, - { HP_POP(bg->getavailablesd), HP_POP2(HP_bg_getavailablesd), 184 }, - { HP_POP(bg->team_delete), HP_POP2(HP_bg_team_delete), 186 }, - { HP_POP(bg->team_warp), HP_POP2(HP_bg_team_warp), 188 }, - { HP_POP(bg->send_dot_remove), HP_POP2(HP_bg_send_dot_remove), 190 }, - { HP_POP(bg->team_join), HP_POP2(HP_bg_team_join), 192 }, - { HP_POP(bg->team_leave), HP_POP2(HP_bg_team_leave), 194 }, - { HP_POP(bg->member_respawn), HP_POP2(HP_bg_member_respawn), 196 }, - { HP_POP(bg->create), HP_POP2(HP_bg_create), 198 }, - { HP_POP(bg->team_get_id), HP_POP2(HP_bg_team_get_id), 200 }, - { HP_POP(bg->send_message), HP_POP2(HP_bg_send_message), 202 }, - { HP_POP(bg->send_xy_timer_sub), HP_POP2(HP_bg_send_xy_timer_sub), 204 }, - { HP_POP(bg->send_xy_timer), HP_POP2(HP_bg_send_xy_timer), 206 }, - { HP_POP(bg->config_read), HP_POP2(HP_bg_config_read), 208 }, + { HP_POP(bg->init, HP_bg_init) }, + { HP_POP(bg->final, HP_bg_final) }, + { HP_POP(bg->name2arena, HP_bg_name2arena) }, + { HP_POP(bg->queue_add, HP_bg_queue_add) }, + { HP_POP(bg->can_queue, HP_bg_can_queue) }, + { HP_POP(bg->id2pos, HP_bg_id2pos) }, + { HP_POP(bg->queue_pc_cleanup, HP_bg_queue_pc_cleanup) }, + { HP_POP(bg->begin, HP_bg_begin) }, + { HP_POP(bg->begin_timer, HP_bg_begin_timer) }, + { HP_POP(bg->queue_pregame, HP_bg_queue_pregame) }, + { HP_POP(bg->fillup_timer, HP_bg_fillup_timer) }, + { HP_POP(bg->queue_ready_ack, HP_bg_queue_ready_ack) }, + { HP_POP(bg->match_over, HP_bg_match_over) }, + { HP_POP(bg->queue_check, HP_bg_queue_check) }, + { HP_POP(bg->team_search, HP_bg_team_search) }, + { HP_POP(bg->getavailablesd, HP_bg_getavailablesd) }, + { HP_POP(bg->team_delete, HP_bg_team_delete) }, + { HP_POP(bg->team_warp, HP_bg_team_warp) }, + { HP_POP(bg->send_dot_remove, HP_bg_send_dot_remove) }, + { HP_POP(bg->team_join, HP_bg_team_join) }, + { HP_POP(bg->team_leave, HP_bg_team_leave) }, + { HP_POP(bg->member_respawn, HP_bg_member_respawn) }, + { HP_POP(bg->create, HP_bg_create) }, + { HP_POP(bg->team_get_id, HP_bg_team_get_id) }, + { HP_POP(bg->send_message, HP_bg_send_message) }, + { HP_POP(bg->send_xy_timer_sub, HP_bg_send_xy_timer_sub) }, + { HP_POP(bg->send_xy_timer, HP_bg_send_xy_timer) }, + { HP_POP(bg->config_read, HP_bg_config_read) }, /* buyingstore */ - { HP_POP(buyingstore->setup), HP_POP2(HP_buyingstore_setup), 210 }, - { HP_POP(buyingstore->create), HP_POP2(HP_buyingstore_create), 212 }, - { HP_POP(buyingstore->close), HP_POP2(HP_buyingstore_close), 214 }, - { HP_POP(buyingstore->open), HP_POP2(HP_buyingstore_open), 216 }, - { HP_POP(buyingstore->trade), HP_POP2(HP_buyingstore_trade), 218 }, - { HP_POP(buyingstore->search), HP_POP2(HP_buyingstore_search), 220 }, - { HP_POP(buyingstore->searchall), HP_POP2(HP_buyingstore_searchall), 222 }, - { HP_POP(buyingstore->getuid), HP_POP2(HP_buyingstore_getuid), 224 }, + { HP_POP(buyingstore->setup, HP_buyingstore_setup) }, + { HP_POP(buyingstore->create, HP_buyingstore_create) }, + { HP_POP(buyingstore->close, HP_buyingstore_close) }, + { HP_POP(buyingstore->open, HP_buyingstore_open) }, + { HP_POP(buyingstore->trade, HP_buyingstore_trade) }, + { HP_POP(buyingstore->search, HP_buyingstore_search) }, + { HP_POP(buyingstore->searchall, HP_buyingstore_searchall) }, + { HP_POP(buyingstore->getuid, HP_buyingstore_getuid) }, /* chat */ - { HP_POP(chat->create_pc_chat), HP_POP2(HP_chat_create_pc_chat), 226 }, - { HP_POP(chat->join), HP_POP2(HP_chat_join), 228 }, - { HP_POP(chat->leave), HP_POP2(HP_chat_leave), 230 }, - { HP_POP(chat->change_owner), HP_POP2(HP_chat_change_owner), 232 }, - { HP_POP(chat->change_status), HP_POP2(HP_chat_change_status), 234 }, - { HP_POP(chat->kick), HP_POP2(HP_chat_kick), 236 }, - { HP_POP(chat->create_npc_chat), HP_POP2(HP_chat_create_npc_chat), 238 }, - { HP_POP(chat->delete_npc_chat), HP_POP2(HP_chat_delete_npc_chat), 240 }, - { HP_POP(chat->enable_event), HP_POP2(HP_chat_enable_event), 242 }, - { HP_POP(chat->disable_event), HP_POP2(HP_chat_disable_event), 244 }, - { HP_POP(chat->npc_kick_all), HP_POP2(HP_chat_npc_kick_all), 246 }, - { HP_POP(chat->trigger_event), HP_POP2(HP_chat_trigger_event), 248 }, - { HP_POP(chat->create), HP_POP2(HP_chat_create), 250 }, + { HP_POP(chat->create_pc_chat, HP_chat_create_pc_chat) }, + { HP_POP(chat->join, HP_chat_join) }, + { HP_POP(chat->leave, HP_chat_leave) }, + { HP_POP(chat->change_owner, HP_chat_change_owner) }, + { HP_POP(chat->change_status, HP_chat_change_status) }, + { HP_POP(chat->kick, HP_chat_kick) }, + { HP_POP(chat->create_npc_chat, HP_chat_create_npc_chat) }, + { HP_POP(chat->delete_npc_chat, HP_chat_delete_npc_chat) }, + { HP_POP(chat->enable_event, HP_chat_enable_event) }, + { HP_POP(chat->disable_event, HP_chat_disable_event) }, + { HP_POP(chat->npc_kick_all, HP_chat_npc_kick_all) }, + { HP_POP(chat->trigger_event, HP_chat_trigger_event) }, + { HP_POP(chat->create, HP_chat_create) }, /* chrif */ - { HP_POP(chrif->final), HP_POP2(HP_chrif_final), 252 }, - { HP_POP(chrif->init), HP_POP2(HP_chrif_init), 254 }, - { HP_POP(chrif->setuserid), HP_POP2(HP_chrif_setuserid), 256 }, - { HP_POP(chrif->setpasswd), HP_POP2(HP_chrif_setpasswd), 258 }, - { HP_POP(chrif->checkdefaultlogin), HP_POP2(HP_chrif_checkdefaultlogin), 260 }, - { HP_POP(chrif->setip), HP_POP2(HP_chrif_setip), 262 }, - { HP_POP(chrif->setport), HP_POP2(HP_chrif_setport), 264 }, - { HP_POP(chrif->isconnected), HP_POP2(HP_chrif_isconnected), 266 }, - { HP_POP(chrif->check_shutdown), HP_POP2(HP_chrif_check_shutdown), 268 }, - { HP_POP(chrif->search), HP_POP2(HP_chrif_search), 270 }, - { HP_POP(chrif->auth_check), HP_POP2(HP_chrif_auth_check), 272 }, - { HP_POP(chrif->auth_delete), HP_POP2(HP_chrif_auth_delete), 274 }, - { HP_POP(chrif->auth_finished), HP_POP2(HP_chrif_auth_finished), 276 }, - { HP_POP(chrif->authreq), HP_POP2(HP_chrif_authreq), 278 }, - { HP_POP(chrif->authok), HP_POP2(HP_chrif_authok), 280 }, - { HP_POP(chrif->scdata_request), HP_POP2(HP_chrif_scdata_request), 282 }, - { HP_POP(chrif->save), HP_POP2(HP_chrif_save), 284 }, - { HP_POP(chrif->charselectreq), HP_POP2(HP_chrif_charselectreq), 286 }, - { HP_POP(chrif->changemapserver), HP_POP2(HP_chrif_changemapserver), 288 }, - { HP_POP(chrif->searchcharid), HP_POP2(HP_chrif_searchcharid), 290 }, - { HP_POP(chrif->changeemail), HP_POP2(HP_chrif_changeemail), 292 }, - { HP_POP(chrif->char_ask_name), HP_POP2(HP_chrif_char_ask_name), 294 }, - { HP_POP(chrif->updatefamelist), HP_POP2(HP_chrif_updatefamelist), 296 }, - { HP_POP(chrif->buildfamelist), HP_POP2(HP_chrif_buildfamelist), 298 }, - { HP_POP(chrif->save_scdata), HP_POP2(HP_chrif_save_scdata), 300 }, - { HP_POP(chrif->ragsrvinfo), HP_POP2(HP_chrif_ragsrvinfo), 302 }, - { HP_POP(chrif->char_offline), HP_POP2(HP_chrif_char_offline), 304 }, - { HP_POP(chrif->char_offline_nsd), HP_POP2(HP_chrif_char_offline_nsd), 306 }, - { HP_POP(chrif->char_reset_offline), HP_POP2(HP_chrif_char_reset_offline), 308 }, - { HP_POP(chrif->send_users_tochar), HP_POP2(HP_chrif_send_users_tochar), 310 }, - { HP_POP(chrif->char_online), HP_POP2(HP_chrif_char_online), 312 }, - { HP_POP(chrif->changesex), HP_POP2(HP_chrif_changesex), 314 }, - { HP_POP(chrif->divorce), HP_POP2(HP_chrif_divorce), 316 }, - { HP_POP(chrif->removefriend), HP_POP2(HP_chrif_removefriend), 318 }, - { HP_POP(chrif->send_report), HP_POP2(HP_chrif_send_report), 320 }, - { HP_POP(chrif->flush_fifo), HP_POP2(HP_chrif_flush_fifo), 322 }, - { HP_POP(chrif->skillid2idx), HP_POP2(HP_chrif_skillid2idx), 324 }, - { HP_POP(chrif->sd_to_auth), HP_POP2(HP_chrif_sd_to_auth), 326 }, - { HP_POP(chrif->check_connect_char_server), HP_POP2(HP_chrif_check_connect_char_server), 328 }, - { HP_POP(chrif->auth_logout), HP_POP2(HP_chrif_auth_logout), 330 }, - { HP_POP(chrif->save_ack), HP_POP2(HP_chrif_save_ack), 332 }, - { HP_POP(chrif->reconnect), HP_POP2(HP_chrif_reconnect), 334 }, - { HP_POP(chrif->auth_db_cleanup_sub), HP_POP2(HP_chrif_auth_db_cleanup_sub), 336 }, - { HP_POP(chrif->char_ask_name_answer), HP_POP2(HP_chrif_char_ask_name_answer), 338 }, - { HP_POP(chrif->auth_db_final), HP_POP2(HP_chrif_auth_db_final), 340 }, - { HP_POP(chrif->send_usercount_tochar), HP_POP2(HP_chrif_send_usercount_tochar), 342 }, - { HP_POP(chrif->auth_db_cleanup), HP_POP2(HP_chrif_auth_db_cleanup), 344 }, - { HP_POP(chrif->connect), HP_POP2(HP_chrif_connect), 346 }, - { HP_POP(chrif->connectack), HP_POP2(HP_chrif_connectack), 348 }, - { HP_POP(chrif->sendmap), HP_POP2(HP_chrif_sendmap), 350 }, - { HP_POP(chrif->sendmapack), HP_POP2(HP_chrif_sendmapack), 352 }, - { HP_POP(chrif->recvmap), HP_POP2(HP_chrif_recvmap), 354 }, - { HP_POP(chrif->changemapserverack), HP_POP2(HP_chrif_changemapserverack), 356 }, - { HP_POP(chrif->changedsex), HP_POP2(HP_chrif_changedsex), 358 }, - { HP_POP(chrif->divorceack), HP_POP2(HP_chrif_divorceack), 360 }, - { HP_POP(chrif->accountban), HP_POP2(HP_chrif_accountban), 362 }, - { HP_POP(chrif->recvfamelist), HP_POP2(HP_chrif_recvfamelist), 364 }, - { HP_POP(chrif->load_scdata), HP_POP2(HP_chrif_load_scdata), 366 }, - { HP_POP(chrif->update_ip), HP_POP2(HP_chrif_update_ip), 368 }, - { HP_POP(chrif->disconnectplayer), HP_POP2(HP_chrif_disconnectplayer), 370 }, - { HP_POP(chrif->removemap), HP_POP2(HP_chrif_removemap), 372 }, - { HP_POP(chrif->updatefamelist_ack), HP_POP2(HP_chrif_updatefamelist_ack), 374 }, - { HP_POP(chrif->keepalive), HP_POP2(HP_chrif_keepalive), 376 }, - { HP_POP(chrif->keepalive_ack), HP_POP2(HP_chrif_keepalive_ack), 378 }, - { HP_POP(chrif->deadopt), HP_POP2(HP_chrif_deadopt), 380 }, - { HP_POP(chrif->authfail), HP_POP2(HP_chrif_authfail), 382 }, - { HP_POP(chrif->on_ready), HP_POP2(HP_chrif_on_ready), 384 }, - { HP_POP(chrif->on_disconnect), HP_POP2(HP_chrif_on_disconnect), 386 }, - { HP_POP(chrif->parse), HP_POP2(HP_chrif_parse), 388 }, + { HP_POP(chrif->init, HP_chrif_init) }, + { HP_POP(chrif->final, HP_chrif_final) }, + { HP_POP(chrif->setuserid, HP_chrif_setuserid) }, + { HP_POP(chrif->setpasswd, HP_chrif_setpasswd) }, + { HP_POP(chrif->checkdefaultlogin, HP_chrif_checkdefaultlogin) }, + { HP_POP(chrif->setip, HP_chrif_setip) }, + { HP_POP(chrif->setport, HP_chrif_setport) }, + { HP_POP(chrif->isconnected, HP_chrif_isconnected) }, + { HP_POP(chrif->check_shutdown, HP_chrif_check_shutdown) }, + { HP_POP(chrif->search, HP_chrif_search) }, + { HP_POP(chrif->auth_check, HP_chrif_auth_check) }, + { HP_POP(chrif->auth_delete, HP_chrif_auth_delete) }, + { HP_POP(chrif->auth_finished, HP_chrif_auth_finished) }, + { HP_POP(chrif->authreq, HP_chrif_authreq) }, + { HP_POP(chrif->authok, HP_chrif_authok) }, + { HP_POP(chrif->scdata_request, HP_chrif_scdata_request) }, + { HP_POP(chrif->save, HP_chrif_save) }, + { HP_POP(chrif->charselectreq, HP_chrif_charselectreq) }, + { HP_POP(chrif->changemapserver, HP_chrif_changemapserver) }, + { HP_POP(chrif->searchcharid, HP_chrif_searchcharid) }, + { HP_POP(chrif->changeemail, HP_chrif_changeemail) }, + { HP_POP(chrif->char_ask_name, HP_chrif_char_ask_name) }, + { HP_POP(chrif->updatefamelist, HP_chrif_updatefamelist) }, + { HP_POP(chrif->buildfamelist, HP_chrif_buildfamelist) }, + { HP_POP(chrif->save_scdata, HP_chrif_save_scdata) }, + { HP_POP(chrif->ragsrvinfo, HP_chrif_ragsrvinfo) }, + { HP_POP(chrif->char_offline_nsd, HP_chrif_char_offline_nsd) }, + { HP_POP(chrif->char_reset_offline, HP_chrif_char_reset_offline) }, + { HP_POP(chrif->send_users_tochar, HP_chrif_send_users_tochar) }, + { HP_POP(chrif->char_online, HP_chrif_char_online) }, + { HP_POP(chrif->changesex, HP_chrif_changesex) }, + { HP_POP(chrif->divorce, HP_chrif_divorce) }, + { HP_POP(chrif->removefriend, HP_chrif_removefriend) }, + { HP_POP(chrif->send_report, HP_chrif_send_report) }, + { HP_POP(chrif->flush, HP_chrif_flush) }, + { HP_POP(chrif->skillid2idx, HP_chrif_skillid2idx) }, + { HP_POP(chrif->sd_to_auth, HP_chrif_sd_to_auth) }, + { HP_POP(chrif->check_connect_char_server, HP_chrif_check_connect_char_server) }, + { HP_POP(chrif->auth_logout, HP_chrif_auth_logout) }, + { HP_POP(chrif->save_ack, HP_chrif_save_ack) }, + { HP_POP(chrif->reconnect, HP_chrif_reconnect) }, + { HP_POP(chrif->auth_db_cleanup_sub, HP_chrif_auth_db_cleanup_sub) }, + { HP_POP(chrif->char_ask_name_answer, HP_chrif_char_ask_name_answer) }, + { HP_POP(chrif->auth_db_final, HP_chrif_auth_db_final) }, + { HP_POP(chrif->send_usercount_tochar, HP_chrif_send_usercount_tochar) }, + { HP_POP(chrif->auth_db_cleanup, HP_chrif_auth_db_cleanup) }, + { HP_POP(chrif->connect, HP_chrif_connect) }, + { HP_POP(chrif->connectack, HP_chrif_connectack) }, + { HP_POP(chrif->sendmap, HP_chrif_sendmap) }, + { HP_POP(chrif->sendmapack, HP_chrif_sendmapack) }, + { HP_POP(chrif->recvmap, HP_chrif_recvmap) }, + { HP_POP(chrif->changemapserverack, HP_chrif_changemapserverack) }, + { HP_POP(chrif->changedsex, HP_chrif_changedsex) }, + { HP_POP(chrif->divorceack, HP_chrif_divorceack) }, + { HP_POP(chrif->idbanned, HP_chrif_idbanned) }, + { HP_POP(chrif->recvfamelist, HP_chrif_recvfamelist) }, + { HP_POP(chrif->load_scdata, HP_chrif_load_scdata) }, + { HP_POP(chrif->update_ip, HP_chrif_update_ip) }, + { HP_POP(chrif->disconnectplayer, HP_chrif_disconnectplayer) }, + { HP_POP(chrif->removemap, HP_chrif_removemap) }, + { HP_POP(chrif->updatefamelist_ack, HP_chrif_updatefamelist_ack) }, + { HP_POP(chrif->keepalive, HP_chrif_keepalive) }, + { HP_POP(chrif->keepalive_ack, HP_chrif_keepalive_ack) }, + { HP_POP(chrif->deadopt, HP_chrif_deadopt) }, + { HP_POP(chrif->authfail, HP_chrif_authfail) }, + { HP_POP(chrif->on_ready, HP_chrif_on_ready) }, + { HP_POP(chrif->on_disconnect, HP_chrif_on_disconnect) }, + { HP_POP(chrif->parse, HP_chrif_parse) }, + { HP_POP(chrif->save_scdata_single, HP_chrif_save_scdata_single) }, + { HP_POP(chrif->del_scdata_single, HP_chrif_del_scdata_single) }, /* clif */ - { HP_POP(clif->init), HP_POP2(HP_clif_init), 390 }, - { HP_POP(clif->final), HP_POP2(HP_clif_final), 392 }, - { HP_POP(clif->setip), HP_POP2(HP_clif_setip), 394 }, - { HP_POP(clif->setbindip), HP_POP2(HP_clif_setbindip), 396 }, - { HP_POP(clif->setport), HP_POP2(HP_clif_setport), 398 }, - { HP_POP(clif->refresh_ip), HP_POP2(HP_clif_refresh_ip), 400 }, - { HP_POP(clif->send), HP_POP2(HP_clif_send), 402 }, - { HP_POP(clif->send_sub), HP_POP2(HP_clif_send_sub), 404 }, - { HP_POP(clif->parse), HP_POP2(HP_clif_parse), 406 }, - { HP_POP(clif->parse_cmd), HP_POP2(HP_clif_parse_cmd), 408 }, - { HP_POP(clif->decrypt_cmd), HP_POP2(HP_clif_decrypt_cmd), 410 }, - { HP_POP(clif->authok), HP_POP2(HP_clif_authok), 412 }, - { HP_POP(clif->authrefuse), HP_POP2(HP_clif_authrefuse), 414 }, - { HP_POP(clif->authfail_fd), HP_POP2(HP_clif_authfail_fd), 416 }, - { HP_POP(clif->charselectok), HP_POP2(HP_clif_charselectok), 418 }, - { HP_POP(clif->dropflooritem), HP_POP2(HP_clif_dropflooritem), 420 }, - { HP_POP(clif->clearflooritem), HP_POP2(HP_clif_clearflooritem), 422 }, - { HP_POP(clif->additem), HP_POP2(HP_clif_additem), 424 }, - { HP_POP(clif->dropitem), HP_POP2(HP_clif_dropitem), 426 }, - { HP_POP(clif->delitem), HP_POP2(HP_clif_delitem), 428 }, - { HP_POP(clif->takeitem), HP_POP2(HP_clif_takeitem), 430 }, - { HP_POP(clif->arrowequip), HP_POP2(HP_clif_arrowequip), 432 }, - { HP_POP(clif->arrow_fail), HP_POP2(HP_clif_arrow_fail), 434 }, - { HP_POP(clif->use_card), HP_POP2(HP_clif_use_card), 436 }, - { HP_POP(clif->cart_additem), HP_POP2(HP_clif_cart_additem), 438 }, - { HP_POP(clif->cart_delitem), HP_POP2(HP_clif_cart_delitem), 440 }, - { HP_POP(clif->equipitemack), HP_POP2(HP_clif_equipitemack), 442 }, - { HP_POP(clif->unequipitemack), HP_POP2(HP_clif_unequipitemack), 444 }, - { HP_POP(clif->useitemack), HP_POP2(HP_clif_useitemack), 446 }, - { HP_POP(clif->addcards), HP_POP2(HP_clif_addcards), 448 }, - { HP_POP(clif->addcards2), HP_POP2(HP_clif_addcards2), 450 }, - { HP_POP(clif->item_sub), HP_POP2(HP_clif_item_sub), 452 }, - { HP_POP(clif->getareachar_item), HP_POP2(HP_clif_getareachar_item), 454 }, - { HP_POP(clif->cart_additem_ack), HP_POP2(HP_clif_cart_additem_ack), 456 }, - { HP_POP(clif->cashshop_load), HP_POP2(HP_clif_cashshop_load), 458 }, - { HP_POP(clif->package_announce), HP_POP2(HP_clif_package_announce), 460 }, - { HP_POP(clif->clearunit_single), HP_POP2(HP_clif_clearunit_single), 462 }, - { HP_POP(clif->clearunit_area), HP_POP2(HP_clif_clearunit_area), 464 }, - { HP_POP(clif->clearunit_delayed), HP_POP2(HP_clif_clearunit_delayed), 466 }, - { HP_POP(clif->walkok), HP_POP2(HP_clif_walkok), 468 }, - { HP_POP(clif->move), HP_POP2(HP_clif_move), 470 }, - { HP_POP(clif->move2), HP_POP2(HP_clif_move2), 472 }, - { HP_POP(clif->blown), HP_POP2(HP_clif_blown), 474 }, - { HP_POP(clif->slide), HP_POP2(HP_clif_slide), 476 }, - { HP_POP(clif->fixpos), HP_POP2(HP_clif_fixpos), 478 }, - { HP_POP(clif->changelook), HP_POP2(HP_clif_changelook), 480 }, - { HP_POP(clif->changetraplook), HP_POP2(HP_clif_changetraplook), 482 }, - { HP_POP(clif->refreshlook), HP_POP2(HP_clif_refreshlook), 484 }, - { HP_POP(clif->class_change), HP_POP2(HP_clif_class_change), 486 }, - { HP_POP(clif->skill_setunit), HP_POP2(HP_clif_skill_setunit), 488 }, - { HP_POP(clif->skill_delunit), HP_POP2(HP_clif_skill_delunit), 490 }, - { HP_POP(clif->skillunit_update), HP_POP2(HP_clif_skillunit_update), 492 }, - { HP_POP(clif->clearunit_delayed_sub), HP_POP2(HP_clif_clearunit_delayed_sub), 494 }, - { HP_POP(clif->set_unit_idle), HP_POP2(HP_clif_set_unit_idle), 496 }, - { HP_POP(clif->spawn_unit), HP_POP2(HP_clif_spawn_unit), 498 }, - { HP_POP(clif->spawn_unit2), HP_POP2(HP_clif_spawn_unit2), 500 }, - { HP_POP(clif->set_unit_idle2), HP_POP2(HP_clif_set_unit_idle2), 502 }, - { HP_POP(clif->set_unit_walking), HP_POP2(HP_clif_set_unit_walking), 504 }, - { HP_POP(clif->calc_walkdelay), HP_POP2(HP_clif_calc_walkdelay), 506 }, - { HP_POP(clif->getareachar_skillunit), HP_POP2(HP_clif_getareachar_skillunit), 508 }, - { HP_POP(clif->getareachar_unit), HP_POP2(HP_clif_getareachar_unit), 510 }, - { HP_POP(clif->clearchar_skillunit), HP_POP2(HP_clif_clearchar_skillunit), 512 }, - { HP_POP(clif->getareachar), HP_POP2(HP_clif_getareachar), 514 }, - { HP_POP(clif->spawn), HP_POP2(HP_clif_spawn), 516 }, - { HP_POP(clif->changemap), HP_POP2(HP_clif_changemap), 518 }, - { HP_POP(clif->changemapcell), HP_POP2(HP_clif_changemapcell), 520 }, - { HP_POP(clif->map_property), HP_POP2(HP_clif_map_property), 522 }, - { HP_POP(clif->pvpset), HP_POP2(HP_clif_pvpset), 524 }, - { HP_POP(clif->map_property_mapall), HP_POP2(HP_clif_map_property_mapall), 526 }, - { HP_POP(clif->bossmapinfo), HP_POP2(HP_clif_bossmapinfo), 528 }, - { HP_POP(clif->map_type), HP_POP2(HP_clif_map_type), 530 }, - { HP_POP(clif->maptypeproperty2), HP_POP2(HP_clif_maptypeproperty2), 532 }, - { HP_POP(clif->changemapserver), HP_POP2(HP_clif_changemapserver), 534 }, - { HP_POP(clif->npcbuysell), HP_POP2(HP_clif_npcbuysell), 536 }, - { HP_POP(clif->buylist), HP_POP2(HP_clif_buylist), 538 }, - { HP_POP(clif->selllist), HP_POP2(HP_clif_selllist), 540 }, - { HP_POP(clif->cashshop_show), HP_POP2(HP_clif_cashshop_show), 542 }, - { HP_POP(clif->npc_buy_result), HP_POP2(HP_clif_npc_buy_result), 544 }, - { HP_POP(clif->npc_sell_result), HP_POP2(HP_clif_npc_sell_result), 546 }, - { HP_POP(clif->cashshop_ack), HP_POP2(HP_clif_cashshop_ack), 548 }, - { HP_POP(clif->scriptmes), HP_POP2(HP_clif_scriptmes), 550 }, - { HP_POP(clif->scriptnext), HP_POP2(HP_clif_scriptnext), 552 }, - { HP_POP(clif->scriptclose), HP_POP2(HP_clif_scriptclose), 554 }, - { HP_POP(clif->scriptmenu), HP_POP2(HP_clif_scriptmenu), 556 }, - { HP_POP(clif->scriptinput), HP_POP2(HP_clif_scriptinput), 558 }, - { HP_POP(clif->scriptinputstr), HP_POP2(HP_clif_scriptinputstr), 560 }, - { HP_POP(clif->cutin), HP_POP2(HP_clif_cutin), 562 }, - { HP_POP(clif->sendfakenpc), HP_POP2(HP_clif_sendfakenpc), 564 }, - { HP_POP(clif->scriptclear), HP_POP2(HP_clif_scriptclear), 566 }, - { HP_POP(clif->viewpoint), HP_POP2(HP_clif_viewpoint), 568 }, - { HP_POP(clif->damage), HP_POP2(HP_clif_damage), 570 }, - { HP_POP(clif->sitting), HP_POP2(HP_clif_sitting), 572 }, - { HP_POP(clif->standing), HP_POP2(HP_clif_standing), 574 }, - { HP_POP(clif->arrow_create_list), HP_POP2(HP_clif_arrow_create_list), 576 }, - { HP_POP(clif->refresh), HP_POP2(HP_clif_refresh), 578 }, - { HP_POP(clif->fame_blacksmith), HP_POP2(HP_clif_fame_blacksmith), 580 }, - { HP_POP(clif->fame_alchemist), HP_POP2(HP_clif_fame_alchemist), 582 }, - { HP_POP(clif->fame_taekwon), HP_POP2(HP_clif_fame_taekwon), 584 }, - { HP_POP(clif->ranklist), HP_POP2(HP_clif_ranklist), 586 }, - { HP_POP(clif->update_rankingpoint), HP_POP2(HP_clif_update_rankingpoint), 588 }, - { HP_POP(clif->pRanklist), HP_POP2(HP_clif_pRanklist), 590 }, - { HP_POP(clif->hotkeys), HP_POP2(HP_clif_hotkeys), 592 }, - { HP_POP(clif->insight), HP_POP2(HP_clif_insight), 594 }, - { HP_POP(clif->outsight), HP_POP2(HP_clif_outsight), 596 }, - { HP_POP(clif->skillcastcancel), HP_POP2(HP_clif_skillcastcancel), 598 }, - { HP_POP(clif->skill_fail), HP_POP2(HP_clif_skill_fail), 600 }, - { HP_POP(clif->skill_cooldown), HP_POP2(HP_clif_skill_cooldown), 602 }, - { HP_POP(clif->skill_memomessage), HP_POP2(HP_clif_skill_memomessage), 604 }, - { HP_POP(clif->skill_mapinfomessage), HP_POP2(HP_clif_skill_mapinfomessage), 606 }, - { HP_POP(clif->skill_produce_mix_list), HP_POP2(HP_clif_skill_produce_mix_list), 608 }, - { HP_POP(clif->cooking_list), HP_POP2(HP_clif_cooking_list), 610 }, - { HP_POP(clif->autospell), HP_POP2(HP_clif_autospell), 612 }, - { HP_POP(clif->combo_delay), HP_POP2(HP_clif_combo_delay), 614 }, - { HP_POP(clif->status_change), HP_POP2(HP_clif_status_change), 616 }, - { HP_POP(clif->insert_card), HP_POP2(HP_clif_insert_card), 618 }, - { HP_POP(clif->inventorylist), HP_POP2(HP_clif_inventorylist), 620 }, - { HP_POP(clif->equiplist), HP_POP2(HP_clif_equiplist), 622 }, - { HP_POP(clif->cartlist), HP_POP2(HP_clif_cartlist), 624 }, - { HP_POP(clif->favorite_item), HP_POP2(HP_clif_favorite_item), 626 }, - { HP_POP(clif->clearcart), HP_POP2(HP_clif_clearcart), 628 }, - { HP_POP(clif->item_identify_list), HP_POP2(HP_clif_item_identify_list), 630 }, - { HP_POP(clif->item_identified), HP_POP2(HP_clif_item_identified), 632 }, - { HP_POP(clif->item_repair_list), HP_POP2(HP_clif_item_repair_list), 634 }, - { HP_POP(clif->item_repaireffect), HP_POP2(HP_clif_item_repaireffect), 636 }, - { HP_POP(clif->item_damaged), HP_POP2(HP_clif_item_damaged), 638 }, - { HP_POP(clif->item_refine_list), HP_POP2(HP_clif_item_refine_list), 640 }, - { HP_POP(clif->item_skill), HP_POP2(HP_clif_item_skill), 642 }, - { HP_POP(clif->mvp_item), HP_POP2(HP_clif_mvp_item), 644 }, - { HP_POP(clif->mvp_exp), HP_POP2(HP_clif_mvp_exp), 646 }, - { HP_POP(clif->mvp_noitem), HP_POP2(HP_clif_mvp_noitem), 648 }, - { HP_POP(clif->changed_dir), HP_POP2(HP_clif_changed_dir), 650 }, - { HP_POP(clif->charnameack), HP_POP2(HP_clif_charnameack), 652 }, - { HP_POP(clif->monster_hp_bar), HP_POP2(HP_clif_monster_hp_bar), 654 }, - { HP_POP(clif->hpmeter), HP_POP2(HP_clif_hpmeter), 656 }, - { HP_POP(clif->hpmeter_single), HP_POP2(HP_clif_hpmeter_single), 658 }, - { HP_POP(clif->hpmeter_sub), HP_POP2(HP_clif_hpmeter_sub), 660 }, - { HP_POP(clif->upgrademessage), HP_POP2(HP_clif_upgrademessage), 662 }, - { HP_POP(clif->get_weapon_view), HP_POP2(HP_clif_get_weapon_view), 664 }, - { HP_POP(clif->gospel_info), HP_POP2(HP_clif_gospel_info), 666 }, - { HP_POP(clif->feel_req), HP_POP2(HP_clif_feel_req), 668 }, - { HP_POP(clif->starskill), HP_POP2(HP_clif_starskill), 670 }, - { HP_POP(clif->feel_info), HP_POP2(HP_clif_feel_info), 672 }, - { HP_POP(clif->hate_info), HP_POP2(HP_clif_hate_info), 674 }, - { HP_POP(clif->mission_info), HP_POP2(HP_clif_mission_info), 676 }, - { HP_POP(clif->feel_hate_reset), HP_POP2(HP_clif_feel_hate_reset), 678 }, - { HP_POP(clif->partytickack), HP_POP2(HP_clif_partytickack), 680 }, - { HP_POP(clif->equiptickack), HP_POP2(HP_clif_equiptickack), 682 }, - { HP_POP(clif->viewequip_ack), HP_POP2(HP_clif_viewequip_ack), 684 }, - { HP_POP(clif->viewequip_fail), HP_POP2(HP_clif_viewequip_fail), 686 }, - { HP_POP(clif->equpcheckbox), HP_POP2(HP_clif_equpcheckbox), 688 }, - { HP_POP(clif->displayexp), HP_POP2(HP_clif_displayexp), 690 }, - { HP_POP(clif->font), HP_POP2(HP_clif_font), 692 }, - { HP_POP(clif->progressbar), HP_POP2(HP_clif_progressbar), 694 }, - { HP_POP(clif->progressbar_abort), HP_POP2(HP_clif_progressbar_abort), 696 }, - { HP_POP(clif->showdigit), HP_POP2(HP_clif_showdigit), 698 }, - { HP_POP(clif->elementalconverter_list), HP_POP2(HP_clif_elementalconverter_list), 700 }, - { HP_POP(clif->spellbook_list), HP_POP2(HP_clif_spellbook_list), 702 }, - { HP_POP(clif->magicdecoy_list), HP_POP2(HP_clif_magicdecoy_list), 704 }, - { HP_POP(clif->poison_list), HP_POP2(HP_clif_poison_list), 706 }, - { HP_POP(clif->autoshadowspell_list), HP_POP2(HP_clif_autoshadowspell_list), 708 }, - { HP_POP(clif->skill_itemlistwindow), HP_POP2(HP_clif_skill_itemlistwindow), 710 }, - { HP_POP(clif->sc_load), HP_POP2(HP_clif_sc_load), 712 }, - { HP_POP(clif->sc_end), HP_POP2(HP_clif_sc_end), 714 }, - { HP_POP(clif->initialstatus), HP_POP2(HP_clif_initialstatus), 716 }, - { HP_POP(clif->cooldown_list), HP_POP2(HP_clif_cooldown_list), 718 }, - { HP_POP(clif->updatestatus), HP_POP2(HP_clif_updatestatus), 720 }, - { HP_POP(clif->changestatus), HP_POP2(HP_clif_changestatus), 722 }, - { HP_POP(clif->statusupack), HP_POP2(HP_clif_statusupack), 724 }, - { HP_POP(clif->movetoattack), HP_POP2(HP_clif_movetoattack), 726 }, - { HP_POP(clif->solved_charname), HP_POP2(HP_clif_solved_charname), 728 }, - { HP_POP(clif->charnameupdate), HP_POP2(HP_clif_charnameupdate), 730 }, - { HP_POP(clif->delayquit), HP_POP2(HP_clif_delayquit), 732 }, - { HP_POP(clif->getareachar_pc), HP_POP2(HP_clif_getareachar_pc), 734 }, - { HP_POP(clif->disconnect_ack), HP_POP2(HP_clif_disconnect_ack), 736 }, - { HP_POP(clif->PVPInfo), HP_POP2(HP_clif_PVPInfo), 738 }, - { HP_POP(clif->blacksmith), HP_POP2(HP_clif_blacksmith), 740 }, - { HP_POP(clif->alchemist), HP_POP2(HP_clif_alchemist), 742 }, - { HP_POP(clif->taekwon), HP_POP2(HP_clif_taekwon), 744 }, - { HP_POP(clif->ranking_pk), HP_POP2(HP_clif_ranking_pk), 746 }, - { HP_POP(clif->quitsave), HP_POP2(HP_clif_quitsave), 748 }, - { HP_POP(clif->misceffect), HP_POP2(HP_clif_misceffect), 750 }, - { HP_POP(clif->changeoption), HP_POP2(HP_clif_changeoption), 752 }, - { HP_POP(clif->changeoption2), HP_POP2(HP_clif_changeoption2), 754 }, - { HP_POP(clif->emotion), HP_POP2(HP_clif_emotion), 756 }, - { HP_POP(clif->talkiebox), HP_POP2(HP_clif_talkiebox), 758 }, - { HP_POP(clif->wedding_effect), HP_POP2(HP_clif_wedding_effect), 760 }, - { HP_POP(clif->divorced), HP_POP2(HP_clif_divorced), 762 }, - { HP_POP(clif->callpartner), HP_POP2(HP_clif_callpartner), 764 }, - { HP_POP(clif->skill_damage), HP_POP2(HP_clif_skill_damage), 766 }, - { HP_POP(clif->skill_nodamage), HP_POP2(HP_clif_skill_nodamage), 768 }, - { HP_POP(clif->skill_poseffect), HP_POP2(HP_clif_skill_poseffect), 770 }, - { HP_POP(clif->skill_estimation), HP_POP2(HP_clif_skill_estimation), 772 }, - { HP_POP(clif->skill_warppoint), HP_POP2(HP_clif_skill_warppoint), 774 }, - { HP_POP(clif->skillcasting), HP_POP2(HP_clif_skillcasting), 776 }, - { HP_POP(clif->produce_effect), HP_POP2(HP_clif_produce_effect), 778 }, - { HP_POP(clif->devotion), HP_POP2(HP_clif_devotion), 780 }, - { HP_POP(clif->spiritball), HP_POP2(HP_clif_spiritball), 782 }, - { HP_POP(clif->spiritball_single), HP_POP2(HP_clif_spiritball_single), 784 }, - { HP_POP(clif->bladestop), HP_POP2(HP_clif_bladestop), 786 }, - { HP_POP(clif->mvp_effect), HP_POP2(HP_clif_mvp_effect), 788 }, - { HP_POP(clif->heal), HP_POP2(HP_clif_heal), 790 }, - { HP_POP(clif->resurrection), HP_POP2(HP_clif_resurrection), 792 }, - { HP_POP(clif->refine), HP_POP2(HP_clif_refine), 794 }, - { HP_POP(clif->weather), HP_POP2(HP_clif_weather), 796 }, - { HP_POP(clif->specialeffect), HP_POP2(HP_clif_specialeffect), 798 }, - { HP_POP(clif->specialeffect_single), HP_POP2(HP_clif_specialeffect_single), 800 }, - { HP_POP(clif->specialeffect_value), HP_POP2(HP_clif_specialeffect_value), 802 }, - { HP_POP(clif->millenniumshield), HP_POP2(HP_clif_millenniumshield), 804 }, - { HP_POP(clif->charm), HP_POP2(HP_clif_charm), 806 }, - { HP_POP(clif->charm_single), HP_POP2(HP_clif_charm_single), 808 }, - { HP_POP(clif->snap), HP_POP2(HP_clif_snap), 810 }, - { HP_POP(clif->weather_check), HP_POP2(HP_clif_weather_check), 812 }, - { HP_POP(clif->playBGM), HP_POP2(HP_clif_playBGM), 814 }, - { HP_POP(clif->soundeffect), HP_POP2(HP_clif_soundeffect), 816 }, - { HP_POP(clif->soundeffectall), HP_POP2(HP_clif_soundeffectall), 818 }, - { HP_POP(clif->GlobalMessage), HP_POP2(HP_clif_GlobalMessage), 820 }, - { HP_POP(clif->createchat), HP_POP2(HP_clif_createchat), 822 }, - { HP_POP(clif->dispchat), HP_POP2(HP_clif_dispchat), 824 }, - { HP_POP(clif->joinchatfail), HP_POP2(HP_clif_joinchatfail), 826 }, - { HP_POP(clif->joinchatok), HP_POP2(HP_clif_joinchatok), 828 }, - { HP_POP(clif->addchat), HP_POP2(HP_clif_addchat), 830 }, - { HP_POP(clif->changechatowner), HP_POP2(HP_clif_changechatowner), 832 }, - { HP_POP(clif->clearchat), HP_POP2(HP_clif_clearchat), 834 }, - { HP_POP(clif->leavechat), HP_POP2(HP_clif_leavechat), 836 }, - { HP_POP(clif->changechatstatus), HP_POP2(HP_clif_changechatstatus), 838 }, - { HP_POP(clif->wis_message), HP_POP2(HP_clif_wis_message), 840 }, - { HP_POP(clif->wis_end), HP_POP2(HP_clif_wis_end), 842 }, - { HP_POP(clif->disp_onlyself), HP_POP2(HP_clif_disp_onlyself), 844 }, - { HP_POP(clif->disp_message), HP_POP2(HP_clif_disp_message), 846 }, - { HP_POP(clif->broadcast), HP_POP2(HP_clif_broadcast), 848 }, - { HP_POP(clif->broadcast2), HP_POP2(HP_clif_broadcast2), 850 }, - { HP_POP(clif->messagecolor), HP_POP2(HP_clif_messagecolor), 852 }, - { HP_POP(clif->disp_overhead), HP_POP2(HP_clif_disp_overhead), 854 }, - { HP_POP(clif->msg), HP_POP2(HP_clif_msg), 856 }, - { HP_POP(clif->msg_value), HP_POP2(HP_clif_msg_value), 858 }, - { HP_POP(clif->msg_skill), HP_POP2(HP_clif_msg_skill), 860 }, - { HP_POP(clif->msgtable), HP_POP2(HP_clif_msgtable), 862 }, - { HP_POP(clif->msgtable_num), HP_POP2(HP_clif_msgtable_num), 864 }, - { HP_POP(clif->message), HP_POP2(HP_clif_message), 866 }, - { HP_POP(clif->messageln), HP_POP2(HP_clif_messageln), 868 }, - { HP_POP(clif->colormes), HP_POP2(HP_clif_colormes), 870 }, - { HP_POP(clif->process_message), HP_POP2(HP_clif_process_message), 872 }, - { HP_POP(clif->wisexin), HP_POP2(HP_clif_wisexin), 874 }, - { HP_POP(clif->wisall), HP_POP2(HP_clif_wisall), 876 }, - { HP_POP(clif->PMIgnoreList), HP_POP2(HP_clif_PMIgnoreList), 878 }, - { HP_POP(clif->traderequest), HP_POP2(HP_clif_traderequest), 880 }, - { HP_POP(clif->tradestart), HP_POP2(HP_clif_tradestart), 882 }, - { HP_POP(clif->tradeadditem), HP_POP2(HP_clif_tradeadditem), 884 }, - { HP_POP(clif->tradeitemok), HP_POP2(HP_clif_tradeitemok), 886 }, - { HP_POP(clif->tradedeal_lock), HP_POP2(HP_clif_tradedeal_lock), 888 }, - { HP_POP(clif->tradecancelled), HP_POP2(HP_clif_tradecancelled), 890 }, - { HP_POP(clif->tradecompleted), HP_POP2(HP_clif_tradecompleted), 892 }, - { HP_POP(clif->tradeundo), HP_POP2(HP_clif_tradeundo), 894 }, - { HP_POP(clif->openvendingreq), HP_POP2(HP_clif_openvendingreq), 896 }, - { HP_POP(clif->showvendingboard), HP_POP2(HP_clif_showvendingboard), 898 }, - { HP_POP(clif->closevendingboard), HP_POP2(HP_clif_closevendingboard), 900 }, - { HP_POP(clif->vendinglist), HP_POP2(HP_clif_vendinglist), 902 }, - { HP_POP(clif->buyvending), HP_POP2(HP_clif_buyvending), 904 }, - { HP_POP(clif->openvending), HP_POP2(HP_clif_openvending), 906 }, - { HP_POP(clif->vendingreport), HP_POP2(HP_clif_vendingreport), 908 }, - { HP_POP(clif->storagelist), HP_POP2(HP_clif_storagelist), 910 }, - { HP_POP(clif->updatestorageamount), HP_POP2(HP_clif_updatestorageamount), 912 }, - { HP_POP(clif->storageitemadded), HP_POP2(HP_clif_storageitemadded), 914 }, - { HP_POP(clif->storageitemremoved), HP_POP2(HP_clif_storageitemremoved), 916 }, - { HP_POP(clif->storageclose), HP_POP2(HP_clif_storageclose), 918 }, - { HP_POP(clif->skillinfoblock), HP_POP2(HP_clif_skillinfoblock), 920 }, - { HP_POP(clif->skillup), HP_POP2(HP_clif_skillup), 922 }, - { HP_POP(clif->skillinfo), HP_POP2(HP_clif_skillinfo), 924 }, - { HP_POP(clif->addskill), HP_POP2(HP_clif_addskill), 926 }, - { HP_POP(clif->deleteskill), HP_POP2(HP_clif_deleteskill), 928 }, - { HP_POP(clif->party_created), HP_POP2(HP_clif_party_created), 930 }, - { HP_POP(clif->party_member_info), HP_POP2(HP_clif_party_member_info), 932 }, - { HP_POP(clif->party_info), HP_POP2(HP_clif_party_info), 934 }, - { HP_POP(clif->party_invite), HP_POP2(HP_clif_party_invite), 936 }, - { HP_POP(clif->party_inviteack), HP_POP2(HP_clif_party_inviteack), 938 }, - { HP_POP(clif->party_option), HP_POP2(HP_clif_party_option), 940 }, - { HP_POP(clif->party_withdraw), HP_POP2(HP_clif_party_withdraw), 942 }, - { HP_POP(clif->party_message), HP_POP2(HP_clif_party_message), 944 }, - { HP_POP(clif->party_xy), HP_POP2(HP_clif_party_xy), 946 }, - { HP_POP(clif->party_xy_single), HP_POP2(HP_clif_party_xy_single), 948 }, - { HP_POP(clif->party_hp), HP_POP2(HP_clif_party_hp), 950 }, - { HP_POP(clif->party_xy_remove), HP_POP2(HP_clif_party_xy_remove), 952 }, - { HP_POP(clif->party_show_picker), HP_POP2(HP_clif_party_show_picker), 954 }, - { HP_POP(clif->partyinvitationstate), HP_POP2(HP_clif_partyinvitationstate), 956 }, - { HP_POP(clif->guild_created), HP_POP2(HP_clif_guild_created), 958 }, - { HP_POP(clif->guild_belonginfo), HP_POP2(HP_clif_guild_belonginfo), 960 }, - { HP_POP(clif->guild_masterormember), HP_POP2(HP_clif_guild_masterormember), 962 }, - { HP_POP(clif->guild_basicinfo), HP_POP2(HP_clif_guild_basicinfo), 964 }, - { HP_POP(clif->guild_allianceinfo), HP_POP2(HP_clif_guild_allianceinfo), 966 }, - { HP_POP(clif->guild_memberlist), HP_POP2(HP_clif_guild_memberlist), 968 }, - { HP_POP(clif->guild_skillinfo), HP_POP2(HP_clif_guild_skillinfo), 970 }, - { HP_POP(clif->guild_send_onlineinfo), HP_POP2(HP_clif_guild_send_onlineinfo), 972 }, - { HP_POP(clif->guild_memberlogin_notice), HP_POP2(HP_clif_guild_memberlogin_notice), 974 }, - { HP_POP(clif->guild_invite), HP_POP2(HP_clif_guild_invite), 976 }, - { HP_POP(clif->guild_inviteack), HP_POP2(HP_clif_guild_inviteack), 978 }, - { HP_POP(clif->guild_leave), HP_POP2(HP_clif_guild_leave), 980 }, - { HP_POP(clif->guild_expulsion), HP_POP2(HP_clif_guild_expulsion), 982 }, - { HP_POP(clif->guild_positionchanged), HP_POP2(HP_clif_guild_positionchanged), 984 }, - { HP_POP(clif->guild_memberpositionchanged), HP_POP2(HP_clif_guild_memberpositionchanged), 986 }, - { HP_POP(clif->guild_emblem), HP_POP2(HP_clif_guild_emblem), 988 }, - { HP_POP(clif->guild_emblem_area), HP_POP2(HP_clif_guild_emblem_area), 990 }, - { HP_POP(clif->guild_notice), HP_POP2(HP_clif_guild_notice), 992 }, - { HP_POP(clif->guild_message), HP_POP2(HP_clif_guild_message), 994 }, - { HP_POP(clif->guild_skillup), HP_POP2(HP_clif_guild_skillup), 996 }, - { HP_POP(clif->guild_reqalliance), HP_POP2(HP_clif_guild_reqalliance), 998 }, - { HP_POP(clif->guild_allianceack), HP_POP2(HP_clif_guild_allianceack), 1000 }, - { HP_POP(clif->guild_delalliance), HP_POP2(HP_clif_guild_delalliance), 1002 }, - { HP_POP(clif->guild_oppositionack), HP_POP2(HP_clif_guild_oppositionack), 1004 }, - { HP_POP(clif->guild_broken), HP_POP2(HP_clif_guild_broken), 1006 }, - { HP_POP(clif->guild_xy), HP_POP2(HP_clif_guild_xy), 1008 }, - { HP_POP(clif->guild_xy_single), HP_POP2(HP_clif_guild_xy_single), 1010 }, - { HP_POP(clif->guild_xy_remove), HP_POP2(HP_clif_guild_xy_remove), 1012 }, - { HP_POP(clif->guild_positionnamelist), HP_POP2(HP_clif_guild_positionnamelist), 1014 }, - { HP_POP(clif->guild_positioninfolist), HP_POP2(HP_clif_guild_positioninfolist), 1016 }, - { HP_POP(clif->guild_expulsionlist), HP_POP2(HP_clif_guild_expulsionlist), 1018 }, - { HP_POP(clif->validate_emblem), HP_POP2(HP_clif_validate_emblem), 1020 }, - { HP_POP(clif->bg_hp), HP_POP2(HP_clif_bg_hp), 1022 }, - { HP_POP(clif->bg_xy), HP_POP2(HP_clif_bg_xy), 1024 }, - { HP_POP(clif->bg_xy_remove), HP_POP2(HP_clif_bg_xy_remove), 1026 }, - { HP_POP(clif->bg_message), HP_POP2(HP_clif_bg_message), 1028 }, - { HP_POP(clif->bg_updatescore), HP_POP2(HP_clif_bg_updatescore), 1030 }, - { HP_POP(clif->bg_updatescore_single), HP_POP2(HP_clif_bg_updatescore_single), 1032 }, - { HP_POP(clif->sendbgemblem_area), HP_POP2(HP_clif_sendbgemblem_area), 1034 }, - { HP_POP(clif->sendbgemblem_single), HP_POP2(HP_clif_sendbgemblem_single), 1036 }, - { HP_POP(clif->instance), HP_POP2(HP_clif_instance), 1038 }, - { HP_POP(clif->instance_join), HP_POP2(HP_clif_instance_join), 1040 }, - { HP_POP(clif->instance_leave), HP_POP2(HP_clif_instance_leave), 1042 }, - { HP_POP(clif->catch_process), HP_POP2(HP_clif_catch_process), 1044 }, - { HP_POP(clif->pet_roulette), HP_POP2(HP_clif_pet_roulette), 1046 }, - { HP_POP(clif->sendegg), HP_POP2(HP_clif_sendegg), 1048 }, - { HP_POP(clif->send_petstatus), HP_POP2(HP_clif_send_petstatus), 1050 }, - { HP_POP(clif->send_petdata), HP_POP2(HP_clif_send_petdata), 1052 }, - { HP_POP(clif->pet_emotion), HP_POP2(HP_clif_pet_emotion), 1054 }, - { HP_POP(clif->pet_food), HP_POP2(HP_clif_pet_food), 1056 }, - { HP_POP(clif->friendslist_toggle_sub), HP_POP2(HP_clif_friendslist_toggle_sub), 1058 }, - { HP_POP(clif->friendslist_send), HP_POP2(HP_clif_friendslist_send), 1060 }, - { HP_POP(clif->friendslist_reqack), HP_POP2(HP_clif_friendslist_reqack), 1062 }, - { HP_POP(clif->friendslist_toggle), HP_POP2(HP_clif_friendslist_toggle), 1064 }, - { HP_POP(clif->friendlist_req), HP_POP2(HP_clif_friendlist_req), 1066 }, - { HP_POP(clif->GM_kickack), HP_POP2(HP_clif_GM_kickack), 1068 }, - { HP_POP(clif->GM_kick), HP_POP2(HP_clif_GM_kick), 1070 }, - { HP_POP(clif->manner_message), HP_POP2(HP_clif_manner_message), 1072 }, - { HP_POP(clif->GM_silence), HP_POP2(HP_clif_GM_silence), 1074 }, - { HP_POP(clif->account_name), HP_POP2(HP_clif_account_name), 1076 }, - { HP_POP(clif->check), HP_POP2(HP_clif_check), 1078 }, - { HP_POP(clif->hominfo), HP_POP2(HP_clif_hominfo), 1080 }, - { HP_POP(clif->homskillinfoblock), HP_POP2(HP_clif_homskillinfoblock), 1082 }, - { HP_POP(clif->homskillup), HP_POP2(HP_clif_homskillup), 1084 }, - { HP_POP(clif->hom_food), HP_POP2(HP_clif_hom_food), 1086 }, - { HP_POP(clif->send_homdata), HP_POP2(HP_clif_send_homdata), 1088 }, - { HP_POP(clif->quest_send_list), HP_POP2(HP_clif_quest_send_list), 1090 }, - { HP_POP(clif->quest_send_mission), HP_POP2(HP_clif_quest_send_mission), 1092 }, - { HP_POP(clif->quest_add), HP_POP2(HP_clif_quest_add), 1094 }, - { HP_POP(clif->quest_delete), HP_POP2(HP_clif_quest_delete), 1096 }, - { HP_POP(clif->quest_update_status), HP_POP2(HP_clif_quest_update_status), 1098 }, - { HP_POP(clif->quest_update_objective), HP_POP2(HP_clif_quest_update_objective), 1100 }, - { HP_POP(clif->quest_show_event), HP_POP2(HP_clif_quest_show_event), 1102 }, - { HP_POP(clif->mail_window), HP_POP2(HP_clif_mail_window), 1104 }, - { HP_POP(clif->mail_read), HP_POP2(HP_clif_mail_read), 1106 }, - { HP_POP(clif->mail_delete), HP_POP2(HP_clif_mail_delete), 1108 }, - { HP_POP(clif->mail_return), HP_POP2(HP_clif_mail_return), 1110 }, - { HP_POP(clif->mail_send), HP_POP2(HP_clif_mail_send), 1112 }, - { HP_POP(clif->mail_new), HP_POP2(HP_clif_mail_new), 1114 }, - { HP_POP(clif->mail_refreshinbox), HP_POP2(HP_clif_mail_refreshinbox), 1116 }, - { HP_POP(clif->mail_getattachment), HP_POP2(HP_clif_mail_getattachment), 1118 }, - { HP_POP(clif->mail_setattachment), HP_POP2(HP_clif_mail_setattachment), 1120 }, - { HP_POP(clif->auction_openwindow), HP_POP2(HP_clif_auction_openwindow), 1122 }, - { HP_POP(clif->auction_results), HP_POP2(HP_clif_auction_results), 1124 }, - { HP_POP(clif->auction_message), HP_POP2(HP_clif_auction_message), 1126 }, - { HP_POP(clif->auction_close), HP_POP2(HP_clif_auction_close), 1128 }, - { HP_POP(clif->auction_setitem), HP_POP2(HP_clif_auction_setitem), 1130 }, - { HP_POP(clif->mercenary_info), HP_POP2(HP_clif_mercenary_info), 1132 }, - { HP_POP(clif->mercenary_skillblock), HP_POP2(HP_clif_mercenary_skillblock), 1134 }, - { HP_POP(clif->mercenary_message), HP_POP2(HP_clif_mercenary_message), 1136 }, - { HP_POP(clif->mercenary_updatestatus), HP_POP2(HP_clif_mercenary_updatestatus), 1138 }, - { HP_POP(clif->rental_time), HP_POP2(HP_clif_rental_time), 1140 }, - { HP_POP(clif->rental_expired), HP_POP2(HP_clif_rental_expired), 1142 }, - { HP_POP(clif->PartyBookingRegisterAck), HP_POP2(HP_clif_PartyBookingRegisterAck), 1144 }, - { HP_POP(clif->PartyBookingDeleteAck), HP_POP2(HP_clif_PartyBookingDeleteAck), 1146 }, - { HP_POP(clif->PartyBookingSearchAck), HP_POP2(HP_clif_PartyBookingSearchAck), 1148 }, - { HP_POP(clif->PartyBookingUpdateNotify), HP_POP2(HP_clif_PartyBookingUpdateNotify), 1150 }, - { HP_POP(clif->PartyBookingDeleteNotify), HP_POP2(HP_clif_PartyBookingDeleteNotify), 1152 }, - { HP_POP(clif->PartyBookingInsertNotify), HP_POP2(HP_clif_PartyBookingInsertNotify), 1154 }, - { HP_POP(clif->PartyRecruitRegisterAck), HP_POP2(HP_clif_PartyRecruitRegisterAck), 1156 }, - { HP_POP(clif->PartyRecruitDeleteAck), HP_POP2(HP_clif_PartyRecruitDeleteAck), 1158 }, - { HP_POP(clif->PartyRecruitSearchAck), HP_POP2(HP_clif_PartyRecruitSearchAck), 1160 }, - { HP_POP(clif->PartyRecruitUpdateNotify), HP_POP2(HP_clif_PartyRecruitUpdateNotify), 1162 }, - { HP_POP(clif->PartyRecruitDeleteNotify), HP_POP2(HP_clif_PartyRecruitDeleteNotify), 1164 }, - { HP_POP(clif->PartyRecruitInsertNotify), HP_POP2(HP_clif_PartyRecruitInsertNotify), 1166 }, - { HP_POP(clif->PartyBookingVolunteerInfo), HP_POP2(HP_clif_PartyBookingVolunteerInfo), 1168 }, - { HP_POP(clif->PartyBookingRefuseVolunteer), HP_POP2(HP_clif_PartyBookingRefuseVolunteer), 1170 }, - { HP_POP(clif->PartyBookingCancelVolunteer), HP_POP2(HP_clif_PartyBookingCancelVolunteer), 1172 }, - { HP_POP(clif->PartyBookingAddFilteringList), HP_POP2(HP_clif_PartyBookingAddFilteringList), 1174 }, - { HP_POP(clif->PartyBookingSubFilteringList), HP_POP2(HP_clif_PartyBookingSubFilteringList), 1176 }, - { HP_POP(clif->buyingstore_open), HP_POP2(HP_clif_buyingstore_open), 1178 }, - { HP_POP(clif->buyingstore_open_failed), HP_POP2(HP_clif_buyingstore_open_failed), 1180 }, - { HP_POP(clif->buyingstore_myitemlist), HP_POP2(HP_clif_buyingstore_myitemlist), 1182 }, - { HP_POP(clif->buyingstore_entry), HP_POP2(HP_clif_buyingstore_entry), 1184 }, - { HP_POP(clif->buyingstore_entry_single), HP_POP2(HP_clif_buyingstore_entry_single), 1186 }, - { HP_POP(clif->buyingstore_disappear_entry), HP_POP2(HP_clif_buyingstore_disappear_entry), 1188 }, - { HP_POP(clif->buyingstore_disappear_entry_single), HP_POP2(HP_clif_buyingstore_disappear_entry_single), 1190 }, - { HP_POP(clif->buyingstore_itemlist), HP_POP2(HP_clif_buyingstore_itemlist), 1192 }, - { HP_POP(clif->buyingstore_trade_failed_buyer), HP_POP2(HP_clif_buyingstore_trade_failed_buyer), 1194 }, - { HP_POP(clif->buyingstore_update_item), HP_POP2(HP_clif_buyingstore_update_item), 1196 }, - { HP_POP(clif->buyingstore_delete_item), HP_POP2(HP_clif_buyingstore_delete_item), 1198 }, - { HP_POP(clif->buyingstore_trade_failed_seller), HP_POP2(HP_clif_buyingstore_trade_failed_seller), 1200 }, - { HP_POP(clif->search_store_info_ack), HP_POP2(HP_clif_search_store_info_ack), 1202 }, - { HP_POP(clif->search_store_info_failed), HP_POP2(HP_clif_search_store_info_failed), 1204 }, - { HP_POP(clif->open_search_store_info), HP_POP2(HP_clif_open_search_store_info), 1206 }, - { HP_POP(clif->search_store_info_click_ack), HP_POP2(HP_clif_search_store_info_click_ack), 1208 }, - { HP_POP(clif->elemental_info), HP_POP2(HP_clif_elemental_info), 1210 }, - { HP_POP(clif->elemental_updatestatus), HP_POP2(HP_clif_elemental_updatestatus), 1212 }, - { HP_POP(clif->bgqueue_ack), HP_POP2(HP_clif_bgqueue_ack), 1214 }, - { HP_POP(clif->bgqueue_notice_delete), HP_POP2(HP_clif_bgqueue_notice_delete), 1216 }, - { HP_POP(clif->bgqueue_update_info), HP_POP2(HP_clif_bgqueue_update_info), 1218 }, - { HP_POP(clif->bgqueue_joined), HP_POP2(HP_clif_bgqueue_joined), 1220 }, - { HP_POP(clif->bgqueue_pcleft), HP_POP2(HP_clif_bgqueue_pcleft), 1222 }, - { HP_POP(clif->bgqueue_battlebegins), HP_POP2(HP_clif_bgqueue_battlebegins), 1224 }, - { HP_POP(clif->adopt_reply), HP_POP2(HP_clif_adopt_reply), 1226 }, - { HP_POP(clif->adopt_request), HP_POP2(HP_clif_adopt_request), 1228 }, - { HP_POP(clif->readbook), HP_POP2(HP_clif_readbook), 1230 }, - { HP_POP(clif->notify_time), HP_POP2(HP_clif_notify_time), 1232 }, - { HP_POP(clif->user_count), HP_POP2(HP_clif_user_count), 1234 }, - { HP_POP(clif->noask_sub), HP_POP2(HP_clif_noask_sub), 1236 }, - { HP_POP(clif->bc_ready), HP_POP2(HP_clif_bc_ready), 1238 }, - { HP_POP(clif->undisguise_timer), HP_POP2(HP_clif_undisguise_timer), 1240 }, - { HP_POP(clif->chsys_create), HP_POP2(HP_clif_chsys_create), 1242 }, - { HP_POP(clif->chsys_msg), HP_POP2(HP_clif_chsys_msg), 1244 }, - { HP_POP(clif->chsys_msg2), HP_POP2(HP_clif_chsys_msg2), 1246 }, - { HP_POP(clif->chsys_send), HP_POP2(HP_clif_chsys_send), 1248 }, - { HP_POP(clif->chsys_join), HP_POP2(HP_clif_chsys_join), 1250 }, - { HP_POP(clif->chsys_left), HP_POP2(HP_clif_chsys_left), 1252 }, - { HP_POP(clif->chsys_delete), HP_POP2(HP_clif_chsys_delete), 1254 }, - { HP_POP(clif->chsys_mjoin), HP_POP2(HP_clif_chsys_mjoin), 1256 }, - { HP_POP(clif->chsys_quit), HP_POP2(HP_clif_chsys_quit), 1258 }, - { HP_POP(clif->chsys_quitg), HP_POP2(HP_clif_chsys_quitg), 1260 }, - { HP_POP(clif->chsys_gjoin), HP_POP2(HP_clif_chsys_gjoin), 1262 }, - { HP_POP(clif->chsys_gleave), HP_POP2(HP_clif_chsys_gleave), 1264 }, - { HP_POP(clif->pWantToConnection), HP_POP2(HP_clif_pWantToConnection), 1266 }, - { HP_POP(clif->pLoadEndAck), HP_POP2(HP_clif_pLoadEndAck), 1268 }, - { HP_POP(clif->pTickSend), HP_POP2(HP_clif_pTickSend), 1270 }, - { HP_POP(clif->pHotkey), HP_POP2(HP_clif_pHotkey), 1272 }, - { HP_POP(clif->pProgressbar), HP_POP2(HP_clif_pProgressbar), 1274 }, - { HP_POP(clif->pWalkToXY), HP_POP2(HP_clif_pWalkToXY), 1276 }, - { HP_POP(clif->pQuitGame), HP_POP2(HP_clif_pQuitGame), 1278 }, - { HP_POP(clif->pGetCharNameRequest), HP_POP2(HP_clif_pGetCharNameRequest), 1280 }, - { HP_POP(clif->pGlobalMessage), HP_POP2(HP_clif_pGlobalMessage), 1282 }, - { HP_POP(clif->pMapMove), HP_POP2(HP_clif_pMapMove), 1284 }, - { HP_POP(clif->pChangeDir), HP_POP2(HP_clif_pChangeDir), 1286 }, - { HP_POP(clif->pEmotion), HP_POP2(HP_clif_pEmotion), 1288 }, - { HP_POP(clif->pHowManyConnections), HP_POP2(HP_clif_pHowManyConnections), 1290 }, - { HP_POP(clif->pActionRequest), HP_POP2(HP_clif_pActionRequest), 1292 }, - { HP_POP(clif->pActionRequest_sub), HP_POP2(HP_clif_pActionRequest_sub), 1294 }, - { HP_POP(clif->pRestart), HP_POP2(HP_clif_pRestart), 1296 }, - { HP_POP(clif->pWisMessage), HP_POP2(HP_clif_pWisMessage), 1298 }, - { HP_POP(clif->pBroadcast), HP_POP2(HP_clif_pBroadcast), 1300 }, - { HP_POP(clif->pTakeItem), HP_POP2(HP_clif_pTakeItem), 1302 }, - { HP_POP(clif->pDropItem), HP_POP2(HP_clif_pDropItem), 1304 }, - { HP_POP(clif->pUseItem), HP_POP2(HP_clif_pUseItem), 1306 }, - { HP_POP(clif->pEquipItem), HP_POP2(HP_clif_pEquipItem), 1308 }, - { HP_POP(clif->pUnequipItem), HP_POP2(HP_clif_pUnequipItem), 1310 }, - { HP_POP(clif->pNpcClicked), HP_POP2(HP_clif_pNpcClicked), 1312 }, - { HP_POP(clif->pNpcBuySellSelected), HP_POP2(HP_clif_pNpcBuySellSelected), 1314 }, - { HP_POP(clif->pNpcBuyListSend), HP_POP2(HP_clif_pNpcBuyListSend), 1316 }, - { HP_POP(clif->pNpcSellListSend), HP_POP2(HP_clif_pNpcSellListSend), 1318 }, - { HP_POP(clif->pCreateChatRoom), HP_POP2(HP_clif_pCreateChatRoom), 1320 }, - { HP_POP(clif->pChatAddMember), HP_POP2(HP_clif_pChatAddMember), 1322 }, - { HP_POP(clif->pChatRoomStatusChange), HP_POP2(HP_clif_pChatRoomStatusChange), 1324 }, - { HP_POP(clif->pChangeChatOwner), HP_POP2(HP_clif_pChangeChatOwner), 1326 }, - { HP_POP(clif->pKickFromChat), HP_POP2(HP_clif_pKickFromChat), 1328 }, - { HP_POP(clif->pChatLeave), HP_POP2(HP_clif_pChatLeave), 1330 }, - { HP_POP(clif->pTradeRequest), HP_POP2(HP_clif_pTradeRequest), 1332 }, - { HP_POP(clif->chann_config_read), HP_POP2(HP_clif_chann_config_read), 1334 }, - { HP_POP(clif->pTradeAck), HP_POP2(HP_clif_pTradeAck), 1336 }, - { HP_POP(clif->pTradeAddItem), HP_POP2(HP_clif_pTradeAddItem), 1338 }, - { HP_POP(clif->pTradeOk), HP_POP2(HP_clif_pTradeOk), 1340 }, - { HP_POP(clif->pTradeCancel), HP_POP2(HP_clif_pTradeCancel), 1342 }, - { HP_POP(clif->pTradeCommit), HP_POP2(HP_clif_pTradeCommit), 1344 }, - { HP_POP(clif->pStopAttack), HP_POP2(HP_clif_pStopAttack), 1346 }, - { HP_POP(clif->pPutItemToCart), HP_POP2(HP_clif_pPutItemToCart), 1348 }, - { HP_POP(clif->pGetItemFromCart), HP_POP2(HP_clif_pGetItemFromCart), 1350 }, - { HP_POP(clif->pRemoveOption), HP_POP2(HP_clif_pRemoveOption), 1352 }, - { HP_POP(clif->pChangeCart), HP_POP2(HP_clif_pChangeCart), 1354 }, - { HP_POP(clif->pStatusUp), HP_POP2(HP_clif_pStatusUp), 1356 }, - { HP_POP(clif->pSkillUp), HP_POP2(HP_clif_pSkillUp), 1358 }, - { HP_POP(clif->pUseSkillToId), HP_POP2(HP_clif_pUseSkillToId), 1360 }, - { HP_POP(clif->pUseSkillToId_homun), HP_POP2(HP_clif_pUseSkillToId_homun), 1362 }, - { HP_POP(clif->pUseSkillToId_mercenary), HP_POP2(HP_clif_pUseSkillToId_mercenary), 1364 }, - { HP_POP(clif->pUseSkillToPos), HP_POP2(HP_clif_pUseSkillToPos), 1366 }, - { HP_POP(clif->pUseSkillToPosSub), HP_POP2(HP_clif_pUseSkillToPosSub), 1368 }, - { HP_POP(clif->pUseSkillToPos_homun), HP_POP2(HP_clif_pUseSkillToPos_homun), 1370 }, - { HP_POP(clif->pUseSkillToPos_mercenary), HP_POP2(HP_clif_pUseSkillToPos_mercenary), 1372 }, - { HP_POP(clif->pUseSkillToPosMoreInfo), HP_POP2(HP_clif_pUseSkillToPosMoreInfo), 1374 }, - { HP_POP(clif->pUseSkillMap), HP_POP2(HP_clif_pUseSkillMap), 1376 }, - { HP_POP(clif->pRequestMemo), HP_POP2(HP_clif_pRequestMemo), 1378 }, - { HP_POP(clif->pProduceMix), HP_POP2(HP_clif_pProduceMix), 1380 }, - { HP_POP(clif->pCooking), HP_POP2(HP_clif_pCooking), 1382 }, - { HP_POP(clif->pRepairItem), HP_POP2(HP_clif_pRepairItem), 1384 }, - { HP_POP(clif->pWeaponRefine), HP_POP2(HP_clif_pWeaponRefine), 1386 }, - { HP_POP(clif->pNpcSelectMenu), HP_POP2(HP_clif_pNpcSelectMenu), 1388 }, - { HP_POP(clif->pNpcNextClicked), HP_POP2(HP_clif_pNpcNextClicked), 1390 }, - { HP_POP(clif->pNpcAmountInput), HP_POP2(HP_clif_pNpcAmountInput), 1392 }, - { HP_POP(clif->pNpcStringInput), HP_POP2(HP_clif_pNpcStringInput), 1394 }, - { HP_POP(clif->pNpcCloseClicked), HP_POP2(HP_clif_pNpcCloseClicked), 1396 }, - { HP_POP(clif->pItemIdentify), HP_POP2(HP_clif_pItemIdentify), 1398 }, - { HP_POP(clif->pSelectArrow), HP_POP2(HP_clif_pSelectArrow), 1400 }, - { HP_POP(clif->pAutoSpell), HP_POP2(HP_clif_pAutoSpell), 1402 }, - { HP_POP(clif->pUseCard), HP_POP2(HP_clif_pUseCard), 1404 }, - { HP_POP(clif->pInsertCard), HP_POP2(HP_clif_pInsertCard), 1406 }, - { HP_POP(clif->pSolveCharName), HP_POP2(HP_clif_pSolveCharName), 1408 }, - { HP_POP(clif->pResetChar), HP_POP2(HP_clif_pResetChar), 1410 }, - { HP_POP(clif->pLocalBroadcast), HP_POP2(HP_clif_pLocalBroadcast), 1412 }, - { HP_POP(clif->pMoveToKafra), HP_POP2(HP_clif_pMoveToKafra), 1414 }, - { HP_POP(clif->pMoveFromKafra), HP_POP2(HP_clif_pMoveFromKafra), 1416 }, - { HP_POP(clif->pMoveToKafraFromCart), HP_POP2(HP_clif_pMoveToKafraFromCart), 1418 }, - { HP_POP(clif->pMoveFromKafraToCart), HP_POP2(HP_clif_pMoveFromKafraToCart), 1420 }, - { HP_POP(clif->pCloseKafra), HP_POP2(HP_clif_pCloseKafra), 1422 }, - { HP_POP(clif->pStoragePassword), HP_POP2(HP_clif_pStoragePassword), 1424 }, - { HP_POP(clif->pCreateParty), HP_POP2(HP_clif_pCreateParty), 1426 }, - { HP_POP(clif->pCreateParty2), HP_POP2(HP_clif_pCreateParty2), 1428 }, - { HP_POP(clif->pPartyInvite), HP_POP2(HP_clif_pPartyInvite), 1430 }, - { HP_POP(clif->pPartyInvite2), HP_POP2(HP_clif_pPartyInvite2), 1432 }, - { HP_POP(clif->pReplyPartyInvite), HP_POP2(HP_clif_pReplyPartyInvite), 1434 }, - { HP_POP(clif->pReplyPartyInvite2), HP_POP2(HP_clif_pReplyPartyInvite2), 1436 }, - { HP_POP(clif->pLeaveParty), HP_POP2(HP_clif_pLeaveParty), 1438 }, - { HP_POP(clif->pRemovePartyMember), HP_POP2(HP_clif_pRemovePartyMember), 1440 }, - { HP_POP(clif->pPartyChangeOption), HP_POP2(HP_clif_pPartyChangeOption), 1442 }, - { HP_POP(clif->pPartyMessage), HP_POP2(HP_clif_pPartyMessage), 1444 }, - { HP_POP(clif->pPartyChangeLeader), HP_POP2(HP_clif_pPartyChangeLeader), 1446 }, - { HP_POP(clif->pPartyBookingRegisterReq), HP_POP2(HP_clif_pPartyBookingRegisterReq), 1448 }, - { HP_POP(clif->pPartyBookingSearchReq), HP_POP2(HP_clif_pPartyBookingSearchReq), 1450 }, - { HP_POP(clif->pPartyBookingDeleteReq), HP_POP2(HP_clif_pPartyBookingDeleteReq), 1452 }, - { HP_POP(clif->pPartyBookingUpdateReq), HP_POP2(HP_clif_pPartyBookingUpdateReq), 1454 }, - { HP_POP(clif->pPartyRecruitRegisterReq), HP_POP2(HP_clif_pPartyRecruitRegisterReq), 1456 }, - { HP_POP(clif->pPartyRecruitSearchReq), HP_POP2(HP_clif_pPartyRecruitSearchReq), 1458 }, - { HP_POP(clif->pPartyRecruitDeleteReq), HP_POP2(HP_clif_pPartyRecruitDeleteReq), 1460 }, - { HP_POP(clif->pPartyRecruitUpdateReq), HP_POP2(HP_clif_pPartyRecruitUpdateReq), 1462 }, - { HP_POP(clif->pCloseVending), HP_POP2(HP_clif_pCloseVending), 1464 }, - { HP_POP(clif->pVendingListReq), HP_POP2(HP_clif_pVendingListReq), 1466 }, - { HP_POP(clif->pPurchaseReq), HP_POP2(HP_clif_pPurchaseReq), 1468 }, - { HP_POP(clif->pPurchaseReq2), HP_POP2(HP_clif_pPurchaseReq2), 1470 }, - { HP_POP(clif->pOpenVending), HP_POP2(HP_clif_pOpenVending), 1472 }, - { HP_POP(clif->pCreateGuild), HP_POP2(HP_clif_pCreateGuild), 1474 }, - { HP_POP(clif->pGuildCheckMaster), HP_POP2(HP_clif_pGuildCheckMaster), 1476 }, - { HP_POP(clif->pGuildRequestInfo), HP_POP2(HP_clif_pGuildRequestInfo), 1478 }, - { HP_POP(clif->pGuildChangePositionInfo), HP_POP2(HP_clif_pGuildChangePositionInfo), 1480 }, - { HP_POP(clif->pGuildChangeMemberPosition), HP_POP2(HP_clif_pGuildChangeMemberPosition), 1482 }, - { HP_POP(clif->pGuildRequestEmblem), HP_POP2(HP_clif_pGuildRequestEmblem), 1484 }, - { HP_POP(clif->pGuildChangeEmblem), HP_POP2(HP_clif_pGuildChangeEmblem), 1486 }, - { HP_POP(clif->pGuildChangeNotice), HP_POP2(HP_clif_pGuildChangeNotice), 1488 }, - { HP_POP(clif->pGuildInvite), HP_POP2(HP_clif_pGuildInvite), 1490 }, - { HP_POP(clif->pGuildReplyInvite), HP_POP2(HP_clif_pGuildReplyInvite), 1492 }, - { HP_POP(clif->pGuildLeave), HP_POP2(HP_clif_pGuildLeave), 1494 }, - { HP_POP(clif->pGuildExpulsion), HP_POP2(HP_clif_pGuildExpulsion), 1496 }, - { HP_POP(clif->pGuildMessage), HP_POP2(HP_clif_pGuildMessage), 1498 }, - { HP_POP(clif->pGuildRequestAlliance), HP_POP2(HP_clif_pGuildRequestAlliance), 1500 }, - { HP_POP(clif->pGuildReplyAlliance), HP_POP2(HP_clif_pGuildReplyAlliance), 1502 }, - { HP_POP(clif->pGuildDelAlliance), HP_POP2(HP_clif_pGuildDelAlliance), 1504 }, - { HP_POP(clif->pGuildOpposition), HP_POP2(HP_clif_pGuildOpposition), 1506 }, - { HP_POP(clif->pGuildBreak), HP_POP2(HP_clif_pGuildBreak), 1508 }, - { HP_POP(clif->pPetMenu), HP_POP2(HP_clif_pPetMenu), 1510 }, - { HP_POP(clif->pCatchPet), HP_POP2(HP_clif_pCatchPet), 1512 }, - { HP_POP(clif->pSelectEgg), HP_POP2(HP_clif_pSelectEgg), 1514 }, - { HP_POP(clif->pSendEmotion), HP_POP2(HP_clif_pSendEmotion), 1516 }, - { HP_POP(clif->pChangePetName), HP_POP2(HP_clif_pChangePetName), 1518 }, - { HP_POP(clif->pGMKick), HP_POP2(HP_clif_pGMKick), 1520 }, - { HP_POP(clif->pGMKickAll), HP_POP2(HP_clif_pGMKickAll), 1522 }, - { HP_POP(clif->pGMShift), HP_POP2(HP_clif_pGMShift), 1524 }, - { HP_POP(clif->pGMRemove2), HP_POP2(HP_clif_pGMRemove2), 1526 }, - { HP_POP(clif->pGMRecall), HP_POP2(HP_clif_pGMRecall), 1528 }, - { HP_POP(clif->pGMRecall2), HP_POP2(HP_clif_pGMRecall2), 1530 }, - { HP_POP(clif->pGM_Monster_Item), HP_POP2(HP_clif_pGM_Monster_Item), 1532 }, - { HP_POP(clif->pGMHide), HP_POP2(HP_clif_pGMHide), 1534 }, - { HP_POP(clif->pGMReqNoChat), HP_POP2(HP_clif_pGMReqNoChat), 1536 }, - { HP_POP(clif->pGMRc), HP_POP2(HP_clif_pGMRc), 1538 }, - { HP_POP(clif->pGMReqAccountName), HP_POP2(HP_clif_pGMReqAccountName), 1540 }, - { HP_POP(clif->pGMChangeMapType), HP_POP2(HP_clif_pGMChangeMapType), 1542 }, - { HP_POP(clif->pPMIgnore), HP_POP2(HP_clif_pPMIgnore), 1544 }, - { HP_POP(clif->pPMIgnoreAll), HP_POP2(HP_clif_pPMIgnoreAll), 1546 }, - { HP_POP(clif->pPMIgnoreList), HP_POP2(HP_clif_pPMIgnoreList), 1548 }, - { HP_POP(clif->pNoviceDoriDori), HP_POP2(HP_clif_pNoviceDoriDori), 1550 }, - { HP_POP(clif->pNoviceExplosionSpirits), HP_POP2(HP_clif_pNoviceExplosionSpirits), 1552 }, - { HP_POP(clif->pFriendsListAdd), HP_POP2(HP_clif_pFriendsListAdd), 1554 }, - { HP_POP(clif->pFriendsListReply), HP_POP2(HP_clif_pFriendsListReply), 1556 }, - { HP_POP(clif->pFriendsListRemove), HP_POP2(HP_clif_pFriendsListRemove), 1558 }, - { HP_POP(clif->pPVPInfo), HP_POP2(HP_clif_pPVPInfo), 1560 }, - { HP_POP(clif->pBlacksmith), HP_POP2(HP_clif_pBlacksmith), 1562 }, - { HP_POP(clif->pAlchemist), HP_POP2(HP_clif_pAlchemist), 1564 }, - { HP_POP(clif->pTaekwon), HP_POP2(HP_clif_pTaekwon), 1566 }, - { HP_POP(clif->pRankingPk), HP_POP2(HP_clif_pRankingPk), 1568 }, - { HP_POP(clif->pFeelSaveOk), HP_POP2(HP_clif_pFeelSaveOk), 1570 }, - { HP_POP(clif->pChangeHomunculusName), HP_POP2(HP_clif_pChangeHomunculusName), 1572 }, - { HP_POP(clif->pHomMoveToMaster), HP_POP2(HP_clif_pHomMoveToMaster), 1574 }, - { HP_POP(clif->pHomMoveTo), HP_POP2(HP_clif_pHomMoveTo), 1576 }, - { HP_POP(clif->pHomAttack), HP_POP2(HP_clif_pHomAttack), 1578 }, - { HP_POP(clif->pHomMenu), HP_POP2(HP_clif_pHomMenu), 1580 }, - { HP_POP(clif->pAutoRevive), HP_POP2(HP_clif_pAutoRevive), 1582 }, - { HP_POP(clif->pCheck), HP_POP2(HP_clif_pCheck), 1584 }, - { HP_POP(clif->pMail_refreshinbox), HP_POP2(HP_clif_pMail_refreshinbox), 1586 }, - { HP_POP(clif->pMail_read), HP_POP2(HP_clif_pMail_read), 1588 }, - { HP_POP(clif->pMail_getattach), HP_POP2(HP_clif_pMail_getattach), 1590 }, - { HP_POP(clif->pMail_delete), HP_POP2(HP_clif_pMail_delete), 1592 }, - { HP_POP(clif->pMail_return), HP_POP2(HP_clif_pMail_return), 1594 }, - { HP_POP(clif->pMail_setattach), HP_POP2(HP_clif_pMail_setattach), 1596 }, - { HP_POP(clif->pMail_winopen), HP_POP2(HP_clif_pMail_winopen), 1598 }, - { HP_POP(clif->pMail_send), HP_POP2(HP_clif_pMail_send), 1600 }, - { HP_POP(clif->pAuction_cancelreg), HP_POP2(HP_clif_pAuction_cancelreg), 1602 }, - { HP_POP(clif->pAuction_setitem), HP_POP2(HP_clif_pAuction_setitem), 1604 }, - { HP_POP(clif->pAuction_register), HP_POP2(HP_clif_pAuction_register), 1606 }, - { HP_POP(clif->pAuction_cancel), HP_POP2(HP_clif_pAuction_cancel), 1608 }, - { HP_POP(clif->pAuction_close), HP_POP2(HP_clif_pAuction_close), 1610 }, - { HP_POP(clif->pAuction_bid), HP_POP2(HP_clif_pAuction_bid), 1612 }, - { HP_POP(clif->pAuction_search), HP_POP2(HP_clif_pAuction_search), 1614 }, - { HP_POP(clif->pAuction_buysell), HP_POP2(HP_clif_pAuction_buysell), 1616 }, - { HP_POP(clif->pcashshop_buy), HP_POP2(HP_clif_pcashshop_buy), 1618 }, - { HP_POP(clif->pAdopt_request), HP_POP2(HP_clif_pAdopt_request), 1620 }, - { HP_POP(clif->pAdopt_reply), HP_POP2(HP_clif_pAdopt_reply), 1622 }, - { HP_POP(clif->pViewPlayerEquip), HP_POP2(HP_clif_pViewPlayerEquip), 1624 }, - { HP_POP(clif->pEquipTick), HP_POP2(HP_clif_pEquipTick), 1626 }, - { HP_POP(clif->pquestStateAck), HP_POP2(HP_clif_pquestStateAck), 1628 }, - { HP_POP(clif->pmercenary_action), HP_POP2(HP_clif_pmercenary_action), 1630 }, - { HP_POP(clif->pBattleChat), HP_POP2(HP_clif_pBattleChat), 1632 }, - { HP_POP(clif->pLessEffect), HP_POP2(HP_clif_pLessEffect), 1634 }, - { HP_POP(clif->pItemListWindowSelected), HP_POP2(HP_clif_pItemListWindowSelected), 1636 }, - { HP_POP(clif->pReqOpenBuyingStore), HP_POP2(HP_clif_pReqOpenBuyingStore), 1638 }, - { HP_POP(clif->pReqCloseBuyingStore), HP_POP2(HP_clif_pReqCloseBuyingStore), 1640 }, - { HP_POP(clif->pReqClickBuyingStore), HP_POP2(HP_clif_pReqClickBuyingStore), 1642 }, - { HP_POP(clif->pReqTradeBuyingStore), HP_POP2(HP_clif_pReqTradeBuyingStore), 1644 }, - { HP_POP(clif->pSearchStoreInfo), HP_POP2(HP_clif_pSearchStoreInfo), 1646 }, - { HP_POP(clif->pSearchStoreInfoNextPage), HP_POP2(HP_clif_pSearchStoreInfoNextPage), 1648 }, - { HP_POP(clif->pCloseSearchStoreInfo), HP_POP2(HP_clif_pCloseSearchStoreInfo), 1650 }, - { HP_POP(clif->pSearchStoreInfoListItemClick), HP_POP2(HP_clif_pSearchStoreInfoListItemClick), 1652 }, - { HP_POP(clif->pDebug), HP_POP2(HP_clif_pDebug), 1654 }, - { HP_POP(clif->pSkillSelectMenu), HP_POP2(HP_clif_pSkillSelectMenu), 1656 }, - { HP_POP(clif->pMoveItem), HP_POP2(HP_clif_pMoveItem), 1658 }, - { HP_POP(clif->pDull), HP_POP2(HP_clif_pDull), 1660 }, - { HP_POP(clif->pBGQueueRegister), HP_POP2(HP_clif_pBGQueueRegister), 1662 }, - { HP_POP(clif->pBGQueueCheckState), HP_POP2(HP_clif_pBGQueueCheckState), 1664 }, - { HP_POP(clif->pBGQueueRevokeReq), HP_POP2(HP_clif_pBGQueueRevokeReq), 1666 }, - { HP_POP(clif->pBGQueueBattleBeginAck), HP_POP2(HP_clif_pBGQueueBattleBeginAck), 1668 }, - { HP_POP(clif->pCashShopOpen), HP_POP2(HP_clif_pCashShopOpen), 1670 }, - { HP_POP(clif->pCashShopClose), HP_POP2(HP_clif_pCashShopClose), 1672 }, - { HP_POP(clif->pCashShopReqTab), HP_POP2(HP_clif_pCashShopReqTab), 1674 }, - { HP_POP(clif->pCashShopSchedule), HP_POP2(HP_clif_pCashShopSchedule), 1676 }, - { HP_POP(clif->pCashShopBuy), HP_POP2(HP_clif_pCashShopBuy), 1678 }, - { HP_POP(clif->pPartyTick), HP_POP2(HP_clif_pPartyTick), 1680 }, - { HP_POP(clif->pGuildInvite2), HP_POP2(HP_clif_pGuildInvite2), 1682 }, - { HP_POP(clif->pPartyBookingAddFilter), HP_POP2(HP_clif_pPartyBookingAddFilter), 1684 }, - { HP_POP(clif->pPartyBookingSubFilter), HP_POP2(HP_clif_pPartyBookingSubFilter), 1686 }, - { HP_POP(clif->pPartyBookingReqVolunteer), HP_POP2(HP_clif_pPartyBookingReqVolunteer), 1688 }, - { HP_POP(clif->pPartyBookingRefuseVolunteer), HP_POP2(HP_clif_pPartyBookingRefuseVolunteer), 1690 }, - { HP_POP(clif->pPartyBookingCancelVolunteer), HP_POP2(HP_clif_pPartyBookingCancelVolunteer), 1692 }, + { HP_POP(clif->init, HP_clif_init) }, + { HP_POP(clif->final, HP_clif_final) }, + { HP_POP(clif->setip, HP_clif_setip) }, + { HP_POP(clif->setbindip, HP_clif_setbindip) }, + { HP_POP(clif->setport, HP_clif_setport) }, + { HP_POP(clif->refresh_ip, HP_clif_refresh_ip) }, + { HP_POP(clif->send, HP_clif_send) }, + { HP_POP(clif->send_sub, HP_clif_send_sub) }, + { HP_POP(clif->parse, HP_clif_parse) }, + { HP_POP(clif->parse_cmd, HP_clif_parse_cmd) }, + { HP_POP(clif->decrypt_cmd, HP_clif_decrypt_cmd) }, + { HP_POP(clif->authok, HP_clif_authok) }, + { HP_POP(clif->authrefuse, HP_clif_authrefuse) }, + { HP_POP(clif->authfail_fd, HP_clif_authfail_fd) }, + { HP_POP(clif->charselectok, HP_clif_charselectok) }, + { HP_POP(clif->dropflooritem, HP_clif_dropflooritem) }, + { HP_POP(clif->clearflooritem, HP_clif_clearflooritem) }, + { HP_POP(clif->additem, HP_clif_additem) }, + { HP_POP(clif->dropitem, HP_clif_dropitem) }, + { HP_POP(clif->delitem, HP_clif_delitem) }, + { HP_POP(clif->takeitem, HP_clif_takeitem) }, + { HP_POP(clif->arrowequip, HP_clif_arrowequip) }, + { HP_POP(clif->arrow_fail, HP_clif_arrow_fail) }, + { HP_POP(clif->use_card, HP_clif_use_card) }, + { HP_POP(clif->cart_additem, HP_clif_cart_additem) }, + { HP_POP(clif->cart_delitem, HP_clif_cart_delitem) }, + { HP_POP(clif->equipitemack, HP_clif_equipitemack) }, + { HP_POP(clif->unequipitemack, HP_clif_unequipitemack) }, + { HP_POP(clif->useitemack, HP_clif_useitemack) }, + { HP_POP(clif->addcards, HP_clif_addcards) }, + { HP_POP(clif->addcards2, HP_clif_addcards2) }, + { HP_POP(clif->item_sub, HP_clif_item_sub) }, + { HP_POP(clif->getareachar_item, HP_clif_getareachar_item) }, + { HP_POP(clif->cart_additem_ack, HP_clif_cart_additem_ack) }, + { HP_POP(clif->cashshop_load, HP_clif_cashshop_load) }, + { HP_POP(clif->package_announce, HP_clif_package_announce) }, + { HP_POP(clif->item_drop_announce, HP_clif_item_drop_announce) }, + { HP_POP(clif->clearunit_single, HP_clif_clearunit_single) }, + { HP_POP(clif->clearunit_area, HP_clif_clearunit_area) }, + { HP_POP(clif->clearunit_delayed, HP_clif_clearunit_delayed) }, + { HP_POP(clif->walkok, HP_clif_walkok) }, + { HP_POP(clif->move, HP_clif_move) }, + { HP_POP(clif->move2, HP_clif_move2) }, + { HP_POP(clif->blown, HP_clif_blown) }, + { HP_POP(clif->slide, HP_clif_slide) }, + { HP_POP(clif->fixpos, HP_clif_fixpos) }, + { HP_POP(clif->changelook, HP_clif_changelook) }, + { HP_POP(clif->changetraplook, HP_clif_changetraplook) }, + { HP_POP(clif->refreshlook, HP_clif_refreshlook) }, + { HP_POP(clif->class_change, HP_clif_class_change) }, + { HP_POP(clif->skill_delunit, HP_clif_skill_delunit) }, + { HP_POP(clif->skillunit_update, HP_clif_skillunit_update) }, + { HP_POP(clif->clearunit_delayed_sub, HP_clif_clearunit_delayed_sub) }, + { HP_POP(clif->set_unit_idle, HP_clif_set_unit_idle) }, + { HP_POP(clif->spawn_unit, HP_clif_spawn_unit) }, + { HP_POP(clif->spawn_unit2, HP_clif_spawn_unit2) }, + { HP_POP(clif->set_unit_idle2, HP_clif_set_unit_idle2) }, + { HP_POP(clif->set_unit_walking, HP_clif_set_unit_walking) }, + { HP_POP(clif->calc_walkdelay, HP_clif_calc_walkdelay) }, + { HP_POP(clif->getareachar_skillunit, HP_clif_getareachar_skillunit) }, + { HP_POP(clif->getareachar_unit, HP_clif_getareachar_unit) }, + { HP_POP(clif->clearchar_skillunit, HP_clif_clearchar_skillunit) }, + { HP_POP(clif->getareachar, HP_clif_getareachar) }, + { HP_POP(clif->graffiti_entry, HP_clif_graffiti_entry) }, + { HP_POP(clif->spawn, HP_clif_spawn) }, + { HP_POP(clif->changemap, HP_clif_changemap) }, + { HP_POP(clif->changemapcell, HP_clif_changemapcell) }, + { HP_POP(clif->map_property, HP_clif_map_property) }, + { HP_POP(clif->pvpset, HP_clif_pvpset) }, + { HP_POP(clif->map_property_mapall, HP_clif_map_property_mapall) }, + { HP_POP(clif->bossmapinfo, HP_clif_bossmapinfo) }, + { HP_POP(clif->map_type, HP_clif_map_type) }, + { HP_POP(clif->maptypeproperty2, HP_clif_maptypeproperty2) }, + { HP_POP(clif->changemapserver, HP_clif_changemapserver) }, + { HP_POP(clif->npcbuysell, HP_clif_npcbuysell) }, + { HP_POP(clif->buylist, HP_clif_buylist) }, + { HP_POP(clif->selllist, HP_clif_selllist) }, + { HP_POP(clif->cashshop_show, HP_clif_cashshop_show) }, + { HP_POP(clif->npc_buy_result, HP_clif_npc_buy_result) }, + { HP_POP(clif->npc_sell_result, HP_clif_npc_sell_result) }, + { HP_POP(clif->cashshop_ack, HP_clif_cashshop_ack) }, + { HP_POP(clif->scriptmes, HP_clif_scriptmes) }, + { HP_POP(clif->scriptnext, HP_clif_scriptnext) }, + { HP_POP(clif->scriptclose, HP_clif_scriptclose) }, + { HP_POP(clif->scriptmenu, HP_clif_scriptmenu) }, + { HP_POP(clif->scriptinput, HP_clif_scriptinput) }, + { HP_POP(clif->scriptinputstr, HP_clif_scriptinputstr) }, + { HP_POP(clif->cutin, HP_clif_cutin) }, + { HP_POP(clif->sendfakenpc, HP_clif_sendfakenpc) }, + { HP_POP(clif->scriptclear, HP_clif_scriptclear) }, + { HP_POP(clif->viewpoint, HP_clif_viewpoint) }, + { HP_POP(clif->damage, HP_clif_damage) }, + { HP_POP(clif->sitting, HP_clif_sitting) }, + { HP_POP(clif->standing, HP_clif_standing) }, + { HP_POP(clif->arrow_create_list, HP_clif_arrow_create_list) }, + { HP_POP(clif->refresh, HP_clif_refresh) }, + { HP_POP(clif->fame_blacksmith, HP_clif_fame_blacksmith) }, + { HP_POP(clif->fame_alchemist, HP_clif_fame_alchemist) }, + { HP_POP(clif->fame_taekwon, HP_clif_fame_taekwon) }, + { HP_POP(clif->ranklist, HP_clif_ranklist) }, + { HP_POP(clif->update_rankingpoint, HP_clif_update_rankingpoint) }, + { HP_POP(clif->pRanklist, HP_clif_pRanklist) }, + { HP_POP(clif->hotkeys, HP_clif_hotkeys) }, + { HP_POP(clif->insight, HP_clif_insight) }, + { HP_POP(clif->outsight, HP_clif_outsight) }, + { HP_POP(clif->skillcastcancel, HP_clif_skillcastcancel) }, + { HP_POP(clif->skill_fail, HP_clif_skill_fail) }, + { HP_POP(clif->skill_cooldown, HP_clif_skill_cooldown) }, + { HP_POP(clif->skill_memomessage, HP_clif_skill_memomessage) }, + { HP_POP(clif->skill_mapinfomessage, HP_clif_skill_mapinfomessage) }, + { HP_POP(clif->skill_produce_mix_list, HP_clif_skill_produce_mix_list) }, + { HP_POP(clif->cooking_list, HP_clif_cooking_list) }, + { HP_POP(clif->autospell, HP_clif_autospell) }, + { HP_POP(clif->combo_delay, HP_clif_combo_delay) }, + { HP_POP(clif->status_change, HP_clif_status_change) }, + { HP_POP(clif->insert_card, HP_clif_insert_card) }, + { HP_POP(clif->inventorylist, HP_clif_inventorylist) }, + { HP_POP(clif->equiplist, HP_clif_equiplist) }, + { HP_POP(clif->cartlist, HP_clif_cartlist) }, + { HP_POP(clif->favorite_item, HP_clif_favorite_item) }, + { HP_POP(clif->clearcart, HP_clif_clearcart) }, + { HP_POP(clif->item_identify_list, HP_clif_item_identify_list) }, + { HP_POP(clif->item_identified, HP_clif_item_identified) }, + { HP_POP(clif->item_repair_list, HP_clif_item_repair_list) }, + { HP_POP(clif->item_repaireffect, HP_clif_item_repaireffect) }, + { HP_POP(clif->item_damaged, HP_clif_item_damaged) }, + { HP_POP(clif->item_refine_list, HP_clif_item_refine_list) }, + { HP_POP(clif->item_skill, HP_clif_item_skill) }, + { HP_POP(clif->mvp_item, HP_clif_mvp_item) }, + { HP_POP(clif->mvp_exp, HP_clif_mvp_exp) }, + { HP_POP(clif->mvp_noitem, HP_clif_mvp_noitem) }, + { HP_POP(clif->changed_dir, HP_clif_changed_dir) }, + { HP_POP(clif->charnameack, HP_clif_charnameack) }, + { HP_POP(clif->monster_hp_bar, HP_clif_monster_hp_bar) }, + { HP_POP(clif->hpmeter, HP_clif_hpmeter) }, + { HP_POP(clif->hpmeter_single, HP_clif_hpmeter_single) }, + { HP_POP(clif->hpmeter_sub, HP_clif_hpmeter_sub) }, + { HP_POP(clif->upgrademessage, HP_clif_upgrademessage) }, + { HP_POP(clif->get_weapon_view, HP_clif_get_weapon_view) }, + { HP_POP(clif->gospel_info, HP_clif_gospel_info) }, + { HP_POP(clif->feel_req, HP_clif_feel_req) }, + { HP_POP(clif->starskill, HP_clif_starskill) }, + { HP_POP(clif->feel_info, HP_clif_feel_info) }, + { HP_POP(clif->hate_info, HP_clif_hate_info) }, + { HP_POP(clif->mission_info, HP_clif_mission_info) }, + { HP_POP(clif->feel_hate_reset, HP_clif_feel_hate_reset) }, + { HP_POP(clif->partytickack, HP_clif_partytickack) }, + { HP_POP(clif->equiptickack, HP_clif_equiptickack) }, + { HP_POP(clif->viewequip_ack, HP_clif_viewequip_ack) }, + { HP_POP(clif->equpcheckbox, HP_clif_equpcheckbox) }, + { HP_POP(clif->displayexp, HP_clif_displayexp) }, + { HP_POP(clif->font, HP_clif_font) }, + { HP_POP(clif->progressbar, HP_clif_progressbar) }, + { HP_POP(clif->progressbar_abort, HP_clif_progressbar_abort) }, + { HP_POP(clif->showdigit, HP_clif_showdigit) }, + { HP_POP(clif->elementalconverter_list, HP_clif_elementalconverter_list) }, + { HP_POP(clif->spellbook_list, HP_clif_spellbook_list) }, + { HP_POP(clif->magicdecoy_list, HP_clif_magicdecoy_list) }, + { HP_POP(clif->poison_list, HP_clif_poison_list) }, + { HP_POP(clif->autoshadowspell_list, HP_clif_autoshadowspell_list) }, + { HP_POP(clif->skill_itemlistwindow, HP_clif_skill_itemlistwindow) }, + { HP_POP(clif->sc_load, HP_clif_sc_load) }, + { HP_POP(clif->sc_end, HP_clif_sc_end) }, + { HP_POP(clif->initialstatus, HP_clif_initialstatus) }, + { HP_POP(clif->cooldown_list, HP_clif_cooldown_list) }, + { HP_POP(clif->updatestatus, HP_clif_updatestatus) }, + { HP_POP(clif->changestatus, HP_clif_changestatus) }, + { HP_POP(clif->statusupack, HP_clif_statusupack) }, + { HP_POP(clif->movetoattack, HP_clif_movetoattack) }, + { HP_POP(clif->solved_charname, HP_clif_solved_charname) }, + { HP_POP(clif->charnameupdate, HP_clif_charnameupdate) }, + { HP_POP(clif->delayquit, HP_clif_delayquit) }, + { HP_POP(clif->getareachar_pc, HP_clif_getareachar_pc) }, + { HP_POP(clif->disconnect_ack, HP_clif_disconnect_ack) }, + { HP_POP(clif->PVPInfo, HP_clif_PVPInfo) }, + { HP_POP(clif->blacksmith, HP_clif_blacksmith) }, + { HP_POP(clif->alchemist, HP_clif_alchemist) }, + { HP_POP(clif->taekwon, HP_clif_taekwon) }, + { HP_POP(clif->ranking_pk, HP_clif_ranking_pk) }, + { HP_POP(clif->quitsave, HP_clif_quitsave) }, + { HP_POP(clif->misceffect, HP_clif_misceffect) }, + { HP_POP(clif->changeoption, HP_clif_changeoption) }, + { HP_POP(clif->changeoption2, HP_clif_changeoption2) }, + { HP_POP(clif->emotion, HP_clif_emotion) }, + { HP_POP(clif->talkiebox, HP_clif_talkiebox) }, + { HP_POP(clif->wedding_effect, HP_clif_wedding_effect) }, + { HP_POP(clif->divorced, HP_clif_divorced) }, + { HP_POP(clif->callpartner, HP_clif_callpartner) }, + { HP_POP(clif->skill_damage, HP_clif_skill_damage) }, + { HP_POP(clif->skill_nodamage, HP_clif_skill_nodamage) }, + { HP_POP(clif->skill_poseffect, HP_clif_skill_poseffect) }, + { HP_POP(clif->skill_estimation, HP_clif_skill_estimation) }, + { HP_POP(clif->skill_warppoint, HP_clif_skill_warppoint) }, + { HP_POP(clif->skillcasting, HP_clif_skillcasting) }, + { HP_POP(clif->produce_effect, HP_clif_produce_effect) }, + { HP_POP(clif->devotion, HP_clif_devotion) }, + { HP_POP(clif->spiritball, HP_clif_spiritball) }, + { HP_POP(clif->spiritball_single, HP_clif_spiritball_single) }, + { HP_POP(clif->bladestop, HP_clif_bladestop) }, + { HP_POP(clif->mvp_effect, HP_clif_mvp_effect) }, + { HP_POP(clif->heal, HP_clif_heal) }, + { HP_POP(clif->resurrection, HP_clif_resurrection) }, + { HP_POP(clif->refine, HP_clif_refine) }, + { HP_POP(clif->weather, HP_clif_weather) }, + { HP_POP(clif->specialeffect, HP_clif_specialeffect) }, + { HP_POP(clif->specialeffect_single, HP_clif_specialeffect_single) }, + { HP_POP(clif->specialeffect_value, HP_clif_specialeffect_value) }, + { HP_POP(clif->millenniumshield, HP_clif_millenniumshield) }, + { HP_POP(clif->charm, HP_clif_charm) }, + { HP_POP(clif->charm_single, HP_clif_charm_single) }, + { HP_POP(clif->snap, HP_clif_snap) }, + { HP_POP(clif->weather_check, HP_clif_weather_check) }, + { HP_POP(clif->playBGM, HP_clif_playBGM) }, + { HP_POP(clif->soundeffect, HP_clif_soundeffect) }, + { HP_POP(clif->soundeffectall, HP_clif_soundeffectall) }, + { HP_POP(clif->GlobalMessage, HP_clif_GlobalMessage) }, + { HP_POP(clif->createchat, HP_clif_createchat) }, + { HP_POP(clif->dispchat, HP_clif_dispchat) }, + { HP_POP(clif->joinchatfail, HP_clif_joinchatfail) }, + { HP_POP(clif->joinchatok, HP_clif_joinchatok) }, + { HP_POP(clif->addchat, HP_clif_addchat) }, + { HP_POP(clif->changechatowner, HP_clif_changechatowner) }, + { HP_POP(clif->clearchat, HP_clif_clearchat) }, + { HP_POP(clif->leavechat, HP_clif_leavechat) }, + { HP_POP(clif->changechatstatus, HP_clif_changechatstatus) }, + { HP_POP(clif->wis_message, HP_clif_wis_message) }, + { HP_POP(clif->wis_end, HP_clif_wis_end) }, + { HP_POP(clif->disp_message, HP_clif_disp_message) }, + { HP_POP(clif->broadcast, HP_clif_broadcast) }, + { HP_POP(clif->broadcast2, HP_clif_broadcast2) }, + { HP_POP(clif->messagecolor, HP_clif_messagecolor) }, + { HP_POP(clif->disp_overhead, HP_clif_disp_overhead) }, + { HP_POP(clif->msg, HP_clif_msg) }, + { HP_POP(clif->msg_value, HP_clif_msg_value) }, + { HP_POP(clif->msg_skill, HP_clif_msg_skill) }, + { HP_POP(clif->msgtable, HP_clif_msgtable) }, + { HP_POP(clif->msgtable_num, HP_clif_msgtable_num) }, + { HP_POP(clif->message, HP_clif_message) }, + { HP_POP(clif->messageln, HP_clif_messageln) }, + { HP_POP(clif->colormes, HP_clif_colormes) }, + { HP_POP(clif->process_message, HP_clif_process_message) }, + { HP_POP(clif->wisexin, HP_clif_wisexin) }, + { HP_POP(clif->wisall, HP_clif_wisall) }, + { HP_POP(clif->PMIgnoreList, HP_clif_PMIgnoreList) }, + { HP_POP(clif->ShowScript, HP_clif_ShowScript) }, + { HP_POP(clif->traderequest, HP_clif_traderequest) }, + { HP_POP(clif->tradestart, HP_clif_tradestart) }, + { HP_POP(clif->tradeadditem, HP_clif_tradeadditem) }, + { HP_POP(clif->tradeitemok, HP_clif_tradeitemok) }, + { HP_POP(clif->tradedeal_lock, HP_clif_tradedeal_lock) }, + { HP_POP(clif->tradecancelled, HP_clif_tradecancelled) }, + { HP_POP(clif->tradecompleted, HP_clif_tradecompleted) }, + { HP_POP(clif->tradeundo, HP_clif_tradeundo) }, + { HP_POP(clif->openvendingreq, HP_clif_openvendingreq) }, + { HP_POP(clif->showvendingboard, HP_clif_showvendingboard) }, + { HP_POP(clif->closevendingboard, HP_clif_closevendingboard) }, + { HP_POP(clif->vendinglist, HP_clif_vendinglist) }, + { HP_POP(clif->buyvending, HP_clif_buyvending) }, + { HP_POP(clif->openvending, HP_clif_openvending) }, + { HP_POP(clif->vendingreport, HP_clif_vendingreport) }, + { HP_POP(clif->storagelist, HP_clif_storagelist) }, + { HP_POP(clif->updatestorageamount, HP_clif_updatestorageamount) }, + { HP_POP(clif->storageitemadded, HP_clif_storageitemadded) }, + { HP_POP(clif->storageitemremoved, HP_clif_storageitemremoved) }, + { HP_POP(clif->storageclose, HP_clif_storageclose) }, + { HP_POP(clif->skillinfoblock, HP_clif_skillinfoblock) }, + { HP_POP(clif->skillup, HP_clif_skillup) }, + { HP_POP(clif->skillinfo, HP_clif_skillinfo) }, + { HP_POP(clif->addskill, HP_clif_addskill) }, + { HP_POP(clif->deleteskill, HP_clif_deleteskill) }, + { HP_POP(clif->party_created, HP_clif_party_created) }, + { HP_POP(clif->party_member_info, HP_clif_party_member_info) }, + { HP_POP(clif->party_info, HP_clif_party_info) }, + { HP_POP(clif->party_invite, HP_clif_party_invite) }, + { HP_POP(clif->party_inviteack, HP_clif_party_inviteack) }, + { HP_POP(clif->party_option, HP_clif_party_option) }, + { HP_POP(clif->party_withdraw, HP_clif_party_withdraw) }, + { HP_POP(clif->party_message, HP_clif_party_message) }, + { HP_POP(clif->party_xy, HP_clif_party_xy) }, + { HP_POP(clif->party_xy_single, HP_clif_party_xy_single) }, + { HP_POP(clif->party_hp, HP_clif_party_hp) }, + { HP_POP(clif->party_xy_remove, HP_clif_party_xy_remove) }, + { HP_POP(clif->party_show_picker, HP_clif_party_show_picker) }, + { HP_POP(clif->partyinvitationstate, HP_clif_partyinvitationstate) }, + { HP_POP(clif->guild_created, HP_clif_guild_created) }, + { HP_POP(clif->guild_belonginfo, HP_clif_guild_belonginfo) }, + { HP_POP(clif->guild_masterormember, HP_clif_guild_masterormember) }, + { HP_POP(clif->guild_basicinfo, HP_clif_guild_basicinfo) }, + { HP_POP(clif->guild_allianceinfo, HP_clif_guild_allianceinfo) }, + { HP_POP(clif->guild_memberlist, HP_clif_guild_memberlist) }, + { HP_POP(clif->guild_skillinfo, HP_clif_guild_skillinfo) }, + { HP_POP(clif->guild_send_onlineinfo, HP_clif_guild_send_onlineinfo) }, + { HP_POP(clif->guild_memberlogin_notice, HP_clif_guild_memberlogin_notice) }, + { HP_POP(clif->guild_invite, HP_clif_guild_invite) }, + { HP_POP(clif->guild_inviteack, HP_clif_guild_inviteack) }, + { HP_POP(clif->guild_leave, HP_clif_guild_leave) }, + { HP_POP(clif->guild_expulsion, HP_clif_guild_expulsion) }, + { HP_POP(clif->guild_positionchanged, HP_clif_guild_positionchanged) }, + { HP_POP(clif->guild_memberpositionchanged, HP_clif_guild_memberpositionchanged) }, + { HP_POP(clif->guild_emblem, HP_clif_guild_emblem) }, + { HP_POP(clif->guild_emblem_area, HP_clif_guild_emblem_area) }, + { HP_POP(clif->guild_notice, HP_clif_guild_notice) }, + { HP_POP(clif->guild_message, HP_clif_guild_message) }, + { HP_POP(clif->guild_reqalliance, HP_clif_guild_reqalliance) }, + { HP_POP(clif->guild_allianceack, HP_clif_guild_allianceack) }, + { HP_POP(clif->guild_delalliance, HP_clif_guild_delalliance) }, + { HP_POP(clif->guild_oppositionack, HP_clif_guild_oppositionack) }, + { HP_POP(clif->guild_broken, HP_clif_guild_broken) }, + { HP_POP(clif->guild_xy, HP_clif_guild_xy) }, + { HP_POP(clif->guild_xy_single, HP_clif_guild_xy_single) }, + { HP_POP(clif->guild_xy_remove, HP_clif_guild_xy_remove) }, + { HP_POP(clif->guild_positionnamelist, HP_clif_guild_positionnamelist) }, + { HP_POP(clif->guild_positioninfolist, HP_clif_guild_positioninfolist) }, + { HP_POP(clif->guild_expulsionlist, HP_clif_guild_expulsionlist) }, + { HP_POP(clif->validate_emblem, HP_clif_validate_emblem) }, + { HP_POP(clif->bg_hp, HP_clif_bg_hp) }, + { HP_POP(clif->bg_xy, HP_clif_bg_xy) }, + { HP_POP(clif->bg_xy_remove, HP_clif_bg_xy_remove) }, + { HP_POP(clif->bg_message, HP_clif_bg_message) }, + { HP_POP(clif->bg_updatescore, HP_clif_bg_updatescore) }, + { HP_POP(clif->bg_updatescore_single, HP_clif_bg_updatescore_single) }, + { HP_POP(clif->sendbgemblem_area, HP_clif_sendbgemblem_area) }, + { HP_POP(clif->sendbgemblem_single, HP_clif_sendbgemblem_single) }, + { HP_POP(clif->instance, HP_clif_instance) }, + { HP_POP(clif->instance_join, HP_clif_instance_join) }, + { HP_POP(clif->instance_leave, HP_clif_instance_leave) }, + { HP_POP(clif->catch_process, HP_clif_catch_process) }, + { HP_POP(clif->pet_roulette, HP_clif_pet_roulette) }, + { HP_POP(clif->sendegg, HP_clif_sendegg) }, + { HP_POP(clif->send_petstatus, HP_clif_send_petstatus) }, + { HP_POP(clif->send_petdata, HP_clif_send_petdata) }, + { HP_POP(clif->pet_emotion, HP_clif_pet_emotion) }, + { HP_POP(clif->pet_food, HP_clif_pet_food) }, + { HP_POP(clif->friendslist_toggle_sub, HP_clif_friendslist_toggle_sub) }, + { HP_POP(clif->friendslist_send, HP_clif_friendslist_send) }, + { HP_POP(clif->friendslist_reqack, HP_clif_friendslist_reqack) }, + { HP_POP(clif->friendslist_toggle, HP_clif_friendslist_toggle) }, + { HP_POP(clif->friendlist_req, HP_clif_friendlist_req) }, + { HP_POP(clif->GM_kickack, HP_clif_GM_kickack) }, + { HP_POP(clif->GM_kick, HP_clif_GM_kick) }, + { HP_POP(clif->manner_message, HP_clif_manner_message) }, + { HP_POP(clif->GM_silence, HP_clif_GM_silence) }, + { HP_POP(clif->account_name, HP_clif_account_name) }, + { HP_POP(clif->check, HP_clif_check) }, + { HP_POP(clif->hominfo, HP_clif_hominfo) }, + { HP_POP(clif->homskillinfoblock, HP_clif_homskillinfoblock) }, + { HP_POP(clif->homskillup, HP_clif_homskillup) }, + { HP_POP(clif->hom_food, HP_clif_hom_food) }, + { HP_POP(clif->send_homdata, HP_clif_send_homdata) }, + { HP_POP(clif->quest_send_list, HP_clif_quest_send_list) }, + { HP_POP(clif->quest_send_mission, HP_clif_quest_send_mission) }, + { HP_POP(clif->quest_add, HP_clif_quest_add) }, + { HP_POP(clif->quest_delete, HP_clif_quest_delete) }, + { HP_POP(clif->quest_update_status, HP_clif_quest_update_status) }, + { HP_POP(clif->quest_update_objective, HP_clif_quest_update_objective) }, + { HP_POP(clif->quest_show_event, HP_clif_quest_show_event) }, + { HP_POP(clif->mail_window, HP_clif_mail_window) }, + { HP_POP(clif->mail_read, HP_clif_mail_read) }, + { HP_POP(clif->mail_delete, HP_clif_mail_delete) }, + { HP_POP(clif->mail_return, HP_clif_mail_return) }, + { HP_POP(clif->mail_send, HP_clif_mail_send) }, + { HP_POP(clif->mail_new, HP_clif_mail_new) }, + { HP_POP(clif->mail_refreshinbox, HP_clif_mail_refreshinbox) }, + { HP_POP(clif->mail_getattachment, HP_clif_mail_getattachment) }, + { HP_POP(clif->mail_setattachment, HP_clif_mail_setattachment) }, + { HP_POP(clif->auction_openwindow, HP_clif_auction_openwindow) }, + { HP_POP(clif->auction_results, HP_clif_auction_results) }, + { HP_POP(clif->auction_message, HP_clif_auction_message) }, + { HP_POP(clif->auction_close, HP_clif_auction_close) }, + { HP_POP(clif->auction_setitem, HP_clif_auction_setitem) }, + { HP_POP(clif->mercenary_info, HP_clif_mercenary_info) }, + { HP_POP(clif->mercenary_skillblock, HP_clif_mercenary_skillblock) }, + { HP_POP(clif->mercenary_message, HP_clif_mercenary_message) }, + { HP_POP(clif->mercenary_updatestatus, HP_clif_mercenary_updatestatus) }, + { HP_POP(clif->rental_time, HP_clif_rental_time) }, + { HP_POP(clif->rental_expired, HP_clif_rental_expired) }, + { HP_POP(clif->PartyBookingRegisterAck, HP_clif_PartyBookingRegisterAck) }, + { HP_POP(clif->PartyBookingDeleteAck, HP_clif_PartyBookingDeleteAck) }, + { HP_POP(clif->PartyBookingSearchAck, HP_clif_PartyBookingSearchAck) }, + { HP_POP(clif->PartyBookingUpdateNotify, HP_clif_PartyBookingUpdateNotify) }, + { HP_POP(clif->PartyBookingDeleteNotify, HP_clif_PartyBookingDeleteNotify) }, + { HP_POP(clif->PartyBookingInsertNotify, HP_clif_PartyBookingInsertNotify) }, + { HP_POP(clif->PartyRecruitRegisterAck, HP_clif_PartyRecruitRegisterAck) }, + { HP_POP(clif->PartyRecruitDeleteAck, HP_clif_PartyRecruitDeleteAck) }, + { HP_POP(clif->PartyRecruitSearchAck, HP_clif_PartyRecruitSearchAck) }, + { HP_POP(clif->PartyRecruitUpdateNotify, HP_clif_PartyRecruitUpdateNotify) }, + { HP_POP(clif->PartyRecruitDeleteNotify, HP_clif_PartyRecruitDeleteNotify) }, + { HP_POP(clif->PartyRecruitInsertNotify, HP_clif_PartyRecruitInsertNotify) }, + { HP_POP(clif->PartyBookingVolunteerInfo, HP_clif_PartyBookingVolunteerInfo) }, + { HP_POP(clif->PartyBookingRefuseVolunteer, HP_clif_PartyBookingRefuseVolunteer) }, + { HP_POP(clif->PartyBookingCancelVolunteer, HP_clif_PartyBookingCancelVolunteer) }, + { HP_POP(clif->PartyBookingAddFilteringList, HP_clif_PartyBookingAddFilteringList) }, + { HP_POP(clif->PartyBookingSubFilteringList, HP_clif_PartyBookingSubFilteringList) }, + { HP_POP(clif->buyingstore_open, HP_clif_buyingstore_open) }, + { HP_POP(clif->buyingstore_open_failed, HP_clif_buyingstore_open_failed) }, + { HP_POP(clif->buyingstore_myitemlist, HP_clif_buyingstore_myitemlist) }, + { HP_POP(clif->buyingstore_entry, HP_clif_buyingstore_entry) }, + { HP_POP(clif->buyingstore_entry_single, HP_clif_buyingstore_entry_single) }, + { HP_POP(clif->buyingstore_disappear_entry, HP_clif_buyingstore_disappear_entry) }, + { HP_POP(clif->buyingstore_disappear_entry_single, HP_clif_buyingstore_disappear_entry_single) }, + { HP_POP(clif->buyingstore_itemlist, HP_clif_buyingstore_itemlist) }, + { HP_POP(clif->buyingstore_trade_failed_buyer, HP_clif_buyingstore_trade_failed_buyer) }, + { HP_POP(clif->buyingstore_update_item, HP_clif_buyingstore_update_item) }, + { HP_POP(clif->buyingstore_delete_item, HP_clif_buyingstore_delete_item) }, + { HP_POP(clif->buyingstore_trade_failed_seller, HP_clif_buyingstore_trade_failed_seller) }, + { HP_POP(clif->search_store_info_ack, HP_clif_search_store_info_ack) }, + { HP_POP(clif->search_store_info_failed, HP_clif_search_store_info_failed) }, + { HP_POP(clif->open_search_store_info, HP_clif_open_search_store_info) }, + { HP_POP(clif->search_store_info_click_ack, HP_clif_search_store_info_click_ack) }, + { HP_POP(clif->elemental_info, HP_clif_elemental_info) }, + { HP_POP(clif->elemental_updatestatus, HP_clif_elemental_updatestatus) }, + { HP_POP(clif->bgqueue_ack, HP_clif_bgqueue_ack) }, + { HP_POP(clif->bgqueue_notice_delete, HP_clif_bgqueue_notice_delete) }, + { HP_POP(clif->bgqueue_update_info, HP_clif_bgqueue_update_info) }, + { HP_POP(clif->bgqueue_joined, HP_clif_bgqueue_joined) }, + { HP_POP(clif->bgqueue_pcleft, HP_clif_bgqueue_pcleft) }, + { HP_POP(clif->bgqueue_battlebegins, HP_clif_bgqueue_battlebegins) }, + { HP_POP(clif->adopt_reply, HP_clif_adopt_reply) }, + { HP_POP(clif->adopt_request, HP_clif_adopt_request) }, + { HP_POP(clif->readbook, HP_clif_readbook) }, + { HP_POP(clif->notify_time, HP_clif_notify_time) }, + { HP_POP(clif->user_count, HP_clif_user_count) }, + { HP_POP(clif->noask_sub, HP_clif_noask_sub) }, + { HP_POP(clif->bc_ready, HP_clif_bc_ready) }, + { HP_POP(clif->undisguise_timer, HP_clif_undisguise_timer) }, + { HP_POP(clif->chsys_create, HP_clif_chsys_create) }, + { HP_POP(clif->chsys_msg, HP_clif_chsys_msg) }, + { HP_POP(clif->chsys_msg2, HP_clif_chsys_msg2) }, + { HP_POP(clif->chsys_send, HP_clif_chsys_send) }, + { HP_POP(clif->chsys_join, HP_clif_chsys_join) }, + { HP_POP(clif->chsys_left, HP_clif_chsys_left) }, + { HP_POP(clif->chsys_delete, HP_clif_chsys_delete) }, + { HP_POP(clif->chsys_mjoin, HP_clif_chsys_mjoin) }, + { HP_POP(clif->chsys_quit, HP_clif_chsys_quit) }, + { HP_POP(clif->chsys_quitg, HP_clif_chsys_quitg) }, + { HP_POP(clif->chsys_gjoin, HP_clif_chsys_gjoin) }, + { HP_POP(clif->chsys_gleave, HP_clif_chsys_gleave) }, + { HP_POP(clif->bank_deposit, HP_clif_bank_deposit) }, + { HP_POP(clif->bank_withdraw, HP_clif_bank_withdraw) }, + { HP_POP(clif->show_modifiers, HP_clif_show_modifiers) }, + { HP_POP(clif->notify_bounditem, HP_clif_notify_bounditem) }, + { HP_POP(clif->delay_damage, HP_clif_delay_damage) }, + { HP_POP(clif->delay_damage_sub, HP_clif_delay_damage_sub) }, + { HP_POP(clif->npc_market_open, HP_clif_npc_market_open) }, + { HP_POP(clif->npc_market_purchase_ack, HP_clif_npc_market_purchase_ack) }, + { HP_POP(clif->pWantToConnection, HP_clif_pWantToConnection) }, + { HP_POP(clif->pLoadEndAck, HP_clif_pLoadEndAck) }, + { HP_POP(clif->pTickSend, HP_clif_pTickSend) }, + { HP_POP(clif->pHotkey, HP_clif_pHotkey) }, + { HP_POP(clif->pProgressbar, HP_clif_pProgressbar) }, + { HP_POP(clif->pWalkToXY, HP_clif_pWalkToXY) }, + { HP_POP(clif->pQuitGame, HP_clif_pQuitGame) }, + { HP_POP(clif->pGetCharNameRequest, HP_clif_pGetCharNameRequest) }, + { HP_POP(clif->pGlobalMessage, HP_clif_pGlobalMessage) }, + { HP_POP(clif->pMapMove, HP_clif_pMapMove) }, + { HP_POP(clif->pChangeDir, HP_clif_pChangeDir) }, + { HP_POP(clif->pEmotion, HP_clif_pEmotion) }, + { HP_POP(clif->pHowManyConnections, HP_clif_pHowManyConnections) }, + { HP_POP(clif->pActionRequest, HP_clif_pActionRequest) }, + { HP_POP(clif->pActionRequest_sub, HP_clif_pActionRequest_sub) }, + { HP_POP(clif->pRestart, HP_clif_pRestart) }, + { HP_POP(clif->pWisMessage, HP_clif_pWisMessage) }, + { HP_POP(clif->pBroadcast, HP_clif_pBroadcast) }, + { HP_POP(clif->pTakeItem, HP_clif_pTakeItem) }, + { HP_POP(clif->pDropItem, HP_clif_pDropItem) }, + { HP_POP(clif->pUseItem, HP_clif_pUseItem) }, + { HP_POP(clif->pEquipItem, HP_clif_pEquipItem) }, + { HP_POP(clif->pUnequipItem, HP_clif_pUnequipItem) }, + { HP_POP(clif->pNpcClicked, HP_clif_pNpcClicked) }, + { HP_POP(clif->pNpcBuySellSelected, HP_clif_pNpcBuySellSelected) }, + { HP_POP(clif->pNpcBuyListSend, HP_clif_pNpcBuyListSend) }, + { HP_POP(clif->pNpcSellListSend, HP_clif_pNpcSellListSend) }, + { HP_POP(clif->pCreateChatRoom, HP_clif_pCreateChatRoom) }, + { HP_POP(clif->pChatAddMember, HP_clif_pChatAddMember) }, + { HP_POP(clif->pChatRoomStatusChange, HP_clif_pChatRoomStatusChange) }, + { HP_POP(clif->pChangeChatOwner, HP_clif_pChangeChatOwner) }, + { HP_POP(clif->pKickFromChat, HP_clif_pKickFromChat) }, + { HP_POP(clif->pChatLeave, HP_clif_pChatLeave) }, + { HP_POP(clif->pTradeRequest, HP_clif_pTradeRequest) }, + { HP_POP(clif->chann_config_read, HP_clif_chann_config_read) }, + { HP_POP(clif->pTradeAck, HP_clif_pTradeAck) }, + { HP_POP(clif->pTradeAddItem, HP_clif_pTradeAddItem) }, + { HP_POP(clif->pTradeOk, HP_clif_pTradeOk) }, + { HP_POP(clif->pTradeCancel, HP_clif_pTradeCancel) }, + { HP_POP(clif->pTradeCommit, HP_clif_pTradeCommit) }, + { HP_POP(clif->pStopAttack, HP_clif_pStopAttack) }, + { HP_POP(clif->pPutItemToCart, HP_clif_pPutItemToCart) }, + { HP_POP(clif->pGetItemFromCart, HP_clif_pGetItemFromCart) }, + { HP_POP(clif->pRemoveOption, HP_clif_pRemoveOption) }, + { HP_POP(clif->pChangeCart, HP_clif_pChangeCart) }, + { HP_POP(clif->pStatusUp, HP_clif_pStatusUp) }, + { HP_POP(clif->pSkillUp, HP_clif_pSkillUp) }, + { HP_POP(clif->pUseSkillToId, HP_clif_pUseSkillToId) }, + { HP_POP(clif->pUseSkillToId_homun, HP_clif_pUseSkillToId_homun) }, + { HP_POP(clif->pUseSkillToId_mercenary, HP_clif_pUseSkillToId_mercenary) }, + { HP_POP(clif->pUseSkillToPos, HP_clif_pUseSkillToPos) }, + { HP_POP(clif->pUseSkillToPosSub, HP_clif_pUseSkillToPosSub) }, + { HP_POP(clif->pUseSkillToPos_homun, HP_clif_pUseSkillToPos_homun) }, + { HP_POP(clif->pUseSkillToPos_mercenary, HP_clif_pUseSkillToPos_mercenary) }, + { HP_POP(clif->pUseSkillToPosMoreInfo, HP_clif_pUseSkillToPosMoreInfo) }, + { HP_POP(clif->pUseSkillMap, HP_clif_pUseSkillMap) }, + { HP_POP(clif->pRequestMemo, HP_clif_pRequestMemo) }, + { HP_POP(clif->pProduceMix, HP_clif_pProduceMix) }, + { HP_POP(clif->pCooking, HP_clif_pCooking) }, + { HP_POP(clif->pRepairItem, HP_clif_pRepairItem) }, + { HP_POP(clif->pWeaponRefine, HP_clif_pWeaponRefine) }, + { HP_POP(clif->pNpcSelectMenu, HP_clif_pNpcSelectMenu) }, + { HP_POP(clif->pNpcNextClicked, HP_clif_pNpcNextClicked) }, + { HP_POP(clif->pNpcAmountInput, HP_clif_pNpcAmountInput) }, + { HP_POP(clif->pNpcStringInput, HP_clif_pNpcStringInput) }, + { HP_POP(clif->pNpcCloseClicked, HP_clif_pNpcCloseClicked) }, + { HP_POP(clif->pItemIdentify, HP_clif_pItemIdentify) }, + { HP_POP(clif->pSelectArrow, HP_clif_pSelectArrow) }, + { HP_POP(clif->pAutoSpell, HP_clif_pAutoSpell) }, + { HP_POP(clif->pUseCard, HP_clif_pUseCard) }, + { HP_POP(clif->pInsertCard, HP_clif_pInsertCard) }, + { HP_POP(clif->pSolveCharName, HP_clif_pSolveCharName) }, + { HP_POP(clif->pResetChar, HP_clif_pResetChar) }, + { HP_POP(clif->pLocalBroadcast, HP_clif_pLocalBroadcast) }, + { HP_POP(clif->pMoveToKafra, HP_clif_pMoveToKafra) }, + { HP_POP(clif->pMoveFromKafra, HP_clif_pMoveFromKafra) }, + { HP_POP(clif->pMoveToKafraFromCart, HP_clif_pMoveToKafraFromCart) }, + { HP_POP(clif->pMoveFromKafraToCart, HP_clif_pMoveFromKafraToCart) }, + { HP_POP(clif->pCloseKafra, HP_clif_pCloseKafra) }, + { HP_POP(clif->pStoragePassword, HP_clif_pStoragePassword) }, + { HP_POP(clif->pCreateParty, HP_clif_pCreateParty) }, + { HP_POP(clif->pCreateParty2, HP_clif_pCreateParty2) }, + { HP_POP(clif->pPartyInvite, HP_clif_pPartyInvite) }, + { HP_POP(clif->pPartyInvite2, HP_clif_pPartyInvite2) }, + { HP_POP(clif->pReplyPartyInvite, HP_clif_pReplyPartyInvite) }, + { HP_POP(clif->pReplyPartyInvite2, HP_clif_pReplyPartyInvite2) }, + { HP_POP(clif->pLeaveParty, HP_clif_pLeaveParty) }, + { HP_POP(clif->pRemovePartyMember, HP_clif_pRemovePartyMember) }, + { HP_POP(clif->pPartyChangeOption, HP_clif_pPartyChangeOption) }, + { HP_POP(clif->pPartyMessage, HP_clif_pPartyMessage) }, + { HP_POP(clif->pPartyChangeLeader, HP_clif_pPartyChangeLeader) }, + { HP_POP(clif->pPartyBookingRegisterReq, HP_clif_pPartyBookingRegisterReq) }, + { HP_POP(clif->pPartyBookingSearchReq, HP_clif_pPartyBookingSearchReq) }, + { HP_POP(clif->pPartyBookingDeleteReq, HP_clif_pPartyBookingDeleteReq) }, + { HP_POP(clif->pPartyBookingUpdateReq, HP_clif_pPartyBookingUpdateReq) }, + { HP_POP(clif->pPartyRecruitRegisterReq, HP_clif_pPartyRecruitRegisterReq) }, + { HP_POP(clif->pPartyRecruitSearchReq, HP_clif_pPartyRecruitSearchReq) }, + { HP_POP(clif->pPartyRecruitDeleteReq, HP_clif_pPartyRecruitDeleteReq) }, + { HP_POP(clif->pPartyRecruitUpdateReq, HP_clif_pPartyRecruitUpdateReq) }, + { HP_POP(clif->pCloseVending, HP_clif_pCloseVending) }, + { HP_POP(clif->pVendingListReq, HP_clif_pVendingListReq) }, + { HP_POP(clif->pPurchaseReq, HP_clif_pPurchaseReq) }, + { HP_POP(clif->pPurchaseReq2, HP_clif_pPurchaseReq2) }, + { HP_POP(clif->pOpenVending, HP_clif_pOpenVending) }, + { HP_POP(clif->pCreateGuild, HP_clif_pCreateGuild) }, + { HP_POP(clif->pGuildCheckMaster, HP_clif_pGuildCheckMaster) }, + { HP_POP(clif->pGuildRequestInfo, HP_clif_pGuildRequestInfo) }, + { HP_POP(clif->pGuildChangePositionInfo, HP_clif_pGuildChangePositionInfo) }, + { HP_POP(clif->pGuildChangeMemberPosition, HP_clif_pGuildChangeMemberPosition) }, + { HP_POP(clif->pGuildRequestEmblem, HP_clif_pGuildRequestEmblem) }, + { HP_POP(clif->pGuildChangeEmblem, HP_clif_pGuildChangeEmblem) }, + { HP_POP(clif->pGuildChangeNotice, HP_clif_pGuildChangeNotice) }, + { HP_POP(clif->pGuildInvite, HP_clif_pGuildInvite) }, + { HP_POP(clif->pGuildReplyInvite, HP_clif_pGuildReplyInvite) }, + { HP_POP(clif->pGuildLeave, HP_clif_pGuildLeave) }, + { HP_POP(clif->pGuildExpulsion, HP_clif_pGuildExpulsion) }, + { HP_POP(clif->pGuildMessage, HP_clif_pGuildMessage) }, + { HP_POP(clif->pGuildRequestAlliance, HP_clif_pGuildRequestAlliance) }, + { HP_POP(clif->pGuildReplyAlliance, HP_clif_pGuildReplyAlliance) }, + { HP_POP(clif->pGuildDelAlliance, HP_clif_pGuildDelAlliance) }, + { HP_POP(clif->pGuildOpposition, HP_clif_pGuildOpposition) }, + { HP_POP(clif->pGuildBreak, HP_clif_pGuildBreak) }, + { HP_POP(clif->pPetMenu, HP_clif_pPetMenu) }, + { HP_POP(clif->pCatchPet, HP_clif_pCatchPet) }, + { HP_POP(clif->pSelectEgg, HP_clif_pSelectEgg) }, + { HP_POP(clif->pSendEmotion, HP_clif_pSendEmotion) }, + { HP_POP(clif->pChangePetName, HP_clif_pChangePetName) }, + { HP_POP(clif->pGMKick, HP_clif_pGMKick) }, + { HP_POP(clif->pGMKickAll, HP_clif_pGMKickAll) }, + { HP_POP(clif->pGMShift, HP_clif_pGMShift) }, + { HP_POP(clif->pGMRemove2, HP_clif_pGMRemove2) }, + { HP_POP(clif->pGMRecall, HP_clif_pGMRecall) }, + { HP_POP(clif->pGMRecall2, HP_clif_pGMRecall2) }, + { HP_POP(clif->pGM_Monster_Item, HP_clif_pGM_Monster_Item) }, + { HP_POP(clif->pGMHide, HP_clif_pGMHide) }, + { HP_POP(clif->pGMReqNoChat, HP_clif_pGMReqNoChat) }, + { HP_POP(clif->pGMRc, HP_clif_pGMRc) }, + { HP_POP(clif->pGMReqAccountName, HP_clif_pGMReqAccountName) }, + { HP_POP(clif->pGMChangeMapType, HP_clif_pGMChangeMapType) }, + { HP_POP(clif->pGMFullStrip, HP_clif_pGMFullStrip) }, + { HP_POP(clif->pPMIgnore, HP_clif_pPMIgnore) }, + { HP_POP(clif->pPMIgnoreAll, HP_clif_pPMIgnoreAll) }, + { HP_POP(clif->pPMIgnoreList, HP_clif_pPMIgnoreList) }, + { HP_POP(clif->pNoviceDoriDori, HP_clif_pNoviceDoriDori) }, + { HP_POP(clif->pNoviceExplosionSpirits, HP_clif_pNoviceExplosionSpirits) }, + { HP_POP(clif->pFriendsListAdd, HP_clif_pFriendsListAdd) }, + { HP_POP(clif->pFriendsListReply, HP_clif_pFriendsListReply) }, + { HP_POP(clif->pFriendsListRemove, HP_clif_pFriendsListRemove) }, + { HP_POP(clif->pPVPInfo, HP_clif_pPVPInfo) }, + { HP_POP(clif->pBlacksmith, HP_clif_pBlacksmith) }, + { HP_POP(clif->pAlchemist, HP_clif_pAlchemist) }, + { HP_POP(clif->pTaekwon, HP_clif_pTaekwon) }, + { HP_POP(clif->pRankingPk, HP_clif_pRankingPk) }, + { HP_POP(clif->pFeelSaveOk, HP_clif_pFeelSaveOk) }, + { HP_POP(clif->pChangeHomunculusName, HP_clif_pChangeHomunculusName) }, + { HP_POP(clif->pHomMoveToMaster, HP_clif_pHomMoveToMaster) }, + { HP_POP(clif->pHomMoveTo, HP_clif_pHomMoveTo) }, + { HP_POP(clif->pHomAttack, HP_clif_pHomAttack) }, + { HP_POP(clif->pHomMenu, HP_clif_pHomMenu) }, + { HP_POP(clif->pAutoRevive, HP_clif_pAutoRevive) }, + { HP_POP(clif->pCheck, HP_clif_pCheck) }, + { HP_POP(clif->pMail_refreshinbox, HP_clif_pMail_refreshinbox) }, + { HP_POP(clif->pMail_read, HP_clif_pMail_read) }, + { HP_POP(clif->pMail_getattach, HP_clif_pMail_getattach) }, + { HP_POP(clif->pMail_delete, HP_clif_pMail_delete) }, + { HP_POP(clif->pMail_return, HP_clif_pMail_return) }, + { HP_POP(clif->pMail_setattach, HP_clif_pMail_setattach) }, + { HP_POP(clif->pMail_winopen, HP_clif_pMail_winopen) }, + { HP_POP(clif->pMail_send, HP_clif_pMail_send) }, + { HP_POP(clif->pAuction_cancelreg, HP_clif_pAuction_cancelreg) }, + { HP_POP(clif->pAuction_setitem, HP_clif_pAuction_setitem) }, + { HP_POP(clif->pAuction_register, HP_clif_pAuction_register) }, + { HP_POP(clif->pAuction_cancel, HP_clif_pAuction_cancel) }, + { HP_POP(clif->pAuction_close, HP_clif_pAuction_close) }, + { HP_POP(clif->pAuction_bid, HP_clif_pAuction_bid) }, + { HP_POP(clif->pAuction_search, HP_clif_pAuction_search) }, + { HP_POP(clif->pAuction_buysell, HP_clif_pAuction_buysell) }, + { HP_POP(clif->pcashshop_buy, HP_clif_pcashshop_buy) }, + { HP_POP(clif->pAdopt_request, HP_clif_pAdopt_request) }, + { HP_POP(clif->pAdopt_reply, HP_clif_pAdopt_reply) }, + { HP_POP(clif->pViewPlayerEquip, HP_clif_pViewPlayerEquip) }, + { HP_POP(clif->pEquipTick, HP_clif_pEquipTick) }, + { HP_POP(clif->pquestStateAck, HP_clif_pquestStateAck) }, + { HP_POP(clif->pmercenary_action, HP_clif_pmercenary_action) }, + { HP_POP(clif->pBattleChat, HP_clif_pBattleChat) }, + { HP_POP(clif->pLessEffect, HP_clif_pLessEffect) }, + { HP_POP(clif->pItemListWindowSelected, HP_clif_pItemListWindowSelected) }, + { HP_POP(clif->pReqOpenBuyingStore, HP_clif_pReqOpenBuyingStore) }, + { HP_POP(clif->pReqCloseBuyingStore, HP_clif_pReqCloseBuyingStore) }, + { HP_POP(clif->pReqClickBuyingStore, HP_clif_pReqClickBuyingStore) }, + { HP_POP(clif->pReqTradeBuyingStore, HP_clif_pReqTradeBuyingStore) }, + { HP_POP(clif->pSearchStoreInfo, HP_clif_pSearchStoreInfo) }, + { HP_POP(clif->pSearchStoreInfoNextPage, HP_clif_pSearchStoreInfoNextPage) }, + { HP_POP(clif->pCloseSearchStoreInfo, HP_clif_pCloseSearchStoreInfo) }, + { HP_POP(clif->pSearchStoreInfoListItemClick, HP_clif_pSearchStoreInfoListItemClick) }, + { HP_POP(clif->pDebug, HP_clif_pDebug) }, + { HP_POP(clif->pSkillSelectMenu, HP_clif_pSkillSelectMenu) }, + { HP_POP(clif->pMoveItem, HP_clif_pMoveItem) }, + { HP_POP(clif->pDull, HP_clif_pDull) }, + { HP_POP(clif->pBGQueueRegister, HP_clif_pBGQueueRegister) }, + { HP_POP(clif->pBGQueueCheckState, HP_clif_pBGQueueCheckState) }, + { HP_POP(clif->pBGQueueRevokeReq, HP_clif_pBGQueueRevokeReq) }, + { HP_POP(clif->pBGQueueBattleBeginAck, HP_clif_pBGQueueBattleBeginAck) }, + { HP_POP(clif->pCashShopOpen, HP_clif_pCashShopOpen) }, + { HP_POP(clif->pCashShopClose, HP_clif_pCashShopClose) }, + { HP_POP(clif->pCashShopReqTab, HP_clif_pCashShopReqTab) }, + { HP_POP(clif->pCashShopSchedule, HP_clif_pCashShopSchedule) }, + { HP_POP(clif->pCashShopBuy, HP_clif_pCashShopBuy) }, + { HP_POP(clif->pPartyTick, HP_clif_pPartyTick) }, + { HP_POP(clif->pGuildInvite2, HP_clif_pGuildInvite2) }, + { HP_POP(clif->pPartyBookingAddFilter, HP_clif_pPartyBookingAddFilter) }, + { HP_POP(clif->pPartyBookingSubFilter, HP_clif_pPartyBookingSubFilter) }, + { HP_POP(clif->pPartyBookingReqVolunteer, HP_clif_pPartyBookingReqVolunteer) }, + { HP_POP(clif->pPartyBookingRefuseVolunteer, HP_clif_pPartyBookingRefuseVolunteer) }, + { HP_POP(clif->pPartyBookingCancelVolunteer, HP_clif_pPartyBookingCancelVolunteer) }, + { HP_POP(clif->pBankDeposit, HP_clif_pBankDeposit) }, + { HP_POP(clif->pBankWithdraw, HP_clif_pBankWithdraw) }, + { HP_POP(clif->pBankCheck, HP_clif_pBankCheck) }, + { HP_POP(clif->pBankOpen, HP_clif_pBankOpen) }, + { HP_POP(clif->pBankClose, HP_clif_pBankClose) }, + { HP_POP(clif->pNPCShopClosed, HP_clif_pNPCShopClosed) }, + { HP_POP(clif->pNPCMarketClosed, HP_clif_pNPCMarketClosed) }, + { HP_POP(clif->pNPCMarketPurchase, HP_clif_pNPCMarketPurchase) }, /* duel */ - { HP_POP(duel->create), HP_POP2(HP_duel_create), 1694 }, - { HP_POP(duel->invite), HP_POP2(HP_duel_invite), 1696 }, - { HP_POP(duel->accept), HP_POP2(HP_duel_accept), 1698 }, - { HP_POP(duel->reject), HP_POP2(HP_duel_reject), 1700 }, - { HP_POP(duel->leave), HP_POP2(HP_duel_leave), 1702 }, - { HP_POP(duel->showinfo), HP_POP2(HP_duel_showinfo), 1704 }, - { HP_POP(duel->checktime), HP_POP2(HP_duel_checktime), 1706 }, - { HP_POP(duel->init), HP_POP2(HP_duel_init), 1708 }, - { HP_POP(duel->final), HP_POP2(HP_duel_final), 1710 }, + { HP_POP(duel->create, HP_duel_create) }, + { HP_POP(duel->invite, HP_duel_invite) }, + { HP_POP(duel->accept, HP_duel_accept) }, + { HP_POP(duel->reject, HP_duel_reject) }, + { HP_POP(duel->leave, HP_duel_leave) }, + { HP_POP(duel->showinfo, HP_duel_showinfo) }, + { HP_POP(duel->checktime, HP_duel_checktime) }, + { HP_POP(duel->init, HP_duel_init) }, + { HP_POP(duel->final, HP_duel_final) }, /* elemental */ - { HP_POP(elemental->init), HP_POP2(HP_elemental_init), 1712 }, - { HP_POP(elemental->final), HP_POP2(HP_elemental_final), 1714 }, - { HP_POP(elemental->class), HP_POP2(HP_elemental_class), 1716 }, - { HP_POP(elemental->get_viewdata), HP_POP2(HP_elemental_get_viewdata), 1718 }, - { HP_POP(elemental->create), HP_POP2(HP_elemental_create), 1720 }, - { HP_POP(elemental->data_received), HP_POP2(HP_elemental_data_received), 1722 }, - { HP_POP(elemental->save), HP_POP2(HP_elemental_save), 1724 }, - { HP_POP(elemental->change_mode_ack), HP_POP2(HP_elemental_change_mode_ack), 1726 }, - { HP_POP(elemental->change_mode), HP_POP2(HP_elemental_change_mode), 1728 }, - { HP_POP(elemental->heal), HP_POP2(HP_elemental_heal), 1730 }, - { HP_POP(elemental->dead), HP_POP2(HP_elemental_dead), 1732 }, - { HP_POP(elemental->delete), HP_POP2(HP_elemental_delete), 1734 }, - { HP_POP(elemental->summon_stop), HP_POP2(HP_elemental_summon_stop), 1736 }, - { HP_POP(elemental->get_lifetime), HP_POP2(HP_elemental_get_lifetime), 1738 }, - { HP_POP(elemental->unlocktarget), HP_POP2(HP_elemental_unlocktarget), 1740 }, - { HP_POP(elemental->skillnotok), HP_POP2(HP_elemental_skillnotok), 1742 }, - { HP_POP(elemental->set_target), HP_POP2(HP_elemental_set_target), 1744 }, - { HP_POP(elemental->clean_single_effect), HP_POP2(HP_elemental_clean_single_effect), 1746 }, - { HP_POP(elemental->clean_effect), HP_POP2(HP_elemental_clean_effect), 1748 }, - { HP_POP(elemental->action), HP_POP2(HP_elemental_action), 1750 }, - { HP_POP(elemental->skill_get_requirements), HP_POP2(HP_elemental_skill_get_requirements), 1752 }, - { HP_POP(elemental->read_skilldb), HP_POP2(HP_elemental_read_skilldb), 1754 }, - { HP_POP(elemental->reload_db), HP_POP2(HP_elemental_reload_db), 1756 }, - { HP_POP(elemental->reload_skilldb), HP_POP2(HP_elemental_reload_skilldb), 1758 }, - { HP_POP(elemental->search_index), HP_POP2(HP_elemental_search_index), 1760 }, - { HP_POP(elemental->summon_init), HP_POP2(HP_elemental_summon_init), 1762 }, - { HP_POP(elemental->summon_end_timer), HP_POP2(HP_elemental_summon_end_timer), 1764 }, - { HP_POP(elemental->ai_sub_timer_activesearch), HP_POP2(HP_elemental_ai_sub_timer_activesearch), 1766 }, - { HP_POP(elemental->ai_sub_timer), HP_POP2(HP_elemental_ai_sub_timer), 1768 }, - { HP_POP(elemental->ai_sub_foreachclient), HP_POP2(HP_elemental_ai_sub_foreachclient), 1770 }, - { HP_POP(elemental->ai_timer), HP_POP2(HP_elemental_ai_timer), 1772 }, - { HP_POP(elemental->read_db), HP_POP2(HP_elemental_read_db), 1774 }, + { HP_POP(elemental->init, HP_elemental_init) }, + { HP_POP(elemental->final, HP_elemental_final) }, + { HP_POP(elemental->class, HP_elemental_class) }, + { HP_POP(elemental->get_viewdata, HP_elemental_get_viewdata) }, + { HP_POP(elemental->create, HP_elemental_create) }, + { HP_POP(elemental->data_received, HP_elemental_data_received) }, + { HP_POP(elemental->save, HP_elemental_save) }, + { HP_POP(elemental->change_mode_ack, HP_elemental_change_mode_ack) }, + { HP_POP(elemental->change_mode, HP_elemental_change_mode) }, + { HP_POP(elemental->heal, HP_elemental_heal) }, + { HP_POP(elemental->dead, HP_elemental_dead) }, + { HP_POP(elemental->delete, HP_elemental_delete) }, + { HP_POP(elemental->summon_stop, HP_elemental_summon_stop) }, + { HP_POP(elemental->get_lifetime, HP_elemental_get_lifetime) }, + { HP_POP(elemental->unlocktarget, HP_elemental_unlocktarget) }, + { HP_POP(elemental->skillnotok, HP_elemental_skillnotok) }, + { HP_POP(elemental->set_target, HP_elemental_set_target) }, + { HP_POP(elemental->clean_single_effect, HP_elemental_clean_single_effect) }, + { HP_POP(elemental->clean_effect, HP_elemental_clean_effect) }, + { HP_POP(elemental->action, HP_elemental_action) }, + { HP_POP(elemental->skill_get_requirements, HP_elemental_skill_get_requirements) }, + { HP_POP(elemental->read_skilldb, HP_elemental_read_skilldb) }, + { HP_POP(elemental->reload_db, HP_elemental_reload_db) }, + { HP_POP(elemental->reload_skilldb, HP_elemental_reload_skilldb) }, + { HP_POP(elemental->search_index, HP_elemental_search_index) }, + { HP_POP(elemental->summon_init, HP_elemental_summon_init) }, + { HP_POP(elemental->summon_end_timer, HP_elemental_summon_end_timer) }, + { HP_POP(elemental->ai_sub_timer_activesearch, HP_elemental_ai_sub_timer_activesearch) }, + { HP_POP(elemental->ai_sub_timer, HP_elemental_ai_sub_timer) }, + { HP_POP(elemental->ai_sub_foreachclient, HP_elemental_ai_sub_foreachclient) }, + { HP_POP(elemental->ai_timer, HP_elemental_ai_timer) }, + { HP_POP(elemental->read_db, HP_elemental_read_db) }, /* guild */ - { HP_POP(guild->init), HP_POP2(HP_guild_init), 1776 }, - { HP_POP(guild->final), HP_POP2(HP_guild_final), 1778 }, - { HP_POP(guild->skill_get_max), HP_POP2(HP_guild_skill_get_max), 1780 }, - { HP_POP(guild->checkskill), HP_POP2(HP_guild_checkskill), 1782 }, - { HP_POP(guild->check_skill_require), HP_POP2(HP_guild_check_skill_require), 1784 }, - { HP_POP(guild->checkcastles), HP_POP2(HP_guild_checkcastles), 1786 }, - { HP_POP(guild->isallied), HP_POP2(HP_guild_isallied), 1788 }, - { HP_POP(guild->search), HP_POP2(HP_guild_search), 1790 }, - { HP_POP(guild->searchname), HP_POP2(HP_guild_searchname), 1792 }, - { HP_POP(guild->castle_search), HP_POP2(HP_guild_castle_search), 1794 }, - { HP_POP(guild->mapname2gc), HP_POP2(HP_guild_mapname2gc), 1796 }, - { HP_POP(guild->mapindex2gc), HP_POP2(HP_guild_mapindex2gc), 1798 }, - { HP_POP(guild->getavailablesd), HP_POP2(HP_guild_getavailablesd), 1800 }, - { HP_POP(guild->getindex), HP_POP2(HP_guild_getindex), 1802 }, - { HP_POP(guild->getposition), HP_POP2(HP_guild_getposition), 1804 }, - { HP_POP(guild->payexp), HP_POP2(HP_guild_payexp), 1806 }, - { HP_POP(guild->getexp), HP_POP2(HP_guild_getexp), 1808 }, - { HP_POP(guild->create), HP_POP2(HP_guild_create), 1810 }, - { HP_POP(guild->created), HP_POP2(HP_guild_created), 1812 }, - { HP_POP(guild->request_info), HP_POP2(HP_guild_request_info), 1814 }, - { HP_POP(guild->recv_noinfo), HP_POP2(HP_guild_recv_noinfo), 1816 }, - { HP_POP(guild->recv_info), HP_POP2(HP_guild_recv_info), 1818 }, - { HP_POP(guild->npc_request_info), HP_POP2(HP_guild_npc_request_info), 1820 }, - { HP_POP(guild->invite), HP_POP2(HP_guild_invite), 1822 }, - { HP_POP(guild->reply_invite), HP_POP2(HP_guild_reply_invite), 1824 }, - { HP_POP(guild->member_joined), HP_POP2(HP_guild_member_joined), 1826 }, - { HP_POP(guild->member_added), HP_POP2(HP_guild_member_added), 1828 }, - { HP_POP(guild->leave), HP_POP2(HP_guild_leave), 1830 }, - { HP_POP(guild->member_withdraw), HP_POP2(HP_guild_member_withdraw), 1832 }, - { HP_POP(guild->expulsion), HP_POP2(HP_guild_expulsion), 1834 }, - { HP_POP(guild->skillup), HP_POP2(HP_guild_skillup), 1836 }, - { HP_POP(guild->block_skill), HP_POP2(HP_guild_block_skill), 1838 }, - { HP_POP(guild->reqalliance), HP_POP2(HP_guild_reqalliance), 1840 }, - { HP_POP(guild->reply_reqalliance), HP_POP2(HP_guild_reply_reqalliance), 1842 }, - { HP_POP(guild->allianceack), HP_POP2(HP_guild_allianceack), 1844 }, - { HP_POP(guild->delalliance), HP_POP2(HP_guild_delalliance), 1846 }, - { HP_POP(guild->opposition), HP_POP2(HP_guild_opposition), 1848 }, - { HP_POP(guild->check_alliance), HP_POP2(HP_guild_check_alliance), 1850 }, - { HP_POP(guild->send_memberinfoshort), HP_POP2(HP_guild_send_memberinfoshort), 1852 }, - { HP_POP(guild->recv_memberinfoshort), HP_POP2(HP_guild_recv_memberinfoshort), 1854 }, - { HP_POP(guild->change_memberposition), HP_POP2(HP_guild_change_memberposition), 1856 }, - { HP_POP(guild->memberposition_changed), HP_POP2(HP_guild_memberposition_changed), 1858 }, - { HP_POP(guild->change_position), HP_POP2(HP_guild_change_position), 1860 }, - { HP_POP(guild->position_changed), HP_POP2(HP_guild_position_changed), 1862 }, - { HP_POP(guild->change_notice), HP_POP2(HP_guild_change_notice), 1864 }, - { HP_POP(guild->notice_changed), HP_POP2(HP_guild_notice_changed), 1866 }, - { HP_POP(guild->change_emblem), HP_POP2(HP_guild_change_emblem), 1868 }, - { HP_POP(guild->emblem_changed), HP_POP2(HP_guild_emblem_changed), 1870 }, - { HP_POP(guild->send_message), HP_POP2(HP_guild_send_message), 1872 }, - { HP_POP(guild->recv_message), HP_POP2(HP_guild_recv_message), 1874 }, - { HP_POP(guild->send_dot_remove), HP_POP2(HP_guild_send_dot_remove), 1876 }, - { HP_POP(guild->skillupack), HP_POP2(HP_guild_skillupack), 1878 }, - { HP_POP(guild->dobreak), HP_POP2(HP_guild_dobreak), 1880 }, - { HP_POP(guild->broken), HP_POP2(HP_guild_broken), 1882 }, - { HP_POP(guild->gm_change), HP_POP2(HP_guild_gm_change), 1884 }, - { HP_POP(guild->gm_changed), HP_POP2(HP_guild_gm_changed), 1886 }, - { HP_POP(guild->castle_map_init), HP_POP2(HP_guild_castle_map_init), 1888 }, - { HP_POP(guild->castledatasave), HP_POP2(HP_guild_castledatasave), 1890 }, - { HP_POP(guild->castledataloadack), HP_POP2(HP_guild_castledataloadack), 1892 }, - { HP_POP(guild->castle_reconnect), HP_POP2(HP_guild_castle_reconnect), 1894 }, - { HP_POP(guild->agit_start), HP_POP2(HP_guild_agit_start), 1896 }, - { HP_POP(guild->agit_end), HP_POP2(HP_guild_agit_end), 1898 }, - { HP_POP(guild->agit2_start), HP_POP2(HP_guild_agit2_start), 1900 }, - { HP_POP(guild->agit2_end), HP_POP2(HP_guild_agit2_end), 1902 }, - { HP_POP(guild->flag_add), HP_POP2(HP_guild_flag_add), 1904 }, - { HP_POP(guild->flag_remove), HP_POP2(HP_guild_flag_remove), 1906 }, - { HP_POP(guild->flags_clear), HP_POP2(HP_guild_flags_clear), 1908 }, - { HP_POP(guild->aura_refresh), HP_POP2(HP_guild_aura_refresh), 1910 }, - { HP_POP(guild->payexp_timer), HP_POP2(HP_guild_payexp_timer), 1912 }, - { HP_POP(guild->sd_check), HP_POP2(HP_guild_sd_check), 1914 }, - { HP_POP(guild->read_guildskill_tree_db), HP_POP2(HP_guild_read_guildskill_tree_db), 1916 }, - { HP_POP(guild->read_castledb), HP_POP2(HP_guild_read_castledb), 1918 }, - { HP_POP(guild->payexp_timer_sub), HP_POP2(HP_guild_payexp_timer_sub), 1920 }, - { HP_POP(guild->send_xy_timer_sub), HP_POP2(HP_guild_send_xy_timer_sub), 1922 }, - { HP_POP(guild->send_xy_timer), HP_POP2(HP_guild_send_xy_timer), 1924 }, - { HP_POP(guild->create_expcache), HP_POP2(HP_guild_create_expcache), 1926 }, - { HP_POP(guild->eventlist_db_final), HP_POP2(HP_guild_eventlist_db_final), 1928 }, - { HP_POP(guild->expcache_db_final), HP_POP2(HP_guild_expcache_db_final), 1930 }, - { HP_POP(guild->castle_db_final), HP_POP2(HP_guild_castle_db_final), 1932 }, - { HP_POP(guild->broken_sub), HP_POP2(HP_guild_broken_sub), 1934 }, - { HP_POP(guild->castle_broken_sub), HP_POP2(HP_guild_castle_broken_sub), 1936 }, - { HP_POP(guild->makemember), HP_POP2(HP_guild_makemember), 1938 }, - { HP_POP(guild->check_member), HP_POP2(HP_guild_check_member), 1940 }, - { HP_POP(guild->get_alliance_count), HP_POP2(HP_guild_get_alliance_count), 1942 }, - { HP_POP(guild->castle_reconnect_sub), HP_POP2(HP_guild_castle_reconnect_sub), 1944 }, + { HP_POP(guild->init, HP_guild_init) }, + { HP_POP(guild->final, HP_guild_final) }, + { HP_POP(guild->skill_get_max, HP_guild_skill_get_max) }, + { HP_POP(guild->checkskill, HP_guild_checkskill) }, + { HP_POP(guild->check_skill_require, HP_guild_check_skill_require) }, + { HP_POP(guild->checkcastles, HP_guild_checkcastles) }, + { HP_POP(guild->isallied, HP_guild_isallied) }, + { HP_POP(guild->search, HP_guild_search) }, + { HP_POP(guild->searchname, HP_guild_searchname) }, + { HP_POP(guild->castle_search, HP_guild_castle_search) }, + { HP_POP(guild->mapname2gc, HP_guild_mapname2gc) }, + { HP_POP(guild->mapindex2gc, HP_guild_mapindex2gc) }, + { HP_POP(guild->getavailablesd, HP_guild_getavailablesd) }, + { HP_POP(guild->getindex, HP_guild_getindex) }, + { HP_POP(guild->getposition, HP_guild_getposition) }, + { HP_POP(guild->payexp, HP_guild_payexp) }, + { HP_POP(guild->getexp, HP_guild_getexp) }, + { HP_POP(guild->create, HP_guild_create) }, + { HP_POP(guild->created, HP_guild_created) }, + { HP_POP(guild->request_info, HP_guild_request_info) }, + { HP_POP(guild->recv_noinfo, HP_guild_recv_noinfo) }, + { HP_POP(guild->recv_info, HP_guild_recv_info) }, + { HP_POP(guild->npc_request_info, HP_guild_npc_request_info) }, + { HP_POP(guild->invite, HP_guild_invite) }, + { HP_POP(guild->reply_invite, HP_guild_reply_invite) }, + { HP_POP(guild->member_joined, HP_guild_member_joined) }, + { HP_POP(guild->member_added, HP_guild_member_added) }, + { HP_POP(guild->leave, HP_guild_leave) }, + { HP_POP(guild->member_withdraw, HP_guild_member_withdraw) }, + { HP_POP(guild->expulsion, HP_guild_expulsion) }, + { HP_POP(guild->skillup, HP_guild_skillup) }, + { HP_POP(guild->block_skill, HP_guild_block_skill) }, + { HP_POP(guild->reqalliance, HP_guild_reqalliance) }, + { HP_POP(guild->reply_reqalliance, HP_guild_reply_reqalliance) }, + { HP_POP(guild->allianceack, HP_guild_allianceack) }, + { HP_POP(guild->delalliance, HP_guild_delalliance) }, + { HP_POP(guild->opposition, HP_guild_opposition) }, + { HP_POP(guild->check_alliance, HP_guild_check_alliance) }, + { HP_POP(guild->send_memberinfoshort, HP_guild_send_memberinfoshort) }, + { HP_POP(guild->recv_memberinfoshort, HP_guild_recv_memberinfoshort) }, + { HP_POP(guild->change_memberposition, HP_guild_change_memberposition) }, + { HP_POP(guild->memberposition_changed, HP_guild_memberposition_changed) }, + { HP_POP(guild->change_position, HP_guild_change_position) }, + { HP_POP(guild->position_changed, HP_guild_position_changed) }, + { HP_POP(guild->change_notice, HP_guild_change_notice) }, + { HP_POP(guild->notice_changed, HP_guild_notice_changed) }, + { HP_POP(guild->change_emblem, HP_guild_change_emblem) }, + { HP_POP(guild->emblem_changed, HP_guild_emblem_changed) }, + { HP_POP(guild->send_message, HP_guild_send_message) }, + { HP_POP(guild->recv_message, HP_guild_recv_message) }, + { HP_POP(guild->send_dot_remove, HP_guild_send_dot_remove) }, + { HP_POP(guild->skillupack, HP_guild_skillupack) }, + { HP_POP(guild->dobreak, HP_guild_dobreak) }, + { HP_POP(guild->broken, HP_guild_broken) }, + { HP_POP(guild->gm_change, HP_guild_gm_change) }, + { HP_POP(guild->gm_changed, HP_guild_gm_changed) }, + { HP_POP(guild->castle_map_init, HP_guild_castle_map_init) }, + { HP_POP(guild->castledatasave, HP_guild_castledatasave) }, + { HP_POP(guild->castledataloadack, HP_guild_castledataloadack) }, + { HP_POP(guild->castle_reconnect, HP_guild_castle_reconnect) }, + { HP_POP(guild->agit_start, HP_guild_agit_start) }, + { HP_POP(guild->agit_end, HP_guild_agit_end) }, + { HP_POP(guild->agit2_start, HP_guild_agit2_start) }, + { HP_POP(guild->agit2_end, HP_guild_agit2_end) }, + { HP_POP(guild->flag_add, HP_guild_flag_add) }, + { HP_POP(guild->flag_remove, HP_guild_flag_remove) }, + { HP_POP(guild->flags_clear, HP_guild_flags_clear) }, + { HP_POP(guild->aura_refresh, HP_guild_aura_refresh) }, + { HP_POP(guild->retrieveitembound, HP_guild_retrieveitembound) }, + { HP_POP(guild->payexp_timer, HP_guild_payexp_timer) }, + { HP_POP(guild->sd_check, HP_guild_sd_check) }, + { HP_POP(guild->read_guildskill_tree_db, HP_guild_read_guildskill_tree_db) }, + { HP_POP(guild->read_castledb, HP_guild_read_castledb) }, + { HP_POP(guild->payexp_timer_sub, HP_guild_payexp_timer_sub) }, + { HP_POP(guild->send_xy_timer_sub, HP_guild_send_xy_timer_sub) }, + { HP_POP(guild->send_xy_timer, HP_guild_send_xy_timer) }, + { HP_POP(guild->create_expcache, HP_guild_create_expcache) }, + { HP_POP(guild->eventlist_db_final, HP_guild_eventlist_db_final) }, + { HP_POP(guild->expcache_db_final, HP_guild_expcache_db_final) }, + { HP_POP(guild->castle_db_final, HP_guild_castle_db_final) }, + { HP_POP(guild->broken_sub, HP_guild_broken_sub) }, + { HP_POP(guild->castle_broken_sub, HP_guild_castle_broken_sub) }, + { HP_POP(guild->makemember, HP_guild_makemember) }, + { HP_POP(guild->check_member, HP_guild_check_member) }, + { HP_POP(guild->get_alliance_count, HP_guild_get_alliance_count) }, + { HP_POP(guild->castle_reconnect_sub, HP_guild_castle_reconnect_sub) }, /* gstorage */ - { HP_POP(gstorage->id2storage), HP_POP2(HP_gstorage_id2storage), 1946 }, - { HP_POP(gstorage->id2storage2), HP_POP2(HP_gstorage_id2storage2), 1948 }, - { HP_POP(gstorage->init), HP_POP2(HP_gstorage_init), 1950 }, - { HP_POP(gstorage->final), HP_POP2(HP_gstorage_final), 1952 }, - { HP_POP(gstorage->delete), HP_POP2(HP_gstorage_delete), 1954 }, - { HP_POP(gstorage->open), HP_POP2(HP_gstorage_open), 1956 }, - { HP_POP(gstorage->additem), HP_POP2(HP_gstorage_additem), 1958 }, - { HP_POP(gstorage->delitem), HP_POP2(HP_gstorage_delitem), 1960 }, - { HP_POP(gstorage->add), HP_POP2(HP_gstorage_add), 1962 }, - { HP_POP(gstorage->get), HP_POP2(HP_gstorage_get), 1964 }, - { HP_POP(gstorage->addfromcart), HP_POP2(HP_gstorage_addfromcart), 1966 }, - { HP_POP(gstorage->gettocart), HP_POP2(HP_gstorage_gettocart), 1968 }, - { HP_POP(gstorage->close), HP_POP2(HP_gstorage_close), 1970 }, - { HP_POP(gstorage->pc_quit), HP_POP2(HP_gstorage_pc_quit), 1972 }, - { HP_POP(gstorage->save), HP_POP2(HP_gstorage_save), 1974 }, - { HP_POP(gstorage->saved), HP_POP2(HP_gstorage_saved), 1976 }, - { HP_POP(gstorage->create), HP_POP2(HP_gstorage_create), 1978 }, + { HP_POP(gstorage->id2storage, HP_gstorage_id2storage) }, + { HP_POP(gstorage->id2storage2, HP_gstorage_id2storage2) }, + { HP_POP(gstorage->init, HP_gstorage_init) }, + { HP_POP(gstorage->final, HP_gstorage_final) }, + { HP_POP(gstorage->delete, HP_gstorage_delete) }, + { HP_POP(gstorage->open, HP_gstorage_open) }, + { HP_POP(gstorage->additem, HP_gstorage_additem) }, + { HP_POP(gstorage->delitem, HP_gstorage_delitem) }, + { HP_POP(gstorage->add, HP_gstorage_add) }, + { HP_POP(gstorage->get, HP_gstorage_get) }, + { HP_POP(gstorage->addfromcart, HP_gstorage_addfromcart) }, + { HP_POP(gstorage->gettocart, HP_gstorage_gettocart) }, + { HP_POP(gstorage->close, HP_gstorage_close) }, + { HP_POP(gstorage->pc_quit, HP_gstorage_pc_quit) }, + { HP_POP(gstorage->save, HP_gstorage_save) }, + { HP_POP(gstorage->saved, HP_gstorage_saved) }, + { HP_POP(gstorage->create, HP_gstorage_create) }, /* homun */ - { HP_POP(homun->init), HP_POP2(HP_homun_init), 1980 }, - { HP_POP(homun->final), HP_POP2(HP_homun_final), 1982 }, - { HP_POP(homun->reload), HP_POP2(HP_homun_reload), 1984 }, - { HP_POP(homun->reload_skill), HP_POP2(HP_homun_reload_skill), 1986 }, - { HP_POP(homun->get_viewdata), HP_POP2(HP_homun_get_viewdata), 1988 }, - { HP_POP(homun->class2type), HP_POP2(HP_homun_class2type), 1990 }, - { HP_POP(homun->damaged), HP_POP2(HP_homun_damaged), 1992 }, - { HP_POP(homun->dead), HP_POP2(HP_homun_dead), 1994 }, - { HP_POP(homun->vaporize), HP_POP2(HP_homun_vaporize), 1996 }, - { HP_POP(homun->delete), HP_POP2(HP_homun_delete), 1998 }, - { HP_POP(homun->checkskill), HP_POP2(HP_homun_checkskill), 2000 }, - { HP_POP(homun->calc_skilltree), HP_POP2(HP_homun_calc_skilltree), 2002 }, - { HP_POP(homun->skill_tree_get_max), HP_POP2(HP_homun_skill_tree_get_max), 2004 }, - { HP_POP(homun->skillup), HP_POP2(HP_homun_skillup), 2006 }, - { HP_POP(homun->levelup), HP_POP2(HP_homun_levelup), 2008 }, - { HP_POP(homun->change_class), HP_POP2(HP_homun_change_class), 2010 }, - { HP_POP(homun->evolve), HP_POP2(HP_homun_evolve), 2012 }, - { HP_POP(homun->mutate), HP_POP2(HP_homun_mutate), 2014 }, - { HP_POP(homun->gainexp), HP_POP2(HP_homun_gainexp), 2016 }, - { HP_POP(homun->add_intimacy), HP_POP2(HP_homun_add_intimacy), 2018 }, - { HP_POP(homun->consume_intimacy), HP_POP2(HP_homun_consume_intimacy), 2020 }, - { HP_POP(homun->healed), HP_POP2(HP_homun_healed), 2022 }, - { HP_POP(homun->save), HP_POP2(HP_homun_save), 2024 }, - { HP_POP(homun->menu), HP_POP2(HP_homun_menu), 2026 }, - { HP_POP(homun->feed), HP_POP2(HP_homun_feed), 2028 }, - { HP_POP(homun->hunger_timer), HP_POP2(HP_homun_hunger_timer), 2030 }, - { HP_POP(homun->hunger_timer_delete), HP_POP2(HP_homun_hunger_timer_delete), 2032 }, - { HP_POP(homun->change_name), HP_POP2(HP_homun_change_name), 2034 }, - { HP_POP(homun->change_name_ack), HP_POP2(HP_homun_change_name_ack), 2036 }, - { HP_POP(homun->db_search), HP_POP2(HP_homun_db_search), 2038 }, - { HP_POP(homun->create), HP_POP2(HP_homun_create), 2040 }, - { HP_POP(homun->init_timers), HP_POP2(HP_homun_init_timers), 2042 }, - { HP_POP(homun->call), HP_POP2(HP_homun_call), 2044 }, - { HP_POP(homun->recv_data), HP_POP2(HP_homun_recv_data), 2046 }, - { HP_POP(homun->creation_request), HP_POP2(HP_homun_creation_request), 2048 }, - { HP_POP(homun->ressurect), HP_POP2(HP_homun_ressurect), 2050 }, - { HP_POP(homun->revive), HP_POP2(HP_homun_revive), 2052 }, - { HP_POP(homun->stat_reset), HP_POP2(HP_homun_stat_reset), 2054 }, - { HP_POP(homun->shuffle), HP_POP2(HP_homun_shuffle), 2056 }, - { HP_POP(homun->read_db_sub), HP_POP2(HP_homun_read_db_sub), 2058 }, - { HP_POP(homun->read_db), HP_POP2(HP_homun_read_db), 2060 }, - { HP_POP(homun->read_skill_db_sub), HP_POP2(HP_homun_read_skill_db_sub), 2062 }, - { HP_POP(homun->skill_db_read), HP_POP2(HP_homun_skill_db_read), 2064 }, - { HP_POP(homun->exp_db_read), HP_POP2(HP_homun_exp_db_read), 2066 }, - { HP_POP(homun->addspiritball), HP_POP2(HP_homun_addspiritball), 2068 }, - { HP_POP(homun->delspiritball), HP_POP2(HP_homun_delspiritball), 2070 }, + { HP_POP(homun->init, HP_homun_init) }, + { HP_POP(homun->final, HP_homun_final) }, + { HP_POP(homun->reload, HP_homun_reload) }, + { HP_POP(homun->reload_skill, HP_homun_reload_skill) }, + { HP_POP(homun->get_viewdata, HP_homun_get_viewdata) }, + { HP_POP(homun->class2type, HP_homun_class2type) }, + { HP_POP(homun->damaged, HP_homun_damaged) }, + { HP_POP(homun->dead, HP_homun_dead) }, + { HP_POP(homun->vaporize, HP_homun_vaporize) }, + { HP_POP(homun->delete, HP_homun_delete) }, + { HP_POP(homun->checkskill, HP_homun_checkskill) }, + { HP_POP(homun->calc_skilltree, HP_homun_calc_skilltree) }, + { HP_POP(homun->skill_tree_get_max, HP_homun_skill_tree_get_max) }, + { HP_POP(homun->skillup, HP_homun_skillup) }, + { HP_POP(homun->levelup, HP_homun_levelup) }, + { HP_POP(homun->change_class, HP_homun_change_class) }, + { HP_POP(homun->evolve, HP_homun_evolve) }, + { HP_POP(homun->mutate, HP_homun_mutate) }, + { HP_POP(homun->gainexp, HP_homun_gainexp) }, + { HP_POP(homun->add_intimacy, HP_homun_add_intimacy) }, + { HP_POP(homun->consume_intimacy, HP_homun_consume_intimacy) }, + { HP_POP(homun->healed, HP_homun_healed) }, + { HP_POP(homun->save, HP_homun_save) }, + { HP_POP(homun->menu, HP_homun_menu) }, + { HP_POP(homun->feed, HP_homun_feed) }, + { HP_POP(homun->hunger_timer, HP_homun_hunger_timer) }, + { HP_POP(homun->hunger_timer_delete, HP_homun_hunger_timer_delete) }, + { HP_POP(homun->change_name, HP_homun_change_name) }, + { HP_POP(homun->change_name_ack, HP_homun_change_name_ack) }, + { HP_POP(homun->db_search, HP_homun_db_search) }, + { HP_POP(homun->create, HP_homun_create) }, + { HP_POP(homun->init_timers, HP_homun_init_timers) }, + { HP_POP(homun->call, HP_homun_call) }, + { HP_POP(homun->recv_data, HP_homun_recv_data) }, + { HP_POP(homun->creation_request, HP_homun_creation_request) }, + { HP_POP(homun->ressurect, HP_homun_ressurect) }, + { HP_POP(homun->revive, HP_homun_revive) }, + { HP_POP(homun->stat_reset, HP_homun_stat_reset) }, + { HP_POP(homun->shuffle, HP_homun_shuffle) }, + { HP_POP(homun->read_db_sub, HP_homun_read_db_sub) }, + { HP_POP(homun->read_db, HP_homun_read_db) }, + { HP_POP(homun->read_skill_db_sub, HP_homun_read_skill_db_sub) }, + { HP_POP(homun->skill_db_read, HP_homun_skill_db_read) }, + { HP_POP(homun->exp_db_read, HP_homun_exp_db_read) }, + { HP_POP(homun->addspiritball, HP_homun_addspiritball) }, + { HP_POP(homun->delspiritball, HP_homun_delspiritball) }, /* instance */ - { HP_POP(instance->init), HP_POP2(HP_instance_init), 2072 }, - { HP_POP(instance->final), HP_POP2(HP_instance_final), 2074 }, - { HP_POP(instance->create), HP_POP2(HP_instance_create), 2076 }, - { HP_POP(instance->add_map), HP_POP2(HP_instance_add_map), 2078 }, - { HP_POP(instance->del_map), HP_POP2(HP_instance_del_map), 2080 }, - { HP_POP(instance->map2imap), HP_POP2(HP_instance_map2imap), 2082 }, - { HP_POP(instance->mapid2imapid), HP_POP2(HP_instance_mapid2imapid), 2084 }, - { HP_POP(instance->destroy), HP_POP2(HP_instance_destroy), 2086 }, - { HP_POP(instance->start), HP_POP2(HP_instance_start), 2088 }, - { HP_POP(instance->check_idle), HP_POP2(HP_instance_check_idle), 2090 }, - { HP_POP(instance->check_kick), HP_POP2(HP_instance_check_kick), 2092 }, - { HP_POP(instance->set_timeout), HP_POP2(HP_instance_set_timeout), 2094 }, - { HP_POP(instance->valid), HP_POP2(HP_instance_valid), 2096 }, - { HP_POP(instance->destroy_timer), HP_POP2(HP_instance_destroy_timer), 2098 }, + { HP_POP(instance->init, HP_instance_init) }, + { HP_POP(instance->final, HP_instance_final) }, + { HP_POP(instance->reload, HP_instance_reload) }, + { HP_POP(instance->create, HP_instance_create) }, + { HP_POP(instance->add_map, HP_instance_add_map) }, + { HP_POP(instance->del_map, HP_instance_del_map) }, + { HP_POP(instance->map2imap, HP_instance_map2imap) }, + { HP_POP(instance->mapid2imapid, HP_instance_mapid2imapid) }, + { HP_POP(instance->mapname2imap, HP_instance_mapname2imap) }, + { HP_POP(instance->map_npcsub, HP_instance_map_npcsub) }, + { HP_POP(instance->init_npc, HP_instance_init_npc) }, + { HP_POP(instance->destroy, HP_instance_destroy) }, + { HP_POP(instance->start, HP_instance_start) }, + { HP_POP(instance->check_idle, HP_instance_check_idle) }, + { HP_POP(instance->check_kick, HP_instance_check_kick) }, + { HP_POP(instance->set_timeout, HP_instance_set_timeout) }, + { HP_POP(instance->valid, HP_instance_valid) }, + { HP_POP(instance->destroy_timer, HP_instance_destroy_timer) }, /* intif */ - { HP_POP(intif->parse), HP_POP2(HP_intif_parse), 2100 }, - { HP_POP(intif->create_pet), HP_POP2(HP_intif_create_pet), 2102 }, - { HP_POP(intif->broadcast), HP_POP2(HP_intif_broadcast), 2104 }, - { HP_POP(intif->broadcast2), HP_POP2(HP_intif_broadcast2), 2106 }, - { HP_POP(intif->main_message), HP_POP2(HP_intif_main_message), 2108 }, - { HP_POP(intif->wis_message), HP_POP2(HP_intif_wis_message), 2110 }, - { HP_POP(intif->wis_message_to_gm), HP_POP2(HP_intif_wis_message_to_gm), 2112 }, - { HP_POP(intif->saveregistry), HP_POP2(HP_intif_saveregistry), 2114 }, - { HP_POP(intif->request_registry), HP_POP2(HP_intif_request_registry), 2116 }, - { HP_POP(intif->request_guild_storage), HP_POP2(HP_intif_request_guild_storage), 2118 }, - { HP_POP(intif->send_guild_storage), HP_POP2(HP_intif_send_guild_storage), 2120 }, - { HP_POP(intif->create_party), HP_POP2(HP_intif_create_party), 2122 }, - { HP_POP(intif->request_partyinfo), HP_POP2(HP_intif_request_partyinfo), 2124 }, - { HP_POP(intif->party_addmember), HP_POP2(HP_intif_party_addmember), 2126 }, - { HP_POP(intif->party_changeoption), HP_POP2(HP_intif_party_changeoption), 2128 }, - { HP_POP(intif->party_leave), HP_POP2(HP_intif_party_leave), 2130 }, - { HP_POP(intif->party_changemap), HP_POP2(HP_intif_party_changemap), 2132 }, - { HP_POP(intif->break_party), HP_POP2(HP_intif_break_party), 2134 }, - { HP_POP(intif->party_message), HP_POP2(HP_intif_party_message), 2136 }, - { HP_POP(intif->party_leaderchange), HP_POP2(HP_intif_party_leaderchange), 2138 }, - { HP_POP(intif->guild_create), HP_POP2(HP_intif_guild_create), 2140 }, - { HP_POP(intif->guild_request_info), HP_POP2(HP_intif_guild_request_info), 2142 }, - { HP_POP(intif->guild_addmember), HP_POP2(HP_intif_guild_addmember), 2144 }, - { HP_POP(intif->guild_leave), HP_POP2(HP_intif_guild_leave), 2146 }, - { HP_POP(intif->guild_memberinfoshort), HP_POP2(HP_intif_guild_memberinfoshort), 2148 }, - { HP_POP(intif->guild_break), HP_POP2(HP_intif_guild_break), 2150 }, - { HP_POP(intif->guild_message), HP_POP2(HP_intif_guild_message), 2152 }, - { HP_POP(intif->guild_change_gm), HP_POP2(HP_intif_guild_change_gm), 2154 }, - { HP_POP(intif->guild_change_basicinfo), HP_POP2(HP_intif_guild_change_basicinfo), 2156 }, - { HP_POP(intif->guild_change_memberinfo), HP_POP2(HP_intif_guild_change_memberinfo), 2158 }, - { HP_POP(intif->guild_position), HP_POP2(HP_intif_guild_position), 2160 }, - { HP_POP(intif->guild_skillup), HP_POP2(HP_intif_guild_skillup), 2162 }, - { HP_POP(intif->guild_alliance), HP_POP2(HP_intif_guild_alliance), 2164 }, - { HP_POP(intif->guild_notice), HP_POP2(HP_intif_guild_notice), 2166 }, - { HP_POP(intif->guild_emblem), HP_POP2(HP_intif_guild_emblem), 2168 }, - { HP_POP(intif->guild_castle_dataload), HP_POP2(HP_intif_guild_castle_dataload), 2170 }, - { HP_POP(intif->guild_castle_datasave), HP_POP2(HP_intif_guild_castle_datasave), 2172 }, - { HP_POP(intif->request_petdata), HP_POP2(HP_intif_request_petdata), 2174 }, - { HP_POP(intif->save_petdata), HP_POP2(HP_intif_save_petdata), 2176 }, - { HP_POP(intif->delete_petdata), HP_POP2(HP_intif_delete_petdata), 2178 }, - { HP_POP(intif->rename), HP_POP2(HP_intif_rename), 2180 }, - { HP_POP(intif->homunculus_create), HP_POP2(HP_intif_homunculus_create), 2182 }, - { HP_POP(intif->homunculus_requestload), HP_POP2(HP_intif_homunculus_requestload), 2184 }, - { HP_POP(intif->homunculus_requestsave), HP_POP2(HP_intif_homunculus_requestsave), 2186 }, - { HP_POP(intif->homunculus_requestdelete), HP_POP2(HP_intif_homunculus_requestdelete), 2188 }, - { HP_POP(intif->request_questlog), HP_POP2(HP_intif_request_questlog), 2190 }, - { HP_POP(intif->quest_save), HP_POP2(HP_intif_quest_save), 2192 }, - { HP_POP(intif->mercenary_create), HP_POP2(HP_intif_mercenary_create), 2194 }, - { HP_POP(intif->mercenary_request), HP_POP2(HP_intif_mercenary_request), 2196 }, - { HP_POP(intif->mercenary_delete), HP_POP2(HP_intif_mercenary_delete), 2198 }, - { HP_POP(intif->mercenary_save), HP_POP2(HP_intif_mercenary_save), 2200 }, - { HP_POP(intif->Mail_requestinbox), HP_POP2(HP_intif_Mail_requestinbox), 2202 }, - { HP_POP(intif->Mail_read), HP_POP2(HP_intif_Mail_read), 2204 }, - { HP_POP(intif->Mail_getattach), HP_POP2(HP_intif_Mail_getattach), 2206 }, - { HP_POP(intif->Mail_delete), HP_POP2(HP_intif_Mail_delete), 2208 }, - { HP_POP(intif->Mail_return), HP_POP2(HP_intif_Mail_return), 2210 }, - { HP_POP(intif->Mail_send), HP_POP2(HP_intif_Mail_send), 2212 }, - { HP_POP(intif->Auction_requestlist), HP_POP2(HP_intif_Auction_requestlist), 2214 }, - { HP_POP(intif->Auction_register), HP_POP2(HP_intif_Auction_register), 2216 }, - { HP_POP(intif->Auction_cancel), HP_POP2(HP_intif_Auction_cancel), 2218 }, - { HP_POP(intif->Auction_close), HP_POP2(HP_intif_Auction_close), 2220 }, - { HP_POP(intif->Auction_bid), HP_POP2(HP_intif_Auction_bid), 2222 }, - { HP_POP(intif->elemental_create), HP_POP2(HP_intif_elemental_create), 2224 }, - { HP_POP(intif->elemental_request), HP_POP2(HP_intif_elemental_request), 2226 }, - { HP_POP(intif->elemental_delete), HP_POP2(HP_intif_elemental_delete), 2228 }, - { HP_POP(intif->elemental_save), HP_POP2(HP_intif_elemental_save), 2230 }, - { HP_POP(intif->request_accinfo), HP_POP2(HP_intif_request_accinfo), 2232 }, - { HP_POP(intif->CheckForCharServer), HP_POP2(HP_intif_CheckForCharServer), 2234 }, - { HP_POP(intif->pWisMessage), HP_POP2(HP_intif_pWisMessage), 2236 }, - { HP_POP(intif->pWisEnd), HP_POP2(HP_intif_pWisEnd), 2238 }, - { HP_POP(intif->pWisToGM_sub), HP_POP2(HP_intif_pWisToGM_sub), 2240 }, - { HP_POP(intif->pWisToGM), HP_POP2(HP_intif_pWisToGM), 2242 }, - { HP_POP(intif->pRegisters), HP_POP2(HP_intif_pRegisters), 2244 }, - { HP_POP(intif->pChangeNameOk), HP_POP2(HP_intif_pChangeNameOk), 2246 }, - { HP_POP(intif->pMessageToFD), HP_POP2(HP_intif_pMessageToFD), 2248 }, - { HP_POP(intif->pLoadGuildStorage), HP_POP2(HP_intif_pLoadGuildStorage), 2250 }, - { HP_POP(intif->pSaveGuildStorage), HP_POP2(HP_intif_pSaveGuildStorage), 2252 }, - { HP_POP(intif->pPartyCreated), HP_POP2(HP_intif_pPartyCreated), 2254 }, - { HP_POP(intif->pPartyInfo), HP_POP2(HP_intif_pPartyInfo), 2256 }, - { HP_POP(intif->pPartyMemberAdded), HP_POP2(HP_intif_pPartyMemberAdded), 2258 }, - { HP_POP(intif->pPartyOptionChanged), HP_POP2(HP_intif_pPartyOptionChanged), 2260 }, - { HP_POP(intif->pPartyMemberWithdraw), HP_POP2(HP_intif_pPartyMemberWithdraw), 2262 }, - { HP_POP(intif->pPartyMove), HP_POP2(HP_intif_pPartyMove), 2264 }, - { HP_POP(intif->pPartyBroken), HP_POP2(HP_intif_pPartyBroken), 2266 }, - { HP_POP(intif->pPartyMessage), HP_POP2(HP_intif_pPartyMessage), 2268 }, - { HP_POP(intif->pGuildCreated), HP_POP2(HP_intif_pGuildCreated), 2270 }, - { HP_POP(intif->pGuildInfo), HP_POP2(HP_intif_pGuildInfo), 2272 }, - { HP_POP(intif->pGuildMemberAdded), HP_POP2(HP_intif_pGuildMemberAdded), 2274 }, - { HP_POP(intif->pGuildMemberWithdraw), HP_POP2(HP_intif_pGuildMemberWithdraw), 2276 }, - { HP_POP(intif->pGuildMemberInfoShort), HP_POP2(HP_intif_pGuildMemberInfoShort), 2278 }, - { HP_POP(intif->pGuildBroken), HP_POP2(HP_intif_pGuildBroken), 2280 }, - { HP_POP(intif->pGuildMessage), HP_POP2(HP_intif_pGuildMessage), 2282 }, - { HP_POP(intif->pGuildBasicInfoChanged), HP_POP2(HP_intif_pGuildBasicInfoChanged), 2284 }, - { HP_POP(intif->pGuildMemberInfoChanged), HP_POP2(HP_intif_pGuildMemberInfoChanged), 2286 }, - { HP_POP(intif->pGuildPosition), HP_POP2(HP_intif_pGuildPosition), 2288 }, - { HP_POP(intif->pGuildSkillUp), HP_POP2(HP_intif_pGuildSkillUp), 2290 }, - { HP_POP(intif->pGuildAlliance), HP_POP2(HP_intif_pGuildAlliance), 2292 }, - { HP_POP(intif->pGuildNotice), HP_POP2(HP_intif_pGuildNotice), 2294 }, - { HP_POP(intif->pGuildEmblem), HP_POP2(HP_intif_pGuildEmblem), 2296 }, - { HP_POP(intif->pGuildCastleDataLoad), HP_POP2(HP_intif_pGuildCastleDataLoad), 2298 }, - { HP_POP(intif->pGuildMasterChanged), HP_POP2(HP_intif_pGuildMasterChanged), 2300 }, - { HP_POP(intif->pQuestLog), HP_POP2(HP_intif_pQuestLog), 2302 }, - { HP_POP(intif->pQuestSave), HP_POP2(HP_intif_pQuestSave), 2304 }, - { HP_POP(intif->pMailInboxReceived), HP_POP2(HP_intif_pMailInboxReceived), 2306 }, - { HP_POP(intif->pMailNew), HP_POP2(HP_intif_pMailNew), 2308 }, - { HP_POP(intif->pMailGetAttach), HP_POP2(HP_intif_pMailGetAttach), 2310 }, - { HP_POP(intif->pMailDelete), HP_POP2(HP_intif_pMailDelete), 2312 }, - { HP_POP(intif->pMailReturn), HP_POP2(HP_intif_pMailReturn), 2314 }, - { HP_POP(intif->pMailSend), HP_POP2(HP_intif_pMailSend), 2316 }, - { HP_POP(intif->pAuctionResults), HP_POP2(HP_intif_pAuctionResults), 2318 }, - { HP_POP(intif->pAuctionRegister), HP_POP2(HP_intif_pAuctionRegister), 2320 }, - { HP_POP(intif->pAuctionCancel), HP_POP2(HP_intif_pAuctionCancel), 2322 }, - { HP_POP(intif->pAuctionClose), HP_POP2(HP_intif_pAuctionClose), 2324 }, - { HP_POP(intif->pAuctionMessage), HP_POP2(HP_intif_pAuctionMessage), 2326 }, - { HP_POP(intif->pAuctionBid), HP_POP2(HP_intif_pAuctionBid), 2328 }, - { HP_POP(intif->pMercenaryReceived), HP_POP2(HP_intif_pMercenaryReceived), 2330 }, - { HP_POP(intif->pMercenaryDeleted), HP_POP2(HP_intif_pMercenaryDeleted), 2332 }, - { HP_POP(intif->pMercenarySaved), HP_POP2(HP_intif_pMercenarySaved), 2334 }, - { HP_POP(intif->pElementalReceived), HP_POP2(HP_intif_pElementalReceived), 2336 }, - { HP_POP(intif->pElementalDeleted), HP_POP2(HP_intif_pElementalDeleted), 2338 }, - { HP_POP(intif->pElementalSaved), HP_POP2(HP_intif_pElementalSaved), 2340 }, - { HP_POP(intif->pCreatePet), HP_POP2(HP_intif_pCreatePet), 2342 }, - { HP_POP(intif->pRecvPetData), HP_POP2(HP_intif_pRecvPetData), 2344 }, - { HP_POP(intif->pSavePetOk), HP_POP2(HP_intif_pSavePetOk), 2346 }, - { HP_POP(intif->pDeletePetOk), HP_POP2(HP_intif_pDeletePetOk), 2348 }, - { HP_POP(intif->pCreateHomunculus), HP_POP2(HP_intif_pCreateHomunculus), 2350 }, - { HP_POP(intif->pRecvHomunculusData), HP_POP2(HP_intif_pRecvHomunculusData), 2352 }, - { HP_POP(intif->pSaveHomunculusOk), HP_POP2(HP_intif_pSaveHomunculusOk), 2354 }, - { HP_POP(intif->pDeleteHomunculusOk), HP_POP2(HP_intif_pDeleteHomunculusOk), 2356 }, + { HP_POP(intif->parse, HP_intif_parse) }, + { HP_POP(intif->create_pet, HP_intif_create_pet) }, + { HP_POP(intif->broadcast, HP_intif_broadcast) }, + { HP_POP(intif->broadcast2, HP_intif_broadcast2) }, + { HP_POP(intif->main_message, HP_intif_main_message) }, + { HP_POP(intif->wis_message, HP_intif_wis_message) }, + { HP_POP(intif->wis_message_to_gm, HP_intif_wis_message_to_gm) }, + { HP_POP(intif->saveregistry, HP_intif_saveregistry) }, + { HP_POP(intif->request_registry, HP_intif_request_registry) }, + { HP_POP(intif->request_guild_storage, HP_intif_request_guild_storage) }, + { HP_POP(intif->send_guild_storage, HP_intif_send_guild_storage) }, + { HP_POP(intif->create_party, HP_intif_create_party) }, + { HP_POP(intif->request_partyinfo, HP_intif_request_partyinfo) }, + { HP_POP(intif->party_addmember, HP_intif_party_addmember) }, + { HP_POP(intif->party_changeoption, HP_intif_party_changeoption) }, + { HP_POP(intif->party_leave, HP_intif_party_leave) }, + { HP_POP(intif->party_changemap, HP_intif_party_changemap) }, + { HP_POP(intif->break_party, HP_intif_break_party) }, + { HP_POP(intif->party_message, HP_intif_party_message) }, + { HP_POP(intif->party_leaderchange, HP_intif_party_leaderchange) }, + { HP_POP(intif->guild_create, HP_intif_guild_create) }, + { HP_POP(intif->guild_request_info, HP_intif_guild_request_info) }, + { HP_POP(intif->guild_addmember, HP_intif_guild_addmember) }, + { HP_POP(intif->guild_leave, HP_intif_guild_leave) }, + { HP_POP(intif->guild_memberinfoshort, HP_intif_guild_memberinfoshort) }, + { HP_POP(intif->guild_break, HP_intif_guild_break) }, + { HP_POP(intif->guild_message, HP_intif_guild_message) }, + { HP_POP(intif->guild_change_gm, HP_intif_guild_change_gm) }, + { HP_POP(intif->guild_change_basicinfo, HP_intif_guild_change_basicinfo) }, + { HP_POP(intif->guild_change_memberinfo, HP_intif_guild_change_memberinfo) }, + { HP_POP(intif->guild_position, HP_intif_guild_position) }, + { HP_POP(intif->guild_skillup, HP_intif_guild_skillup) }, + { HP_POP(intif->guild_alliance, HP_intif_guild_alliance) }, + { HP_POP(intif->guild_notice, HP_intif_guild_notice) }, + { HP_POP(intif->guild_emblem, HP_intif_guild_emblem) }, + { HP_POP(intif->guild_castle_dataload, HP_intif_guild_castle_dataload) }, + { HP_POP(intif->guild_castle_datasave, HP_intif_guild_castle_datasave) }, + { HP_POP(intif->itembound_req, HP_intif_itembound_req) }, + { HP_POP(intif->request_petdata, HP_intif_request_petdata) }, + { HP_POP(intif->save_petdata, HP_intif_save_petdata) }, + { HP_POP(intif->delete_petdata, HP_intif_delete_petdata) }, + { HP_POP(intif->rename, HP_intif_rename) }, + { HP_POP(intif->homunculus_create, HP_intif_homunculus_create) }, + { HP_POP(intif->homunculus_requestload, HP_intif_homunculus_requestload) }, + { HP_POP(intif->homunculus_requestsave, HP_intif_homunculus_requestsave) }, + { HP_POP(intif->homunculus_requestdelete, HP_intif_homunculus_requestdelete) }, + { HP_POP(intif->request_questlog, HP_intif_request_questlog) }, + { HP_POP(intif->quest_save, HP_intif_quest_save) }, + { HP_POP(intif->mercenary_create, HP_intif_mercenary_create) }, + { HP_POP(intif->mercenary_request, HP_intif_mercenary_request) }, + { HP_POP(intif->mercenary_delete, HP_intif_mercenary_delete) }, + { HP_POP(intif->mercenary_save, HP_intif_mercenary_save) }, + { HP_POP(intif->Mail_requestinbox, HP_intif_Mail_requestinbox) }, + { HP_POP(intif->Mail_read, HP_intif_Mail_read) }, + { HP_POP(intif->Mail_getattach, HP_intif_Mail_getattach) }, + { HP_POP(intif->Mail_delete, HP_intif_Mail_delete) }, + { HP_POP(intif->Mail_return, HP_intif_Mail_return) }, + { HP_POP(intif->Mail_send, HP_intif_Mail_send) }, + { HP_POP(intif->Auction_requestlist, HP_intif_Auction_requestlist) }, + { HP_POP(intif->Auction_register, HP_intif_Auction_register) }, + { HP_POP(intif->Auction_cancel, HP_intif_Auction_cancel) }, + { HP_POP(intif->Auction_close, HP_intif_Auction_close) }, + { HP_POP(intif->Auction_bid, HP_intif_Auction_bid) }, + { HP_POP(intif->elemental_create, HP_intif_elemental_create) }, + { HP_POP(intif->elemental_request, HP_intif_elemental_request) }, + { HP_POP(intif->elemental_delete, HP_intif_elemental_delete) }, + { HP_POP(intif->elemental_save, HP_intif_elemental_save) }, + { HP_POP(intif->request_accinfo, HP_intif_request_accinfo) }, + { HP_POP(intif->CheckForCharServer, HP_intif_CheckForCharServer) }, + { HP_POP(intif->pWisMessage, HP_intif_pWisMessage) }, + { HP_POP(intif->pWisEnd, HP_intif_pWisEnd) }, + { HP_POP(intif->pWisToGM_sub, HP_intif_pWisToGM_sub) }, + { HP_POP(intif->pWisToGM, HP_intif_pWisToGM) }, + { HP_POP(intif->pRegisters, HP_intif_pRegisters) }, + { HP_POP(intif->pChangeNameOk, HP_intif_pChangeNameOk) }, + { HP_POP(intif->pMessageToFD, HP_intif_pMessageToFD) }, + { HP_POP(intif->pLoadGuildStorage, HP_intif_pLoadGuildStorage) }, + { HP_POP(intif->pSaveGuildStorage, HP_intif_pSaveGuildStorage) }, + { HP_POP(intif->pPartyCreated, HP_intif_pPartyCreated) }, + { HP_POP(intif->pPartyInfo, HP_intif_pPartyInfo) }, + { HP_POP(intif->pPartyMemberAdded, HP_intif_pPartyMemberAdded) }, + { HP_POP(intif->pPartyOptionChanged, HP_intif_pPartyOptionChanged) }, + { HP_POP(intif->pPartyMemberWithdraw, HP_intif_pPartyMemberWithdraw) }, + { HP_POP(intif->pPartyMove, HP_intif_pPartyMove) }, + { HP_POP(intif->pPartyBroken, HP_intif_pPartyBroken) }, + { HP_POP(intif->pPartyMessage, HP_intif_pPartyMessage) }, + { HP_POP(intif->pGuildCreated, HP_intif_pGuildCreated) }, + { HP_POP(intif->pGuildInfo, HP_intif_pGuildInfo) }, + { HP_POP(intif->pGuildMemberAdded, HP_intif_pGuildMemberAdded) }, + { HP_POP(intif->pGuildMemberWithdraw, HP_intif_pGuildMemberWithdraw) }, + { HP_POP(intif->pGuildMemberInfoShort, HP_intif_pGuildMemberInfoShort) }, + { HP_POP(intif->pGuildBroken, HP_intif_pGuildBroken) }, + { HP_POP(intif->pGuildMessage, HP_intif_pGuildMessage) }, + { HP_POP(intif->pGuildBasicInfoChanged, HP_intif_pGuildBasicInfoChanged) }, + { HP_POP(intif->pGuildMemberInfoChanged, HP_intif_pGuildMemberInfoChanged) }, + { HP_POP(intif->pGuildPosition, HP_intif_pGuildPosition) }, + { HP_POP(intif->pGuildSkillUp, HP_intif_pGuildSkillUp) }, + { HP_POP(intif->pGuildAlliance, HP_intif_pGuildAlliance) }, + { HP_POP(intif->pGuildNotice, HP_intif_pGuildNotice) }, + { HP_POP(intif->pGuildEmblem, HP_intif_pGuildEmblem) }, + { HP_POP(intif->pGuildCastleDataLoad, HP_intif_pGuildCastleDataLoad) }, + { HP_POP(intif->pGuildMasterChanged, HP_intif_pGuildMasterChanged) }, + { HP_POP(intif->pQuestLog, HP_intif_pQuestLog) }, + { HP_POP(intif->pQuestSave, HP_intif_pQuestSave) }, + { HP_POP(intif->pMailInboxReceived, HP_intif_pMailInboxReceived) }, + { HP_POP(intif->pMailNew, HP_intif_pMailNew) }, + { HP_POP(intif->pMailGetAttach, HP_intif_pMailGetAttach) }, + { HP_POP(intif->pMailDelete, HP_intif_pMailDelete) }, + { HP_POP(intif->pMailReturn, HP_intif_pMailReturn) }, + { HP_POP(intif->pMailSend, HP_intif_pMailSend) }, + { HP_POP(intif->pAuctionResults, HP_intif_pAuctionResults) }, + { HP_POP(intif->pAuctionRegister, HP_intif_pAuctionRegister) }, + { HP_POP(intif->pAuctionCancel, HP_intif_pAuctionCancel) }, + { HP_POP(intif->pAuctionClose, HP_intif_pAuctionClose) }, + { HP_POP(intif->pAuctionMessage, HP_intif_pAuctionMessage) }, + { HP_POP(intif->pAuctionBid, HP_intif_pAuctionBid) }, + { HP_POP(intif->pItembound_ack, HP_intif_pItembound_ack) }, + { HP_POP(intif->pMercenaryReceived, HP_intif_pMercenaryReceived) }, + { HP_POP(intif->pMercenaryDeleted, HP_intif_pMercenaryDeleted) }, + { HP_POP(intif->pMercenarySaved, HP_intif_pMercenarySaved) }, + { HP_POP(intif->pElementalReceived, HP_intif_pElementalReceived) }, + { HP_POP(intif->pElementalDeleted, HP_intif_pElementalDeleted) }, + { HP_POP(intif->pElementalSaved, HP_intif_pElementalSaved) }, + { HP_POP(intif->pCreatePet, HP_intif_pCreatePet) }, + { HP_POP(intif->pRecvPetData, HP_intif_pRecvPetData) }, + { HP_POP(intif->pSavePetOk, HP_intif_pSavePetOk) }, + { HP_POP(intif->pDeletePetOk, HP_intif_pDeletePetOk) }, + { HP_POP(intif->pCreateHomunculus, HP_intif_pCreateHomunculus) }, + { HP_POP(intif->pRecvHomunculusData, HP_intif_pRecvHomunculusData) }, + { HP_POP(intif->pSaveHomunculusOk, HP_intif_pSaveHomunculusOk) }, + { HP_POP(intif->pDeleteHomunculusOk, HP_intif_pDeleteHomunculusOk) }, /* ircbot */ - { HP_POP(ircbot->init), HP_POP2(HP_ircbot_init), 2358 }, - { HP_POP(ircbot->final), HP_POP2(HP_ircbot_final), 2360 }, - { HP_POP(ircbot->parse), HP_POP2(HP_ircbot_parse), 2362 }, - { HP_POP(ircbot->parse_sub), HP_POP2(HP_ircbot_parse_sub), 2364 }, - { HP_POP(ircbot->parse_source), HP_POP2(HP_ircbot_parse_source), 2366 }, - { HP_POP(ircbot->func_search), HP_POP2(HP_ircbot_func_search), 2368 }, - { HP_POP(ircbot->connect_timer), HP_POP2(HP_ircbot_connect_timer), 2370 }, - { HP_POP(ircbot->identify_timer), HP_POP2(HP_ircbot_identify_timer), 2372 }, - { HP_POP(ircbot->join_timer), HP_POP2(HP_ircbot_join_timer), 2374 }, - { HP_POP(ircbot->send), HP_POP2(HP_ircbot_send), 2376 }, - { HP_POP(ircbot->relay), HP_POP2(HP_ircbot_relay), 2378 }, - { HP_POP(ircbot->pong), HP_POP2(HP_ircbot_pong), 2380 }, - { HP_POP(ircbot->privmsg), HP_POP2(HP_ircbot_privmsg), 2382 }, - { HP_POP(ircbot->userjoin), HP_POP2(HP_ircbot_userjoin), 2384 }, - { HP_POP(ircbot->userleave), HP_POP2(HP_ircbot_userleave), 2386 }, - { HP_POP(ircbot->usernick), HP_POP2(HP_ircbot_usernick), 2388 }, + { HP_POP(ircbot->init, HP_ircbot_init) }, + { HP_POP(ircbot->final, HP_ircbot_final) }, + { HP_POP(ircbot->parse, HP_ircbot_parse) }, + { HP_POP(ircbot->parse_sub, HP_ircbot_parse_sub) }, + { HP_POP(ircbot->parse_source, HP_ircbot_parse_source) }, + { HP_POP(ircbot->func_search, HP_ircbot_func_search) }, + { HP_POP(ircbot->connect_timer, HP_ircbot_connect_timer) }, + { HP_POP(ircbot->identify_timer, HP_ircbot_identify_timer) }, + { HP_POP(ircbot->join_timer, HP_ircbot_join_timer) }, + { HP_POP(ircbot->send, HP_ircbot_send) }, + { HP_POP(ircbot->relay, HP_ircbot_relay) }, + { HP_POP(ircbot->pong, HP_ircbot_pong) }, + { HP_POP(ircbot->privmsg, HP_ircbot_privmsg) }, + { HP_POP(ircbot->userjoin, HP_ircbot_userjoin) }, + { HP_POP(ircbot->userleave, HP_ircbot_userleave) }, + { HP_POP(ircbot->usernick, HP_ircbot_usernick) }, /* itemdb */ - { HP_POP(itemdb->init), HP_POP2(HP_itemdb_init), 2390 }, - { HP_POP(itemdb->final), HP_POP2(HP_itemdb_final), 2392 }, - { HP_POP(itemdb->reload), HP_POP2(HP_itemdb_reload), 2394 }, - { HP_POP(itemdb->name_constants), HP_POP2(HP_itemdb_name_constants), 2396 }, - { HP_POP(itemdb->force_name_constants), HP_POP2(HP_itemdb_force_name_constants), 2398 }, - { HP_POP(itemdb->read_groups), HP_POP2(HP_itemdb_read_groups), 2400 }, - { HP_POP(itemdb->read_chains), HP_POP2(HP_itemdb_read_chains), 2402 }, - { HP_POP(itemdb->read_packages), HP_POP2(HP_itemdb_read_packages), 2404 }, - { HP_POP(itemdb->write_cached_packages), HP_POP2(HP_itemdb_write_cached_packages), 2406 }, - { HP_POP(itemdb->read_cached_packages), HP_POP2(HP_itemdb_read_cached_packages), 2408 }, - { HP_POP(itemdb->name2id), HP_POP2(HP_itemdb_name2id), 2410 }, - { HP_POP(itemdb->search_name), HP_POP2(HP_itemdb_search_name), 2412 }, - { HP_POP(itemdb->search_name_array), HP_POP2(HP_itemdb_search_name_array), 2414 }, - { HP_POP(itemdb->load), HP_POP2(HP_itemdb_load), 2416 }, - { HP_POP(itemdb->search), HP_POP2(HP_itemdb_search), 2418 }, - { HP_POP(itemdb->parse_dbrow), HP_POP2(HP_itemdb_parse_dbrow), 2420 }, - { HP_POP(itemdb->exists), HP_POP2(HP_itemdb_exists), 2422 }, - { HP_POP(itemdb->in_group), HP_POP2(HP_itemdb_in_group), 2424 }, - { HP_POP(itemdb->group_item), HP_POP2(HP_itemdb_group_item), 2426 }, - { HP_POP(itemdb->chain_item), HP_POP2(HP_itemdb_chain_item), 2428 }, - { HP_POP(itemdb->package_item), HP_POP2(HP_itemdb_package_item), 2430 }, - { HP_POP(itemdb->searchname_sub), HP_POP2(HP_itemdb_searchname_sub), 2432 }, - { HP_POP(itemdb->searchname_array_sub), HP_POP2(HP_itemdb_searchname_array_sub), 2434 }, - { HP_POP(itemdb->searchrandomid), HP_POP2(HP_itemdb_searchrandomid), 2436 }, - { HP_POP(itemdb->typename), HP_POP2(HP_itemdb_typename), 2438 }, - { HP_POP(itemdb->jobid2mapid), HP_POP2(HP_itemdb_jobid2mapid), 2440 }, - { HP_POP(itemdb->create_dummy_data), HP_POP2(HP_itemdb_create_dummy_data), 2442 }, - { HP_POP(itemdb->create_item_data), HP_POP2(HP_itemdb_create_item_data), 2444 }, - { HP_POP(itemdb->isequip), HP_POP2(HP_itemdb_isequip), 2446 }, - { HP_POP(itemdb->isequip2), HP_POP2(HP_itemdb_isequip2), 2448 }, - { HP_POP(itemdb->isstackable), HP_POP2(HP_itemdb_isstackable), 2450 }, - { HP_POP(itemdb->isstackable2), HP_POP2(HP_itemdb_isstackable2), 2452 }, - { HP_POP(itemdb->isdropable_sub), HP_POP2(HP_itemdb_isdropable_sub), 2454 }, - { HP_POP(itemdb->cantrade_sub), HP_POP2(HP_itemdb_cantrade_sub), 2456 }, - { HP_POP(itemdb->canpartnertrade_sub), HP_POP2(HP_itemdb_canpartnertrade_sub), 2458 }, - { HP_POP(itemdb->cansell_sub), HP_POP2(HP_itemdb_cansell_sub), 2460 }, - { HP_POP(itemdb->cancartstore_sub), HP_POP2(HP_itemdb_cancartstore_sub), 2462 }, - { HP_POP(itemdb->canstore_sub), HP_POP2(HP_itemdb_canstore_sub), 2464 }, - { HP_POP(itemdb->canguildstore_sub), HP_POP2(HP_itemdb_canguildstore_sub), 2466 }, - { HP_POP(itemdb->canmail_sub), HP_POP2(HP_itemdb_canmail_sub), 2468 }, - { HP_POP(itemdb->canauction_sub), HP_POP2(HP_itemdb_canauction_sub), 2470 }, - { HP_POP(itemdb->isrestricted), HP_POP2(HP_itemdb_isrestricted), 2472 }, - { HP_POP(itemdb->isidentified), HP_POP2(HP_itemdb_isidentified), 2474 }, - { HP_POP(itemdb->isidentified2), HP_POP2(HP_itemdb_isidentified2), 2476 }, - { HP_POP(itemdb->read_itemavail), HP_POP2(HP_itemdb_read_itemavail), 2478 }, - { HP_POP(itemdb->read_itemtrade), HP_POP2(HP_itemdb_read_itemtrade), 2480 }, - { HP_POP(itemdb->read_itemdelay), HP_POP2(HP_itemdb_read_itemdelay), 2482 }, - { HP_POP(itemdb->read_stack), HP_POP2(HP_itemdb_read_stack), 2484 }, - { HP_POP(itemdb->read_buyingstore), HP_POP2(HP_itemdb_read_buyingstore), 2486 }, - { HP_POP(itemdb->read_nouse), HP_POP2(HP_itemdb_read_nouse), 2488 }, - { HP_POP(itemdb->combo_split_atoi), HP_POP2(HP_itemdb_combo_split_atoi), 2490 }, - { HP_POP(itemdb->read_combos), HP_POP2(HP_itemdb_read_combos), 2492 }, - { HP_POP(itemdb->gendercheck), HP_POP2(HP_itemdb_gendercheck), 2494 }, - { HP_POP(itemdb->re_split_atoi), HP_POP2(HP_itemdb_re_split_atoi), 2496 }, - { HP_POP(itemdb->readdb), HP_POP2(HP_itemdb_readdb), 2498 }, - { HP_POP(itemdb->read_sqldb), HP_POP2(HP_itemdb_read_sqldb), 2500 }, - { HP_POP(itemdb->unique_id), HP_POP2(HP_itemdb_unique_id), 2502 }, - { HP_POP(itemdb->uid_load), HP_POP2(HP_itemdb_uid_load), 2504 }, - { HP_POP(itemdb->read), HP_POP2(HP_itemdb_read), 2506 }, - { HP_POP(itemdb->destroy_item_data), HP_POP2(HP_itemdb_destroy_item_data), 2508 }, - { HP_POP(itemdb->final_sub), HP_POP2(HP_itemdb_final_sub), 2510 }, + { HP_POP(itemdb->init, HP_itemdb_init) }, + { HP_POP(itemdb->final, HP_itemdb_final) }, + { HP_POP(itemdb->reload, HP_itemdb_reload) }, + { HP_POP(itemdb->name_constants, HP_itemdb_name_constants) }, + { HP_POP(itemdb->read_groups, HP_itemdb_read_groups) }, + { HP_POP(itemdb->read_chains, HP_itemdb_read_chains) }, + { HP_POP(itemdb->read_packages, HP_itemdb_read_packages) }, + { HP_POP(itemdb->write_cached_packages, HP_itemdb_write_cached_packages) }, + { HP_POP(itemdb->read_cached_packages, HP_itemdb_read_cached_packages) }, + { HP_POP(itemdb->name2id, HP_itemdb_name2id) }, + { HP_POP(itemdb->search_name, HP_itemdb_search_name) }, + { HP_POP(itemdb->search_name_array, HP_itemdb_search_name_array) }, + { HP_POP(itemdb->load, HP_itemdb_load) }, + { HP_POP(itemdb->search, HP_itemdb_search) }, + { HP_POP(itemdb->exists, HP_itemdb_exists) }, + { HP_POP(itemdb->in_group, HP_itemdb_in_group) }, + { HP_POP(itemdb->group_item, HP_itemdb_group_item) }, + { HP_POP(itemdb->chain_item, HP_itemdb_chain_item) }, + { HP_POP(itemdb->package_item, HP_itemdb_package_item) }, + { HP_POP(itemdb->searchname_sub, HP_itemdb_searchname_sub) }, + { HP_POP(itemdb->searchname_array_sub, HP_itemdb_searchname_array_sub) }, + { HP_POP(itemdb->searchrandomid, HP_itemdb_searchrandomid) }, + { HP_POP(itemdb->typename, HP_itemdb_typename) }, + { HP_POP(itemdb->jobid2mapid, HP_itemdb_jobid2mapid) }, + { HP_POP(itemdb->create_dummy_data, HP_itemdb_create_dummy_data) }, + { HP_POP(itemdb->create_item_data, HP_itemdb_create_item_data) }, + { HP_POP(itemdb->isequip, HP_itemdb_isequip) }, + { HP_POP(itemdb->isequip2, HP_itemdb_isequip2) }, + { HP_POP(itemdb->isstackable, HP_itemdb_isstackable) }, + { HP_POP(itemdb->isstackable2, HP_itemdb_isstackable2) }, + { HP_POP(itemdb->isdropable_sub, HP_itemdb_isdropable_sub) }, + { HP_POP(itemdb->cantrade_sub, HP_itemdb_cantrade_sub) }, + { HP_POP(itemdb->canpartnertrade_sub, HP_itemdb_canpartnertrade_sub) }, + { HP_POP(itemdb->cansell_sub, HP_itemdb_cansell_sub) }, + { HP_POP(itemdb->cancartstore_sub, HP_itemdb_cancartstore_sub) }, + { HP_POP(itemdb->canstore_sub, HP_itemdb_canstore_sub) }, + { HP_POP(itemdb->canguildstore_sub, HP_itemdb_canguildstore_sub) }, + { HP_POP(itemdb->canmail_sub, HP_itemdb_canmail_sub) }, + { HP_POP(itemdb->canauction_sub, HP_itemdb_canauction_sub) }, + { HP_POP(itemdb->isrestricted, HP_itemdb_isrestricted) }, + { HP_POP(itemdb->isidentified, HP_itemdb_isidentified) }, + { HP_POP(itemdb->isidentified2, HP_itemdb_isidentified2) }, + { HP_POP(itemdb->read_itemavail, HP_itemdb_read_itemavail) }, + { HP_POP(itemdb->read_itemtrade, HP_itemdb_read_itemtrade) }, + { HP_POP(itemdb->read_itemdelay, HP_itemdb_read_itemdelay) }, + { HP_POP(itemdb->read_stack, HP_itemdb_read_stack) }, + { HP_POP(itemdb->read_buyingstore, HP_itemdb_read_buyingstore) }, + { HP_POP(itemdb->read_nouse, HP_itemdb_read_nouse) }, + { HP_POP(itemdb->combo_split_atoi, HP_itemdb_combo_split_atoi) }, + { HP_POP(itemdb->read_combos, HP_itemdb_read_combos) }, + { HP_POP(itemdb->gendercheck, HP_itemdb_gendercheck) }, + { HP_POP(itemdb->validate_entry, HP_itemdb_validate_entry) }, + { HP_POP(itemdb->readdb_sql_sub, HP_itemdb_readdb_sql_sub) }, + { HP_POP(itemdb->readdb_libconfig_sub, HP_itemdb_readdb_libconfig_sub) }, + { HP_POP(itemdb->readdb_libconfig, HP_itemdb_readdb_libconfig) }, + { HP_POP(itemdb->readdb_sql, HP_itemdb_readdb_sql) }, + { HP_POP(itemdb->unique_id, HP_itemdb_unique_id) }, + { HP_POP(itemdb->uid_load, HP_itemdb_uid_load) }, + { HP_POP(itemdb->read, HP_itemdb_read) }, + { HP_POP(itemdb->destroy_item_data, HP_itemdb_destroy_item_data) }, + { HP_POP(itemdb->final_sub, HP_itemdb_final_sub) }, + { HP_POP(itemdb->clear, HP_itemdb_clear) }, + { HP_POP(itemdb->id2combo, HP_itemdb_id2combo) }, /* logs */ - { HP_POP(logs->pick_pc), HP_POP2(HP_logs_pick_pc), 2512 }, - { HP_POP(logs->pick_mob), HP_POP2(HP_logs_pick_mob), 2514 }, - { HP_POP(logs->zeny), HP_POP2(HP_logs_zeny), 2516 }, - { HP_POP(logs->npc), HP_POP2(HP_logs_npc), 2518 }, - { HP_POP(logs->chat), HP_POP2(HP_logs_chat), 2520 }, - { HP_POP(logs->atcommand), HP_POP2(HP_logs_atcommand), 2522 }, - { HP_POP(logs->branch), HP_POP2(HP_logs_branch), 2524 }, - { HP_POP(logs->mvpdrop), HP_POP2(HP_logs_mvpdrop), 2526 }, - { HP_POP(logs->pick_sub), HP_POP2(HP_logs_pick_sub), 2528 }, - { HP_POP(logs->zeny_sub), HP_POP2(HP_logs_zeny_sub), 2530 }, - { HP_POP(logs->npc_sub), HP_POP2(HP_logs_npc_sub), 2532 }, - { HP_POP(logs->chat_sub), HP_POP2(HP_logs_chat_sub), 2534 }, - { HP_POP(logs->atcommand_sub), HP_POP2(HP_logs_atcommand_sub), 2536 }, - { HP_POP(logs->branch_sub), HP_POP2(HP_logs_branch_sub), 2538 }, - { HP_POP(logs->mvpdrop_sub), HP_POP2(HP_logs_mvpdrop_sub), 2540 }, - { HP_POP(logs->config_read), HP_POP2(HP_logs_config_read), 2542 }, - { HP_POP(logs->config_done), HP_POP2(HP_logs_config_done), 2544 }, - { HP_POP(logs->sql_init), HP_POP2(HP_logs_sql_init), 2546 }, - { HP_POP(logs->sql_final), HP_POP2(HP_logs_sql_final), 2548 }, - { HP_POP(logs->picktype2char), HP_POP2(HP_logs_picktype2char), 2550 }, - { HP_POP(logs->chattype2char), HP_POP2(HP_logs_chattype2char), 2552 }, - { HP_POP(logs->should_log_item), HP_POP2(HP_logs_should_log_item), 2554 }, + { HP_POP(logs->pick_pc, HP_logs_pick_pc) }, + { HP_POP(logs->pick_mob, HP_logs_pick_mob) }, + { HP_POP(logs->zeny, HP_logs_zeny) }, + { HP_POP(logs->npc, HP_logs_npc) }, + { HP_POP(logs->chat, HP_logs_chat) }, + { HP_POP(logs->atcommand, HP_logs_atcommand) }, + { HP_POP(logs->branch, HP_logs_branch) }, + { HP_POP(logs->mvpdrop, HP_logs_mvpdrop) }, + { HP_POP(logs->pick_sub, HP_logs_pick_sub) }, + { HP_POP(logs->zeny_sub, HP_logs_zeny_sub) }, + { HP_POP(logs->npc_sub, HP_logs_npc_sub) }, + { HP_POP(logs->chat_sub, HP_logs_chat_sub) }, + { HP_POP(logs->atcommand_sub, HP_logs_atcommand_sub) }, + { HP_POP(logs->branch_sub, HP_logs_branch_sub) }, + { HP_POP(logs->mvpdrop_sub, HP_logs_mvpdrop_sub) }, + { HP_POP(logs->config_read, HP_logs_config_read) }, + { HP_POP(logs->config_done, HP_logs_config_done) }, + { HP_POP(logs->sql_init, HP_logs_sql_init) }, + { HP_POP(logs->sql_final, HP_logs_sql_final) }, + { HP_POP(logs->picktype2char, HP_logs_picktype2char) }, + { HP_POP(logs->chattype2char, HP_logs_chattype2char) }, + { HP_POP(logs->should_log_item, HP_logs_should_log_item) }, /* mail */ - { HP_POP(mail->clear), HP_POP2(HP_mail_clear), 2556 }, - { HP_POP(mail->removeitem), HP_POP2(HP_mail_removeitem), 2558 }, - { HP_POP(mail->removezeny), HP_POP2(HP_mail_removezeny), 2560 }, - { HP_POP(mail->setitem), HP_POP2(HP_mail_setitem), 2562 }, - { HP_POP(mail->setattachment), HP_POP2(HP_mail_setattachment), 2564 }, - { HP_POP(mail->getattachment), HP_POP2(HP_mail_getattachment), 2566 }, - { HP_POP(mail->openmail), HP_POP2(HP_mail_openmail), 2568 }, - { HP_POP(mail->deliveryfail), HP_POP2(HP_mail_deliveryfail), 2570 }, - { HP_POP(mail->invalid_operation), HP_POP2(HP_mail_invalid_operation), 2572 }, + { HP_POP(mail->clear, HP_mail_clear) }, + { HP_POP(mail->removeitem, HP_mail_removeitem) }, + { HP_POP(mail->removezeny, HP_mail_removezeny) }, + { HP_POP(mail->setitem, HP_mail_setitem) }, + { HP_POP(mail->setattachment, HP_mail_setattachment) }, + { HP_POP(mail->getattachment, HP_mail_getattachment) }, + { HP_POP(mail->openmail, HP_mail_openmail) }, + { HP_POP(mail->deliveryfail, HP_mail_deliveryfail) }, + { HP_POP(mail->invalid_operation, HP_mail_invalid_operation) }, /* map */ - { HP_POP(map->zone_init), HP_POP2(HP_map_zone_init), 2574 }, - { HP_POP(map->zone_remove), HP_POP2(HP_map_zone_remove), 2576 }, - { HP_POP(map->zone_apply), HP_POP2(HP_map_zone_apply), 2578 }, - { HP_POP(map->zone_change), HP_POP2(HP_map_zone_change), 2580 }, - { HP_POP(map->zone_change2), HP_POP2(HP_map_zone_change2), 2582 }, - { HP_POP(map->getcell), HP_POP2(HP_map_getcell), 2584 }, - { HP_POP(map->setgatcell), HP_POP2(HP_map_setgatcell), 2586 }, - { HP_POP(map->cellfromcache), HP_POP2(HP_map_cellfromcache), 2588 }, - { HP_POP(map->setusers), HP_POP2(HP_map_setusers), 2590 }, - { HP_POP(map->getusers), HP_POP2(HP_map_getusers), 2592 }, - { HP_POP(map->usercount), HP_POP2(HP_map_usercount), 2594 }, - { HP_POP(map->freeblock), HP_POP2(HP_map_freeblock), 2596 }, - { HP_POP(map->freeblock_lock), HP_POP2(HP_map_freeblock_lock), 2598 }, - { HP_POP(map->freeblock_unlock), HP_POP2(HP_map_freeblock_unlock), 2600 }, - { HP_POP(map->addblock), HP_POP2(HP_map_addblock), 2602 }, - { HP_POP(map->delblock), HP_POP2(HP_map_delblock), 2604 }, - { HP_POP(map->moveblock), HP_POP2(HP_map_moveblock), 2606 }, - { HP_POP(map->count_oncell), HP_POP2(HP_map_count_oncell), 2608 }, - { HP_POP(map->find_skill_unit_oncell), HP_POP2(HP_map_find_skill_unit_oncell), 2610 }, - { HP_POP(map->get_new_object_id), HP_POP2(HP_map_get_new_object_id), 2612 }, - { HP_POP(map->search_freecell), HP_POP2(HP_map_search_freecell), 2614 }, - { HP_POP(map->quit), HP_POP2(HP_map_quit), 2616 }, - { HP_POP(map->addnpc), HP_POP2(HP_map_addnpc), 2618 }, - { HP_POP(map->clearflooritem_timer), HP_POP2(HP_map_clearflooritem_timer), 2620 }, - { HP_POP(map->removemobs_timer), HP_POP2(HP_map_removemobs_timer), 2622 }, - { HP_POP(map->clearflooritem), HP_POP2(HP_map_clearflooritem), 2624 }, - { HP_POP(map->addflooritem), HP_POP2(HP_map_addflooritem), 2626 }, - { HP_POP(map->addnickdb), HP_POP2(HP_map_addnickdb), 2628 }, - { HP_POP(map->delnickdb), HP_POP2(HP_map_delnickdb), 2630 }, - { HP_POP(map->reqnickdb), HP_POP2(HP_map_reqnickdb), 2632 }, - { HP_POP(map->charid2nick), HP_POP2(HP_map_charid2nick), 2634 }, - { HP_POP(map->charid2sd), HP_POP2(HP_map_charid2sd), 2636 }, - { HP_POP(map->vforeachpc), HP_POP2(HP_map_vforeachpc), 2638 }, - { HP_POP(map->vforeachmob), HP_POP2(HP_map_vforeachmob), 2640 }, - { HP_POP(map->vforeachnpc), HP_POP2(HP_map_vforeachnpc), 2642 }, - { HP_POP(map->vforeachregen), HP_POP2(HP_map_vforeachregen), 2644 }, - { HP_POP(map->vforeachiddb), HP_POP2(HP_map_vforeachiddb), 2646 }, - { HP_POP(map->vforeachinrange), HP_POP2(HP_map_vforeachinrange), 2648 }, - { HP_POP(map->vforeachinshootrange), HP_POP2(HP_map_vforeachinshootrange), 2650 }, - { HP_POP(map->vforeachinarea), HP_POP2(HP_map_vforeachinarea), 2652 }, - { HP_POP(map->vforcountinrange), HP_POP2(HP_map_vforcountinrange), 2654 }, - { HP_POP(map->vforcountinarea), HP_POP2(HP_map_vforcountinarea), 2656 }, - { HP_POP(map->vforeachinmovearea), HP_POP2(HP_map_vforeachinmovearea), 2658 }, - { HP_POP(map->vforeachincell), HP_POP2(HP_map_vforeachincell), 2660 }, - { HP_POP(map->vforeachinpath), HP_POP2(HP_map_vforeachinpath), 2662 }, - { HP_POP(map->vforeachinmap), HP_POP2(HP_map_vforeachinmap), 2664 }, - { HP_POP(map->vforeachininstance), HP_POP2(HP_map_vforeachininstance), 2666 }, - { HP_POP(map->id2sd), HP_POP2(HP_map_id2sd), 2668 }, - { HP_POP(map->id2md), HP_POP2(HP_map_id2md), 2670 }, - { HP_POP(map->id2nd), HP_POP2(HP_map_id2nd), 2672 }, - { HP_POP(map->id2hd), HP_POP2(HP_map_id2hd), 2674 }, - { HP_POP(map->id2mc), HP_POP2(HP_map_id2mc), 2676 }, - { HP_POP(map->id2cd), HP_POP2(HP_map_id2cd), 2678 }, - { HP_POP(map->id2bl), HP_POP2(HP_map_id2bl), 2680 }, - { HP_POP(map->blid_exists), HP_POP2(HP_map_blid_exists), 2682 }, - { HP_POP(map->mapindex2mapid), HP_POP2(HP_map_mapindex2mapid), 2684 }, - { HP_POP(map->mapname2mapid), HP_POP2(HP_map_mapname2mapid), 2686 }, - { HP_POP(map->mapname2ipport), HP_POP2(HP_map_mapname2ipport), 2688 }, - { HP_POP(map->setipport), HP_POP2(HP_map_setipport), 2690 }, - { HP_POP(map->eraseipport), HP_POP2(HP_map_eraseipport), 2692 }, - { HP_POP(map->eraseallipport), HP_POP2(HP_map_eraseallipport), 2694 }, - { HP_POP(map->addiddb), HP_POP2(HP_map_addiddb), 2696 }, - { HP_POP(map->deliddb), HP_POP2(HP_map_deliddb), 2698 }, - { HP_POP(map->nick2sd), HP_POP2(HP_map_nick2sd), 2700 }, - { HP_POP(map->getmob_boss), HP_POP2(HP_map_getmob_boss), 2702 }, - { HP_POP(map->id2boss), HP_POP2(HP_map_id2boss), 2704 }, - { HP_POP(map->reloadnpc), HP_POP2(HP_map_reloadnpc), 2706 }, - { HP_POP(map->check_dir), HP_POP2(HP_map_check_dir), 2708 }, - { HP_POP(map->calc_dir), HP_POP2(HP_map_calc_dir), 2710 }, - { HP_POP(map->random_dir), HP_POP2(HP_map_random_dir), 2712 }, - { HP_POP(map->cleanup_sub), HP_POP2(HP_map_cleanup_sub), 2714 }, - { HP_POP(map->delmap), HP_POP2(HP_map_delmap), 2716 }, - { HP_POP(map->flags_init), HP_POP2(HP_map_flags_init), 2718 }, - { HP_POP(map->iwall_set), HP_POP2(HP_map_iwall_set), 2720 }, - { HP_POP(map->iwall_get), HP_POP2(HP_map_iwall_get), 2722 }, - { HP_POP(map->iwall_remove), HP_POP2(HP_map_iwall_remove), 2724 }, - { HP_POP(map->addmobtolist), HP_POP2(HP_map_addmobtolist), 2726 }, - { HP_POP(map->spawnmobs), HP_POP2(HP_map_spawnmobs), 2728 }, - { HP_POP(map->removemobs), HP_POP2(HP_map_removemobs), 2730 }, - { HP_POP(map->addmap2db), HP_POP2(HP_map_addmap2db), 2732 }, - { HP_POP(map->removemapdb), HP_POP2(HP_map_removemapdb), 2734 }, - { HP_POP(map->clean), HP_POP2(HP_map_clean), 2736 }, - { HP_POP(map->do_shutdown), HP_POP2(HP_map_do_shutdown), 2738 }, - { HP_POP(map->freeblock_timer), HP_POP2(HP_map_freeblock_timer), 2740 }, - { HP_POP(map->searchrandfreecell), HP_POP2(HP_map_searchrandfreecell), 2742 }, - { HP_POP(map->count_sub), HP_POP2(HP_map_count_sub), 2744 }, - { HP_POP(map->create_charid2nick), HP_POP2(HP_map_create_charid2nick), 2746 }, - { HP_POP(map->removemobs_sub), HP_POP2(HP_map_removemobs_sub), 2748 }, - { HP_POP(map->gat2cell), HP_POP2(HP_map_gat2cell), 2750 }, - { HP_POP(map->cell2gat), HP_POP2(HP_map_cell2gat), 2752 }, - { HP_POP(map->getcellp), HP_POP2(HP_map_getcellp), 2754 }, - { HP_POP(map->setcell), HP_POP2(HP_map_setcell), 2756 }, - { HP_POP(map->sub_getcellp), HP_POP2(HP_map_sub_getcellp), 2758 }, - { HP_POP(map->sub_setcell), HP_POP2(HP_map_sub_setcell), 2760 }, - { HP_POP(map->iwall_nextxy), HP_POP2(HP_map_iwall_nextxy), 2762 }, - { HP_POP(map->create_map_data_other_server), HP_POP2(HP_map_create_map_data_other_server), 2764 }, - { HP_POP(map->eraseallipport_sub), HP_POP2(HP_map_eraseallipport_sub), 2766 }, - { HP_POP(map->init_mapcache), HP_POP2(HP_map_init_mapcache), 2768 }, - { HP_POP(map->readfromcache), HP_POP2(HP_map_readfromcache), 2770 }, - { HP_POP(map->addmap), HP_POP2(HP_map_addmap), 2772 }, - { HP_POP(map->delmapid), HP_POP2(HP_map_delmapid), 2774 }, - { HP_POP(map->zone_db_clear), HP_POP2(HP_map_zone_db_clear), 2776 }, - { HP_POP(map->list_final), HP_POP2(HP_map_list_final), 2778 }, - { HP_POP(map->waterheight), HP_POP2(HP_map_waterheight), 2780 }, - { HP_POP(map->readgat), HP_POP2(HP_map_readgat), 2782 }, - { HP_POP(map->readallmaps), HP_POP2(HP_map_readallmaps), 2784 }, - { HP_POP(map->config_read), HP_POP2(HP_map_config_read), 2786 }, - { HP_POP(map->config_read_sub), HP_POP2(HP_map_config_read_sub), 2788 }, - { HP_POP(map->reloadnpc_sub), HP_POP2(HP_map_reloadnpc_sub), 2790 }, - { HP_POP(map->inter_config_read), HP_POP2(HP_map_inter_config_read), 2792 }, - { HP_POP(map->sql_init), HP_POP2(HP_map_sql_init), 2794 }, - { HP_POP(map->sql_close), HP_POP2(HP_map_sql_close), 2796 }, - { HP_POP(map->zone_mf_cache), HP_POP2(HP_map_zone_mf_cache), 2798 }, - { HP_POP(map->zone_str2itemid), HP_POP2(HP_map_zone_str2itemid), 2800 }, - { HP_POP(map->zone_str2skillid), HP_POP2(HP_map_zone_str2skillid), 2802 }, - { HP_POP(map->zone_bl_type), HP_POP2(HP_map_zone_bl_type), 2804 }, - { HP_POP(map->read_zone_db), HP_POP2(HP_map_read_zone_db), 2806 }, - { HP_POP(map->db_final), HP_POP2(HP_map_db_final), 2808 }, - { HP_POP(map->nick_db_final), HP_POP2(HP_map_nick_db_final), 2810 }, - { HP_POP(map->cleanup_db_sub), HP_POP2(HP_map_cleanup_db_sub), 2812 }, - { HP_POP(map->abort_sub), HP_POP2(HP_map_abort_sub), 2814 }, - { HP_POP(map->helpscreen), HP_POP2(HP_map_helpscreen), 2816 }, - { HP_POP(map->versionscreen), HP_POP2(HP_map_versionscreen), 2818 }, - { HP_POP(map->arg_next_value), HP_POP2(HP_map_arg_next_value), 2820 }, - { HP_POP(map->addblcell), HP_POP2(HP_map_addblcell), 2822 }, - { HP_POP(map->delblcell), HP_POP2(HP_map_delblcell), 2824 }, + { HP_POP(map->zone_init, HP_map_zone_init) }, + { HP_POP(map->zone_remove, HP_map_zone_remove) }, + { HP_POP(map->zone_apply, HP_map_zone_apply) }, + { HP_POP(map->zone_change, HP_map_zone_change) }, + { HP_POP(map->zone_change2, HP_map_zone_change2) }, + { HP_POP(map->getcell, HP_map_getcell) }, + { HP_POP(map->setgatcell, HP_map_setgatcell) }, + { HP_POP(map->cellfromcache, HP_map_cellfromcache) }, + { HP_POP(map->setusers, HP_map_setusers) }, + { HP_POP(map->getusers, HP_map_getusers) }, + { HP_POP(map->usercount, HP_map_usercount) }, + { HP_POP(map->freeblock, HP_map_freeblock) }, + { HP_POP(map->freeblock_lock, HP_map_freeblock_lock) }, + { HP_POP(map->freeblock_unlock, HP_map_freeblock_unlock) }, + { HP_POP(map->addblock, HP_map_addblock) }, + { HP_POP(map->delblock, HP_map_delblock) }, + { HP_POP(map->moveblock, HP_map_moveblock) }, + { HP_POP(map->count_oncell, HP_map_count_oncell) }, + { HP_POP(map->find_skill_unit_oncell, HP_map_find_skill_unit_oncell) }, + { HP_POP(map->get_new_object_id, HP_map_get_new_object_id) }, + { HP_POP(map->search_freecell, HP_map_search_freecell) }, + { HP_POP(map->quit, HP_map_quit) }, + { HP_POP(map->addnpc, HP_map_addnpc) }, + { HP_POP(map->clearflooritem_timer, HP_map_clearflooritem_timer) }, + { HP_POP(map->removemobs_timer, HP_map_removemobs_timer) }, + { HP_POP(map->clearflooritem, HP_map_clearflooritem) }, + { HP_POP(map->addflooritem, HP_map_addflooritem) }, + { HP_POP(map->addnickdb, HP_map_addnickdb) }, + { HP_POP(map->delnickdb, HP_map_delnickdb) }, + { HP_POP(map->reqnickdb, HP_map_reqnickdb) }, + { HP_POP(map->charid2nick, HP_map_charid2nick) }, + { HP_POP(map->charid2sd, HP_map_charid2sd) }, + { HP_POP(map->vforeachpc, HP_map_vforeachpc) }, + { HP_POP(map->vforeachmob, HP_map_vforeachmob) }, + { HP_POP(map->vforeachnpc, HP_map_vforeachnpc) }, + { HP_POP(map->vforeachregen, HP_map_vforeachregen) }, + { HP_POP(map->vforeachiddb, HP_map_vforeachiddb) }, + { HP_POP(map->vforeachinrange, HP_map_vforeachinrange) }, + { HP_POP(map->vforeachinshootrange, HP_map_vforeachinshootrange) }, + { HP_POP(map->vforeachinarea, HP_map_vforeachinarea) }, + { HP_POP(map->vforcountinrange, HP_map_vforcountinrange) }, + { HP_POP(map->vforcountinarea, HP_map_vforcountinarea) }, + { HP_POP(map->vforeachinmovearea, HP_map_vforeachinmovearea) }, + { HP_POP(map->vforeachincell, HP_map_vforeachincell) }, + { HP_POP(map->vforeachinpath, HP_map_vforeachinpath) }, + { HP_POP(map->vforeachinmap, HP_map_vforeachinmap) }, + { HP_POP(map->vforeachininstance, HP_map_vforeachininstance) }, + { HP_POP(map->id2sd, HP_map_id2sd) }, + { HP_POP(map->id2md, HP_map_id2md) }, + { HP_POP(map->id2nd, HP_map_id2nd) }, + { HP_POP(map->id2hd, HP_map_id2hd) }, + { HP_POP(map->id2mc, HP_map_id2mc) }, + { HP_POP(map->id2cd, HP_map_id2cd) }, + { HP_POP(map->id2bl, HP_map_id2bl) }, + { HP_POP(map->blid_exists, HP_map_blid_exists) }, + { HP_POP(map->mapindex2mapid, HP_map_mapindex2mapid) }, + { HP_POP(map->mapname2mapid, HP_map_mapname2mapid) }, + { HP_POP(map->mapname2ipport, HP_map_mapname2ipport) }, + { HP_POP(map->setipport, HP_map_setipport) }, + { HP_POP(map->eraseipport, HP_map_eraseipport) }, + { HP_POP(map->eraseallipport, HP_map_eraseallipport) }, + { HP_POP(map->addiddb, HP_map_addiddb) }, + { HP_POP(map->deliddb, HP_map_deliddb) }, + { HP_POP(map->nick2sd, HP_map_nick2sd) }, + { HP_POP(map->getmob_boss, HP_map_getmob_boss) }, + { HP_POP(map->id2boss, HP_map_id2boss) }, + { HP_POP(map->reloadnpc, HP_map_reloadnpc) }, + { HP_POP(map->check_dir, HP_map_check_dir) }, + { HP_POP(map->calc_dir, HP_map_calc_dir) }, + { HP_POP(map->random_dir, HP_map_random_dir) }, + { HP_POP(map->cleanup_sub, HP_map_cleanup_sub) }, + { HP_POP(map->delmap, HP_map_delmap) }, + { HP_POP(map->flags_init, HP_map_flags_init) }, + { HP_POP(map->iwall_set, HP_map_iwall_set) }, + { HP_POP(map->iwall_get, HP_map_iwall_get) }, + { HP_POP(map->iwall_remove, HP_map_iwall_remove) }, + { HP_POP(map->addmobtolist, HP_map_addmobtolist) }, + { HP_POP(map->spawnmobs, HP_map_spawnmobs) }, + { HP_POP(map->removemobs, HP_map_removemobs) }, + { HP_POP(map->addmap2db, HP_map_addmap2db) }, + { HP_POP(map->removemapdb, HP_map_removemapdb) }, + { HP_POP(map->clean, HP_map_clean) }, + { HP_POP(map->do_shutdown, HP_map_do_shutdown) }, + { HP_POP(map->freeblock_timer, HP_map_freeblock_timer) }, + { HP_POP(map->searchrandfreecell, HP_map_searchrandfreecell) }, + { HP_POP(map->count_sub, HP_map_count_sub) }, + { HP_POP(map->create_charid2nick, HP_map_create_charid2nick) }, + { HP_POP(map->removemobs_sub, HP_map_removemobs_sub) }, + { HP_POP(map->gat2cell, HP_map_gat2cell) }, + { HP_POP(map->cell2gat, HP_map_cell2gat) }, + { HP_POP(map->getcellp, HP_map_getcellp) }, + { HP_POP(map->setcell, HP_map_setcell) }, + { HP_POP(map->sub_getcellp, HP_map_sub_getcellp) }, + { HP_POP(map->sub_setcell, HP_map_sub_setcell) }, + { HP_POP(map->iwall_nextxy, HP_map_iwall_nextxy) }, + { HP_POP(map->create_map_data_other_server, HP_map_create_map_data_other_server) }, + { HP_POP(map->eraseallipport_sub, HP_map_eraseallipport_sub) }, + { HP_POP(map->init_mapcache, HP_map_init_mapcache) }, + { HP_POP(map->readfromcache, HP_map_readfromcache) }, + { HP_POP(map->addmap, HP_map_addmap) }, + { HP_POP(map->delmapid, HP_map_delmapid) }, + { HP_POP(map->zone_db_clear, HP_map_zone_db_clear) }, + { HP_POP(map->list_final, HP_map_list_final) }, + { HP_POP(map->waterheight, HP_map_waterheight) }, + { HP_POP(map->readgat, HP_map_readgat) }, + { HP_POP(map->readallmaps, HP_map_readallmaps) }, + { HP_POP(map->config_read, HP_map_config_read) }, + { HP_POP(map->config_read_sub, HP_map_config_read_sub) }, + { HP_POP(map->reloadnpc_sub, HP_map_reloadnpc_sub) }, + { HP_POP(map->inter_config_read, HP_map_inter_config_read) }, + { HP_POP(map->sql_init, HP_map_sql_init) }, + { HP_POP(map->sql_close, HP_map_sql_close) }, + { HP_POP(map->zone_mf_cache, HP_map_zone_mf_cache) }, + { HP_POP(map->zone_str2itemid, HP_map_zone_str2itemid) }, + { HP_POP(map->zone_str2skillid, HP_map_zone_str2skillid) }, + { HP_POP(map->zone_bl_type, HP_map_zone_bl_type) }, + { HP_POP(map->read_zone_db, HP_map_read_zone_db) }, + { HP_POP(map->db_final, HP_map_db_final) }, + { HP_POP(map->nick_db_final, HP_map_nick_db_final) }, + { HP_POP(map->cleanup_db_sub, HP_map_cleanup_db_sub) }, + { HP_POP(map->abort_sub, HP_map_abort_sub) }, + { HP_POP(map->helpscreen, HP_map_helpscreen) }, + { HP_POP(map->versionscreen, HP_map_versionscreen) }, + { HP_POP(map->arg_next_value, HP_map_arg_next_value) }, + { HP_POP(map->addblcell, HP_map_addblcell) }, + { HP_POP(map->delblcell, HP_map_delblcell) }, + { HP_POP(map->get_new_bonus_id, HP_map_get_new_bonus_id) }, + { HP_POP(map->add_questinfo, HP_map_add_questinfo) }, + { HP_POP(map->remove_questinfo, HP_map_remove_questinfo) }, + { HP_POP(map->merge_zone, HP_map_merge_zone) }, /* mapit */ - { HP_POP(mapit->alloc), HP_POP2(HP_mapit_alloc), 2826 }, - { HP_POP(mapit->free), HP_POP2(HP_mapit_free), 2828 }, - { HP_POP(mapit->first), HP_POP2(HP_mapit_first), 2830 }, - { HP_POP(mapit->last), HP_POP2(HP_mapit_last), 2832 }, - { HP_POP(mapit->next), HP_POP2(HP_mapit_next), 2834 }, - { HP_POP(mapit->prev), HP_POP2(HP_mapit_prev), 2836 }, - { HP_POP(mapit->exists), HP_POP2(HP_mapit_exists), 2838 }, + { HP_POP(mapit->alloc, HP_mapit_alloc) }, + { HP_POP(mapit->free, HP_mapit_free) }, + { HP_POP(mapit->first, HP_mapit_first) }, + { HP_POP(mapit->last, HP_mapit_last) }, + { HP_POP(mapit->next, HP_mapit_next) }, + { HP_POP(mapit->prev, HP_mapit_prev) }, + { HP_POP(mapit->exists, HP_mapit_exists) }, /* mapreg */ - { HP_POP(mapreg->init), HP_POP2(HP_mapreg_init), 2840 }, - { HP_POP(mapreg->final), HP_POP2(HP_mapreg_final), 2842 }, - { HP_POP(mapreg->readreg), HP_POP2(HP_mapreg_readreg), 2844 }, - { HP_POP(mapreg->readregstr), HP_POP2(HP_mapreg_readregstr), 2846 }, - { HP_POP(mapreg->setreg), HP_POP2(HP_mapreg_setreg), 2848 }, - { HP_POP(mapreg->setregstr), HP_POP2(HP_mapreg_setregstr), 2850 }, - { HP_POP(mapreg->load), HP_POP2(HP_mapreg_load), 2852 }, - { HP_POP(mapreg->save), HP_POP2(HP_mapreg_save), 2854 }, - { HP_POP(mapreg->save_timer), HP_POP2(HP_mapreg_save_timer), 2856 }, - { HP_POP(mapreg->reload), HP_POP2(HP_mapreg_reload), 2858 }, - { HP_POP(mapreg->config_read), HP_POP2(HP_mapreg_config_read), 2860 }, + { HP_POP(mapreg->init, HP_mapreg_init) }, + { HP_POP(mapreg->final, HP_mapreg_final) }, + { HP_POP(mapreg->readreg, HP_mapreg_readreg) }, + { HP_POP(mapreg->readregstr, HP_mapreg_readregstr) }, + { HP_POP(mapreg->setreg, HP_mapreg_setreg) }, + { HP_POP(mapreg->setregstr, HP_mapreg_setregstr) }, + { HP_POP(mapreg->load, HP_mapreg_load) }, + { HP_POP(mapreg->save, HP_mapreg_save) }, + { HP_POP(mapreg->save_timer, HP_mapreg_save_timer) }, + { HP_POP(mapreg->reload, HP_mapreg_reload) }, + { HP_POP(mapreg->config_read, HP_mapreg_config_read) }, /* mercenary */ - { HP_POP(mercenary->init), HP_POP2(HP_mercenary_init), 2862 }, - { HP_POP(mercenary->class), HP_POP2(HP_mercenary_class), 2864 }, - { HP_POP(mercenary->get_viewdata), HP_POP2(HP_mercenary_get_viewdata), 2866 }, - { HP_POP(mercenary->create), HP_POP2(HP_mercenary_create), 2868 }, - { HP_POP(mercenary->data_received), HP_POP2(HP_mercenary_data_received), 2870 }, - { HP_POP(mercenary->save), HP_POP2(HP_mercenary_save), 2872 }, - { HP_POP(mercenary->heal), HP_POP2(HP_mercenary_heal), 2874 }, - { HP_POP(mercenary->dead), HP_POP2(HP_mercenary_dead), 2876 }, - { HP_POP(mercenary->delete), HP_POP2(HP_mercenary_delete), 2878 }, - { HP_POP(mercenary->contract_stop), HP_POP2(HP_mercenary_contract_stop), 2880 }, - { HP_POP(mercenary->get_lifetime), HP_POP2(HP_mercenary_get_lifetime), 2882 }, - { HP_POP(mercenary->get_guild), HP_POP2(HP_mercenary_get_guild), 2884 }, - { HP_POP(mercenary->get_faith), HP_POP2(HP_mercenary_get_faith), 2886 }, - { HP_POP(mercenary->set_faith), HP_POP2(HP_mercenary_set_faith), 2888 }, - { HP_POP(mercenary->get_calls), HP_POP2(HP_mercenary_get_calls), 2890 }, - { HP_POP(mercenary->set_calls), HP_POP2(HP_mercenary_set_calls), 2892 }, - { HP_POP(mercenary->kills), HP_POP2(HP_mercenary_kills), 2894 }, - { HP_POP(mercenary->checkskill), HP_POP2(HP_mercenary_checkskill), 2896 }, - { HP_POP(mercenary->read_db), HP_POP2(HP_mercenary_read_db), 2898 }, - { HP_POP(mercenary->read_skilldb), HP_POP2(HP_mercenary_read_skilldb), 2900 }, - { HP_POP(mercenary->killbonus), HP_POP2(HP_mercenary_killbonus), 2902 }, - { HP_POP(mercenary->search_index), HP_POP2(HP_mercenary_search_index), 2904 }, - { HP_POP(mercenary->contract_end_timer), HP_POP2(HP_mercenary_contract_end_timer), 2906 }, - { HP_POP(mercenary->read_db_sub), HP_POP2(HP_mercenary_read_db_sub), 2908 }, - { HP_POP(mercenary->read_skill_db_sub), HP_POP2(HP_mercenary_read_skill_db_sub), 2910 }, + { HP_POP(mercenary->init, HP_mercenary_init) }, + { HP_POP(mercenary->class, HP_mercenary_class) }, + { HP_POP(mercenary->get_viewdata, HP_mercenary_get_viewdata) }, + { HP_POP(mercenary->create, HP_mercenary_create) }, + { HP_POP(mercenary->data_received, HP_mercenary_data_received) }, + { HP_POP(mercenary->save, HP_mercenary_save) }, + { HP_POP(mercenary->heal, HP_mercenary_heal) }, + { HP_POP(mercenary->dead, HP_mercenary_dead) }, + { HP_POP(mercenary->delete, HP_mercenary_delete) }, + { HP_POP(mercenary->contract_stop, HP_mercenary_contract_stop) }, + { HP_POP(mercenary->get_lifetime, HP_mercenary_get_lifetime) }, + { HP_POP(mercenary->get_guild, HP_mercenary_get_guild) }, + { HP_POP(mercenary->get_faith, HP_mercenary_get_faith) }, + { HP_POP(mercenary->set_faith, HP_mercenary_set_faith) }, + { HP_POP(mercenary->get_calls, HP_mercenary_get_calls) }, + { HP_POP(mercenary->set_calls, HP_mercenary_set_calls) }, + { HP_POP(mercenary->kills, HP_mercenary_kills) }, + { HP_POP(mercenary->checkskill, HP_mercenary_checkskill) }, + { HP_POP(mercenary->read_db, HP_mercenary_read_db) }, + { HP_POP(mercenary->read_skilldb, HP_mercenary_read_skilldb) }, + { HP_POP(mercenary->killbonus, HP_mercenary_killbonus) }, + { HP_POP(mercenary->search_index, HP_mercenary_search_index) }, + { HP_POP(mercenary->contract_end_timer, HP_mercenary_contract_end_timer) }, + { HP_POP(mercenary->read_db_sub, HP_mercenary_read_db_sub) }, + { HP_POP(mercenary->read_skill_db_sub, HP_mercenary_read_skill_db_sub) }, /* mob */ - { HP_POP(mob->init), HP_POP2(HP_mob_init), 2912 }, - { HP_POP(mob->final), HP_POP2(HP_mob_final), 2914 }, - { HP_POP(mob->reload), HP_POP2(HP_mob_reload), 2916 }, - { HP_POP(mob->db), HP_POP2(HP_mob_db), 2918 }, - { HP_POP(mob->chat), HP_POP2(HP_mob_chat), 2920 }, - { HP_POP(mob->makedummymobdb), HP_POP2(HP_mob_makedummymobdb), 2922 }, - { HP_POP(mob->spawn_guardian_sub), HP_POP2(HP_mob_spawn_guardian_sub), 2924 }, - { HP_POP(mob->skill_id2skill_idx), HP_POP2(HP_mob_skill_id2skill_idx), 2926 }, - { HP_POP(mob->db_searchname), HP_POP2(HP_mob_db_searchname), 2928 }, - { HP_POP(mob->db_searchname_array_sub), HP_POP2(HP_mob_db_searchname_array_sub), 2930 }, - { HP_POP(mob->mvptomb_create), HP_POP2(HP_mob_mvptomb_create), 2932 }, - { HP_POP(mob->mvptomb_destroy), HP_POP2(HP_mob_mvptomb_destroy), 2934 }, - { HP_POP(mob->db_searchname_array), HP_POP2(HP_mob_db_searchname_array), 2936 }, - { HP_POP(mob->db_checkid), HP_POP2(HP_mob_db_checkid), 2938 }, - { HP_POP(mob->get_viewdata), HP_POP2(HP_mob_get_viewdata), 2940 }, - { HP_POP(mob->parse_dataset), HP_POP2(HP_mob_parse_dataset), 2942 }, - { HP_POP(mob->spawn_dataset), HP_POP2(HP_mob_spawn_dataset), 2944 }, - { HP_POP(mob->get_random_id), HP_POP2(HP_mob_get_random_id), 2946 }, - { HP_POP(mob->ksprotected), HP_POP2(HP_mob_ksprotected), 2948 }, - { HP_POP(mob->once_spawn_sub), HP_POP2(HP_mob_once_spawn_sub), 2950 }, - { HP_POP(mob->once_spawn), HP_POP2(HP_mob_once_spawn), 2952 }, - { HP_POP(mob->once_spawn_area), HP_POP2(HP_mob_once_spawn_area), 2954 }, - { HP_POP(mob->spawn_guardian), HP_POP2(HP_mob_spawn_guardian), 2956 }, - { HP_POP(mob->spawn_bg), HP_POP2(HP_mob_spawn_bg), 2958 }, - { HP_POP(mob->can_reach), HP_POP2(HP_mob_can_reach), 2960 }, - { HP_POP(mob->linksearch), HP_POP2(HP_mob_linksearch), 2962 }, - { HP_POP(mob->delayspawn), HP_POP2(HP_mob_delayspawn), 2964 }, - { HP_POP(mob->setdelayspawn), HP_POP2(HP_mob_setdelayspawn), 2966 }, - { HP_POP(mob->count_sub), HP_POP2(HP_mob_count_sub), 2968 }, - { HP_POP(mob->spawn), HP_POP2(HP_mob_spawn), 2970 }, - { HP_POP(mob->can_changetarget), HP_POP2(HP_mob_can_changetarget), 2972 }, - { HP_POP(mob->target), HP_POP2(HP_mob_target), 2974 }, - { HP_POP(mob->ai_sub_hard_activesearch), HP_POP2(HP_mob_ai_sub_hard_activesearch), 2976 }, - { HP_POP(mob->ai_sub_hard_changechase), HP_POP2(HP_mob_ai_sub_hard_changechase), 2978 }, - { HP_POP(mob->ai_sub_hard_bg_ally), HP_POP2(HP_mob_ai_sub_hard_bg_ally), 2980 }, - { HP_POP(mob->ai_sub_hard_lootsearch), HP_POP2(HP_mob_ai_sub_hard_lootsearch), 2982 }, - { HP_POP(mob->warpchase_sub), HP_POP2(HP_mob_warpchase_sub), 2984 }, - { HP_POP(mob->ai_sub_hard_slavemob), HP_POP2(HP_mob_ai_sub_hard_slavemob), 2986 }, - { HP_POP(mob->unlocktarget), HP_POP2(HP_mob_unlocktarget), 2988 }, - { HP_POP(mob->randomwalk), HP_POP2(HP_mob_randomwalk), 2990 }, - { HP_POP(mob->warpchase), HP_POP2(HP_mob_warpchase), 2992 }, - { HP_POP(mob->ai_sub_hard), HP_POP2(HP_mob_ai_sub_hard), 2994 }, - { HP_POP(mob->ai_sub_hard_timer), HP_POP2(HP_mob_ai_sub_hard_timer), 2996 }, - { HP_POP(mob->ai_sub_foreachclient), HP_POP2(HP_mob_ai_sub_foreachclient), 2998 }, - { HP_POP(mob->ai_sub_lazy), HP_POP2(HP_mob_ai_sub_lazy), 3000 }, - { HP_POP(mob->ai_lazy), HP_POP2(HP_mob_ai_lazy), 3002 }, - { HP_POP(mob->ai_hard), HP_POP2(HP_mob_ai_hard), 3004 }, - { HP_POP(mob->setdropitem), HP_POP2(HP_mob_setdropitem), 3006 }, - { HP_POP(mob->setlootitem), HP_POP2(HP_mob_setlootitem), 3008 }, - { HP_POP(mob->delay_item_drop), HP_POP2(HP_mob_delay_item_drop), 3010 }, - { HP_POP(mob->item_drop), HP_POP2(HP_mob_item_drop), 3012 }, - { HP_POP(mob->timer_delete), HP_POP2(HP_mob_timer_delete), 3014 }, - { HP_POP(mob->deleteslave_sub), HP_POP2(HP_mob_deleteslave_sub), 3016 }, - { HP_POP(mob->deleteslave), HP_POP2(HP_mob_deleteslave), 3018 }, - { HP_POP(mob->respawn), HP_POP2(HP_mob_respawn), 3020 }, - { HP_POP(mob->log_damage), HP_POP2(HP_mob_log_damage), 3022 }, - { HP_POP(mob->damage), HP_POP2(HP_mob_damage), 3024 }, - { HP_POP(mob->dead), HP_POP2(HP_mob_dead), 3026 }, - { HP_POP(mob->revive), HP_POP2(HP_mob_revive), 3028 }, - { HP_POP(mob->guardian_guildchange), HP_POP2(HP_mob_guardian_guildchange), 3030 }, - { HP_POP(mob->random_class), HP_POP2(HP_mob_random_class), 3032 }, - { HP_POP(mob->class_change), HP_POP2(HP_mob_class_change), 3034 }, - { HP_POP(mob->heal), HP_POP2(HP_mob_heal), 3036 }, - { HP_POP(mob->warpslave_sub), HP_POP2(HP_mob_warpslave_sub), 3038 }, - { HP_POP(mob->warpslave), HP_POP2(HP_mob_warpslave), 3040 }, - { HP_POP(mob->countslave_sub), HP_POP2(HP_mob_countslave_sub), 3042 }, - { HP_POP(mob->countslave), HP_POP2(HP_mob_countslave), 3044 }, - { HP_POP(mob->summonslave), HP_POP2(HP_mob_summonslave), 3046 }, - { HP_POP(mob->getfriendhprate_sub), HP_POP2(HP_mob_getfriendhprate_sub), 3048 }, - { HP_POP(mob->getfriendhprate), HP_POP2(HP_mob_getfriendhprate), 3050 }, - { HP_POP(mob->getmasterhpltmaxrate), HP_POP2(HP_mob_getmasterhpltmaxrate), 3052 }, - { HP_POP(mob->getfriendstatus_sub), HP_POP2(HP_mob_getfriendstatus_sub), 3054 }, - { HP_POP(mob->getfriendstatus), HP_POP2(HP_mob_getfriendstatus), 3056 }, - { HP_POP(mob->skill_use), HP_POP2(HP_mob_skill_use), 3058 }, - { HP_POP(mob->skill_event), HP_POP2(HP_mob_skill_event), 3060 }, - { HP_POP(mob->is_clone), HP_POP2(HP_mob_is_clone), 3062 }, - { HP_POP(mob->clone_spawn), HP_POP2(HP_mob_clone_spawn), 3064 }, - { HP_POP(mob->clone_delete), HP_POP2(HP_mob_clone_delete), 3066 }, - { HP_POP(mob->drop_adjust), HP_POP2(HP_mob_drop_adjust), 3068 }, - { HP_POP(mob->item_dropratio_adjust), HP_POP2(HP_mob_item_dropratio_adjust), 3070 }, - { HP_POP(mob->parse_dbrow), HP_POP2(HP_mob_parse_dbrow), 3072 }, - { HP_POP(mob->readdb_sub), HP_POP2(HP_mob_readdb_sub), 3074 }, - { HP_POP(mob->readdb), HP_POP2(HP_mob_readdb), 3076 }, - { HP_POP(mob->read_sqldb), HP_POP2(HP_mob_read_sqldb), 3078 }, - { HP_POP(mob->readdb_mobavail), HP_POP2(HP_mob_readdb_mobavail), 3080 }, - { HP_POP(mob->read_randommonster), HP_POP2(HP_mob_read_randommonster), 3082 }, - { HP_POP(mob->parse_row_chatdb), HP_POP2(HP_mob_parse_row_chatdb), 3084 }, - { HP_POP(mob->readchatdb), HP_POP2(HP_mob_readchatdb), 3086 }, - { HP_POP(mob->parse_row_mobskilldb), HP_POP2(HP_mob_parse_row_mobskilldb), 3088 }, - { HP_POP(mob->readskilldb), HP_POP2(HP_mob_readskilldb), 3090 }, - { HP_POP(mob->read_sqlskilldb), HP_POP2(HP_mob_read_sqlskilldb), 3092 }, - { HP_POP(mob->readdb_race2), HP_POP2(HP_mob_readdb_race2), 3094 }, - { HP_POP(mob->readdb_itemratio), HP_POP2(HP_mob_readdb_itemratio), 3096 }, - { HP_POP(mob->load), HP_POP2(HP_mob_load), 3098 }, - { HP_POP(mob->clear_spawninfo), HP_POP2(HP_mob_clear_spawninfo), 3100 }, + { HP_POP(mob->init, HP_mob_init) }, + { HP_POP(mob->final, HP_mob_final) }, + { HP_POP(mob->reload, HP_mob_reload) }, + { HP_POP(mob->db, HP_mob_db) }, + { HP_POP(mob->chat, HP_mob_chat) }, + { HP_POP(mob->makedummymobdb, HP_mob_makedummymobdb) }, + { HP_POP(mob->spawn_guardian_sub, HP_mob_spawn_guardian_sub) }, + { HP_POP(mob->skill_id2skill_idx, HP_mob_skill_id2skill_idx) }, + { HP_POP(mob->db_searchname, HP_mob_db_searchname) }, + { HP_POP(mob->db_searchname_array_sub, HP_mob_db_searchname_array_sub) }, + { HP_POP(mob->mvptomb_create, HP_mob_mvptomb_create) }, + { HP_POP(mob->mvptomb_destroy, HP_mob_mvptomb_destroy) }, + { HP_POP(mob->db_searchname_array, HP_mob_db_searchname_array) }, + { HP_POP(mob->db_checkid, HP_mob_db_checkid) }, + { HP_POP(mob->get_viewdata, HP_mob_get_viewdata) }, + { HP_POP(mob->parse_dataset, HP_mob_parse_dataset) }, + { HP_POP(mob->spawn_dataset, HP_mob_spawn_dataset) }, + { HP_POP(mob->get_random_id, HP_mob_get_random_id) }, + { HP_POP(mob->ksprotected, HP_mob_ksprotected) }, + { HP_POP(mob->once_spawn_sub, HP_mob_once_spawn_sub) }, + { HP_POP(mob->once_spawn, HP_mob_once_spawn) }, + { HP_POP(mob->once_spawn_area, HP_mob_once_spawn_area) }, + { HP_POP(mob->spawn_guardian, HP_mob_spawn_guardian) }, + { HP_POP(mob->spawn_bg, HP_mob_spawn_bg) }, + { HP_POP(mob->can_reach, HP_mob_can_reach) }, + { HP_POP(mob->linksearch, HP_mob_linksearch) }, + { HP_POP(mob->delayspawn, HP_mob_delayspawn) }, + { HP_POP(mob->setdelayspawn, HP_mob_setdelayspawn) }, + { HP_POP(mob->count_sub, HP_mob_count_sub) }, + { HP_POP(mob->spawn, HP_mob_spawn) }, + { HP_POP(mob->can_changetarget, HP_mob_can_changetarget) }, + { HP_POP(mob->target, HP_mob_target) }, + { HP_POP(mob->ai_sub_hard_activesearch, HP_mob_ai_sub_hard_activesearch) }, + { HP_POP(mob->ai_sub_hard_changechase, HP_mob_ai_sub_hard_changechase) }, + { HP_POP(mob->ai_sub_hard_bg_ally, HP_mob_ai_sub_hard_bg_ally) }, + { HP_POP(mob->ai_sub_hard_lootsearch, HP_mob_ai_sub_hard_lootsearch) }, + { HP_POP(mob->warpchase_sub, HP_mob_warpchase_sub) }, + { HP_POP(mob->ai_sub_hard_slavemob, HP_mob_ai_sub_hard_slavemob) }, + { HP_POP(mob->unlocktarget, HP_mob_unlocktarget) }, + { HP_POP(mob->randomwalk, HP_mob_randomwalk) }, + { HP_POP(mob->warpchase, HP_mob_warpchase) }, + { HP_POP(mob->ai_sub_hard, HP_mob_ai_sub_hard) }, + { HP_POP(mob->ai_sub_hard_timer, HP_mob_ai_sub_hard_timer) }, + { HP_POP(mob->ai_sub_foreachclient, HP_mob_ai_sub_foreachclient) }, + { HP_POP(mob->ai_sub_lazy, HP_mob_ai_sub_lazy) }, + { HP_POP(mob->ai_lazy, HP_mob_ai_lazy) }, + { HP_POP(mob->ai_hard, HP_mob_ai_hard) }, + { HP_POP(mob->setdropitem, HP_mob_setdropitem) }, + { HP_POP(mob->setlootitem, HP_mob_setlootitem) }, + { HP_POP(mob->delay_item_drop, HP_mob_delay_item_drop) }, + { HP_POP(mob->item_drop, HP_mob_item_drop) }, + { HP_POP(mob->timer_delete, HP_mob_timer_delete) }, + { HP_POP(mob->deleteslave_sub, HP_mob_deleteslave_sub) }, + { HP_POP(mob->deleteslave, HP_mob_deleteslave) }, + { HP_POP(mob->respawn, HP_mob_respawn) }, + { HP_POP(mob->log_damage, HP_mob_log_damage) }, + { HP_POP(mob->damage, HP_mob_damage) }, + { HP_POP(mob->dead, HP_mob_dead) }, + { HP_POP(mob->revive, HP_mob_revive) }, + { HP_POP(mob->guardian_guildchange, HP_mob_guardian_guildchange) }, + { HP_POP(mob->random_class, HP_mob_random_class) }, + { HP_POP(mob->class_change, HP_mob_class_change) }, + { HP_POP(mob->heal, HP_mob_heal) }, + { HP_POP(mob->warpslave_sub, HP_mob_warpslave_sub) }, + { HP_POP(mob->warpslave, HP_mob_warpslave) }, + { HP_POP(mob->countslave_sub, HP_mob_countslave_sub) }, + { HP_POP(mob->countslave, HP_mob_countslave) }, + { HP_POP(mob->summonslave, HP_mob_summonslave) }, + { HP_POP(mob->getfriendhprate_sub, HP_mob_getfriendhprate_sub) }, + { HP_POP(mob->getfriendhprate, HP_mob_getfriendhprate) }, + { HP_POP(mob->getmasterhpltmaxrate, HP_mob_getmasterhpltmaxrate) }, + { HP_POP(mob->getfriendstatus_sub, HP_mob_getfriendstatus_sub) }, + { HP_POP(mob->getfriendstatus, HP_mob_getfriendstatus) }, + { HP_POP(mob->skill_use, HP_mob_skill_use) }, + { HP_POP(mob->skill_event, HP_mob_skill_event) }, + { HP_POP(mob->is_clone, HP_mob_is_clone) }, + { HP_POP(mob->clone_spawn, HP_mob_clone_spawn) }, + { HP_POP(mob->clone_delete, HP_mob_clone_delete) }, + { HP_POP(mob->drop_adjust, HP_mob_drop_adjust) }, + { HP_POP(mob->item_dropratio_adjust, HP_mob_item_dropratio_adjust) }, + { HP_POP(mob->parse_dbrow, HP_mob_parse_dbrow) }, + { HP_POP(mob->readdb_sub, HP_mob_readdb_sub) }, + { HP_POP(mob->readdb, HP_mob_readdb) }, + { HP_POP(mob->read_sqldb, HP_mob_read_sqldb) }, + { HP_POP(mob->name_constants, HP_mob_name_constants) }, + { HP_POP(mob->readdb_mobavail, HP_mob_readdb_mobavail) }, + { HP_POP(mob->read_randommonster, HP_mob_read_randommonster) }, + { HP_POP(mob->parse_row_chatdb, HP_mob_parse_row_chatdb) }, + { HP_POP(mob->readchatdb, HP_mob_readchatdb) }, + { HP_POP(mob->parse_row_mobskilldb, HP_mob_parse_row_mobskilldb) }, + { HP_POP(mob->readskilldb, HP_mob_readskilldb) }, + { HP_POP(mob->read_sqlskilldb, HP_mob_read_sqlskilldb) }, + { HP_POP(mob->readdb_race2, HP_mob_readdb_race2) }, + { HP_POP(mob->readdb_itemratio, HP_mob_readdb_itemratio) }, + { HP_POP(mob->load, HP_mob_load) }, + { HP_POP(mob->clear_spawninfo, HP_mob_clear_spawninfo) }, /* npc */ - { HP_POP(npc->init), HP_POP2(HP_npc_init), 3102 }, - { HP_POP(npc->final), HP_POP2(HP_npc_final), 3104 }, - { HP_POP(npc->get_new_npc_id), HP_POP2(HP_npc_get_new_npc_id), 3106 }, - { HP_POP(npc->get_viewdata), HP_POP2(HP_npc_get_viewdata), 3108 }, - { HP_POP(npc->isnear_sub), HP_POP2(HP_npc_isnear_sub), 3110 }, - { HP_POP(npc->isnear), HP_POP2(HP_npc_isnear), 3112 }, - { HP_POP(npc->ontouch_event), HP_POP2(HP_npc_ontouch_event), 3114 }, - { HP_POP(npc->ontouch2_event), HP_POP2(HP_npc_ontouch2_event), 3116 }, - { HP_POP(npc->enable_sub), HP_POP2(HP_npc_enable_sub), 3118 }, - { HP_POP(npc->enable), HP_POP2(HP_npc_enable), 3120 }, - { HP_POP(npc->name2id), HP_POP2(HP_npc_name2id), 3122 }, - { HP_POP(npc->event_dequeue), HP_POP2(HP_npc_event_dequeue), 3124 }, - { HP_POP(npc->event_export_create), HP_POP2(HP_npc_event_export_create), 3126 }, - { HP_POP(npc->event_export), HP_POP2(HP_npc_event_export), 3128 }, - { HP_POP(npc->event_sub), HP_POP2(HP_npc_event_sub), 3130 }, - { HP_POP(npc->event_doall_sub), HP_POP2(HP_npc_event_doall_sub), 3132 }, - { HP_POP(npc->event_do), HP_POP2(HP_npc_event_do), 3134 }, - { HP_POP(npc->event_doall_id), HP_POP2(HP_npc_event_doall_id), 3136 }, - { HP_POP(npc->event_doall), HP_POP2(HP_npc_event_doall), 3138 }, - { HP_POP(npc->event_do_clock), HP_POP2(HP_npc_event_do_clock), 3140 }, - { HP_POP(npc->event_do_oninit), HP_POP2(HP_npc_event_do_oninit), 3142 }, - { HP_POP(npc->timerevent_export), HP_POP2(HP_npc_timerevent_export), 3144 }, - { HP_POP(npc->timerevent), HP_POP2(HP_npc_timerevent), 3146 }, - { HP_POP(npc->timerevent_start), HP_POP2(HP_npc_timerevent_start), 3148 }, - { HP_POP(npc->timerevent_stop), HP_POP2(HP_npc_timerevent_stop), 3150 }, - { HP_POP(npc->timerevent_quit), HP_POP2(HP_npc_timerevent_quit), 3152 }, - { HP_POP(npc->gettimerevent_tick), HP_POP2(HP_npc_gettimerevent_tick), 3154 }, - { HP_POP(npc->settimerevent_tick), HP_POP2(HP_npc_settimerevent_tick), 3156 }, - { HP_POP(npc->event), HP_POP2(HP_npc_event), 3158 }, - { HP_POP(npc->touch_areanpc_sub), HP_POP2(HP_npc_touch_areanpc_sub), 3160 }, - { HP_POP(npc->touchnext_areanpc), HP_POP2(HP_npc_touchnext_areanpc), 3162 }, - { HP_POP(npc->touch_areanpc), HP_POP2(HP_npc_touch_areanpc), 3164 }, - { HP_POP(npc->touch_areanpc2), HP_POP2(HP_npc_touch_areanpc2), 3166 }, - { HP_POP(npc->check_areanpc), HP_POP2(HP_npc_check_areanpc), 3168 }, - { HP_POP(npc->checknear), HP_POP2(HP_npc_checknear), 3170 }, - { HP_POP(npc->globalmessage), HP_POP2(HP_npc_globalmessage), 3172 }, - { HP_POP(npc->run_tomb), HP_POP2(HP_npc_run_tomb), 3174 }, - { HP_POP(npc->click), HP_POP2(HP_npc_click), 3176 }, - { HP_POP(npc->scriptcont), HP_POP2(HP_npc_scriptcont), 3178 }, - { HP_POP(npc->buysellsel), HP_POP2(HP_npc_buysellsel), 3180 }, - { HP_POP(npc->cashshop_buylist), HP_POP2(HP_npc_cashshop_buylist), 3182 }, - { HP_POP(npc->buylist_sub), HP_POP2(HP_npc_buylist_sub), 3184 }, - { HP_POP(npc->cashshop_buy), HP_POP2(HP_npc_cashshop_buy), 3186 }, - { HP_POP(npc->buylist), HP_POP2(HP_npc_buylist), 3188 }, - { HP_POP(npc->selllist_sub), HP_POP2(HP_npc_selllist_sub), 3190 }, - { HP_POP(npc->selllist), HP_POP2(HP_npc_selllist), 3192 }, - { HP_POP(npc->remove_map), HP_POP2(HP_npc_remove_map), 3194 }, - { HP_POP(npc->unload_ev), HP_POP2(HP_npc_unload_ev), 3196 }, - { HP_POP(npc->unload_ev_label), HP_POP2(HP_npc_unload_ev_label), 3198 }, - { HP_POP(npc->unload_dup_sub), HP_POP2(HP_npc_unload_dup_sub), 3200 }, - { HP_POP(npc->unload_duplicates), HP_POP2(HP_npc_unload_duplicates), 3202 }, - { HP_POP(npc->unload), HP_POP2(HP_npc_unload), 3204 }, - { HP_POP(npc->clearsrcfile), HP_POP2(HP_npc_clearsrcfile), 3206 }, - { HP_POP(npc->addsrcfile), HP_POP2(HP_npc_addsrcfile), 3208 }, - { HP_POP(npc->delsrcfile), HP_POP2(HP_npc_delsrcfile), 3210 }, - { HP_POP(npc->parsename), HP_POP2(HP_npc_parsename), 3212 }, - { HP_POP(npc->add_warp), HP_POP2(HP_npc_add_warp), 3214 }, - { HP_POP(npc->parse_warp), HP_POP2(HP_npc_parse_warp), 3216 }, - { HP_POP(npc->parse_shop), HP_POP2(HP_npc_parse_shop), 3218 }, - { HP_POP(npc->convertlabel_db), HP_POP2(HP_npc_convertlabel_db), 3220 }, - { HP_POP(npc->skip_script), HP_POP2(HP_npc_skip_script), 3222 }, - { HP_POP(npc->parse_script), HP_POP2(HP_npc_parse_script), 3224 }, - { HP_POP(npc->parse_duplicate), HP_POP2(HP_npc_parse_duplicate), 3226 }, - { HP_POP(npc->duplicate4instance), HP_POP2(HP_npc_duplicate4instance), 3228 }, - { HP_POP(npc->setcells), HP_POP2(HP_npc_setcells), 3230 }, - { HP_POP(npc->unsetcells_sub), HP_POP2(HP_npc_unsetcells_sub), 3232 }, - { HP_POP(npc->unsetcells), HP_POP2(HP_npc_unsetcells), 3234 }, - { HP_POP(npc->movenpc), HP_POP2(HP_npc_movenpc), 3236 }, - { HP_POP(npc->setdisplayname), HP_POP2(HP_npc_setdisplayname), 3238 }, - { HP_POP(npc->setclass), HP_POP2(HP_npc_setclass), 3240 }, - { HP_POP(npc->do_atcmd_event), HP_POP2(HP_npc_do_atcmd_event), 3242 }, - { HP_POP(npc->parse_function), HP_POP2(HP_npc_parse_function), 3244 }, - { HP_POP(npc->parse_mob2), HP_POP2(HP_npc_parse_mob2), 3246 }, - { HP_POP(npc->parse_mob), HP_POP2(HP_npc_parse_mob), 3248 }, - { HP_POP(npc->parse_mapflag), HP_POP2(HP_npc_parse_mapflag), 3250 }, - { HP_POP(npc->parsesrcfile), HP_POP2(HP_npc_parsesrcfile), 3252 }, - { HP_POP(npc->script_event), HP_POP2(HP_npc_script_event), 3254 }, - { HP_POP(npc->read_event_script), HP_POP2(HP_npc_read_event_script), 3256 }, - { HP_POP(npc->path_db_clear_sub), HP_POP2(HP_npc_path_db_clear_sub), 3258 }, - { HP_POP(npc->ev_label_db_clear_sub), HP_POP2(HP_npc_ev_label_db_clear_sub), 3260 }, - { HP_POP(npc->reload), HP_POP2(HP_npc_reload), 3262 }, - { HP_POP(npc->unloadfile), HP_POP2(HP_npc_unloadfile), 3264 }, - { HP_POP(npc->do_clear_npc), HP_POP2(HP_npc_do_clear_npc), 3266 }, - { HP_POP(npc->debug_warps_sub), HP_POP2(HP_npc_debug_warps_sub), 3268 }, - { HP_POP(npc->debug_warps), HP_POP2(HP_npc_debug_warps), 3270 }, - { HP_POP(npc->secure_timeout_timer), HP_POP2(HP_npc_secure_timeout_timer), 3272 }, + { HP_POP(npc->init, HP_npc_init) }, + { HP_POP(npc->final, HP_npc_final) }, + { HP_POP(npc->get_new_npc_id, HP_npc_get_new_npc_id) }, + { HP_POP(npc->get_viewdata, HP_npc_get_viewdata) }, + { HP_POP(npc->isnear_sub, HP_npc_isnear_sub) }, + { HP_POP(npc->isnear, HP_npc_isnear) }, + { HP_POP(npc->ontouch_event, HP_npc_ontouch_event) }, + { HP_POP(npc->ontouch2_event, HP_npc_ontouch2_event) }, + { HP_POP(npc->enable_sub, HP_npc_enable_sub) }, + { HP_POP(npc->enable, HP_npc_enable) }, + { HP_POP(npc->name2id, HP_npc_name2id) }, + { HP_POP(npc->event_dequeue, HP_npc_event_dequeue) }, + { HP_POP(npc->event_export_create, HP_npc_event_export_create) }, + { HP_POP(npc->event_export, HP_npc_event_export) }, + { HP_POP(npc->event_sub, HP_npc_event_sub) }, + { HP_POP(npc->event_doall_sub, HP_npc_event_doall_sub) }, + { HP_POP(npc->event_do, HP_npc_event_do) }, + { HP_POP(npc->event_doall_id, HP_npc_event_doall_id) }, + { HP_POP(npc->event_doall, HP_npc_event_doall) }, + { HP_POP(npc->event_do_clock, HP_npc_event_do_clock) }, + { HP_POP(npc->event_do_oninit, HP_npc_event_do_oninit) }, + { HP_POP(npc->timerevent_export, HP_npc_timerevent_export) }, + { HP_POP(npc->timerevent, HP_npc_timerevent) }, + { HP_POP(npc->timerevent_start, HP_npc_timerevent_start) }, + { HP_POP(npc->timerevent_stop, HP_npc_timerevent_stop) }, + { HP_POP(npc->timerevent_quit, HP_npc_timerevent_quit) }, + { HP_POP(npc->gettimerevent_tick, HP_npc_gettimerevent_tick) }, + { HP_POP(npc->settimerevent_tick, HP_npc_settimerevent_tick) }, + { HP_POP(npc->event, HP_npc_event) }, + { HP_POP(npc->touch_areanpc_sub, HP_npc_touch_areanpc_sub) }, + { HP_POP(npc->touchnext_areanpc, HP_npc_touchnext_areanpc) }, + { HP_POP(npc->touch_areanpc, HP_npc_touch_areanpc) }, + { HP_POP(npc->touch_areanpc2, HP_npc_touch_areanpc2) }, + { HP_POP(npc->check_areanpc, HP_npc_check_areanpc) }, + { HP_POP(npc->checknear, HP_npc_checknear) }, + { HP_POP(npc->globalmessage, HP_npc_globalmessage) }, + { HP_POP(npc->run_tomb, HP_npc_run_tomb) }, + { HP_POP(npc->click, HP_npc_click) }, + { HP_POP(npc->scriptcont, HP_npc_scriptcont) }, + { HP_POP(npc->buysellsel, HP_npc_buysellsel) }, + { HP_POP(npc->cashshop_buylist, HP_npc_cashshop_buylist) }, + { HP_POP(npc->buylist_sub, HP_npc_buylist_sub) }, + { HP_POP(npc->cashshop_buy, HP_npc_cashshop_buy) }, + { HP_POP(npc->buylist, HP_npc_buylist) }, + { HP_POP(npc->selllist_sub, HP_npc_selllist_sub) }, + { HP_POP(npc->selllist, HP_npc_selllist) }, + { HP_POP(npc->remove_map, HP_npc_remove_map) }, + { HP_POP(npc->unload_ev, HP_npc_unload_ev) }, + { HP_POP(npc->unload_ev_label, HP_npc_unload_ev_label) }, + { HP_POP(npc->unload_dup_sub, HP_npc_unload_dup_sub) }, + { HP_POP(npc->unload_duplicates, HP_npc_unload_duplicates) }, + { HP_POP(npc->unload, HP_npc_unload) }, + { HP_POP(npc->clearsrcfile, HP_npc_clearsrcfile) }, + { HP_POP(npc->addsrcfile, HP_npc_addsrcfile) }, + { HP_POP(npc->delsrcfile, HP_npc_delsrcfile) }, + { HP_POP(npc->parsename, HP_npc_parsename) }, + { HP_POP(npc->parseview, HP_npc_parseview) }, + { HP_POP(npc->viewisid, HP_npc_viewisid) }, + { HP_POP(npc->add_warp, HP_npc_add_warp) }, + { HP_POP(npc->parse_warp, HP_npc_parse_warp) }, + { HP_POP(npc->parse_shop, HP_npc_parse_shop) }, + { HP_POP(npc->convertlabel_db, HP_npc_convertlabel_db) }, + { HP_POP(npc->skip_script, HP_npc_skip_script) }, + { HP_POP(npc->parse_script, HP_npc_parse_script) }, + { HP_POP(npc->parse_duplicate, HP_npc_parse_duplicate) }, + { HP_POP(npc->duplicate4instance, HP_npc_duplicate4instance) }, + { HP_POP(npc->setcells, HP_npc_setcells) }, + { HP_POP(npc->unsetcells_sub, HP_npc_unsetcells_sub) }, + { HP_POP(npc->unsetcells, HP_npc_unsetcells) }, + { HP_POP(npc->movenpc, HP_npc_movenpc) }, + { HP_POP(npc->setdisplayname, HP_npc_setdisplayname) }, + { HP_POP(npc->setclass, HP_npc_setclass) }, + { HP_POP(npc->do_atcmd_event, HP_npc_do_atcmd_event) }, + { HP_POP(npc->parse_function, HP_npc_parse_function) }, + { HP_POP(npc->parse_mob2, HP_npc_parse_mob2) }, + { HP_POP(npc->parse_mob, HP_npc_parse_mob) }, + { HP_POP(npc->parse_mapflag, HP_npc_parse_mapflag) }, + { HP_POP(npc->parsesrcfile, HP_npc_parsesrcfile) }, + { HP_POP(npc->script_event, HP_npc_script_event) }, + { HP_POP(npc->read_event_script, HP_npc_read_event_script) }, + { HP_POP(npc->path_db_clear_sub, HP_npc_path_db_clear_sub) }, + { HP_POP(npc->ev_label_db_clear_sub, HP_npc_ev_label_db_clear_sub) }, + { HP_POP(npc->reload, HP_npc_reload) }, + { HP_POP(npc->unloadfile, HP_npc_unloadfile) }, + { HP_POP(npc->do_clear_npc, HP_npc_do_clear_npc) }, + { HP_POP(npc->debug_warps_sub, HP_npc_debug_warps_sub) }, + { HP_POP(npc->debug_warps, HP_npc_debug_warps) }, + { HP_POP(npc->trader_count_funds, HP_npc_trader_count_funds) }, + { HP_POP(npc->trader_pay, HP_npc_trader_pay) }, + { HP_POP(npc->trader_update, HP_npc_trader_update) }, + { HP_POP(npc->market_buylist, HP_npc_market_buylist) }, + { HP_POP(npc->trader_open, HP_npc_trader_open) }, + { HP_POP(npc->market_fromsql, HP_npc_market_fromsql) }, + { HP_POP(npc->market_tosql, HP_npc_market_tosql) }, + { HP_POP(npc->market_delfromsql, HP_npc_market_delfromsql) }, + { HP_POP(npc->market_delfromsql_sub, HP_npc_market_delfromsql_sub) }, + { HP_POP(npc->secure_timeout_timer, HP_npc_secure_timeout_timer) }, /* party */ - { HP_POP(party->init), HP_POP2(HP_party_init), 3274 }, - { HP_POP(party->final), HP_POP2(HP_party_final), 3276 }, - { HP_POP(party->search), HP_POP2(HP_party_search), 3278 }, - { HP_POP(party->searchname), HP_POP2(HP_party_searchname), 3280 }, - { HP_POP(party->getmemberid), HP_POP2(HP_party_getmemberid), 3282 }, - { HP_POP(party->getavailablesd), HP_POP2(HP_party_getavailablesd), 3284 }, - { HP_POP(party->create), HP_POP2(HP_party_create), 3286 }, - { HP_POP(party->created), HP_POP2(HP_party_created), 3288 }, - { HP_POP(party->request_info), HP_POP2(HP_party_request_info), 3290 }, - { HP_POP(party->invite), HP_POP2(HP_party_invite), 3292 }, - { HP_POP(party->member_joined), HP_POP2(HP_party_member_joined), 3294 }, - { HP_POP(party->member_added), HP_POP2(HP_party_member_added), 3296 }, - { HP_POP(party->leave), HP_POP2(HP_party_leave), 3298 }, - { HP_POP(party->removemember), HP_POP2(HP_party_removemember), 3300 }, - { HP_POP(party->member_withdraw), HP_POP2(HP_party_member_withdraw), 3302 }, - { HP_POP(party->reply_invite), HP_POP2(HP_party_reply_invite), 3304 }, - { HP_POP(party->recv_noinfo), HP_POP2(HP_party_recv_noinfo), 3306 }, - { HP_POP(party->recv_info), HP_POP2(HP_party_recv_info), 3308 }, - { HP_POP(party->recv_movemap), HP_POP2(HP_party_recv_movemap), 3310 }, - { HP_POP(party->broken), HP_POP2(HP_party_broken), 3312 }, - { HP_POP(party->optionchanged), HP_POP2(HP_party_optionchanged), 3314 }, - { HP_POP(party->changeoption), HP_POP2(HP_party_changeoption), 3316 }, - { HP_POP(party->changeleader), HP_POP2(HP_party_changeleader), 3318 }, - { HP_POP(party->send_movemap), HP_POP2(HP_party_send_movemap), 3320 }, - { HP_POP(party->send_levelup), HP_POP2(HP_party_send_levelup), 3322 }, - { HP_POP(party->send_logout), HP_POP2(HP_party_send_logout), 3324 }, - { HP_POP(party->send_message), HP_POP2(HP_party_send_message), 3326 }, - { HP_POP(party->recv_message), HP_POP2(HP_party_recv_message), 3328 }, - { HP_POP(party->skill_check), HP_POP2(HP_party_skill_check), 3330 }, - { HP_POP(party->send_xy_clear), HP_POP2(HP_party_send_xy_clear), 3332 }, - { HP_POP(party->exp_share), HP_POP2(HP_party_exp_share), 3334 }, - { HP_POP(party->share_loot), HP_POP2(HP_party_share_loot), 3336 }, - { HP_POP(party->send_dot_remove), HP_POP2(HP_party_send_dot_remove), 3338 }, - { HP_POP(party->sub_count), HP_POP2(HP_party_sub_count), 3340 }, - { HP_POP(party->booking_register), HP_POP2(HP_party_booking_register), 3342 }, - { HP_POP(party->booking_update), HP_POP2(HP_party_booking_update), 3344 }, - { HP_POP(party->booking_search), HP_POP2(HP_party_booking_search), 3346 }, - { HP_POP(party->recruit_register), HP_POP2(HP_party_recruit_register), 3348 }, - { HP_POP(party->recruit_update), HP_POP2(HP_party_recruit_update), 3350 }, - { HP_POP(party->recruit_search), HP_POP2(HP_party_recruit_search), 3352 }, - { HP_POP(party->booking_delete), HP_POP2(HP_party_booking_delete), 3354 }, - { HP_POP(party->vforeachsamemap), HP_POP2(HP_party_vforeachsamemap), 3356 }, - { HP_POP(party->send_xy_timer), HP_POP2(HP_party_send_xy_timer), 3358 }, - { HP_POP(party->fill_member), HP_POP2(HP_party_fill_member), 3360 }, - { HP_POP(party->sd_check), HP_POP2(HP_party_sd_check), 3362 }, - { HP_POP(party->check_state), HP_POP2(HP_party_check_state), 3364 }, - { HP_POP(party->create_booking_data), HP_POP2(HP_party_create_booking_data), 3366 }, - { HP_POP(party->db_final), HP_POP2(HP_party_db_final), 3368 }, + { HP_POP(party->init, HP_party_init) }, + { HP_POP(party->final, HP_party_final) }, + { HP_POP(party->search, HP_party_search) }, + { HP_POP(party->searchname, HP_party_searchname) }, + { HP_POP(party->getmemberid, HP_party_getmemberid) }, + { HP_POP(party->getavailablesd, HP_party_getavailablesd) }, + { HP_POP(party->create, HP_party_create) }, + { HP_POP(party->created, HP_party_created) }, + { HP_POP(party->request_info, HP_party_request_info) }, + { HP_POP(party->invite, HP_party_invite) }, + { HP_POP(party->member_joined, HP_party_member_joined) }, + { HP_POP(party->member_added, HP_party_member_added) }, + { HP_POP(party->leave, HP_party_leave) }, + { HP_POP(party->removemember, HP_party_removemember) }, + { HP_POP(party->member_withdraw, HP_party_member_withdraw) }, + { HP_POP(party->reply_invite, HP_party_reply_invite) }, + { HP_POP(party->recv_noinfo, HP_party_recv_noinfo) }, + { HP_POP(party->recv_info, HP_party_recv_info) }, + { HP_POP(party->recv_movemap, HP_party_recv_movemap) }, + { HP_POP(party->broken, HP_party_broken) }, + { HP_POP(party->optionchanged, HP_party_optionchanged) }, + { HP_POP(party->changeoption, HP_party_changeoption) }, + { HP_POP(party->changeleader, HP_party_changeleader) }, + { HP_POP(party->send_movemap, HP_party_send_movemap) }, + { HP_POP(party->send_levelup, HP_party_send_levelup) }, + { HP_POP(party->send_logout, HP_party_send_logout) }, + { HP_POP(party->send_message, HP_party_send_message) }, + { HP_POP(party->recv_message, HP_party_recv_message) }, + { HP_POP(party->skill_check, HP_party_skill_check) }, + { HP_POP(party->send_xy_clear, HP_party_send_xy_clear) }, + { HP_POP(party->exp_share, HP_party_exp_share) }, + { HP_POP(party->share_loot, HP_party_share_loot) }, + { HP_POP(party->send_dot_remove, HP_party_send_dot_remove) }, + { HP_POP(party->sub_count, HP_party_sub_count) }, + { HP_POP(party->sub_count_chorus, HP_party_sub_count_chorus) }, + { HP_POP(party->booking_register, HP_party_booking_register) }, + { HP_POP(party->booking_update, HP_party_booking_update) }, + { HP_POP(party->booking_search, HP_party_booking_search) }, + { HP_POP(party->recruit_register, HP_party_recruit_register) }, + { HP_POP(party->recruit_update, HP_party_recruit_update) }, + { HP_POP(party->recruit_search, HP_party_recruit_search) }, + { HP_POP(party->booking_delete, HP_party_booking_delete) }, + { HP_POP(party->vforeachsamemap, HP_party_vforeachsamemap) }, + { HP_POP(party->send_xy_timer, HP_party_send_xy_timer) }, + { HP_POP(party->fill_member, HP_party_fill_member) }, + { HP_POP(party->sd_check, HP_party_sd_check) }, + { HP_POP(party->check_state, HP_party_check_state) }, + { HP_POP(party->create_booking_data, HP_party_create_booking_data) }, + { HP_POP(party->db_final, HP_party_db_final) }, /* path */ - { HP_POP(path->blownpos), HP_POP2(HP_path_blownpos), 3370 }, - { HP_POP(path->search), HP_POP2(HP_path_search), 3372 }, - { HP_POP(path->search_long), HP_POP2(HP_path_search_long), 3374 }, - { HP_POP(path->check_distance), HP_POP2(HP_path_check_distance), 3376 }, - { HP_POP(path->distance), HP_POP2(HP_path_distance), 3378 }, + { HP_POP(path->blownpos, HP_path_blownpos) }, + { HP_POP(path->search, HP_path_search) }, + { HP_POP(path->search_long, HP_path_search_long) }, + { HP_POP(path->check_distance, HP_path_check_distance) }, + { HP_POP(path->distance, HP_path_distance) }, +/* pcg */ + { HP_POP(pcg->init, HP_pcg_init) }, + { HP_POP(pcg->final, HP_pcg_final) }, + { HP_POP(pcg->reload, HP_pcg_reload) }, + { HP_POP(pcg->get_dummy_group, HP_pcg_get_dummy_group) }, + { HP_POP(pcg->exists, HP_pcg_exists) }, + { HP_POP(pcg->id2group, HP_pcg_id2group) }, + { HP_POP(pcg->has_permission, HP_pcg_has_permission) }, + { HP_POP(pcg->should_log_commands, HP_pcg_should_log_commands) }, + { HP_POP(pcg->get_name, HP_pcg_get_name) }, + { HP_POP(pcg->get_level, HP_pcg_get_level) }, + { HP_POP(pcg->get_idx, HP_pcg_get_idx) }, /* pc */ - { HP_POP(pc->init), HP_POP2(HP_pc_init), 3380 }, - { HP_POP(pc->final), HP_POP2(HP_pc_final), 3382 }, - { HP_POP(pc->get_dummy_sd), HP_POP2(HP_pc_get_dummy_sd), 3384 }, - { HP_POP(pc->class2idx), HP_POP2(HP_pc_class2idx), 3386 }, - { HP_POP(pc->get_group_level), HP_POP2(HP_pc_get_group_level), 3388 }, - { HP_POP(pc->can_give_items), HP_POP2(HP_pc_can_give_items), 3390 }, - { HP_POP(pc->can_use_command), HP_POP2(HP_pc_can_use_command), 3392 }, - { HP_POP(pc->has_permission), HP_POP2(HP_pc_has_permission), 3394 }, - { HP_POP(pc->set_group), HP_POP2(HP_pc_set_group), 3396 }, - { HP_POP(pc->should_log_commands), HP_POP2(HP_pc_should_log_commands), 3398 }, - { HP_POP(pc->setrestartvalue), HP_POP2(HP_pc_setrestartvalue), 3400 }, - { HP_POP(pc->makesavestatus), HP_POP2(HP_pc_makesavestatus), 3402 }, - { HP_POP(pc->respawn), HP_POP2(HP_pc_respawn), 3404 }, - { HP_POP(pc->setnewpc), HP_POP2(HP_pc_setnewpc), 3406 }, - { HP_POP(pc->authok), HP_POP2(HP_pc_authok), 3408 }, - { HP_POP(pc->authfail), HP_POP2(HP_pc_authfail), 3410 }, - { HP_POP(pc->reg_received), HP_POP2(HP_pc_reg_received), 3412 }, - { HP_POP(pc->isequip), HP_POP2(HP_pc_isequip), 3414 }, - { HP_POP(pc->equippoint), HP_POP2(HP_pc_equippoint), 3416 }, - { HP_POP(pc->setinventorydata), HP_POP2(HP_pc_setinventorydata), 3418 }, - { HP_POP(pc->checkskill), HP_POP2(HP_pc_checkskill), 3420 }, - { HP_POP(pc->checkskill2), HP_POP2(HP_pc_checkskill2), 3422 }, - { HP_POP(pc->checkallowskill), HP_POP2(HP_pc_checkallowskill), 3424 }, - { HP_POP(pc->checkequip), HP_POP2(HP_pc_checkequip), 3426 }, - { HP_POP(pc->calc_skilltree), HP_POP2(HP_pc_calc_skilltree), 3428 }, - { HP_POP(pc->calc_skilltree_normalize_job), HP_POP2(HP_pc_calc_skilltree_normalize_job), 3430 }, - { HP_POP(pc->clean_skilltree), HP_POP2(HP_pc_clean_skilltree), 3432 }, - { HP_POP(pc->setpos), HP_POP2(HP_pc_setpos), 3434 }, - { HP_POP(pc->setsavepoint), HP_POP2(HP_pc_setsavepoint), 3436 }, - { HP_POP(pc->randomwarp), HP_POP2(HP_pc_randomwarp), 3438 }, - { HP_POP(pc->memo), HP_POP2(HP_pc_memo), 3440 }, - { HP_POP(pc->checkadditem), HP_POP2(HP_pc_checkadditem), 3442 }, - { HP_POP(pc->inventoryblank), HP_POP2(HP_pc_inventoryblank), 3444 }, - { HP_POP(pc->search_inventory), HP_POP2(HP_pc_search_inventory), 3446 }, - { HP_POP(pc->payzeny), HP_POP2(HP_pc_payzeny), 3448 }, - { HP_POP(pc->additem), HP_POP2(HP_pc_additem), 3450 }, - { HP_POP(pc->getzeny), HP_POP2(HP_pc_getzeny), 3452 }, - { HP_POP(pc->delitem), HP_POP2(HP_pc_delitem), 3454 }, - { HP_POP(pc->paycash), HP_POP2(HP_pc_paycash), 3456 }, - { HP_POP(pc->getcash), HP_POP2(HP_pc_getcash), 3458 }, - { HP_POP(pc->cart_additem), HP_POP2(HP_pc_cart_additem), 3460 }, - { HP_POP(pc->cart_delitem), HP_POP2(HP_pc_cart_delitem), 3462 }, - { HP_POP(pc->putitemtocart), HP_POP2(HP_pc_putitemtocart), 3464 }, - { HP_POP(pc->getitemfromcart), HP_POP2(HP_pc_getitemfromcart), 3466 }, - { HP_POP(pc->cartitem_amount), HP_POP2(HP_pc_cartitem_amount), 3468 }, - { HP_POP(pc->takeitem), HP_POP2(HP_pc_takeitem), 3470 }, - { HP_POP(pc->dropitem), HP_POP2(HP_pc_dropitem), 3472 }, - { HP_POP(pc->isequipped), HP_POP2(HP_pc_isequipped), 3474 }, - { HP_POP(pc->can_Adopt), HP_POP2(HP_pc_can_Adopt), 3476 }, - { HP_POP(pc->adoption), HP_POP2(HP_pc_adoption), 3478 }, - { HP_POP(pc->updateweightstatus), HP_POP2(HP_pc_updateweightstatus), 3480 }, - { HP_POP(pc->addautobonus), HP_POP2(HP_pc_addautobonus), 3482 }, - { HP_POP(pc->exeautobonus), HP_POP2(HP_pc_exeautobonus), 3484 }, - { HP_POP(pc->endautobonus), HP_POP2(HP_pc_endautobonus), 3486 }, - { HP_POP(pc->delautobonus), HP_POP2(HP_pc_delautobonus), 3488 }, - { HP_POP(pc->bonus), HP_POP2(HP_pc_bonus), 3490 }, - { HP_POP(pc->bonus2), HP_POP2(HP_pc_bonus2), 3492 }, - { HP_POP(pc->bonus3), HP_POP2(HP_pc_bonus3), 3494 }, - { HP_POP(pc->bonus4), HP_POP2(HP_pc_bonus4), 3496 }, - { HP_POP(pc->bonus5), HP_POP2(HP_pc_bonus5), 3498 }, - { HP_POP(pc->skill), HP_POP2(HP_pc_skill), 3500 }, - { HP_POP(pc->insert_card), HP_POP2(HP_pc_insert_card), 3502 }, - { HP_POP(pc->steal_item), HP_POP2(HP_pc_steal_item), 3504 }, - { HP_POP(pc->steal_coin), HP_POP2(HP_pc_steal_coin), 3506 }, - { HP_POP(pc->modifybuyvalue), HP_POP2(HP_pc_modifybuyvalue), 3508 }, - { HP_POP(pc->modifysellvalue), HP_POP2(HP_pc_modifysellvalue), 3510 }, - { HP_POP(pc->follow), HP_POP2(HP_pc_follow), 3512 }, - { HP_POP(pc->stop_following), HP_POP2(HP_pc_stop_following), 3514 }, - { HP_POP(pc->maxbaselv), HP_POP2(HP_pc_maxbaselv), 3516 }, - { HP_POP(pc->maxjoblv), HP_POP2(HP_pc_maxjoblv), 3518 }, - { HP_POP(pc->checkbaselevelup), HP_POP2(HP_pc_checkbaselevelup), 3520 }, - { HP_POP(pc->checkjoblevelup), HP_POP2(HP_pc_checkjoblevelup), 3522 }, - { HP_POP(pc->gainexp), HP_POP2(HP_pc_gainexp), 3524 }, - { HP_POP(pc->nextbaseexp), HP_POP2(HP_pc_nextbaseexp), 3526 }, - { HP_POP(pc->thisbaseexp), HP_POP2(HP_pc_thisbaseexp), 3528 }, - { HP_POP(pc->nextjobexp), HP_POP2(HP_pc_nextjobexp), 3530 }, - { HP_POP(pc->thisjobexp), HP_POP2(HP_pc_thisjobexp), 3532 }, - { HP_POP(pc->gets_status_point), HP_POP2(HP_pc_gets_status_point), 3534 }, - { HP_POP(pc->need_status_point), HP_POP2(HP_pc_need_status_point), 3536 }, - { HP_POP(pc->statusup), HP_POP2(HP_pc_statusup), 3538 }, - { HP_POP(pc->statusup2), HP_POP2(HP_pc_statusup2), 3540 }, - { HP_POP(pc->skillup), HP_POP2(HP_pc_skillup), 3542 }, - { HP_POP(pc->allskillup), HP_POP2(HP_pc_allskillup), 3544 }, - { HP_POP(pc->resetlvl), HP_POP2(HP_pc_resetlvl), 3546 }, - { HP_POP(pc->resetstate), HP_POP2(HP_pc_resetstate), 3548 }, - { HP_POP(pc->resetskill), HP_POP2(HP_pc_resetskill), 3550 }, - { HP_POP(pc->resetfeel), HP_POP2(HP_pc_resetfeel), 3552 }, - { HP_POP(pc->resethate), HP_POP2(HP_pc_resethate), 3554 }, - { HP_POP(pc->equipitem), HP_POP2(HP_pc_equipitem), 3556 }, - { HP_POP(pc->unequipitem), HP_POP2(HP_pc_unequipitem), 3558 }, - { HP_POP(pc->checkitem), HP_POP2(HP_pc_checkitem), 3560 }, - { HP_POP(pc->useitem), HP_POP2(HP_pc_useitem), 3562 }, - { HP_POP(pc->skillatk_bonus), HP_POP2(HP_pc_skillatk_bonus), 3564 }, - { HP_POP(pc->skillheal_bonus), HP_POP2(HP_pc_skillheal_bonus), 3566 }, - { HP_POP(pc->skillheal2_bonus), HP_POP2(HP_pc_skillheal2_bonus), 3568 }, - { HP_POP(pc->damage), HP_POP2(HP_pc_damage), 3570 }, - { HP_POP(pc->dead), HP_POP2(HP_pc_dead), 3572 }, - { HP_POP(pc->revive), HP_POP2(HP_pc_revive), 3574 }, - { HP_POP(pc->heal), HP_POP2(HP_pc_heal), 3576 }, - { HP_POP(pc->itemheal), HP_POP2(HP_pc_itemheal), 3578 }, - { HP_POP(pc->percentheal), HP_POP2(HP_pc_percentheal), 3580 }, - { HP_POP(pc->jobchange), HP_POP2(HP_pc_jobchange), 3582 }, - { HP_POP(pc->setoption), HP_POP2(HP_pc_setoption), 3584 }, - { HP_POP(pc->setcart), HP_POP2(HP_pc_setcart), 3586 }, - { HP_POP(pc->setfalcon), HP_POP2(HP_pc_setfalcon), 3588 }, - { HP_POP(pc->setriding), HP_POP2(HP_pc_setriding), 3590 }, - { HP_POP(pc->setmadogear), HP_POP2(HP_pc_setmadogear), 3592 }, - { HP_POP(pc->changelook), HP_POP2(HP_pc_changelook), 3594 }, - { HP_POP(pc->equiplookall), HP_POP2(HP_pc_equiplookall), 3596 }, - { HP_POP(pc->readparam), HP_POP2(HP_pc_readparam), 3598 }, - { HP_POP(pc->setparam), HP_POP2(HP_pc_setparam), 3600 }, - { HP_POP(pc->readreg), HP_POP2(HP_pc_readreg), 3602 }, - { HP_POP(pc->setreg), HP_POP2(HP_pc_setreg), 3604 }, - { HP_POP(pc->readregstr), HP_POP2(HP_pc_readregstr), 3606 }, - { HP_POP(pc->setregstr), HP_POP2(HP_pc_setregstr), 3608 }, - { HP_POP(pc->readregistry), HP_POP2(HP_pc_readregistry), 3610 }, - { HP_POP(pc->setregistry), HP_POP2(HP_pc_setregistry), 3612 }, - { HP_POP(pc->readregistry_str), HP_POP2(HP_pc_readregistry_str), 3614 }, - { HP_POP(pc->setregistry_str), HP_POP2(HP_pc_setregistry_str), 3616 }, - { HP_POP(pc->addeventtimer), HP_POP2(HP_pc_addeventtimer), 3618 }, - { HP_POP(pc->deleventtimer), HP_POP2(HP_pc_deleventtimer), 3620 }, - { HP_POP(pc->cleareventtimer), HP_POP2(HP_pc_cleareventtimer), 3622 }, - { HP_POP(pc->addeventtimercount), HP_POP2(HP_pc_addeventtimercount), 3624 }, - { HP_POP(pc->calc_pvprank), HP_POP2(HP_pc_calc_pvprank), 3626 }, - { HP_POP(pc->calc_pvprank_timer), HP_POP2(HP_pc_calc_pvprank_timer), 3628 }, - { HP_POP(pc->ismarried), HP_POP2(HP_pc_ismarried), 3630 }, - { HP_POP(pc->marriage), HP_POP2(HP_pc_marriage), 3632 }, - { HP_POP(pc->divorce), HP_POP2(HP_pc_divorce), 3634 }, - { HP_POP(pc->get_partner), HP_POP2(HP_pc_get_partner), 3636 }, - { HP_POP(pc->get_father), HP_POP2(HP_pc_get_father), 3638 }, - { HP_POP(pc->get_mother), HP_POP2(HP_pc_get_mother), 3640 }, - { HP_POP(pc->get_child), HP_POP2(HP_pc_get_child), 3642 }, - { HP_POP(pc->bleeding), HP_POP2(HP_pc_bleeding), 3644 }, - { HP_POP(pc->regen), HP_POP2(HP_pc_regen), 3646 }, - { HP_POP(pc->setstand), HP_POP2(HP_pc_setstand), 3648 }, - { HP_POP(pc->candrop), HP_POP2(HP_pc_candrop), 3650 }, - { HP_POP(pc->jobid2mapid), HP_POP2(HP_pc_jobid2mapid), 3652 }, - { HP_POP(pc->mapid2jobid), HP_POP2(HP_pc_mapid2jobid), 3654 }, - { HP_POP(pc->job_name), HP_POP2(HP_pc_job_name), 3656 }, - { HP_POP(pc->setinvincibletimer), HP_POP2(HP_pc_setinvincibletimer), 3658 }, - { HP_POP(pc->delinvincibletimer), HP_POP2(HP_pc_delinvincibletimer), 3660 }, - { HP_POP(pc->addspiritball), HP_POP2(HP_pc_addspiritball), 3662 }, - { HP_POP(pc->delspiritball), HP_POP2(HP_pc_delspiritball), 3664 }, - { HP_POP(pc->addfame), HP_POP2(HP_pc_addfame), 3666 }, - { HP_POP(pc->famerank), HP_POP2(HP_pc_famerank), 3668 }, - { HP_POP(pc->set_hate_mob), HP_POP2(HP_pc_set_hate_mob), 3670 }, - { HP_POP(pc->readdb), HP_POP2(HP_pc_readdb), 3672 }, - { HP_POP(pc->map_day_timer), HP_POP2(HP_pc_map_day_timer), 3674 }, - { HP_POP(pc->map_night_timer), HP_POP2(HP_pc_map_night_timer), 3676 }, - { HP_POP(pc->inventory_rentals), HP_POP2(HP_pc_inventory_rentals), 3678 }, - { HP_POP(pc->inventory_rental_clear), HP_POP2(HP_pc_inventory_rental_clear), 3680 }, - { HP_POP(pc->inventory_rental_add), HP_POP2(HP_pc_inventory_rental_add), 3682 }, - { HP_POP(pc->disguise), HP_POP2(HP_pc_disguise), 3684 }, - { HP_POP(pc->isautolooting), HP_POP2(HP_pc_isautolooting), 3686 }, - { HP_POP(pc->overheat), HP_POP2(HP_pc_overheat), 3688 }, - { HP_POP(pc->banding), HP_POP2(HP_pc_banding), 3690 }, - { HP_POP(pc->itemcd_do), HP_POP2(HP_pc_itemcd_do), 3692 }, - { HP_POP(pc->load_combo), HP_POP2(HP_pc_load_combo), 3694 }, - { HP_POP(pc->add_charm), HP_POP2(HP_pc_add_charm), 3696 }, - { HP_POP(pc->del_charm), HP_POP2(HP_pc_del_charm), 3698 }, - { HP_POP(pc->baselevelchanged), HP_POP2(HP_pc_baselevelchanged), 3700 }, - { HP_POP(pc->level_penalty_mod), HP_POP2(HP_pc_level_penalty_mod), 3702 }, - { HP_POP(pc->calc_skillpoint), HP_POP2(HP_pc_calc_skillpoint), 3704 }, - { HP_POP(pc->invincible_timer), HP_POP2(HP_pc_invincible_timer), 3706 }, - { HP_POP(pc->spiritball_timer), HP_POP2(HP_pc_spiritball_timer), 3708 }, - { HP_POP(pc->check_banding), HP_POP2(HP_pc_check_banding), 3710 }, - { HP_POP(pc->inventory_rental_end), HP_POP2(HP_pc_inventory_rental_end), 3712 }, - { HP_POP(pc->check_skilltree), HP_POP2(HP_pc_check_skilltree), 3714 }, - { HP_POP(pc->bonus_autospell), HP_POP2(HP_pc_bonus_autospell), 3716 }, - { HP_POP(pc->bonus_autospell_onskill), HP_POP2(HP_pc_bonus_autospell_onskill), 3718 }, - { HP_POP(pc->bonus_addeff), HP_POP2(HP_pc_bonus_addeff), 3720 }, - { HP_POP(pc->bonus_addeff_onskill), HP_POP2(HP_pc_bonus_addeff_onskill), 3722 }, - { HP_POP(pc->bonus_item_drop), HP_POP2(HP_pc_bonus_item_drop), 3724 }, - { HP_POP(pc->calcexp), HP_POP2(HP_pc_calcexp), 3726 }, - { HP_POP(pc->respawn_timer), HP_POP2(HP_pc_respawn_timer), 3728 }, - { HP_POP(pc->jobchange_killclone), HP_POP2(HP_pc_jobchange_killclone), 3730 }, - { HP_POP(pc->getstat), HP_POP2(HP_pc_getstat), 3732 }, - { HP_POP(pc->setstat), HP_POP2(HP_pc_setstat), 3734 }, - { HP_POP(pc->eventtimer), HP_POP2(HP_pc_eventtimer), 3736 }, - { HP_POP(pc->daynight_timer_sub), HP_POP2(HP_pc_daynight_timer_sub), 3738 }, - { HP_POP(pc->charm_timer), HP_POP2(HP_pc_charm_timer), 3740 }, - { HP_POP(pc->readdb_levelpenalty), HP_POP2(HP_pc_readdb_levelpenalty), 3742 }, - { HP_POP(pc->autosave), HP_POP2(HP_pc_autosave), 3744 }, - { HP_POP(pc->follow_timer), HP_POP2(HP_pc_follow_timer), 3746 }, - { HP_POP(pc->read_skill_tree), HP_POP2(HP_pc_read_skill_tree), 3748 }, - { HP_POP(pc->isUseitem), HP_POP2(HP_pc_isUseitem), 3750 }, - { HP_POP(pc->show_steal), HP_POP2(HP_pc_show_steal), 3752 }, - { HP_POP(pc->checkcombo), HP_POP2(HP_pc_checkcombo), 3754 }, - { HP_POP(pc->calcweapontype), HP_POP2(HP_pc_calcweapontype), 3756 }, - { HP_POP(pc->removecombo), HP_POP2(HP_pc_removecombo), 3758 }, + { HP_POP(pc->init, HP_pc_init) }, + { HP_POP(pc->final, HP_pc_final) }, + { HP_POP(pc->get_dummy_sd, HP_pc_get_dummy_sd) }, + { HP_POP(pc->class2idx, HP_pc_class2idx) }, + { HP_POP(pc->can_give_items, HP_pc_can_give_items) }, + { HP_POP(pc->can_give_bound_items, HP_pc_can_give_bound_items) }, + { HP_POP(pc->can_use_command, HP_pc_can_use_command) }, + { HP_POP(pc->set_group, HP_pc_set_group) }, + { HP_POP(pc->should_log_commands, HP_pc_should_log_commands) }, + { HP_POP(pc->setrestartvalue, HP_pc_setrestartvalue) }, + { HP_POP(pc->makesavestatus, HP_pc_makesavestatus) }, + { HP_POP(pc->respawn, HP_pc_respawn) }, + { HP_POP(pc->setnewpc, HP_pc_setnewpc) }, + { HP_POP(pc->authok, HP_pc_authok) }, + { HP_POP(pc->authfail, HP_pc_authfail) }, + { HP_POP(pc->reg_received, HP_pc_reg_received) }, + { HP_POP(pc->isequip, HP_pc_isequip) }, + { HP_POP(pc->equippoint, HP_pc_equippoint) }, + { HP_POP(pc->setinventorydata, HP_pc_setinventorydata) }, + { HP_POP(pc->checkskill, HP_pc_checkskill) }, + { HP_POP(pc->checkskill2, HP_pc_checkskill2) }, + { HP_POP(pc->checkallowskill, HP_pc_checkallowskill) }, + { HP_POP(pc->checkequip, HP_pc_checkequip) }, + { HP_POP(pc->calc_skilltree, HP_pc_calc_skilltree) }, + { HP_POP(pc->calc_skilltree_normalize_job, HP_pc_calc_skilltree_normalize_job) }, + { HP_POP(pc->clean_skilltree, HP_pc_clean_skilltree) }, + { HP_POP(pc->setpos, HP_pc_setpos) }, + { HP_POP(pc->setsavepoint, HP_pc_setsavepoint) }, + { HP_POP(pc->randomwarp, HP_pc_randomwarp) }, + { HP_POP(pc->memo, HP_pc_memo) }, + { HP_POP(pc->checkadditem, HP_pc_checkadditem) }, + { HP_POP(pc->inventoryblank, HP_pc_inventoryblank) }, + { HP_POP(pc->search_inventory, HP_pc_search_inventory) }, + { HP_POP(pc->payzeny, HP_pc_payzeny) }, + { HP_POP(pc->additem, HP_pc_additem) }, + { HP_POP(pc->getzeny, HP_pc_getzeny) }, + { HP_POP(pc->delitem, HP_pc_delitem) }, + { HP_POP(pc->paycash, HP_pc_paycash) }, + { HP_POP(pc->getcash, HP_pc_getcash) }, + { HP_POP(pc->cart_additem, HP_pc_cart_additem) }, + { HP_POP(pc->cart_delitem, HP_pc_cart_delitem) }, + { HP_POP(pc->putitemtocart, HP_pc_putitemtocart) }, + { HP_POP(pc->getitemfromcart, HP_pc_getitemfromcart) }, + { HP_POP(pc->cartitem_amount, HP_pc_cartitem_amount) }, + { HP_POP(pc->takeitem, HP_pc_takeitem) }, + { HP_POP(pc->dropitem, HP_pc_dropitem) }, + { HP_POP(pc->isequipped, HP_pc_isequipped) }, + { HP_POP(pc->can_Adopt, HP_pc_can_Adopt) }, + { HP_POP(pc->adoption, HP_pc_adoption) }, + { HP_POP(pc->updateweightstatus, HP_pc_updateweightstatus) }, + { HP_POP(pc->addautobonus, HP_pc_addautobonus) }, + { HP_POP(pc->exeautobonus, HP_pc_exeautobonus) }, + { HP_POP(pc->endautobonus, HP_pc_endautobonus) }, + { HP_POP(pc->delautobonus, HP_pc_delautobonus) }, + { HP_POP(pc->bonus, HP_pc_bonus) }, + { HP_POP(pc->bonus2, HP_pc_bonus2) }, + { HP_POP(pc->bonus3, HP_pc_bonus3) }, + { HP_POP(pc->bonus4, HP_pc_bonus4) }, + { HP_POP(pc->bonus5, HP_pc_bonus5) }, + { HP_POP(pc->skill, HP_pc_skill) }, + { HP_POP(pc->insert_card, HP_pc_insert_card) }, + { HP_POP(pc->steal_item, HP_pc_steal_item) }, + { HP_POP(pc->steal_coin, HP_pc_steal_coin) }, + { HP_POP(pc->modifybuyvalue, HP_pc_modifybuyvalue) }, + { HP_POP(pc->modifysellvalue, HP_pc_modifysellvalue) }, + { HP_POP(pc->follow, HP_pc_follow) }, + { HP_POP(pc->stop_following, HP_pc_stop_following) }, + { HP_POP(pc->maxbaselv, HP_pc_maxbaselv) }, + { HP_POP(pc->maxjoblv, HP_pc_maxjoblv) }, + { HP_POP(pc->checkbaselevelup, HP_pc_checkbaselevelup) }, + { HP_POP(pc->checkjoblevelup, HP_pc_checkjoblevelup) }, + { HP_POP(pc->gainexp, HP_pc_gainexp) }, + { HP_POP(pc->nextbaseexp, HP_pc_nextbaseexp) }, + { HP_POP(pc->thisbaseexp, HP_pc_thisbaseexp) }, + { HP_POP(pc->nextjobexp, HP_pc_nextjobexp) }, + { HP_POP(pc->thisjobexp, HP_pc_thisjobexp) }, + { HP_POP(pc->gets_status_point, HP_pc_gets_status_point) }, + { HP_POP(pc->need_status_point, HP_pc_need_status_point) }, + { HP_POP(pc->maxparameterincrease, HP_pc_maxparameterincrease) }, + { HP_POP(pc->statusup, HP_pc_statusup) }, + { HP_POP(pc->statusup2, HP_pc_statusup2) }, + { HP_POP(pc->skillup, HP_pc_skillup) }, + { HP_POP(pc->allskillup, HP_pc_allskillup) }, + { HP_POP(pc->resetlvl, HP_pc_resetlvl) }, + { HP_POP(pc->resetstate, HP_pc_resetstate) }, + { HP_POP(pc->resetskill, HP_pc_resetskill) }, + { HP_POP(pc->resetfeel, HP_pc_resetfeel) }, + { HP_POP(pc->resethate, HP_pc_resethate) }, + { HP_POP(pc->equipitem, HP_pc_equipitem) }, + { HP_POP(pc->unequipitem, HP_pc_unequipitem) }, + { HP_POP(pc->checkitem, HP_pc_checkitem) }, + { HP_POP(pc->useitem, HP_pc_useitem) }, + { HP_POP(pc->skillatk_bonus, HP_pc_skillatk_bonus) }, + { HP_POP(pc->skillheal_bonus, HP_pc_skillheal_bonus) }, + { HP_POP(pc->skillheal2_bonus, HP_pc_skillheal2_bonus) }, + { HP_POP(pc->damage, HP_pc_damage) }, + { HP_POP(pc->dead, HP_pc_dead) }, + { HP_POP(pc->revive, HP_pc_revive) }, + { HP_POP(pc->heal, HP_pc_heal) }, + { HP_POP(pc->itemheal, HP_pc_itemheal) }, + { HP_POP(pc->percentheal, HP_pc_percentheal) }, + { HP_POP(pc->jobchange, HP_pc_jobchange) }, + { HP_POP(pc->setoption, HP_pc_setoption) }, + { HP_POP(pc->setcart, HP_pc_setcart) }, + { HP_POP(pc->setfalcon, HP_pc_setfalcon) }, + { HP_POP(pc->setriding, HP_pc_setriding) }, + { HP_POP(pc->setmadogear, HP_pc_setmadogear) }, + { HP_POP(pc->changelook, HP_pc_changelook) }, + { HP_POP(pc->equiplookall, HP_pc_equiplookall) }, + { HP_POP(pc->readparam, HP_pc_readparam) }, + { HP_POP(pc->setparam, HP_pc_setparam) }, + { HP_POP(pc->readreg, HP_pc_readreg) }, + { HP_POP(pc->setreg, HP_pc_setreg) }, + { HP_POP(pc->readregstr, HP_pc_readregstr) }, + { HP_POP(pc->setregstr, HP_pc_setregstr) }, + { HP_POP(pc->readregistry, HP_pc_readregistry) }, + { HP_POP(pc->setregistry, HP_pc_setregistry) }, + { HP_POP(pc->readregistry_str, HP_pc_readregistry_str) }, + { HP_POP(pc->setregistry_str, HP_pc_setregistry_str) }, + { HP_POP(pc->addeventtimer, HP_pc_addeventtimer) }, + { HP_POP(pc->deleventtimer, HP_pc_deleventtimer) }, + { HP_POP(pc->cleareventtimer, HP_pc_cleareventtimer) }, + { HP_POP(pc->addeventtimercount, HP_pc_addeventtimercount) }, + { HP_POP(pc->calc_pvprank, HP_pc_calc_pvprank) }, + { HP_POP(pc->calc_pvprank_timer, HP_pc_calc_pvprank_timer) }, + { HP_POP(pc->ismarried, HP_pc_ismarried) }, + { HP_POP(pc->marriage, HP_pc_marriage) }, + { HP_POP(pc->divorce, HP_pc_divorce) }, + { HP_POP(pc->get_partner, HP_pc_get_partner) }, + { HP_POP(pc->get_father, HP_pc_get_father) }, + { HP_POP(pc->get_mother, HP_pc_get_mother) }, + { HP_POP(pc->get_child, HP_pc_get_child) }, + { HP_POP(pc->bleeding, HP_pc_bleeding) }, + { HP_POP(pc->regen, HP_pc_regen) }, + { HP_POP(pc->setstand, HP_pc_setstand) }, + { HP_POP(pc->candrop, HP_pc_candrop) }, + { HP_POP(pc->jobid2mapid, HP_pc_jobid2mapid) }, + { HP_POP(pc->mapid2jobid, HP_pc_mapid2jobid) }, + { HP_POP(pc->job_name, HP_pc_job_name) }, + { HP_POP(pc->setinvincibletimer, HP_pc_setinvincibletimer) }, + { HP_POP(pc->delinvincibletimer, HP_pc_delinvincibletimer) }, + { HP_POP(pc->addspiritball, HP_pc_addspiritball) }, + { HP_POP(pc->delspiritball, HP_pc_delspiritball) }, + { HP_POP(pc->addfame, HP_pc_addfame) }, + { HP_POP(pc->famerank, HP_pc_famerank) }, + { HP_POP(pc->set_hate_mob, HP_pc_set_hate_mob) }, + { HP_POP(pc->readdb, HP_pc_readdb) }, + { HP_POP(pc->map_day_timer, HP_pc_map_day_timer) }, + { HP_POP(pc->map_night_timer, HP_pc_map_night_timer) }, + { HP_POP(pc->inventory_rentals, HP_pc_inventory_rentals) }, + { HP_POP(pc->inventory_rental_clear, HP_pc_inventory_rental_clear) }, + { HP_POP(pc->inventory_rental_add, HP_pc_inventory_rental_add) }, + { HP_POP(pc->disguise, HP_pc_disguise) }, + { HP_POP(pc->isautolooting, HP_pc_isautolooting) }, + { HP_POP(pc->overheat, HP_pc_overheat) }, + { HP_POP(pc->banding, HP_pc_banding) }, + { HP_POP(pc->itemcd_do, HP_pc_itemcd_do) }, + { HP_POP(pc->load_combo, HP_pc_load_combo) }, + { HP_POP(pc->add_charm, HP_pc_add_charm) }, + { HP_POP(pc->del_charm, HP_pc_del_charm) }, + { HP_POP(pc->baselevelchanged, HP_pc_baselevelchanged) }, + { HP_POP(pc->level_penalty_mod, HP_pc_level_penalty_mod) }, + { HP_POP(pc->calc_skillpoint, HP_pc_calc_skillpoint) }, + { HP_POP(pc->invincible_timer, HP_pc_invincible_timer) }, + { HP_POP(pc->spiritball_timer, HP_pc_spiritball_timer) }, + { HP_POP(pc->check_banding, HP_pc_check_banding) }, + { HP_POP(pc->inventory_rental_end, HP_pc_inventory_rental_end) }, + { HP_POP(pc->check_skilltree, HP_pc_check_skilltree) }, + { HP_POP(pc->bonus_autospell, HP_pc_bonus_autospell) }, + { HP_POP(pc->bonus_autospell_onskill, HP_pc_bonus_autospell_onskill) }, + { HP_POP(pc->bonus_addeff, HP_pc_bonus_addeff) }, + { HP_POP(pc->bonus_addeff_onskill, HP_pc_bonus_addeff_onskill) }, + { HP_POP(pc->bonus_item_drop, HP_pc_bonus_item_drop) }, + { HP_POP(pc->calcexp, HP_pc_calcexp) }, + { HP_POP(pc->respawn_timer, HP_pc_respawn_timer) }, + { HP_POP(pc->jobchange_killclone, HP_pc_jobchange_killclone) }, + { HP_POP(pc->getstat, HP_pc_getstat) }, + { HP_POP(pc->setstat, HP_pc_setstat) }, + { HP_POP(pc->eventtimer, HP_pc_eventtimer) }, + { HP_POP(pc->daynight_timer_sub, HP_pc_daynight_timer_sub) }, + { HP_POP(pc->charm_timer, HP_pc_charm_timer) }, + { HP_POP(pc->readdb_levelpenalty, HP_pc_readdb_levelpenalty) }, + { HP_POP(pc->autosave, HP_pc_autosave) }, + { HP_POP(pc->follow_timer, HP_pc_follow_timer) }, + { HP_POP(pc->read_skill_tree, HP_pc_read_skill_tree) }, + { HP_POP(pc->isUseitem, HP_pc_isUseitem) }, + { HP_POP(pc->show_steal, HP_pc_show_steal) }, + { HP_POP(pc->checkcombo, HP_pc_checkcombo) }, + { HP_POP(pc->calcweapontype, HP_pc_calcweapontype) }, + { HP_POP(pc->removecombo, HP_pc_removecombo) }, + { HP_POP(pc->bank_deposit, HP_pc_bank_deposit) }, + { HP_POP(pc->bank_withdraw, HP_pc_bank_withdraw) }, + { HP_POP(pc->rental_expire, HP_pc_rental_expire) }, + { HP_POP(pc->scdata_received, HP_pc_scdata_received) }, + { HP_POP(pc->bound_clear, HP_pc_bound_clear) }, + { HP_POP(pc->expiration_timer, HP_pc_expiration_timer) }, + { HP_POP(pc->global_expiration_timer, HP_pc_global_expiration_timer) }, + { HP_POP(pc->expire_check, HP_pc_expire_check) }, + { HP_POP(pc->autotrade_load, HP_pc_autotrade_load) }, + { HP_POP(pc->autotrade_update, HP_pc_autotrade_update) }, + { HP_POP(pc->autotrade_start, HP_pc_autotrade_start) }, + { HP_POP(pc->autotrade_prepare, HP_pc_autotrade_prepare) }, + { HP_POP(pc->autotrade_populate, HP_pc_autotrade_populate) }, /* pet */ - { HP_POP(pet->init), HP_POP2(HP_pet_init), 3760 }, - { HP_POP(pet->final), HP_POP2(HP_pet_final), 3762 }, - { HP_POP(pet->hungry_val), HP_POP2(HP_pet_hungry_val), 3764 }, - { HP_POP(pet->set_intimate), HP_POP2(HP_pet_set_intimate), 3766 }, - { HP_POP(pet->create_egg), HP_POP2(HP_pet_create_egg), 3768 }, - { HP_POP(pet->unlocktarget), HP_POP2(HP_pet_unlocktarget), 3770 }, - { HP_POP(pet->attackskill), HP_POP2(HP_pet_attackskill), 3772 }, - { HP_POP(pet->target_check), HP_POP2(HP_pet_target_check), 3774 }, - { HP_POP(pet->sc_check), HP_POP2(HP_pet_sc_check), 3776 }, - { HP_POP(pet->hungry), HP_POP2(HP_pet_hungry), 3778 }, - { HP_POP(pet->search_petDB_index), HP_POP2(HP_pet_search_petDB_index), 3780 }, - { HP_POP(pet->hungry_timer_delete), HP_POP2(HP_pet_hungry_timer_delete), 3782 }, - { HP_POP(pet->performance), HP_POP2(HP_pet_performance), 3784 }, - { HP_POP(pet->return_egg), HP_POP2(HP_pet_return_egg), 3786 }, - { HP_POP(pet->data_init), HP_POP2(HP_pet_data_init), 3788 }, - { HP_POP(pet->birth_process), HP_POP2(HP_pet_birth_process), 3790 }, - { HP_POP(pet->recv_petdata), HP_POP2(HP_pet_recv_petdata), 3792 }, - { HP_POP(pet->select_egg), HP_POP2(HP_pet_select_egg), 3794 }, - { HP_POP(pet->catch_process1), HP_POP2(HP_pet_catch_process1), 3796 }, - { HP_POP(pet->catch_process2), HP_POP2(HP_pet_catch_process2), 3798 }, - { HP_POP(pet->get_egg), HP_POP2(HP_pet_get_egg), 3800 }, - { HP_POP(pet->unequipitem), HP_POP2(HP_pet_unequipitem), 3802 }, - { HP_POP(pet->food), HP_POP2(HP_pet_food), 3804 }, - { HP_POP(pet->ai_sub_hard_lootsearch), HP_POP2(HP_pet_ai_sub_hard_lootsearch), 3806 }, - { HP_POP(pet->menu), HP_POP2(HP_pet_menu), 3808 }, - { HP_POP(pet->change_name), HP_POP2(HP_pet_change_name), 3810 }, - { HP_POP(pet->change_name_ack), HP_POP2(HP_pet_change_name_ack), 3812 }, - { HP_POP(pet->equipitem), HP_POP2(HP_pet_equipitem), 3814 }, - { HP_POP(pet->randomwalk), HP_POP2(HP_pet_randomwalk), 3816 }, - { HP_POP(pet->ai_sub_hard), HP_POP2(HP_pet_ai_sub_hard), 3818 }, - { HP_POP(pet->ai_sub_foreachclient), HP_POP2(HP_pet_ai_sub_foreachclient), 3820 }, - { HP_POP(pet->ai_hard), HP_POP2(HP_pet_ai_hard), 3822 }, - { HP_POP(pet->delay_item_drop), HP_POP2(HP_pet_delay_item_drop), 3824 }, - { HP_POP(pet->lootitem_drop), HP_POP2(HP_pet_lootitem_drop), 3826 }, - { HP_POP(pet->skill_bonus_timer), HP_POP2(HP_pet_skill_bonus_timer), 3828 }, - { HP_POP(pet->recovery_timer), HP_POP2(HP_pet_recovery_timer), 3830 }, - { HP_POP(pet->heal_timer), HP_POP2(HP_pet_heal_timer), 3832 }, - { HP_POP(pet->skill_support_timer), HP_POP2(HP_pet_skill_support_timer), 3834 }, - { HP_POP(pet->read_db), HP_POP2(HP_pet_read_db), 3836 }, + { HP_POP(pet->init, HP_pet_init) }, + { HP_POP(pet->final, HP_pet_final) }, + { HP_POP(pet->hungry_val, HP_pet_hungry_val) }, + { HP_POP(pet->set_intimate, HP_pet_set_intimate) }, + { HP_POP(pet->create_egg, HP_pet_create_egg) }, + { HP_POP(pet->unlocktarget, HP_pet_unlocktarget) }, + { HP_POP(pet->attackskill, HP_pet_attackskill) }, + { HP_POP(pet->target_check, HP_pet_target_check) }, + { HP_POP(pet->sc_check, HP_pet_sc_check) }, + { HP_POP(pet->hungry, HP_pet_hungry) }, + { HP_POP(pet->search_petDB_index, HP_pet_search_petDB_index) }, + { HP_POP(pet->hungry_timer_delete, HP_pet_hungry_timer_delete) }, + { HP_POP(pet->performance, HP_pet_performance) }, + { HP_POP(pet->return_egg, HP_pet_return_egg) }, + { HP_POP(pet->data_init, HP_pet_data_init) }, + { HP_POP(pet->birth_process, HP_pet_birth_process) }, + { HP_POP(pet->recv_petdata, HP_pet_recv_petdata) }, + { HP_POP(pet->select_egg, HP_pet_select_egg) }, + { HP_POP(pet->catch_process1, HP_pet_catch_process1) }, + { HP_POP(pet->catch_process2, HP_pet_catch_process2) }, + { HP_POP(pet->get_egg, HP_pet_get_egg) }, + { HP_POP(pet->unequipitem, HP_pet_unequipitem) }, + { HP_POP(pet->food, HP_pet_food) }, + { HP_POP(pet->ai_sub_hard_lootsearch, HP_pet_ai_sub_hard_lootsearch) }, + { HP_POP(pet->menu, HP_pet_menu) }, + { HP_POP(pet->change_name, HP_pet_change_name) }, + { HP_POP(pet->change_name_ack, HP_pet_change_name_ack) }, + { HP_POP(pet->equipitem, HP_pet_equipitem) }, + { HP_POP(pet->randomwalk, HP_pet_randomwalk) }, + { HP_POP(pet->ai_sub_hard, HP_pet_ai_sub_hard) }, + { HP_POP(pet->ai_sub_foreachclient, HP_pet_ai_sub_foreachclient) }, + { HP_POP(pet->ai_hard, HP_pet_ai_hard) }, + { HP_POP(pet->delay_item_drop, HP_pet_delay_item_drop) }, + { HP_POP(pet->lootitem_drop, HP_pet_lootitem_drop) }, + { HP_POP(pet->skill_bonus_timer, HP_pet_skill_bonus_timer) }, + { HP_POP(pet->recovery_timer, HP_pet_recovery_timer) }, + { HP_POP(pet->heal_timer, HP_pet_heal_timer) }, + { HP_POP(pet->skill_support_timer, HP_pet_skill_support_timer) }, + { HP_POP(pet->read_db, HP_pet_read_db) }, /* quest */ - { HP_POP(quest->init), HP_POP2(HP_quest_init), 3838 }, - { HP_POP(quest->reload), HP_POP2(HP_quest_reload), 3840 }, - { HP_POP(quest->search_db), HP_POP2(HP_quest_search_db), 3842 }, - { HP_POP(quest->pc_login), HP_POP2(HP_quest_pc_login), 3844 }, - { HP_POP(quest->add), HP_POP2(HP_quest_add), 3846 }, - { HP_POP(quest->change), HP_POP2(HP_quest_change), 3848 }, - { HP_POP(quest->delete), HP_POP2(HP_quest_delete), 3850 }, - { HP_POP(quest->update_objective_sub), HP_POP2(HP_quest_update_objective_sub), 3852 }, - { HP_POP(quest->update_objective), HP_POP2(HP_quest_update_objective), 3854 }, - { HP_POP(quest->update_status), HP_POP2(HP_quest_update_status), 3856 }, - { HP_POP(quest->check), HP_POP2(HP_quest_check), 3858 }, - { HP_POP(quest->read_db), HP_POP2(HP_quest_read_db), 3860 }, + { HP_POP(quest->init, HP_quest_init) }, + { HP_POP(quest->final, HP_quest_final) }, + { HP_POP(quest->reload, HP_quest_reload) }, + { HP_POP(quest->db, HP_quest_db) }, + { HP_POP(quest->pc_login, HP_quest_pc_login) }, + { HP_POP(quest->add, HP_quest_add) }, + { HP_POP(quest->change, HP_quest_change) }, + { HP_POP(quest->delete, HP_quest_delete) }, + { HP_POP(quest->update_objective_sub, HP_quest_update_objective_sub) }, + { HP_POP(quest->update_objective, HP_quest_update_objective) }, + { HP_POP(quest->update_status, HP_quest_update_status) }, + { HP_POP(quest->check, HP_quest_check) }, + { HP_POP(quest->clear, HP_quest_clear) }, + { HP_POP(quest->read_db, HP_quest_read_db) }, /* script */ - { HP_POP(script->init), HP_POP2(HP_script_init), 3862 }, - { HP_POP(script->final), HP_POP2(HP_script_final), 3864 }, - { HP_POP(script->reload), HP_POP2(HP_script_reload), 3866 }, - { HP_POP(script->parse), HP_POP2(HP_script_parse), 3868 }, - { HP_POP(script->parse_builtin), HP_POP2(HP_script_parse_builtin), 3870 }, - { HP_POP(script->parse_subexpr), HP_POP2(HP_script_parse_subexpr), 3872 }, - { HP_POP(script->skip_space), HP_POP2(HP_script_skip_space), 3874 }, - { HP_POP(script->error), HP_POP2(HP_script_error), 3876 }, - { HP_POP(script->warning), HP_POP2(HP_script_warning), 3878 }, - { HP_POP(script->addScript), HP_POP2(HP_script_addScript), 3880 }, - { HP_POP(script->conv_num), HP_POP2(HP_script_conv_num), 3882 }, - { HP_POP(script->conv_str), HP_POP2(HP_script_conv_str), 3884 }, - { HP_POP(script->rid2sd), HP_POP2(HP_script_rid2sd), 3886 }, - { HP_POP(script->detach_rid), HP_POP2(HP_script_detach_rid), 3888 }, - { HP_POP(script->push_val), HP_POP2(HP_script_push_val), 3890 }, - { HP_POP(script->get_val), HP_POP2(HP_script_get_val), 3892 }, - { HP_POP(script->get_val2), HP_POP2(HP_script_get_val2), 3894 }, - { HP_POP(script->push_str), HP_POP2(HP_script_push_str), 3896 }, - { HP_POP(script->push_copy), HP_POP2(HP_script_push_copy), 3898 }, - { HP_POP(script->pop_stack), HP_POP2(HP_script_pop_stack), 3900 }, - { HP_POP(script->set_constant), HP_POP2(HP_script_set_constant), 3902 }, - { HP_POP(script->set_constant2), HP_POP2(HP_script_set_constant2), 3904 }, - { HP_POP(script->set_constant_force), HP_POP2(HP_script_set_constant_force), 3906 }, - { HP_POP(script->get_constant), HP_POP2(HP_script_get_constant), 3908 }, - { HP_POP(script->label_add), HP_POP2(HP_script_label_add), 3910 }, - { HP_POP(script->run), HP_POP2(HP_script_run), 3912 }, - { HP_POP(script->run_main), HP_POP2(HP_script_run_main), 3914 }, - { HP_POP(script->run_timer), HP_POP2(HP_script_run_timer), 3916 }, - { HP_POP(script->set_var), HP_POP2(HP_script_set_var), 3918 }, - { HP_POP(script->stop_instances), HP_POP2(HP_script_stop_instances), 3920 }, - { HP_POP(script->free_code), HP_POP2(HP_script_free_code), 3922 }, - { HP_POP(script->free_vars), HP_POP2(HP_script_free_vars), 3924 }, - { HP_POP(script->alloc_state), HP_POP2(HP_script_alloc_state), 3926 }, - { HP_POP(script->free_state), HP_POP2(HP_script_free_state), 3928 }, - { HP_POP(script->run_autobonus), HP_POP2(HP_script_run_autobonus), 3930 }, - { HP_POP(script->cleararray_pc), HP_POP2(HP_script_cleararray_pc), 3932 }, - { HP_POP(script->setarray_pc), HP_POP2(HP_script_setarray_pc), 3934 }, - { HP_POP(script->config_read), HP_POP2(HP_script_config_read), 3936 }, - { HP_POP(script->add_str), HP_POP2(HP_script_add_str), 3938 }, - { HP_POP(script->get_str), HP_POP2(HP_script_get_str), 3940 }, - { HP_POP(script->search_str), HP_POP2(HP_script_search_str), 3942 }, - { HP_POP(script->setd_sub), HP_POP2(HP_script_setd_sub), 3944 }, - { HP_POP(script->attach_state), HP_POP2(HP_script_attach_state), 3946 }, - { HP_POP(script->queue), HP_POP2(HP_script_queue), 3948 }, - { HP_POP(script->queue_add), HP_POP2(HP_script_queue_add), 3950 }, - { HP_POP(script->queue_del), HP_POP2(HP_script_queue_del), 3952 }, - { HP_POP(script->queue_remove), HP_POP2(HP_script_queue_remove), 3954 }, - { HP_POP(script->queue_create), HP_POP2(HP_script_queue_create), 3956 }, - { HP_POP(script->queue_clear), HP_POP2(HP_script_queue_clear), 3958 }, - { HP_POP(script->parse_curly_close), HP_POP2(HP_script_parse_curly_close), 3960 }, - { HP_POP(script->parse_syntax_close), HP_POP2(HP_script_parse_syntax_close), 3962 }, - { HP_POP(script->parse_syntax_close_sub), HP_POP2(HP_script_parse_syntax_close_sub), 3964 }, - { HP_POP(script->parse_syntax), HP_POP2(HP_script_parse_syntax), 3966 }, - { HP_POP(script->get_com), HP_POP2(HP_script_get_com), 3968 }, - { HP_POP(script->get_num), HP_POP2(HP_script_get_num), 3970 }, - { HP_POP(script->op2name), HP_POP2(HP_script_op2name), 3972 }, - { HP_POP(script->reportsrc), HP_POP2(HP_script_reportsrc), 3974 }, - { HP_POP(script->reportdata), HP_POP2(HP_script_reportdata), 3976 }, - { HP_POP(script->reportfunc), HP_POP2(HP_script_reportfunc), 3978 }, - { HP_POP(script->disp_error_message2), HP_POP2(HP_script_disp_error_message2), 3980 }, - { HP_POP(script->disp_warning_message), HP_POP2(HP_script_disp_warning_message), 3982 }, - { HP_POP(script->check_event), HP_POP2(HP_script_check_event), 3984 }, - { HP_POP(script->calc_hash), HP_POP2(HP_script_calc_hash), 3986 }, - { HP_POP(script->addb), HP_POP2(HP_script_addb), 3988 }, - { HP_POP(script->addc), HP_POP2(HP_script_addc), 3990 }, - { HP_POP(script->addi), HP_POP2(HP_script_addi), 3992 }, - { HP_POP(script->addl), HP_POP2(HP_script_addl), 3994 }, - { HP_POP(script->set_label), HP_POP2(HP_script_set_label), 3996 }, - { HP_POP(script->skip_word), HP_POP2(HP_script_skip_word), 3998 }, - { HP_POP(script->add_word), HP_POP2(HP_script_add_word), 4000 }, - { HP_POP(script->parse_callfunc), HP_POP2(HP_script_parse_callfunc), 4002 }, - { HP_POP(script->parse_nextline), HP_POP2(HP_script_parse_nextline), 4004 }, - { HP_POP(script->parse_variable), HP_POP2(HP_script_parse_variable), 4006 }, - { HP_POP(script->parse_simpleexpr), HP_POP2(HP_script_parse_simpleexpr), 4008 }, - { HP_POP(script->parse_expr), HP_POP2(HP_script_parse_expr), 4010 }, - { HP_POP(script->parse_line), HP_POP2(HP_script_parse_line), 4012 }, - { HP_POP(script->read_constdb), HP_POP2(HP_script_read_constdb), 4014 }, - { HP_POP(script->print_line), HP_POP2(HP_script_print_line), 4016 }, - { HP_POP(script->errorwarning_sub), HP_POP2(HP_script_errorwarning_sub), 4018 }, - { HP_POP(script->set_reg), HP_POP2(HP_script_set_reg), 4020 }, - { HP_POP(script->stack_expand), HP_POP2(HP_script_stack_expand), 4022 }, - { HP_POP(script->push_retinfo), HP_POP2(HP_script_push_retinfo), 4024 }, - { HP_POP(script->pop_val), HP_POP2(HP_script_pop_val), 4026 }, - { HP_POP(script->op_3), HP_POP2(HP_script_op_3), 4028 }, - { HP_POP(script->op_2str), HP_POP2(HP_script_op_2str), 4030 }, - { HP_POP(script->op_2num), HP_POP2(HP_script_op_2num), 4032 }, - { HP_POP(script->op_2), HP_POP2(HP_script_op_2), 4034 }, - { HP_POP(script->op_1), HP_POP2(HP_script_op_1), 4036 }, - { HP_POP(script->check_buildin_argtype), HP_POP2(HP_script_check_buildin_argtype), 4038 }, - { HP_POP(script->detach_state), HP_POP2(HP_script_detach_state), 4040 }, - { HP_POP(script->db_free_code_sub), HP_POP2(HP_script_db_free_code_sub), 4042 }, - { HP_POP(script->add_autobonus), HP_POP2(HP_script_add_autobonus), 4044 }, - { HP_POP(script->menu_countoptions), HP_POP2(HP_script_menu_countoptions), 4046 }, - { HP_POP(script->buildin_areawarp_sub), HP_POP2(HP_script_buildin_areawarp_sub), 4048 }, - { HP_POP(script->buildin_areapercentheal_sub), HP_POP2(HP_script_buildin_areapercentheal_sub), 4050 }, - { HP_POP(script->getarraysize), HP_POP2(HP_script_getarraysize), 4052 }, - { HP_POP(script->buildin_delitem_delete), HP_POP2(HP_script_buildin_delitem_delete), 4054 }, - { HP_POP(script->buildin_delitem_search), HP_POP2(HP_script_buildin_delitem_search), 4056 }, - { HP_POP(script->buildin_killmonster_sub_strip), HP_POP2(HP_script_buildin_killmonster_sub_strip), 4058 }, - { HP_POP(script->buildin_killmonster_sub), HP_POP2(HP_script_buildin_killmonster_sub), 4060 }, - { HP_POP(script->buildin_killmonsterall_sub_strip), HP_POP2(HP_script_buildin_killmonsterall_sub_strip), 4062 }, - { HP_POP(script->buildin_killmonsterall_sub), HP_POP2(HP_script_buildin_killmonsterall_sub), 4064 }, - { HP_POP(script->buildin_announce_sub), HP_POP2(HP_script_buildin_announce_sub), 4066 }, - { HP_POP(script->buildin_getareausers_sub), HP_POP2(HP_script_buildin_getareausers_sub), 4068 }, - { HP_POP(script->buildin_getareadropitem_sub), HP_POP2(HP_script_buildin_getareadropitem_sub), 4070 }, - { HP_POP(script->mapflag_pvp_sub), HP_POP2(HP_script_mapflag_pvp_sub), 4072 }, - { HP_POP(script->buildin_pvpoff_sub), HP_POP2(HP_script_buildin_pvpoff_sub), 4074 }, - { HP_POP(script->buildin_maprespawnguildid_sub_pc), HP_POP2(HP_script_buildin_maprespawnguildid_sub_pc), 4076 }, - { HP_POP(script->buildin_maprespawnguildid_sub_mob), HP_POP2(HP_script_buildin_maprespawnguildid_sub_mob), 4078 }, - { HP_POP(script->buildin_mobcount_sub), HP_POP2(HP_script_buildin_mobcount_sub), 4080 }, - { HP_POP(script->playBGM_sub), HP_POP2(HP_script_playBGM_sub), 4082 }, - { HP_POP(script->playBGM_foreachpc_sub), HP_POP2(HP_script_playBGM_foreachpc_sub), 4084 }, - { HP_POP(script->soundeffect_sub), HP_POP2(HP_script_soundeffect_sub), 4086 }, - { HP_POP(script->buildin_query_sql_sub), HP_POP2(HP_script_buildin_query_sql_sub), 4088 }, - { HP_POP(script->axtoi), HP_POP2(HP_script_axtoi), 4090 }, - { HP_POP(script->buildin_instance_warpall_sub), HP_POP2(HP_script_buildin_instance_warpall_sub), 4092 }, - { HP_POP(script->buildin_mobuseskill_sub), HP_POP2(HP_script_buildin_mobuseskill_sub), 4094 }, - { HP_POP(script->cleanfloor_sub), HP_POP2(HP_script_cleanfloor_sub), 4096 }, - { HP_POP(script->run_func), HP_POP2(HP_script_run_func), 4098 }, + { HP_POP(script->init, HP_script_init) }, + { HP_POP(script->final, HP_script_final) }, + { HP_POP(script->reload, HP_script_reload) }, + { HP_POP(script->parse, HP_script_parse) }, + { HP_POP(script->add_builtin, HP_script_add_builtin) }, + { HP_POP(script->parse_builtin, HP_script_parse_builtin) }, + { HP_POP(script->parse_subexpr, HP_script_parse_subexpr) }, + { HP_POP(script->skip_space, HP_script_skip_space) }, + { HP_POP(script->error, HP_script_error) }, + { HP_POP(script->warning, HP_script_warning) }, + { HP_POP(script->addScript, HP_script_addScript) }, + { HP_POP(script->conv_num, HP_script_conv_num) }, + { HP_POP(script->conv_str, HP_script_conv_str) }, + { HP_POP(script->rid2sd, HP_script_rid2sd) }, + { HP_POP(script->detach_rid, HP_script_detach_rid) }, + { HP_POP(script->push_val, HP_script_push_val) }, + { HP_POP(script->get_val, HP_script_get_val) }, + { HP_POP(script->get_val2, HP_script_get_val2) }, + { HP_POP(script->push_str, HP_script_push_str) }, + { HP_POP(script->push_copy, HP_script_push_copy) }, + { HP_POP(script->pop_stack, HP_script_pop_stack) }, + { HP_POP(script->set_constant, HP_script_set_constant) }, + { HP_POP(script->set_constant2, HP_script_set_constant2) }, + { HP_POP(script->get_constant, HP_script_get_constant) }, + { HP_POP(script->label_add, HP_script_label_add) }, + { HP_POP(script->run, HP_script_run) }, + { HP_POP(script->run_main, HP_script_run_main) }, + { HP_POP(script->run_timer, HP_script_run_timer) }, + { HP_POP(script->set_var, HP_script_set_var) }, + { HP_POP(script->stop_instances, HP_script_stop_instances) }, + { HP_POP(script->free_code, HP_script_free_code) }, + { HP_POP(script->free_vars, HP_script_free_vars) }, + { HP_POP(script->alloc_state, HP_script_alloc_state) }, + { HP_POP(script->free_state, HP_script_free_state) }, + { HP_POP(script->run_autobonus, HP_script_run_autobonus) }, + { HP_POP(script->cleararray_pc, HP_script_cleararray_pc) }, + { HP_POP(script->setarray_pc, HP_script_setarray_pc) }, + { HP_POP(script->config_read, HP_script_config_read) }, + { HP_POP(script->add_str, HP_script_add_str) }, + { HP_POP(script->get_str, HP_script_get_str) }, + { HP_POP(script->search_str, HP_script_search_str) }, + { HP_POP(script->setd_sub, HP_script_setd_sub) }, + { HP_POP(script->attach_state, HP_script_attach_state) }, + { HP_POP(script->queue, HP_script_queue) }, + { HP_POP(script->queue_add, HP_script_queue_add) }, + { HP_POP(script->queue_del, HP_script_queue_del) }, + { HP_POP(script->queue_remove, HP_script_queue_remove) }, + { HP_POP(script->queue_create, HP_script_queue_create) }, + { HP_POP(script->queue_clear, HP_script_queue_clear) }, + { HP_POP(script->parse_curly_close, HP_script_parse_curly_close) }, + { HP_POP(script->parse_syntax_close, HP_script_parse_syntax_close) }, + { HP_POP(script->parse_syntax_close_sub, HP_script_parse_syntax_close_sub) }, + { HP_POP(script->parse_syntax, HP_script_parse_syntax) }, + { HP_POP(script->get_com, HP_script_get_com) }, + { HP_POP(script->get_num, HP_script_get_num) }, + { HP_POP(script->op2name, HP_script_op2name) }, + { HP_POP(script->reportsrc, HP_script_reportsrc) }, + { HP_POP(script->reportdata, HP_script_reportdata) }, + { HP_POP(script->reportfunc, HP_script_reportfunc) }, + { HP_POP(script->disp_warning_message, HP_script_disp_warning_message) }, + { HP_POP(script->check_event, HP_script_check_event) }, + { HP_POP(script->calc_hash, HP_script_calc_hash) }, + { HP_POP(script->addb, HP_script_addb) }, + { HP_POP(script->addc, HP_script_addc) }, + { HP_POP(script->addi, HP_script_addi) }, + { HP_POP(script->addl, HP_script_addl) }, + { HP_POP(script->set_label, HP_script_set_label) }, + { HP_POP(script->skip_word, HP_script_skip_word) }, + { HP_POP(script->add_word, HP_script_add_word) }, + { HP_POP(script->parse_callfunc, HP_script_parse_callfunc) }, + { HP_POP(script->parse_nextline, HP_script_parse_nextline) }, + { HP_POP(script->parse_variable, HP_script_parse_variable) }, + { HP_POP(script->parse_simpleexpr, HP_script_parse_simpleexpr) }, + { HP_POP(script->parse_expr, HP_script_parse_expr) }, + { HP_POP(script->parse_line, HP_script_parse_line) }, + { HP_POP(script->read_constdb, HP_script_read_constdb) }, + { HP_POP(script->print_line, HP_script_print_line) }, + { HP_POP(script->errorwarning_sub, HP_script_errorwarning_sub) }, + { HP_POP(script->set_reg, HP_script_set_reg) }, + { HP_POP(script->stack_expand, HP_script_stack_expand) }, + { HP_POP(script->push_retinfo, HP_script_push_retinfo) }, + { HP_POP(script->op_3, HP_script_op_3) }, + { HP_POP(script->op_2str, HP_script_op_2str) }, + { HP_POP(script->op_2num, HP_script_op_2num) }, + { HP_POP(script->op_2, HP_script_op_2) }, + { HP_POP(script->op_1, HP_script_op_1) }, + { HP_POP(script->check_buildin_argtype, HP_script_check_buildin_argtype) }, + { HP_POP(script->detach_state, HP_script_detach_state) }, + { HP_POP(script->db_free_code_sub, HP_script_db_free_code_sub) }, + { HP_POP(script->add_autobonus, HP_script_add_autobonus) }, + { HP_POP(script->menu_countoptions, HP_script_menu_countoptions) }, + { HP_POP(script->buildin_areawarp_sub, HP_script_buildin_areawarp_sub) }, + { HP_POP(script->buildin_areapercentheal_sub, HP_script_buildin_areapercentheal_sub) }, + { HP_POP(script->buildin_delitem_delete, HP_script_buildin_delitem_delete) }, + { HP_POP(script->buildin_delitem_search, HP_script_buildin_delitem_search) }, + { HP_POP(script->buildin_killmonster_sub_strip, HP_script_buildin_killmonster_sub_strip) }, + { HP_POP(script->buildin_killmonster_sub, HP_script_buildin_killmonster_sub) }, + { HP_POP(script->buildin_killmonsterall_sub_strip, HP_script_buildin_killmonsterall_sub_strip) }, + { HP_POP(script->buildin_killmonsterall_sub, HP_script_buildin_killmonsterall_sub) }, + { HP_POP(script->buildin_announce_sub, HP_script_buildin_announce_sub) }, + { HP_POP(script->buildin_getareausers_sub, HP_script_buildin_getareausers_sub) }, + { HP_POP(script->buildin_getareadropitem_sub, HP_script_buildin_getareadropitem_sub) }, + { HP_POP(script->mapflag_pvp_sub, HP_script_mapflag_pvp_sub) }, + { HP_POP(script->buildin_pvpoff_sub, HP_script_buildin_pvpoff_sub) }, + { HP_POP(script->buildin_maprespawnguildid_sub_pc, HP_script_buildin_maprespawnguildid_sub_pc) }, + { HP_POP(script->buildin_maprespawnguildid_sub_mob, HP_script_buildin_maprespawnguildid_sub_mob) }, + { HP_POP(script->buildin_mobcount_sub, HP_script_buildin_mobcount_sub) }, + { HP_POP(script->playbgm_sub, HP_script_playbgm_sub) }, + { HP_POP(script->playbgm_foreachpc_sub, HP_script_playbgm_foreachpc_sub) }, + { HP_POP(script->soundeffect_sub, HP_script_soundeffect_sub) }, + { HP_POP(script->buildin_query_sql_sub, HP_script_buildin_query_sql_sub) }, + { HP_POP(script->buildin_instance_warpall_sub, HP_script_buildin_instance_warpall_sub) }, + { HP_POP(script->buildin_mobuseskill_sub, HP_script_buildin_mobuseskill_sub) }, + { HP_POP(script->cleanfloor_sub, HP_script_cleanfloor_sub) }, + { HP_POP(script->run_func, HP_script_run_func) }, + { HP_POP(script->getfuncname, HP_script_getfuncname) }, + { HP_POP(script->calc_hash_ci, HP_script_calc_hash_ci) }, + { HP_POP(script->array_src, HP_script_array_src) }, + { HP_POP(script->array_update, HP_script_array_update) }, + { HP_POP(script->array_delete, HP_script_array_delete) }, + { HP_POP(script->array_remove_member, HP_script_array_remove_member) }, + { HP_POP(script->array_add_member, HP_script_array_add_member) }, + { HP_POP(script->array_size, HP_script_array_size) }, + { HP_POP(script->array_highest_key, HP_script_array_highest_key) }, + { HP_POP(script->array_free_db, HP_script_array_free_db) }, + { HP_POP(script->array_ensure_zero, HP_script_array_ensure_zero) }, + { HP_POP(script->reg_destroy_single, HP_script_reg_destroy_single) }, + { HP_POP(script->reg_destroy, HP_script_reg_destroy) }, + { HP_POP(script->generic_ui_array_expand, HP_script_generic_ui_array_expand) }, + { HP_POP(script->array_cpy_list, HP_script_array_cpy_list) }, /* searchstore */ - { HP_POP(searchstore->open), HP_POP2(HP_searchstore_open), 4100 }, - { HP_POP(searchstore->query), HP_POP2(HP_searchstore_query), 4102 }, - { HP_POP(searchstore->querynext), HP_POP2(HP_searchstore_querynext), 4104 }, - { HP_POP(searchstore->next), HP_POP2(HP_searchstore_next), 4106 }, - { HP_POP(searchstore->clear), HP_POP2(HP_searchstore_clear), 4108 }, - { HP_POP(searchstore->close), HP_POP2(HP_searchstore_close), 4110 }, - { HP_POP(searchstore->click), HP_POP2(HP_searchstore_click), 4112 }, - { HP_POP(searchstore->queryremote), HP_POP2(HP_searchstore_queryremote), 4114 }, - { HP_POP(searchstore->clearremote), HP_POP2(HP_searchstore_clearremote), 4116 }, - { HP_POP(searchstore->result), HP_POP2(HP_searchstore_result), 4118 }, + { HP_POP(searchstore->open, HP_searchstore_open) }, + { HP_POP(searchstore->query, HP_searchstore_query) }, + { HP_POP(searchstore->querynext, HP_searchstore_querynext) }, + { HP_POP(searchstore->next, HP_searchstore_next) }, + { HP_POP(searchstore->clear, HP_searchstore_clear) }, + { HP_POP(searchstore->close, HP_searchstore_close) }, + { HP_POP(searchstore->click, HP_searchstore_click) }, + { HP_POP(searchstore->queryremote, HP_searchstore_queryremote) }, + { HP_POP(searchstore->clearremote, HP_searchstore_clearremote) }, + { HP_POP(searchstore->result, HP_searchstore_result) }, /* skill */ - { HP_POP(skill->init), HP_POP2(HP_skill_init), 4120 }, - { HP_POP(skill->final), HP_POP2(HP_skill_final), 4122 }, - { HP_POP(skill->reload), HP_POP2(HP_skill_reload), 4124 }, - { HP_POP(skill->read_db), HP_POP2(HP_skill_read_db), 4126 }, - { HP_POP(skill->get_index), HP_POP2(HP_skill_get_index), 4128 }, - { HP_POP(skill->get_type), HP_POP2(HP_skill_get_type), 4130 }, - { HP_POP(skill->get_hit), HP_POP2(HP_skill_get_hit), 4132 }, - { HP_POP(skill->get_inf), HP_POP2(HP_skill_get_inf), 4134 }, - { HP_POP(skill->get_ele), HP_POP2(HP_skill_get_ele), 4136 }, - { HP_POP(skill->get_nk), HP_POP2(HP_skill_get_nk), 4138 }, - { HP_POP(skill->get_max), HP_POP2(HP_skill_get_max), 4140 }, - { HP_POP(skill->get_range), HP_POP2(HP_skill_get_range), 4142 }, - { HP_POP(skill->get_range2), HP_POP2(HP_skill_get_range2), 4144 }, - { HP_POP(skill->get_splash), HP_POP2(HP_skill_get_splash), 4146 }, - { HP_POP(skill->get_hp), HP_POP2(HP_skill_get_hp), 4148 }, - { HP_POP(skill->get_mhp), HP_POP2(HP_skill_get_mhp), 4150 }, - { HP_POP(skill->get_sp), HP_POP2(HP_skill_get_sp), 4152 }, - { HP_POP(skill->get_state), HP_POP2(HP_skill_get_state), 4154 }, - { HP_POP(skill->get_spiritball), HP_POP2(HP_skill_get_spiritball), 4156 }, - { HP_POP(skill->get_zeny), HP_POP2(HP_skill_get_zeny), 4158 }, - { HP_POP(skill->get_num), HP_POP2(HP_skill_get_num), 4160 }, - { HP_POP(skill->get_cast), HP_POP2(HP_skill_get_cast), 4162 }, - { HP_POP(skill->get_delay), HP_POP2(HP_skill_get_delay), 4164 }, - { HP_POP(skill->get_walkdelay), HP_POP2(HP_skill_get_walkdelay), 4166 }, - { HP_POP(skill->get_time), HP_POP2(HP_skill_get_time), 4168 }, - { HP_POP(skill->get_time2), HP_POP2(HP_skill_get_time2), 4170 }, - { HP_POP(skill->get_castnodex), HP_POP2(HP_skill_get_castnodex), 4172 }, - { HP_POP(skill->get_delaynodex), HP_POP2(HP_skill_get_delaynodex), 4174 }, - { HP_POP(skill->get_castdef), HP_POP2(HP_skill_get_castdef), 4176 }, - { HP_POP(skill->get_weapontype), HP_POP2(HP_skill_get_weapontype), 4178 }, - { HP_POP(skill->get_ammotype), HP_POP2(HP_skill_get_ammotype), 4180 }, - { HP_POP(skill->get_ammo_qty), HP_POP2(HP_skill_get_ammo_qty), 4182 }, - { HP_POP(skill->get_unit_id), HP_POP2(HP_skill_get_unit_id), 4184 }, - { HP_POP(skill->get_inf2), HP_POP2(HP_skill_get_inf2), 4186 }, - { HP_POP(skill->get_castcancel), HP_POP2(HP_skill_get_castcancel), 4188 }, - { HP_POP(skill->get_maxcount), HP_POP2(HP_skill_get_maxcount), 4190 }, - { HP_POP(skill->get_blewcount), HP_POP2(HP_skill_get_blewcount), 4192 }, - { HP_POP(skill->get_unit_flag), HP_POP2(HP_skill_get_unit_flag), 4194 }, - { HP_POP(skill->get_unit_target), HP_POP2(HP_skill_get_unit_target), 4196 }, - { HP_POP(skill->get_unit_interval), HP_POP2(HP_skill_get_unit_interval), 4198 }, - { HP_POP(skill->get_unit_bl_target), HP_POP2(HP_skill_get_unit_bl_target), 4200 }, - { HP_POP(skill->get_unit_layout_type), HP_POP2(HP_skill_get_unit_layout_type), 4202 }, - { HP_POP(skill->get_unit_range), HP_POP2(HP_skill_get_unit_range), 4204 }, - { HP_POP(skill->get_cooldown), HP_POP2(HP_skill_get_cooldown), 4206 }, - { HP_POP(skill->tree_get_max), HP_POP2(HP_skill_tree_get_max), 4208 }, - { HP_POP(skill->get_name), HP_POP2(HP_skill_get_name), 4210 }, - { HP_POP(skill->get_desc), HP_POP2(HP_skill_get_desc), 4212 }, - { HP_POP(skill->chk), HP_POP2(HP_skill_chk), 4214 }, - { HP_POP(skill->get_casttype), HP_POP2(HP_skill_get_casttype), 4216 }, - { HP_POP(skill->get_casttype2), HP_POP2(HP_skill_get_casttype2), 4218 }, - { HP_POP(skill->name2id), HP_POP2(HP_skill_name2id), 4220 }, - { HP_POP(skill->isammotype), HP_POP2(HP_skill_isammotype), 4222 }, - { HP_POP(skill->castend_id), HP_POP2(HP_skill_castend_id), 4224 }, - { HP_POP(skill->castend_pos), HP_POP2(HP_skill_castend_pos), 4226 }, - { HP_POP(skill->castend_map), HP_POP2(HP_skill_castend_map), 4228 }, - { HP_POP(skill->cleartimerskill), HP_POP2(HP_skill_cleartimerskill), 4230 }, - { HP_POP(skill->addtimerskill), HP_POP2(HP_skill_addtimerskill), 4232 }, - { HP_POP(skill->additional_effect), HP_POP2(HP_skill_additional_effect), 4234 }, - { HP_POP(skill->counter_additional_effect), HP_POP2(HP_skill_counter_additional_effect), 4236 }, - { HP_POP(skill->blown), HP_POP2(HP_skill_blown), 4238 }, - { HP_POP(skill->break_equip), HP_POP2(HP_skill_break_equip), 4240 }, - { HP_POP(skill->strip_equip), HP_POP2(HP_skill_strip_equip), 4242 }, - { HP_POP(skill->id2group), HP_POP2(HP_skill_id2group), 4244 }, - { HP_POP(skill->unitsetting), HP_POP2(HP_skill_unitsetting), 4246 }, - { HP_POP(skill->initunit), HP_POP2(HP_skill_initunit), 4248 }, - { HP_POP(skill->delunit), HP_POP2(HP_skill_delunit), 4250 }, - { HP_POP(skill->init_unitgroup), HP_POP2(HP_skill_init_unitgroup), 4252 }, - { HP_POP(skill->del_unitgroup), HP_POP2(HP_skill_del_unitgroup), 4254 }, - { HP_POP(skill->clear_unitgroup), HP_POP2(HP_skill_clear_unitgroup), 4256 }, - { HP_POP(skill->clear_group), HP_POP2(HP_skill_clear_group), 4258 }, - { HP_POP(skill->unit_onplace), HP_POP2(HP_skill_unit_onplace), 4260 }, - { HP_POP(skill->unit_ondamaged), HP_POP2(HP_skill_unit_ondamaged), 4262 }, - { HP_POP(skill->cast_fix), HP_POP2(HP_skill_cast_fix), 4264 }, - { HP_POP(skill->cast_fix_sc), HP_POP2(HP_skill_cast_fix_sc), 4266 }, - { HP_POP(skill->vf_cast_fix), HP_POP2(HP_skill_vf_cast_fix), 4268 }, - { HP_POP(skill->delay_fix), HP_POP2(HP_skill_delay_fix), 4270 }, - { HP_POP(skill->check_condition_castbegin), HP_POP2(HP_skill_check_condition_castbegin), 4272 }, - { HP_POP(skill->check_condition_castend), HP_POP2(HP_skill_check_condition_castend), 4274 }, - { HP_POP(skill->consume_requirement), HP_POP2(HP_skill_consume_requirement), 4276 }, - { HP_POP(skill->get_requirement), HP_POP2(HP_skill_get_requirement), 4278 }, - { HP_POP(skill->check_pc_partner), HP_POP2(HP_skill_check_pc_partner), 4280 }, - { HP_POP(skill->unit_move), HP_POP2(HP_skill_unit_move), 4282 }, - { HP_POP(skill->unit_onleft), HP_POP2(HP_skill_unit_onleft), 4284 }, - { HP_POP(skill->unit_onout), HP_POP2(HP_skill_unit_onout), 4286 }, - { HP_POP(skill->unit_move_unit_group), HP_POP2(HP_skill_unit_move_unit_group), 4288 }, - { HP_POP(skill->sit), HP_POP2(HP_skill_sit), 4290 }, - { HP_POP(skill->brandishspear), HP_POP2(HP_skill_brandishspear), 4292 }, - { HP_POP(skill->repairweapon), HP_POP2(HP_skill_repairweapon), 4294 }, - { HP_POP(skill->identify), HP_POP2(HP_skill_identify), 4296 }, - { HP_POP(skill->weaponrefine), HP_POP2(HP_skill_weaponrefine), 4298 }, - { HP_POP(skill->autospell), HP_POP2(HP_skill_autospell), 4300 }, - { HP_POP(skill->calc_heal), HP_POP2(HP_skill_calc_heal), 4302 }, - { HP_POP(skill->check_cloaking), HP_POP2(HP_skill_check_cloaking), 4304 }, - { HP_POP(skill->enchant_elemental_end), HP_POP2(HP_skill_enchant_elemental_end), 4306 }, - { HP_POP(skill->not_ok), HP_POP2(HP_skill_not_ok), 4308 }, - { HP_POP(skill->not_ok_hom), HP_POP2(HP_skill_not_ok_hom), 4310 }, - { HP_POP(skill->not_ok_mercenary), HP_POP2(HP_skill_not_ok_mercenary), 4312 }, - { HP_POP(skill->chastle_mob_changetarget), HP_POP2(HP_skill_chastle_mob_changetarget), 4314 }, - { HP_POP(skill->can_produce_mix), HP_POP2(HP_skill_can_produce_mix), 4316 }, - { HP_POP(skill->produce_mix), HP_POP2(HP_skill_produce_mix), 4318 }, - { HP_POP(skill->arrow_create), HP_POP2(HP_skill_arrow_create), 4320 }, - { HP_POP(skill->castend_nodamage_id), HP_POP2(HP_skill_castend_nodamage_id), 4322 }, - { HP_POP(skill->castend_damage_id), HP_POP2(HP_skill_castend_damage_id), 4324 }, - { HP_POP(skill->castend_pos2), HP_POP2(HP_skill_castend_pos2), 4326 }, - { HP_POP(skill->blockpc_start), HP_POP2(HP_skill_blockpc_start), 4328 }, - { HP_POP(skill->blockhomun_start), HP_POP2(HP_skill_blockhomun_start), 4330 }, - { HP_POP(skill->blockmerc_start), HP_POP2(HP_skill_blockmerc_start), 4332 }, - { HP_POP(skill->attack), HP_POP2(HP_skill_attack), 4334 }, - { HP_POP(skill->attack_area), HP_POP2(HP_skill_attack_area), 4336 }, - { HP_POP(skill->area_sub), HP_POP2(HP_skill_area_sub), 4338 }, - { HP_POP(skill->area_sub_count), HP_POP2(HP_skill_area_sub_count), 4340 }, - { HP_POP(skill->check_unit_range), HP_POP2(HP_skill_check_unit_range), 4342 }, - { HP_POP(skill->check_unit_range_sub), HP_POP2(HP_skill_check_unit_range_sub), 4344 }, - { HP_POP(skill->check_unit_range2), HP_POP2(HP_skill_check_unit_range2), 4346 }, - { HP_POP(skill->check_unit_range2_sub), HP_POP2(HP_skill_check_unit_range2_sub), 4348 }, - { HP_POP(skill->toggle_magicpower), HP_POP2(HP_skill_toggle_magicpower), 4350 }, - { HP_POP(skill->magic_reflect), HP_POP2(HP_skill_magic_reflect), 4352 }, - { HP_POP(skill->onskillusage), HP_POP2(HP_skill_onskillusage), 4354 }, - { HP_POP(skill->cell_overlap), HP_POP2(HP_skill_cell_overlap), 4356 }, - { HP_POP(skill->timerskill), HP_POP2(HP_skill_timerskill), 4358 }, - { HP_POP(skill->trap_splash), HP_POP2(HP_skill_trap_splash), 4360 }, - { HP_POP(skill->check_condition_mercenary), HP_POP2(HP_skill_check_condition_mercenary), 4362 }, - { HP_POP(skill->locate_element_field), HP_POP2(HP_skill_locate_element_field), 4364 }, - { HP_POP(skill->graffitiremover), HP_POP2(HP_skill_graffitiremover), 4366 }, - { HP_POP(skill->activate_reverberation), HP_POP2(HP_skill_activate_reverberation), 4368 }, - { HP_POP(skill->dance_overlap_sub), HP_POP2(HP_skill_dance_overlap_sub), 4370 }, - { HP_POP(skill->dance_overlap), HP_POP2(HP_skill_dance_overlap), 4372 }, - { HP_POP(skill->get_unit_layout), HP_POP2(HP_skill_get_unit_layout), 4374 }, - { HP_POP(skill->frostjoke_scream), HP_POP2(HP_skill_frostjoke_scream), 4376 }, - { HP_POP(skill->greed), HP_POP2(HP_skill_greed), 4378 }, - { HP_POP(skill->destroy_trap), HP_POP2(HP_skill_destroy_trap), 4380 }, - { HP_POP(skill->icewall_block), HP_POP2(HP_skill_icewall_block), 4382 }, - { HP_POP(skill->unitgrouptickset_search), HP_POP2(HP_skill_unitgrouptickset_search), 4384 }, - { HP_POP(skill->dance_switch), HP_POP2(HP_skill_dance_switch), 4386 }, - { HP_POP(skill->check_condition_char_sub), HP_POP2(HP_skill_check_condition_char_sub), 4388 }, - { HP_POP(skill->check_condition_mob_master_sub), HP_POP2(HP_skill_check_condition_mob_master_sub), 4390 }, - { HP_POP(skill->brandishspear_first), HP_POP2(HP_skill_brandishspear_first), 4392 }, - { HP_POP(skill->brandishspear_dir), HP_POP2(HP_skill_brandishspear_dir), 4394 }, - { HP_POP(skill->get_fixed_cast), HP_POP2(HP_skill_get_fixed_cast), 4396 }, - { HP_POP(skill->sit_count), HP_POP2(HP_skill_sit_count), 4398 }, - { HP_POP(skill->sit_in), HP_POP2(HP_skill_sit_in), 4400 }, - { HP_POP(skill->sit_out), HP_POP2(HP_skill_sit_out), 4402 }, - { HP_POP(skill->unitsetmapcell), HP_POP2(HP_skill_unitsetmapcell), 4404 }, - { HP_POP(skill->unit_onplace_timer), HP_POP2(HP_skill_unit_onplace_timer), 4406 }, - { HP_POP(skill->unit_effect), HP_POP2(HP_skill_unit_effect), 4408 }, - { HP_POP(skill->unit_timer_sub_onplace), HP_POP2(HP_skill_unit_timer_sub_onplace), 4410 }, - { HP_POP(skill->unit_move_sub), HP_POP2(HP_skill_unit_move_sub), 4412 }, - { HP_POP(skill->blockpc_end), HP_POP2(HP_skill_blockpc_end), 4414 }, - { HP_POP(skill->blockhomun_end), HP_POP2(HP_skill_blockhomun_end), 4416 }, - { HP_POP(skill->blockmerc_end), HP_POP2(HP_skill_blockmerc_end), 4418 }, - { HP_POP(skill->split_atoi), HP_POP2(HP_skill_split_atoi), 4420 }, - { HP_POP(skill->unit_timer), HP_POP2(HP_skill_unit_timer), 4422 }, - { HP_POP(skill->unit_timer_sub), HP_POP2(HP_skill_unit_timer_sub), 4424 }, - { HP_POP(skill->init_unit_layout), HP_POP2(HP_skill_init_unit_layout), 4426 }, - { HP_POP(skill->parse_row_skilldb), HP_POP2(HP_skill_parse_row_skilldb), 4428 }, - { HP_POP(skill->parse_row_requiredb), HP_POP2(HP_skill_parse_row_requiredb), 4430 }, - { HP_POP(skill->parse_row_castdb), HP_POP2(HP_skill_parse_row_castdb), 4432 }, - { HP_POP(skill->parse_row_castnodexdb), HP_POP2(HP_skill_parse_row_castnodexdb), 4434 }, - { HP_POP(skill->parse_row_unitdb), HP_POP2(HP_skill_parse_row_unitdb), 4436 }, - { HP_POP(skill->parse_row_producedb), HP_POP2(HP_skill_parse_row_producedb), 4438 }, - { HP_POP(skill->parse_row_createarrowdb), HP_POP2(HP_skill_parse_row_createarrowdb), 4440 }, - { HP_POP(skill->parse_row_abradb), HP_POP2(HP_skill_parse_row_abradb), 4442 }, - { HP_POP(skill->parse_row_spellbookdb), HP_POP2(HP_skill_parse_row_spellbookdb), 4444 }, - { HP_POP(skill->parse_row_magicmushroomdb), HP_POP2(HP_skill_parse_row_magicmushroomdb), 4446 }, - { HP_POP(skill->parse_row_reproducedb), HP_POP2(HP_skill_parse_row_reproducedb), 4448 }, - { HP_POP(skill->parse_row_improvisedb), HP_POP2(HP_skill_parse_row_improvisedb), 4450 }, - { HP_POP(skill->parse_row_changematerialdb), HP_POP2(HP_skill_parse_row_changematerialdb), 4452 }, - { HP_POP(skill->usave_add), HP_POP2(HP_skill_usave_add), 4454 }, - { HP_POP(skill->usave_trigger), HP_POP2(HP_skill_usave_trigger), 4456 }, - { HP_POP(skill->cooldown_load), HP_POP2(HP_skill_cooldown_load), 4458 }, - { HP_POP(skill->spellbook), HP_POP2(HP_skill_spellbook), 4460 }, - { HP_POP(skill->block_check), HP_POP2(HP_skill_block_check), 4462 }, - { HP_POP(skill->detonator), HP_POP2(HP_skill_detonator), 4464 }, - { HP_POP(skill->check_camouflage), HP_POP2(HP_skill_check_camouflage), 4466 }, - { HP_POP(skill->magicdecoy), HP_POP2(HP_skill_magicdecoy), 4468 }, - { HP_POP(skill->poisoningweapon), HP_POP2(HP_skill_poisoningweapon), 4470 }, - { HP_POP(skill->select_menu), HP_POP2(HP_skill_select_menu), 4472 }, - { HP_POP(skill->elementalanalysis), HP_POP2(HP_skill_elementalanalysis), 4474 }, - { HP_POP(skill->changematerial), HP_POP2(HP_skill_changematerial), 4476 }, - { HP_POP(skill->get_elemental_type), HP_POP2(HP_skill_get_elemental_type), 4478 }, - { HP_POP(skill->cooldown_save), HP_POP2(HP_skill_cooldown_save), 4480 }, - { HP_POP(skill->maelstrom_suction), HP_POP2(HP_skill_maelstrom_suction), 4482 }, - { HP_POP(skill->get_new_group_id), HP_POP2(HP_skill_get_new_group_id), 4484 }, + { HP_POP(skill->init, HP_skill_init) }, + { HP_POP(skill->final, HP_skill_final) }, + { HP_POP(skill->reload, HP_skill_reload) }, + { HP_POP(skill->read_db, HP_skill_read_db) }, + { HP_POP(skill->get_index, HP_skill_get_index) }, + { HP_POP(skill->get_type, HP_skill_get_type) }, + { HP_POP(skill->get_hit, HP_skill_get_hit) }, + { HP_POP(skill->get_inf, HP_skill_get_inf) }, + { HP_POP(skill->get_ele, HP_skill_get_ele) }, + { HP_POP(skill->get_nk, HP_skill_get_nk) }, + { HP_POP(skill->get_max, HP_skill_get_max) }, + { HP_POP(skill->get_range, HP_skill_get_range) }, + { HP_POP(skill->get_range2, HP_skill_get_range2) }, + { HP_POP(skill->get_splash, HP_skill_get_splash) }, + { HP_POP(skill->get_hp, HP_skill_get_hp) }, + { HP_POP(skill->get_mhp, HP_skill_get_mhp) }, + { HP_POP(skill->get_sp, HP_skill_get_sp) }, + { HP_POP(skill->get_state, HP_skill_get_state) }, + { HP_POP(skill->get_spiritball, HP_skill_get_spiritball) }, + { HP_POP(skill->get_zeny, HP_skill_get_zeny) }, + { HP_POP(skill->get_num, HP_skill_get_num) }, + { HP_POP(skill->get_cast, HP_skill_get_cast) }, + { HP_POP(skill->get_delay, HP_skill_get_delay) }, + { HP_POP(skill->get_walkdelay, HP_skill_get_walkdelay) }, + { HP_POP(skill->get_time, HP_skill_get_time) }, + { HP_POP(skill->get_time2, HP_skill_get_time2) }, + { HP_POP(skill->get_castnodex, HP_skill_get_castnodex) }, + { HP_POP(skill->get_delaynodex, HP_skill_get_delaynodex) }, + { HP_POP(skill->get_castdef, HP_skill_get_castdef) }, + { HP_POP(skill->get_weapontype, HP_skill_get_weapontype) }, + { HP_POP(skill->get_ammotype, HP_skill_get_ammotype) }, + { HP_POP(skill->get_ammo_qty, HP_skill_get_ammo_qty) }, + { HP_POP(skill->get_unit_id, HP_skill_get_unit_id) }, + { HP_POP(skill->get_inf2, HP_skill_get_inf2) }, + { HP_POP(skill->get_castcancel, HP_skill_get_castcancel) }, + { HP_POP(skill->get_maxcount, HP_skill_get_maxcount) }, + { HP_POP(skill->get_blewcount, HP_skill_get_blewcount) }, + { HP_POP(skill->get_unit_flag, HP_skill_get_unit_flag) }, + { HP_POP(skill->get_unit_target, HP_skill_get_unit_target) }, + { HP_POP(skill->get_unit_interval, HP_skill_get_unit_interval) }, + { HP_POP(skill->get_unit_bl_target, HP_skill_get_unit_bl_target) }, + { HP_POP(skill->get_unit_layout_type, HP_skill_get_unit_layout_type) }, + { HP_POP(skill->get_unit_range, HP_skill_get_unit_range) }, + { HP_POP(skill->get_cooldown, HP_skill_get_cooldown) }, + { HP_POP(skill->tree_get_max, HP_skill_tree_get_max) }, + { HP_POP(skill->get_name, HP_skill_get_name) }, + { HP_POP(skill->get_desc, HP_skill_get_desc) }, + { HP_POP(skill->chk, HP_skill_chk) }, + { HP_POP(skill->get_casttype, HP_skill_get_casttype) }, + { HP_POP(skill->get_casttype2, HP_skill_get_casttype2) }, + { HP_POP(skill->name2id, HP_skill_name2id) }, + { HP_POP(skill->isammotype, HP_skill_isammotype) }, + { HP_POP(skill->castend_id, HP_skill_castend_id) }, + { HP_POP(skill->castend_pos, HP_skill_castend_pos) }, + { HP_POP(skill->castend_map, HP_skill_castend_map) }, + { HP_POP(skill->cleartimerskill, HP_skill_cleartimerskill) }, + { HP_POP(skill->addtimerskill, HP_skill_addtimerskill) }, + { HP_POP(skill->additional_effect, HP_skill_additional_effect) }, + { HP_POP(skill->counter_additional_effect, HP_skill_counter_additional_effect) }, + { HP_POP(skill->blown, HP_skill_blown) }, + { HP_POP(skill->break_equip, HP_skill_break_equip) }, + { HP_POP(skill->strip_equip, HP_skill_strip_equip) }, + { HP_POP(skill->id2group, HP_skill_id2group) }, + { HP_POP(skill->unitsetting, HP_skill_unitsetting) }, + { HP_POP(skill->initunit, HP_skill_initunit) }, + { HP_POP(skill->delunit, HP_skill_delunit) }, + { HP_POP(skill->init_unitgroup, HP_skill_init_unitgroup) }, + { HP_POP(skill->del_unitgroup, HP_skill_del_unitgroup) }, + { HP_POP(skill->clear_unitgroup, HP_skill_clear_unitgroup) }, + { HP_POP(skill->clear_group, HP_skill_clear_group) }, + { HP_POP(skill->unit_onplace, HP_skill_unit_onplace) }, + { HP_POP(skill->unit_ondamaged, HP_skill_unit_ondamaged) }, + { HP_POP(skill->cast_fix, HP_skill_cast_fix) }, + { HP_POP(skill->cast_fix_sc, HP_skill_cast_fix_sc) }, + { HP_POP(skill->vf_cast_fix, HP_skill_vf_cast_fix) }, + { HP_POP(skill->delay_fix, HP_skill_delay_fix) }, + { HP_POP(skill->check_condition_castbegin, HP_skill_check_condition_castbegin) }, + { HP_POP(skill->check_condition_castend, HP_skill_check_condition_castend) }, + { HP_POP(skill->consume_requirement, HP_skill_consume_requirement) }, + { HP_POP(skill->get_requirement, HP_skill_get_requirement) }, + { HP_POP(skill->check_pc_partner, HP_skill_check_pc_partner) }, + { HP_POP(skill->unit_move, HP_skill_unit_move) }, + { HP_POP(skill->unit_onleft, HP_skill_unit_onleft) }, + { HP_POP(skill->unit_onout, HP_skill_unit_onout) }, + { HP_POP(skill->unit_move_unit_group, HP_skill_unit_move_unit_group) }, + { HP_POP(skill->sit, HP_skill_sit) }, + { HP_POP(skill->brandishspear, HP_skill_brandishspear) }, + { HP_POP(skill->repairweapon, HP_skill_repairweapon) }, + { HP_POP(skill->identify, HP_skill_identify) }, + { HP_POP(skill->weaponrefine, HP_skill_weaponrefine) }, + { HP_POP(skill->autospell, HP_skill_autospell) }, + { HP_POP(skill->calc_heal, HP_skill_calc_heal) }, + { HP_POP(skill->check_cloaking, HP_skill_check_cloaking) }, + { HP_POP(skill->enchant_elemental_end, HP_skill_enchant_elemental_end) }, + { HP_POP(skill->not_ok, HP_skill_not_ok) }, + { HP_POP(skill->not_ok_hom, HP_skill_not_ok_hom) }, + { HP_POP(skill->not_ok_mercenary, HP_skill_not_ok_mercenary) }, + { HP_POP(skill->chastle_mob_changetarget, HP_skill_chastle_mob_changetarget) }, + { HP_POP(skill->can_produce_mix, HP_skill_can_produce_mix) }, + { HP_POP(skill->produce_mix, HP_skill_produce_mix) }, + { HP_POP(skill->arrow_create, HP_skill_arrow_create) }, + { HP_POP(skill->castend_nodamage_id, HP_skill_castend_nodamage_id) }, + { HP_POP(skill->castend_damage_id, HP_skill_castend_damage_id) }, + { HP_POP(skill->castend_pos2, HP_skill_castend_pos2) }, + { HP_POP(skill->blockpc_start, HP_skill_blockpc_start) }, + { HP_POP(skill->blockhomun_start, HP_skill_blockhomun_start) }, + { HP_POP(skill->blockmerc_start, HP_skill_blockmerc_start) }, + { HP_POP(skill->attack, HP_skill_attack) }, + { HP_POP(skill->attack_area, HP_skill_attack_area) }, + { HP_POP(skill->area_sub, HP_skill_area_sub) }, + { HP_POP(skill->area_sub_count, HP_skill_area_sub_count) }, + { HP_POP(skill->check_unit_range, HP_skill_check_unit_range) }, + { HP_POP(skill->check_unit_range_sub, HP_skill_check_unit_range_sub) }, + { HP_POP(skill->check_unit_range2, HP_skill_check_unit_range2) }, + { HP_POP(skill->check_unit_range2_sub, HP_skill_check_unit_range2_sub) }, + { HP_POP(skill->toggle_magicpower, HP_skill_toggle_magicpower) }, + { HP_POP(skill->magic_reflect, HP_skill_magic_reflect) }, + { HP_POP(skill->onskillusage, HP_skill_onskillusage) }, + { HP_POP(skill->cell_overlap, HP_skill_cell_overlap) }, + { HP_POP(skill->timerskill, HP_skill_timerskill) }, + { HP_POP(skill->trap_splash, HP_skill_trap_splash) }, + { HP_POP(skill->check_condition_mercenary, HP_skill_check_condition_mercenary) }, + { HP_POP(skill->locate_element_field, HP_skill_locate_element_field) }, + { HP_POP(skill->graffitiremover, HP_skill_graffitiremover) }, + { HP_POP(skill->activate_reverberation, HP_skill_activate_reverberation) }, + { HP_POP(skill->dance_overlap_sub, HP_skill_dance_overlap_sub) }, + { HP_POP(skill->dance_overlap, HP_skill_dance_overlap) }, + { HP_POP(skill->get_unit_layout, HP_skill_get_unit_layout) }, + { HP_POP(skill->frostjoke_scream, HP_skill_frostjoke_scream) }, + { HP_POP(skill->greed, HP_skill_greed) }, + { HP_POP(skill->destroy_trap, HP_skill_destroy_trap) }, + { HP_POP(skill->icewall_block, HP_skill_icewall_block) }, + { HP_POP(skill->unitgrouptickset_search, HP_skill_unitgrouptickset_search) }, + { HP_POP(skill->dance_switch, HP_skill_dance_switch) }, + { HP_POP(skill->check_condition_char_sub, HP_skill_check_condition_char_sub) }, + { HP_POP(skill->check_condition_mob_master_sub, HP_skill_check_condition_mob_master_sub) }, + { HP_POP(skill->brandishspear_first, HP_skill_brandishspear_first) }, + { HP_POP(skill->brandishspear_dir, HP_skill_brandishspear_dir) }, + { HP_POP(skill->get_fixed_cast, HP_skill_get_fixed_cast) }, + { HP_POP(skill->sit_count, HP_skill_sit_count) }, + { HP_POP(skill->sit_in, HP_skill_sit_in) }, + { HP_POP(skill->sit_out, HP_skill_sit_out) }, + { HP_POP(skill->unitsetmapcell, HP_skill_unitsetmapcell) }, + { HP_POP(skill->unit_onplace_timer, HP_skill_unit_onplace_timer) }, + { HP_POP(skill->unit_effect, HP_skill_unit_effect) }, + { HP_POP(skill->unit_timer_sub_onplace, HP_skill_unit_timer_sub_onplace) }, + { HP_POP(skill->unit_move_sub, HP_skill_unit_move_sub) }, + { HP_POP(skill->blockpc_end, HP_skill_blockpc_end) }, + { HP_POP(skill->blockhomun_end, HP_skill_blockhomun_end) }, + { HP_POP(skill->blockmerc_end, HP_skill_blockmerc_end) }, + { HP_POP(skill->split_atoi, HP_skill_split_atoi) }, + { HP_POP(skill->unit_timer, HP_skill_unit_timer) }, + { HP_POP(skill->unit_timer_sub, HP_skill_unit_timer_sub) }, + { HP_POP(skill->init_unit_layout, HP_skill_init_unit_layout) }, + { HP_POP(skill->parse_row_skilldb, HP_skill_parse_row_skilldb) }, + { HP_POP(skill->parse_row_requiredb, HP_skill_parse_row_requiredb) }, + { HP_POP(skill->parse_row_castdb, HP_skill_parse_row_castdb) }, + { HP_POP(skill->parse_row_castnodexdb, HP_skill_parse_row_castnodexdb) }, + { HP_POP(skill->parse_row_unitdb, HP_skill_parse_row_unitdb) }, + { HP_POP(skill->parse_row_producedb, HP_skill_parse_row_producedb) }, + { HP_POP(skill->parse_row_createarrowdb, HP_skill_parse_row_createarrowdb) }, + { HP_POP(skill->parse_row_abradb, HP_skill_parse_row_abradb) }, + { HP_POP(skill->parse_row_spellbookdb, HP_skill_parse_row_spellbookdb) }, + { HP_POP(skill->parse_row_magicmushroomdb, HP_skill_parse_row_magicmushroomdb) }, + { HP_POP(skill->parse_row_reproducedb, HP_skill_parse_row_reproducedb) }, + { HP_POP(skill->parse_row_improvisedb, HP_skill_parse_row_improvisedb) }, + { HP_POP(skill->parse_row_changematerialdb, HP_skill_parse_row_changematerialdb) }, + { HP_POP(skill->usave_add, HP_skill_usave_add) }, + { HP_POP(skill->usave_trigger, HP_skill_usave_trigger) }, + { HP_POP(skill->cooldown_load, HP_skill_cooldown_load) }, + { HP_POP(skill->spellbook, HP_skill_spellbook) }, + { HP_POP(skill->block_check, HP_skill_block_check) }, + { HP_POP(skill->detonator, HP_skill_detonator) }, + { HP_POP(skill->check_camouflage, HP_skill_check_camouflage) }, + { HP_POP(skill->magicdecoy, HP_skill_magicdecoy) }, + { HP_POP(skill->poisoningweapon, HP_skill_poisoningweapon) }, + { HP_POP(skill->select_menu, HP_skill_select_menu) }, + { HP_POP(skill->elementalanalysis, HP_skill_elementalanalysis) }, + { HP_POP(skill->changematerial, HP_skill_changematerial) }, + { HP_POP(skill->get_elemental_type, HP_skill_get_elemental_type) }, + { HP_POP(skill->cooldown_save, HP_skill_cooldown_save) }, + { HP_POP(skill->get_new_group_id, HP_skill_get_new_group_id) }, + { HP_POP(skill->check_shadowform, HP_skill_check_shadowform) }, /* status */ - { HP_POP(status->init), HP_POP2(HP_status_init), 4486 }, - { HP_POP(status->final), HP_POP2(HP_status_final), 4488 }, - { HP_POP(status->get_refine_chance), HP_POP2(HP_status_get_refine_chance), 4490 }, - { HP_POP(status->skill2sc), HP_POP2(HP_status_skill2sc), 4492 }, - { HP_POP(status->sc2skill), HP_POP2(HP_status_sc2skill), 4494 }, - { HP_POP(status->sc2scb_flag), HP_POP2(HP_status_sc2scb_flag), 4496 }, - { HP_POP(status->type2relevant_bl_types), HP_POP2(HP_status_type2relevant_bl_types), 4498 }, - { HP_POP(status->get_sc_type), HP_POP2(HP_status_get_sc_type), 4500 }, - { HP_POP(status->damage), HP_POP2(HP_status_damage), 4502 }, - { HP_POP(status->charge), HP_POP2(HP_status_charge), 4504 }, - { HP_POP(status->percent_change), HP_POP2(HP_status_percent_change), 4506 }, - { HP_POP(status->set_hp), HP_POP2(HP_status_set_hp), 4508 }, - { HP_POP(status->set_sp), HP_POP2(HP_status_set_sp), 4510 }, - { HP_POP(status->heal), HP_POP2(HP_status_heal), 4512 }, - { HP_POP(status->revive), HP_POP2(HP_status_revive), 4514 }, - { HP_POP(status->get_regen_data), HP_POP2(HP_status_get_regen_data), 4516 }, - { HP_POP(status->get_status_data), HP_POP2(HP_status_get_status_data), 4518 }, - { HP_POP(status->get_base_status), HP_POP2(HP_status_get_base_status), 4520 }, - { HP_POP(status->get_name), HP_POP2(HP_status_get_name), 4522 }, - { HP_POP(status->get_class), HP_POP2(HP_status_get_class), 4524 }, - { HP_POP(status->get_lv), HP_POP2(HP_status_get_lv), 4526 }, - { HP_POP(status->get_def), HP_POP2(HP_status_get_def), 4528 }, - { HP_POP(status->get_speed), HP_POP2(HP_status_get_speed), 4530 }, - { HP_POP(status->calc_attack_element), HP_POP2(HP_status_calc_attack_element), 4532 }, - { HP_POP(status->get_party_id), HP_POP2(HP_status_get_party_id), 4534 }, - { HP_POP(status->get_guild_id), HP_POP2(HP_status_get_guild_id), 4536 }, - { HP_POP(status->get_emblem_id), HP_POP2(HP_status_get_emblem_id), 4538 }, - { HP_POP(status->get_mexp), HP_POP2(HP_status_get_mexp), 4540 }, - { HP_POP(status->get_race2), HP_POP2(HP_status_get_race2), 4542 }, - { HP_POP(status->get_viewdata), HP_POP2(HP_status_get_viewdata), 4544 }, - { HP_POP(status->set_viewdata), HP_POP2(HP_status_set_viewdata), 4546 }, - { HP_POP(status->change_init), HP_POP2(HP_status_change_init), 4548 }, - { HP_POP(status->get_sc), HP_POP2(HP_status_get_sc), 4550 }, - { HP_POP(status->isdead), HP_POP2(HP_status_isdead), 4552 }, - { HP_POP(status->isimmune), HP_POP2(HP_status_isimmune), 4554 }, - { HP_POP(status->get_sc_def), HP_POP2(HP_status_get_sc_def), 4556 }, - { HP_POP(status->change_start), HP_POP2(HP_status_change_start), 4558 }, - { HP_POP(status->change_end_), HP_POP2(HP_status_change_end_), 4560 }, - { HP_POP(status->kaahi_heal_timer), HP_POP2(HP_status_kaahi_heal_timer), 4562 }, - { HP_POP(status->change_timer), HP_POP2(HP_status_change_timer), 4564 }, - { HP_POP(status->change_timer_sub), HP_POP2(HP_status_change_timer_sub), 4566 }, - { HP_POP(status->change_clear), HP_POP2(HP_status_change_clear), 4568 }, - { HP_POP(status->change_clear_buffs), HP_POP2(HP_status_change_clear_buffs), 4570 }, - { HP_POP(status->calc_bl_), HP_POP2(HP_status_calc_bl_), 4572 }, - { HP_POP(status->calc_mob_), HP_POP2(HP_status_calc_mob_), 4574 }, - { HP_POP(status->calc_pet_), HP_POP2(HP_status_calc_pet_), 4576 }, - { HP_POP(status->calc_pc_), HP_POP2(HP_status_calc_pc_), 4578 }, - { HP_POP(status->calc_homunculus_), HP_POP2(HP_status_calc_homunculus_), 4580 }, - { HP_POP(status->calc_mercenary_), HP_POP2(HP_status_calc_mercenary_), 4582 }, - { HP_POP(status->calc_elemental_), HP_POP2(HP_status_calc_elemental_), 4584 }, - { HP_POP(status->calc_misc), HP_POP2(HP_status_calc_misc), 4586 }, - { HP_POP(status->calc_regen), HP_POP2(HP_status_calc_regen), 4588 }, - { HP_POP(status->calc_regen_rate), HP_POP2(HP_status_calc_regen_rate), 4590 }, - { HP_POP(status->check_skilluse), HP_POP2(HP_status_check_skilluse), 4592 }, - { HP_POP(status->check_visibility), HP_POP2(HP_status_check_visibility), 4594 }, - { HP_POP(status->change_spread), HP_POP2(HP_status_change_spread), 4596 }, - { HP_POP(status->calc_def), HP_POP2(HP_status_calc_def), 4598 }, - { HP_POP(status->calc_def2), HP_POP2(HP_status_calc_def2), 4600 }, - { HP_POP(status->calc_mdef), HP_POP2(HP_status_calc_mdef), 4602 }, - { HP_POP(status->calc_mdef2), HP_POP2(HP_status_calc_mdef2), 4604 }, - { HP_POP(status->calc_batk), HP_POP2(HP_status_calc_batk), 4606 }, - { HP_POP(status->base_matk), HP_POP2(HP_status_base_matk), 4608 }, - { HP_POP(status->get_weapon_atk), HP_POP2(HP_status_get_weapon_atk), 4610 }, - { HP_POP(status->get_total_mdef), HP_POP2(HP_status_get_total_mdef), 4612 }, - { HP_POP(status->get_total_def), HP_POP2(HP_status_get_total_def), 4614 }, - { HP_POP(status->get_matk), HP_POP2(HP_status_get_matk), 4616 }, - { HP_POP(status->readdb), HP_POP2(HP_status_readdb), 4618 }, - { HP_POP(status->initChangeTables), HP_POP2(HP_status_initChangeTables), 4620 }, - { HP_POP(status->initDummyData), HP_POP2(HP_status_initDummyData), 4622 }, - { HP_POP(status->base_amotion_pc), HP_POP2(HP_status_base_amotion_pc), 4624 }, - { HP_POP(status->base_atk), HP_POP2(HP_status_base_atk), 4626 }, - { HP_POP(status->calc_sigma), HP_POP2(HP_status_calc_sigma), 4628 }, - { HP_POP(status->base_pc_maxhp), HP_POP2(HP_status_base_pc_maxhp), 4630 }, - { HP_POP(status->base_pc_maxsp), HP_POP2(HP_status_base_pc_maxsp), 4632 }, - { HP_POP(status->calc_npc_), HP_POP2(HP_status_calc_npc_), 4634 }, - { HP_POP(status->calc_str), HP_POP2(HP_status_calc_str), 4636 }, - { HP_POP(status->calc_agi), HP_POP2(HP_status_calc_agi), 4638 }, - { HP_POP(status->calc_vit), HP_POP2(HP_status_calc_vit), 4640 }, - { HP_POP(status->calc_int), HP_POP2(HP_status_calc_int), 4642 }, - { HP_POP(status->calc_dex), HP_POP2(HP_status_calc_dex), 4644 }, - { HP_POP(status->calc_luk), HP_POP2(HP_status_calc_luk), 4646 }, - { HP_POP(status->calc_watk), HP_POP2(HP_status_calc_watk), 4648 }, - { HP_POP(status->calc_matk), HP_POP2(HP_status_calc_matk), 4650 }, - { HP_POP(status->calc_hit), HP_POP2(HP_status_calc_hit), 4652 }, - { HP_POP(status->calc_critical), HP_POP2(HP_status_calc_critical), 4654 }, - { HP_POP(status->calc_flee), HP_POP2(HP_status_calc_flee), 4656 }, - { HP_POP(status->calc_flee2), HP_POP2(HP_status_calc_flee2), 4658 }, - { HP_POP(status->calc_speed), HP_POP2(HP_status_calc_speed), 4660 }, - { HP_POP(status->calc_aspd_rate), HP_POP2(HP_status_calc_aspd_rate), 4662 }, - { HP_POP(status->calc_dmotion), HP_POP2(HP_status_calc_dmotion), 4664 }, - { HP_POP(status->calc_aspd), HP_POP2(HP_status_calc_aspd), 4666 }, - { HP_POP(status->calc_fix_aspd), HP_POP2(HP_status_calc_fix_aspd), 4668 }, - { HP_POP(status->calc_maxhp), HP_POP2(HP_status_calc_maxhp), 4670 }, - { HP_POP(status->calc_maxsp), HP_POP2(HP_status_calc_maxsp), 4672 }, - { HP_POP(status->calc_element), HP_POP2(HP_status_calc_element), 4674 }, - { HP_POP(status->calc_element_lv), HP_POP2(HP_status_calc_element_lv), 4676 }, - { HP_POP(status->calc_mode), HP_POP2(HP_status_calc_mode), 4678 }, - { HP_POP(status->calc_ematk), HP_POP2(HP_status_calc_ematk), 4680 }, - { HP_POP(status->calc_bl_main), HP_POP2(HP_status_calc_bl_main), 4682 }, - { HP_POP(status->display_add), HP_POP2(HP_status_display_add), 4684 }, - { HP_POP(status->display_remove), HP_POP2(HP_status_display_remove), 4686 }, - { HP_POP(status->natural_heal), HP_POP2(HP_status_natural_heal), 4688 }, - { HP_POP(status->natural_heal_timer), HP_POP2(HP_status_natural_heal_timer), 4690 }, - { HP_POP(status->readdb_job1), HP_POP2(HP_status_readdb_job1), 4692 }, - { HP_POP(status->readdb_job2), HP_POP2(HP_status_readdb_job2), 4694 }, - { HP_POP(status->readdb_sizefix), HP_POP2(HP_status_readdb_sizefix), 4696 }, - { HP_POP(status->readdb_refine), HP_POP2(HP_status_readdb_refine), 4698 }, - { HP_POP(status->readdb_scconfig), HP_POP2(HP_status_readdb_scconfig), 4700 }, + { HP_POP(status->init, HP_status_init) }, + { HP_POP(status->final, HP_status_final) }, + { HP_POP(status->get_refine_chance, HP_status_get_refine_chance) }, + { HP_POP(status->skill2sc, HP_status_skill2sc) }, + { HP_POP(status->sc2skill, HP_status_sc2skill) }, + { HP_POP(status->sc2scb_flag, HP_status_sc2scb_flag) }, + { HP_POP(status->type2relevant_bl_types, HP_status_type2relevant_bl_types) }, + { HP_POP(status->get_sc_type, HP_status_get_sc_type) }, + { HP_POP(status->damage, HP_status_damage) }, + { HP_POP(status->charge, HP_status_charge) }, + { HP_POP(status->percent_change, HP_status_percent_change) }, + { HP_POP(status->set_hp, HP_status_set_hp) }, + { HP_POP(status->set_sp, HP_status_set_sp) }, + { HP_POP(status->heal, HP_status_heal) }, + { HP_POP(status->revive, HP_status_revive) }, + { HP_POP(status->fixed_revive, HP_status_fixed_revive) }, + { HP_POP(status->get_regen_data, HP_status_get_regen_data) }, + { HP_POP(status->get_status_data, HP_status_get_status_data) }, + { HP_POP(status->get_base_status, HP_status_get_base_status) }, + { HP_POP(status->get_name, HP_status_get_name) }, + { HP_POP(status->get_class, HP_status_get_class) }, + { HP_POP(status->get_lv, HP_status_get_lv) }, + { HP_POP(status->get_def, HP_status_get_def) }, + { HP_POP(status->get_speed, HP_status_get_speed) }, + { HP_POP(status->calc_attack_element, HP_status_calc_attack_element) }, + { HP_POP(status->get_party_id, HP_status_get_party_id) }, + { HP_POP(status->get_guild_id, HP_status_get_guild_id) }, + { HP_POP(status->get_emblem_id, HP_status_get_emblem_id) }, + { HP_POP(status->get_mexp, HP_status_get_mexp) }, + { HP_POP(status->get_race2, HP_status_get_race2) }, + { HP_POP(status->get_viewdata, HP_status_get_viewdata) }, + { HP_POP(status->set_viewdata, HP_status_set_viewdata) }, + { HP_POP(status->change_init, HP_status_change_init) }, + { HP_POP(status->get_sc, HP_status_get_sc) }, + { HP_POP(status->isdead, HP_status_isdead) }, + { HP_POP(status->isimmune, HP_status_isimmune) }, + { HP_POP(status->get_sc_def, HP_status_get_sc_def) }, + { HP_POP(status->change_start, HP_status_change_start) }, + { HP_POP(status->change_end_, HP_status_change_end_) }, + { HP_POP(status->kaahi_heal_timer, HP_status_kaahi_heal_timer) }, + { HP_POP(status->change_timer, HP_status_change_timer) }, + { HP_POP(status->change_timer_sub, HP_status_change_timer_sub) }, + { HP_POP(status->change_clear, HP_status_change_clear) }, + { HP_POP(status->change_clear_buffs, HP_status_change_clear_buffs) }, + { HP_POP(status->calc_bl_, HP_status_calc_bl_) }, + { HP_POP(status->calc_mob_, HP_status_calc_mob_) }, + { HP_POP(status->calc_pet_, HP_status_calc_pet_) }, + { HP_POP(status->calc_pc_, HP_status_calc_pc_) }, + { HP_POP(status->calc_homunculus_, HP_status_calc_homunculus_) }, + { HP_POP(status->calc_mercenary_, HP_status_calc_mercenary_) }, + { HP_POP(status->calc_elemental_, HP_status_calc_elemental_) }, + { HP_POP(status->calc_misc, HP_status_calc_misc) }, + { HP_POP(status->calc_regen, HP_status_calc_regen) }, + { HP_POP(status->calc_regen_rate, HP_status_calc_regen_rate) }, + { HP_POP(status->check_skilluse, HP_status_check_skilluse) }, + { HP_POP(status->check_visibility, HP_status_check_visibility) }, + { HP_POP(status->change_spread, HP_status_change_spread) }, + { HP_POP(status->calc_def, HP_status_calc_def) }, + { HP_POP(status->calc_def2, HP_status_calc_def2) }, + { HP_POP(status->calc_mdef, HP_status_calc_mdef) }, + { HP_POP(status->calc_mdef2, HP_status_calc_mdef2) }, + { HP_POP(status->calc_batk, HP_status_calc_batk) }, + { HP_POP(status->base_matk, HP_status_base_matk) }, + { HP_POP(status->get_weapon_atk, HP_status_get_weapon_atk) }, + { HP_POP(status->get_total_mdef, HP_status_get_total_mdef) }, + { HP_POP(status->get_total_def, HP_status_get_total_def) }, + { HP_POP(status->get_matk, HP_status_get_matk) }, + { HP_POP(status->readdb, HP_status_readdb) }, + { HP_POP(status->initChangeTables, HP_status_initChangeTables) }, + { HP_POP(status->initDummyData, HP_status_initDummyData) }, + { HP_POP(status->base_amotion_pc, HP_status_base_amotion_pc) }, + { HP_POP(status->base_atk, HP_status_base_atk) }, + { HP_POP(status->calc_sigma, HP_status_calc_sigma) }, + { HP_POP(status->base_pc_maxhp, HP_status_base_pc_maxhp) }, + { HP_POP(status->base_pc_maxsp, HP_status_base_pc_maxsp) }, + { HP_POP(status->calc_npc_, HP_status_calc_npc_) }, + { HP_POP(status->calc_str, HP_status_calc_str) }, + { HP_POP(status->calc_agi, HP_status_calc_agi) }, + { HP_POP(status->calc_vit, HP_status_calc_vit) }, + { HP_POP(status->calc_int, HP_status_calc_int) }, + { HP_POP(status->calc_dex, HP_status_calc_dex) }, + { HP_POP(status->calc_luk, HP_status_calc_luk) }, + { HP_POP(status->calc_watk, HP_status_calc_watk) }, + { HP_POP(status->calc_matk, HP_status_calc_matk) }, + { HP_POP(status->calc_hit, HP_status_calc_hit) }, + { HP_POP(status->calc_critical, HP_status_calc_critical) }, + { HP_POP(status->calc_flee, HP_status_calc_flee) }, + { HP_POP(status->calc_flee2, HP_status_calc_flee2) }, + { HP_POP(status->calc_speed, HP_status_calc_speed) }, + { HP_POP(status->calc_aspd_rate, HP_status_calc_aspd_rate) }, + { HP_POP(status->calc_dmotion, HP_status_calc_dmotion) }, + { HP_POP(status->calc_aspd, HP_status_calc_aspd) }, + { HP_POP(status->calc_fix_aspd, HP_status_calc_fix_aspd) }, + { HP_POP(status->calc_maxhp, HP_status_calc_maxhp) }, + { HP_POP(status->calc_maxsp, HP_status_calc_maxsp) }, + { HP_POP(status->calc_element, HP_status_calc_element) }, + { HP_POP(status->calc_element_lv, HP_status_calc_element_lv) }, + { HP_POP(status->calc_mode, HP_status_calc_mode) }, + { HP_POP(status->calc_ematk, HP_status_calc_ematk) }, + { HP_POP(status->calc_bl_main, HP_status_calc_bl_main) }, + { HP_POP(status->display_add, HP_status_display_add) }, + { HP_POP(status->display_remove, HP_status_display_remove) }, + { HP_POP(status->natural_heal, HP_status_natural_heal) }, + { HP_POP(status->natural_heal_timer, HP_status_natural_heal_timer) }, + { HP_POP(status->readdb_job1, HP_status_readdb_job1) }, + { HP_POP(status->readdb_job2, HP_status_readdb_job2) }, + { HP_POP(status->readdb_sizefix, HP_status_readdb_sizefix) }, + { HP_POP(status->readdb_refine, HP_status_readdb_refine) }, + { HP_POP(status->readdb_scconfig, HP_status_readdb_scconfig) }, /* storage */ - { HP_POP(storage->reconnect), HP_POP2(HP_storage_reconnect), 4702 }, - { HP_POP(storage->delitem), HP_POP2(HP_storage_delitem), 4704 }, - { HP_POP(storage->open), HP_POP2(HP_storage_open), 4706 }, - { HP_POP(storage->add), HP_POP2(HP_storage_add), 4708 }, - { HP_POP(storage->get), HP_POP2(HP_storage_get), 4710 }, - { HP_POP(storage->additem), HP_POP2(HP_storage_additem), 4712 }, - { HP_POP(storage->addfromcart), HP_POP2(HP_storage_addfromcart), 4714 }, - { HP_POP(storage->gettocart), HP_POP2(HP_storage_gettocart), 4716 }, - { HP_POP(storage->close), HP_POP2(HP_storage_close), 4718 }, - { HP_POP(storage->pc_quit), HP_POP2(HP_storage_pc_quit), 4720 }, - { HP_POP(storage->comp_item), HP_POP2(HP_storage_comp_item), 4722 }, - { HP_POP(storage->sortitem), HP_POP2(HP_storage_sortitem), 4724 }, - { HP_POP(storage->reconnect_sub), HP_POP2(HP_storage_reconnect_sub), 4726 }, + { HP_POP(storage->reconnect, HP_storage_reconnect) }, + { HP_POP(storage->delitem, HP_storage_delitem) }, + { HP_POP(storage->open, HP_storage_open) }, + { HP_POP(storage->add, HP_storage_add) }, + { HP_POP(storage->get, HP_storage_get) }, + { HP_POP(storage->additem, HP_storage_additem) }, + { HP_POP(storage->addfromcart, HP_storage_addfromcart) }, + { HP_POP(storage->gettocart, HP_storage_gettocart) }, + { HP_POP(storage->close, HP_storage_close) }, + { HP_POP(storage->pc_quit, HP_storage_pc_quit) }, + { HP_POP(storage->comp_item, HP_storage_comp_item) }, + { HP_POP(storage->sortitem, HP_storage_sortitem) }, + { HP_POP(storage->reconnect_sub, HP_storage_reconnect_sub) }, /* trade */ - { HP_POP(trade->request), HP_POP2(HP_trade_request), 4728 }, - { HP_POP(trade->ack), HP_POP2(HP_trade_ack), 4730 }, - { HP_POP(trade->check_impossible), HP_POP2(HP_trade_check_impossible), 4732 }, - { HP_POP(trade->check), HP_POP2(HP_trade_check), 4734 }, - { HP_POP(trade->additem), HP_POP2(HP_trade_additem), 4736 }, - { HP_POP(trade->addzeny), HP_POP2(HP_trade_addzeny), 4738 }, - { HP_POP(trade->ok), HP_POP2(HP_trade_ok), 4740 }, - { HP_POP(trade->cancel), HP_POP2(HP_trade_cancel), 4742 }, - { HP_POP(trade->commit), HP_POP2(HP_trade_commit), 4744 }, + { HP_POP(trade->request, HP_trade_request) }, + { HP_POP(trade->ack, HP_trade_ack) }, + { HP_POP(trade->check_impossible, HP_trade_check_impossible) }, + { HP_POP(trade->check, HP_trade_check) }, + { HP_POP(trade->additem, HP_trade_additem) }, + { HP_POP(trade->addzeny, HP_trade_addzeny) }, + { HP_POP(trade->ok, HP_trade_ok) }, + { HP_POP(trade->cancel, HP_trade_cancel) }, + { HP_POP(trade->commit, HP_trade_commit) }, /* unit */ - { HP_POP(unit->init), HP_POP2(HP_unit_init), 4746 }, - { HP_POP(unit->final), HP_POP2(HP_unit_final), 4748 }, - { HP_POP(unit->bl2ud), HP_POP2(HP_unit_bl2ud), 4750 }, - { HP_POP(unit->bl2ud2), HP_POP2(HP_unit_bl2ud2), 4752 }, - { HP_POP(unit->attack_timer), HP_POP2(HP_unit_attack_timer), 4754 }, - { HP_POP(unit->walktoxy_timer), HP_POP2(HP_unit_walktoxy_timer), 4756 }, - { HP_POP(unit->walktoxy_sub), HP_POP2(HP_unit_walktoxy_sub), 4758 }, - { HP_POP(unit->delay_walktoxy_timer), HP_POP2(HP_unit_delay_walktoxy_timer), 4760 }, - { HP_POP(unit->walktoxy), HP_POP2(HP_unit_walktoxy), 4762 }, - { HP_POP(unit->walktobl_sub), HP_POP2(HP_unit_walktobl_sub), 4764 }, - { HP_POP(unit->walktobl), HP_POP2(HP_unit_walktobl), 4766 }, - { HP_POP(unit->run), HP_POP2(HP_unit_run), 4768 }, - { HP_POP(unit->wugdash), HP_POP2(HP_unit_wugdash), 4770 }, - { HP_POP(unit->escape), HP_POP2(HP_unit_escape), 4772 }, - { HP_POP(unit->movepos), HP_POP2(HP_unit_movepos), 4774 }, - { HP_POP(unit->setdir), HP_POP2(HP_unit_setdir), 4776 }, - { HP_POP(unit->getdir), HP_POP2(HP_unit_getdir), 4778 }, - { HP_POP(unit->blown), HP_POP2(HP_unit_blown), 4780 }, - { HP_POP(unit->warp), HP_POP2(HP_unit_warp), 4782 }, - { HP_POP(unit->stop_walking), HP_POP2(HP_unit_stop_walking), 4784 }, - { HP_POP(unit->skilluse_id), HP_POP2(HP_unit_skilluse_id), 4786 }, - { HP_POP(unit->is_walking), HP_POP2(HP_unit_is_walking), 4788 }, - { HP_POP(unit->can_move), HP_POP2(HP_unit_can_move), 4790 }, - { HP_POP(unit->resume_running), HP_POP2(HP_unit_resume_running), 4792 }, - { HP_POP(unit->set_walkdelay), HP_POP2(HP_unit_set_walkdelay), 4794 }, - { HP_POP(unit->skilluse_id2), HP_POP2(HP_unit_skilluse_id2), 4796 }, - { HP_POP(unit->skilluse_pos), HP_POP2(HP_unit_skilluse_pos), 4798 }, - { HP_POP(unit->skilluse_pos2), HP_POP2(HP_unit_skilluse_pos2), 4800 }, - { HP_POP(unit->set_target), HP_POP2(HP_unit_set_target), 4802 }, - { HP_POP(unit->stop_attack), HP_POP2(HP_unit_stop_attack), 4804 }, - { HP_POP(unit->unattackable), HP_POP2(HP_unit_unattackable), 4806 }, - { HP_POP(unit->attack), HP_POP2(HP_unit_attack), 4808 }, - { HP_POP(unit->cancel_combo), HP_POP2(HP_unit_cancel_combo), 4810 }, - { HP_POP(unit->can_reach_pos), HP_POP2(HP_unit_can_reach_pos), 4812 }, - { HP_POP(unit->can_reach_bl), HP_POP2(HP_unit_can_reach_bl), 4814 }, - { HP_POP(unit->calc_pos), HP_POP2(HP_unit_calc_pos), 4816 }, - { HP_POP(unit->attack_timer_sub), HP_POP2(HP_unit_attack_timer_sub), 4818 }, - { HP_POP(unit->skillcastcancel), HP_POP2(HP_unit_skillcastcancel), 4820 }, - { HP_POP(unit->dataset), HP_POP2(HP_unit_dataset), 4822 }, - { HP_POP(unit->counttargeted), HP_POP2(HP_unit_counttargeted), 4824 }, - { HP_POP(unit->fixdamage), HP_POP2(HP_unit_fixdamage), 4826 }, - { HP_POP(unit->changeviewsize), HP_POP2(HP_unit_changeviewsize), 4828 }, - { HP_POP(unit->remove_map), HP_POP2(HP_unit_remove_map), 4830 }, - { HP_POP(unit->remove_map_pc), HP_POP2(HP_unit_remove_map_pc), 4832 }, - { HP_POP(unit->free_pc), HP_POP2(HP_unit_free_pc), 4834 }, - { HP_POP(unit->free), HP_POP2(HP_unit_free), 4836 }, + { HP_POP(unit->init, HP_unit_init) }, + { HP_POP(unit->final, HP_unit_final) }, + { HP_POP(unit->bl2ud, HP_unit_bl2ud) }, + { HP_POP(unit->bl2ud2, HP_unit_bl2ud2) }, + { HP_POP(unit->attack_timer, HP_unit_attack_timer) }, + { HP_POP(unit->walktoxy_timer, HP_unit_walktoxy_timer) }, + { HP_POP(unit->walktoxy_sub, HP_unit_walktoxy_sub) }, + { HP_POP(unit->delay_walktoxy_timer, HP_unit_delay_walktoxy_timer) }, + { HP_POP(unit->walktoxy, HP_unit_walktoxy) }, + { HP_POP(unit->walktobl_sub, HP_unit_walktobl_sub) }, + { HP_POP(unit->walktobl, HP_unit_walktobl) }, + { HP_POP(unit->run, HP_unit_run) }, + { HP_POP(unit->wugdash, HP_unit_wugdash) }, + { HP_POP(unit->escape, HP_unit_escape) }, + { HP_POP(unit->movepos, HP_unit_movepos) }, + { HP_POP(unit->setdir, HP_unit_setdir) }, + { HP_POP(unit->getdir, HP_unit_getdir) }, + { HP_POP(unit->blown, HP_unit_blown) }, + { HP_POP(unit->warp, HP_unit_warp) }, + { HP_POP(unit->stop_walking, HP_unit_stop_walking) }, + { HP_POP(unit->skilluse_id, HP_unit_skilluse_id) }, + { HP_POP(unit->is_walking, HP_unit_is_walking) }, + { HP_POP(unit->can_move, HP_unit_can_move) }, + { HP_POP(unit->resume_running, HP_unit_resume_running) }, + { HP_POP(unit->set_walkdelay, HP_unit_set_walkdelay) }, + { HP_POP(unit->skilluse_id2, HP_unit_skilluse_id2) }, + { HP_POP(unit->skilluse_pos, HP_unit_skilluse_pos) }, + { HP_POP(unit->skilluse_pos2, HP_unit_skilluse_pos2) }, + { HP_POP(unit->set_target, HP_unit_set_target) }, + { HP_POP(unit->stop_attack, HP_unit_stop_attack) }, + { HP_POP(unit->unattackable, HP_unit_unattackable) }, + { HP_POP(unit->attack, HP_unit_attack) }, + { HP_POP(unit->cancel_combo, HP_unit_cancel_combo) }, + { HP_POP(unit->can_reach_pos, HP_unit_can_reach_pos) }, + { HP_POP(unit->can_reach_bl, HP_unit_can_reach_bl) }, + { HP_POP(unit->calc_pos, HP_unit_calc_pos) }, + { HP_POP(unit->attack_timer_sub, HP_unit_attack_timer_sub) }, + { HP_POP(unit->skillcastcancel, HP_unit_skillcastcancel) }, + { HP_POP(unit->dataset, HP_unit_dataset) }, + { HP_POP(unit->counttargeted, HP_unit_counttargeted) }, + { HP_POP(unit->fixdamage, HP_unit_fixdamage) }, + { HP_POP(unit->changeviewsize, HP_unit_changeviewsize) }, + { HP_POP(unit->remove_map, HP_unit_remove_map) }, + { HP_POP(unit->remove_map_pc, HP_unit_remove_map_pc) }, + { HP_POP(unit->free_pc, HP_unit_free_pc) }, + { HP_POP(unit->free, HP_unit_free) }, /* vending */ - { HP_POP(vending->init), HP_POP2(HP_vending_init), 4838 }, - { HP_POP(vending->final), HP_POP2(HP_vending_final), 4840 }, - { HP_POP(vending->close), HP_POP2(HP_vending_close), 4842 }, - { HP_POP(vending->open), HP_POP2(HP_vending_open), 4844 }, - { HP_POP(vending->list), HP_POP2(HP_vending_list), 4846 }, - { HP_POP(vending->purchase), HP_POP2(HP_vending_purchase), 4848 }, - { HP_POP(vending->search), HP_POP2(HP_vending_search), 4850 }, - { HP_POP(vending->searchall), HP_POP2(HP_vending_searchall), 4852 }, + { HP_POP(vending->init, HP_vending_init) }, + { HP_POP(vending->final, HP_vending_final) }, + { HP_POP(vending->close, HP_vending_close) }, + { HP_POP(vending->open, HP_vending_open) }, + { HP_POP(vending->list, HP_vending_list) }, + { HP_POP(vending->purchase, HP_vending_purchase) }, + { HP_POP(vending->search, HP_vending_search) }, + { HP_POP(vending->searchall, HP_vending_searchall) }, }; int HookingPointsLenMax = 41; diff --git a/src/plugins/HPMHooking/HPMHooking.Hooks.inc b/src/plugins/HPMHooking/HPMHooking.Hooks.inc index 3eafd4dbb..3bc658d24 100644 --- a/src/plugins/HPMHooking/HPMHooking.Hooks.inc +++ b/src/plugins/HPMHooking/HPMHooking.Hooks.inc @@ -5,13 +5,13 @@ // as it will get overwritten. /* atcommand */ -void HP_atcommand_init(void) { +void HP_atcommand_init(bool minimal) { int hIndex = 0; if( HPMHooks.count.HP_atcommand_init_pre ) { - void (*preHookFunc) (void); + void (*preHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_atcommand_init_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_atcommand_init_pre[hIndex].func; - preHookFunc(); + preHookFunc(&minimal); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -19,13 +19,13 @@ void HP_atcommand_init(void) { } } { - HPMHooks.source.atcommand.init(); + HPMHooks.source.atcommand.init(minimal); } if( HPMHooks.count.HP_atcommand_init_post ) { - void (*postHookFunc) (void); + void (*postHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_atcommand_init_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_atcommand_init_post[hIndex].func; - postHookFunc(); + postHookFunc(&minimal); } } return; @@ -55,14 +55,14 @@ void HP_atcommand_final(void) { } return; } -bool HP_atcommand_parse(const int fd, struct map_session_data *sd, const char *message, int type) { +bool HP_atcommand_exec(const int fd, struct map_session_data *sd, const char *message, bool player_invoked) { int hIndex = 0; bool retVal___ = false; - if( HPMHooks.count.HP_atcommand_parse_pre ) { - bool (*preHookFunc) (const int *fd, struct map_session_data *sd, const char *message, int *type); - for(hIndex = 0; hIndex < HPMHooks.count.HP_atcommand_parse_pre; hIndex++ ) { - preHookFunc = HPMHooks.list.HP_atcommand_parse_pre[hIndex].func; - retVal___ = preHookFunc(&fd, sd, message, &type); + if( HPMHooks.count.HP_atcommand_exec_pre ) { + bool (*preHookFunc) (const int *fd, struct map_session_data *sd, const char *message, bool *player_invoked); + for(hIndex = 0; hIndex < HPMHooks.count.HP_atcommand_exec_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_atcommand_exec_pre[hIndex].func; + retVal___ = preHookFunc(&fd, sd, message, &player_invoked); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -70,13 +70,13 @@ bool HP_atcommand_parse(const int fd, struct map_session_data *sd, const char *m } } { - retVal___ = HPMHooks.source.atcommand.parse(fd, sd, message, type); + retVal___ = HPMHooks.source.atcommand.exec(fd, sd, message, player_invoked); } - if( HPMHooks.count.HP_atcommand_parse_post ) { - bool (*postHookFunc) (bool retVal___, const int *fd, struct map_session_data *sd, const char *message, int *type); - for(hIndex = 0; hIndex < HPMHooks.count.HP_atcommand_parse_post; hIndex++ ) { - postHookFunc = HPMHooks.list.HP_atcommand_parse_post[hIndex].func; - retVal___ = postHookFunc(retVal___, &fd, sd, message, &type); + if( HPMHooks.count.HP_atcommand_exec_post ) { + bool (*postHookFunc) (bool retVal___, const int *fd, struct map_session_data *sd, const char *message, bool *player_invoked); + for(hIndex = 0; hIndex < HPMHooks.count.HP_atcommand_exec_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_atcommand_exec_post[hIndex].func; + retVal___ = postHookFunc(retVal___, &fd, sd, message, &player_invoked); } } return retVal___; @@ -210,11 +210,11 @@ AtCommandInfo* HP_atcommand_exists(const char *name) { } return retVal___; } -int HP_atcommand_msg_read(const char *cfgName) { +bool HP_atcommand_msg_read(const char *cfgName) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_atcommand_msg_read_pre ) { - int (*preHookFunc) (const char *cfgName); + bool (*preHookFunc) (const char *cfgName); for(hIndex = 0; hIndex < HPMHooks.count.HP_atcommand_msg_read_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_atcommand_msg_read_pre[hIndex].func; retVal___ = preHookFunc(cfgName); @@ -228,7 +228,7 @@ int HP_atcommand_msg_read(const char *cfgName) { retVal___ = HPMHooks.source.atcommand.msg_read(cfgName); } if( HPMHooks.count.HP_atcommand_msg_read_post ) { - int (*postHookFunc) (int retVal___, const char *cfgName); + bool (*postHookFunc) (bool retVal___, const char *cfgName); for(hIndex = 0; hIndex < HPMHooks.count.HP_atcommand_msg_read_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_atcommand_msg_read_post[hIndex].func; retVal___ = postHookFunc(retVal___, cfgName); @@ -763,14 +763,66 @@ void HP_atcommand_base_commands(void) { } return; } +bool HP_atcommand_add(char *name, AtCommandFunc func, bool replace) { + int hIndex = 0; + bool retVal___ = false; + if( HPMHooks.count.HP_atcommand_add_pre ) { + bool (*preHookFunc) (char *name, AtCommandFunc *func, bool *replace); + for(hIndex = 0; hIndex < HPMHooks.count.HP_atcommand_add_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_atcommand_add_pre[hIndex].func; + retVal___ = preHookFunc(name, &func, &replace); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.atcommand.add(name, func, replace); + } + if( HPMHooks.count.HP_atcommand_add_post ) { + bool (*postHookFunc) (bool retVal___, char *name, AtCommandFunc *func, bool *replace); + for(hIndex = 0; hIndex < HPMHooks.count.HP_atcommand_add_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_atcommand_add_post[hIndex].func; + retVal___ = postHookFunc(retVal___, name, &func, &replace); + } + } + return retVal___; +} +const char* HP_atcommand_msg(int msg_number) { + int hIndex = 0; + const char* retVal___ = NULL; + if( HPMHooks.count.HP_atcommand_msg_pre ) { + const char* (*preHookFunc) (int *msg_number); + for(hIndex = 0; hIndex < HPMHooks.count.HP_atcommand_msg_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_atcommand_msg_pre[hIndex].func; + retVal___ = preHookFunc(&msg_number); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.atcommand.msg(msg_number); + } + if( HPMHooks.count.HP_atcommand_msg_post ) { + const char* (*postHookFunc) (const char* retVal___, int *msg_number); + for(hIndex = 0; hIndex < HPMHooks.count.HP_atcommand_msg_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_atcommand_msg_post[hIndex].func; + retVal___ = postHookFunc(retVal___, &msg_number); + } + } + return retVal___; +} /* battle */ -void HP_battle_init(void) { +void HP_battle_init(bool minimal) { int hIndex = 0; if( HPMHooks.count.HP_battle_init_pre ) { - void (*preHookFunc) (void); + void (*preHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_battle_init_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_battle_init_pre[hIndex].func; - preHookFunc(); + preHookFunc(&minimal); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -778,13 +830,13 @@ void HP_battle_init(void) { } } { - HPMHooks.source.battle.init(); + HPMHooks.source.battle.init(minimal); } if( HPMHooks.count.HP_battle_init_post ) { - void (*postHookFunc) (void); + void (*postHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_battle_init_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_battle_init_post[hIndex].func; - postHookFunc(); + postHookFunc(&minimal); } } return; @@ -919,11 +971,11 @@ int64 HP_battle_calc_bg_damage(struct block_list *src, struct block_list *bl, in } return retVal___; } -enum damage_lv HP_battle_weapon_attack(struct block_list *bl, struct block_list *target, unsigned int tick, int flag) { +enum damage_lv HP_battle_weapon_attack(struct block_list *bl, struct block_list *target, int64 tick, int flag) { int hIndex = 0; enum damage_lv retVal___ = ATK_NONE; if( HPMHooks.count.HP_battle_weapon_attack_pre ) { - enum damage_lv (*preHookFunc) (struct block_list *bl, struct block_list *target, unsigned int *tick, int *flag); + enum damage_lv (*preHookFunc) (struct block_list *bl, struct block_list *target, int64 *tick, int *flag); for(hIndex = 0; hIndex < HPMHooks.count.HP_battle_weapon_attack_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_battle_weapon_attack_pre[hIndex].func; retVal___ = preHookFunc(bl, target, &tick, &flag); @@ -937,7 +989,7 @@ enum damage_lv HP_battle_weapon_attack(struct block_list *bl, struct block_list retVal___ = HPMHooks.source.battle.weapon_attack(bl, target, tick, flag); } if( HPMHooks.count.HP_battle_weapon_attack_post ) { - enum damage_lv (*postHookFunc) (enum damage_lv retVal___, struct block_list *bl, struct block_list *target, unsigned int *tick, int *flag); + enum damage_lv (*postHookFunc) (enum damage_lv retVal___, struct block_list *bl, struct block_list *target, int64 *tick, int *flag); for(hIndex = 0; hIndex < HPMHooks.count.HP_battle_weapon_attack_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_battle_weapon_attack_post[hIndex].func; retVal___ = postHookFunc(retVal___, bl, target, &tick, &flag); @@ -972,11 +1024,11 @@ struct Damage HP_battle_calc_weapon_attack(struct block_list *src, struct block_ } return retVal___; } -int HP_battle_delay_damage(unsigned int tick, int amotion, struct block_list *src, struct block_list *target, int attack_type, uint16 skill_id, uint16 skill_lv, int64 damage, enum damage_lv dmg_lv, int ddelay, bool additional_effects) { +int HP_battle_delay_damage(int64 tick, int amotion, struct block_list *src, struct block_list *target, int attack_type, uint16 skill_id, uint16 skill_lv, int64 damage, enum damage_lv dmg_lv, int ddelay, bool additional_effects) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_battle_delay_damage_pre ) { - int (*preHookFunc) (unsigned int *tick, int *amotion, struct block_list *src, struct block_list *target, int *attack_type, uint16 *skill_id, uint16 *skill_lv, int64 *damage, enum damage_lv *dmg_lv, int *ddelay, bool *additional_effects); + int (*preHookFunc) (int64 *tick, int *amotion, struct block_list *src, struct block_list *target, int *attack_type, uint16 *skill_id, uint16 *skill_lv, int64 *damage, enum damage_lv *dmg_lv, int *ddelay, bool *additional_effects); for(hIndex = 0; hIndex < HPMHooks.count.HP_battle_delay_damage_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_battle_delay_damage_pre[hIndex].func; retVal___ = preHookFunc(&tick, &amotion, src, target, &attack_type, &skill_id, &skill_lv, &damage, &dmg_lv, &ddelay, &additional_effects); @@ -990,7 +1042,7 @@ int HP_battle_delay_damage(unsigned int tick, int amotion, struct block_list *sr retVal___ = HPMHooks.source.battle.delay_damage(tick, amotion, src, target, attack_type, skill_id, skill_lv, damage, dmg_lv, ddelay, additional_effects); } if( HPMHooks.count.HP_battle_delay_damage_post ) { - int (*postHookFunc) (int retVal___, unsigned int *tick, int *amotion, struct block_list *src, struct block_list *target, int *attack_type, uint16 *skill_id, uint16 *skill_lv, int64 *damage, enum damage_lv *dmg_lv, int *ddelay, bool *additional_effects); + int (*postHookFunc) (int retVal___, int64 *tick, int *amotion, struct block_list *src, struct block_list *target, int *attack_type, uint16 *skill_id, uint16 *skill_lv, int64 *damage, enum damage_lv *dmg_lv, int *ddelay, bool *additional_effects); for(hIndex = 0; hIndex < HPMHooks.count.HP_battle_delay_damage_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_battle_delay_damage_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tick, &amotion, src, target, &attack_type, &skill_id, &skill_lv, &damage, &dmg_lv, &ddelay, &additional_effects); @@ -1023,31 +1075,30 @@ void HP_battle_drain(struct map_session_data *sd, struct block_list *tbl, int64 } return; } -int64 HP_battle_calc_return_damage(struct block_list *bl, struct block_list *src, int64 *p1, int flag, uint16 skill_id, int *rdelay) { +void HP_battle_reflect_damage(struct block_list *target, struct block_list *src, struct Damage *wd, uint16 skill_id) { int hIndex = 0; - int64 retVal___ = 0; - if( HPMHooks.count.HP_battle_calc_return_damage_pre ) { - int64 (*preHookFunc) (struct block_list *bl, struct block_list *src, int64 *p1, int *flag, uint16 *skill_id, int *rdelay); - for(hIndex = 0; hIndex < HPMHooks.count.HP_battle_calc_return_damage_pre; hIndex++ ) { - preHookFunc = HPMHooks.list.HP_battle_calc_return_damage_pre[hIndex].func; - retVal___ = preHookFunc(bl, src, p1, &flag, &skill_id, rdelay); + if( HPMHooks.count.HP_battle_reflect_damage_pre ) { + void (*preHookFunc) (struct block_list *target, struct block_list *src, struct Damage *wd, uint16 *skill_id); + for(hIndex = 0; hIndex < HPMHooks.count.HP_battle_reflect_damage_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_battle_reflect_damage_pre[hIndex].func; + preHookFunc(target, src, wd, &skill_id); } if( *HPMforce_return ) { *HPMforce_return = false; - return retVal___; + return; } } { - retVal___ = HPMHooks.source.battle.calc_return_damage(bl, src, p1, flag, skill_id, rdelay); + HPMHooks.source.battle.reflect_damage(target, src, wd, skill_id); } - if( HPMHooks.count.HP_battle_calc_return_damage_post ) { - int64 (*postHookFunc) (int64 retVal___, struct block_list *bl, struct block_list *src, int64 *p1, int *flag, uint16 *skill_id, int *rdelay); - for(hIndex = 0; hIndex < HPMHooks.count.HP_battle_calc_return_damage_post; hIndex++ ) { - postHookFunc = HPMHooks.list.HP_battle_calc_return_damage_post[hIndex].func; - retVal___ = postHookFunc(retVal___, bl, src, p1, &flag, &skill_id, rdelay); + if( HPMHooks.count.HP_battle_reflect_damage_post ) { + void (*postHookFunc) (struct block_list *target, struct block_list *src, struct Damage *wd, uint16 *skill_id); + for(hIndex = 0; hIndex < HPMHooks.count.HP_battle_reflect_damage_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_battle_reflect_damage_post[hIndex].func; + postHookFunc(target, src, wd, &skill_id); } } - return retVal___; + return; } int HP_battle_attr_ratio(int atk_elem, int def_type, int def_lv) { int hIndex = 0; @@ -1179,6 +1230,32 @@ int64 HP_battle_calc_masteryfix(struct block_list *src, struct block_list *targe } return retVal___; } +int HP_battle_calc_chorusbonus(struct map_session_data *sd) { + int hIndex = 0; + int retVal___ = 0; + if( HPMHooks.count.HP_battle_calc_chorusbonus_pre ) { + int (*preHookFunc) (struct map_session_data *sd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_battle_calc_chorusbonus_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_battle_calc_chorusbonus_pre[hIndex].func; + retVal___ = preHookFunc(sd); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.battle.calc_chorusbonus(sd); + } + if( HPMHooks.count.HP_battle_calc_chorusbonus_post ) { + int (*postHookFunc) (int retVal___, struct map_session_data *sd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_battle_calc_chorusbonus_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_battle_calc_chorusbonus_post[hIndex].func; + retVal___ = postHookFunc(retVal___, sd); + } + } + return retVal___; +} int HP_battle_calc_skillratio(int attack_type, struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int skillratio, int flag) { int hIndex = 0; int retVal___ = 0; @@ -1413,11 +1490,11 @@ int HP_battle_get_current_skill(struct block_list *bl) { } return retVal___; } -int HP_battle_check_undead(int race, int element) { +bool HP_battle_check_undead(int race, int element) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_battle_check_undead_pre ) { - int (*preHookFunc) (int *race, int *element); + bool (*preHookFunc) (int *race, int *element); for(hIndex = 0; hIndex < HPMHooks.count.HP_battle_check_undead_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_battle_check_undead_pre[hIndex].func; retVal___ = preHookFunc(&race, &element); @@ -1431,7 +1508,7 @@ int HP_battle_check_undead(int race, int element) { retVal___ = HPMHooks.source.battle.check_undead(race, element); } if( HPMHooks.count.HP_battle_check_undead_post ) { - int (*postHookFunc) (int retVal___, int *race, int *element); + bool (*postHookFunc) (bool retVal___, int *race, int *element); for(hIndex = 0; hIndex < HPMHooks.count.HP_battle_check_undead_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_battle_check_undead_post[hIndex].func; retVal___ = postHookFunc(retVal___, &race, &element); @@ -1612,11 +1689,11 @@ int HP_battle_get_enemy_area_sub(struct block_list *bl, va_list ap) { } return retVal___; } -int HP_battle_delay_damage_sub(int tid, unsigned int tick, int id, intptr_t data) { +int HP_battle_delay_damage_sub(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_battle_delay_damage_sub_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_battle_delay_damage_sub_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_battle_delay_damage_sub_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -1630,7 +1707,7 @@ int HP_battle_delay_damage_sub(int tid, unsigned int tick, int id, intptr_t data retVal___ = HPMHooks.source.battle.delay_damage_sub(tid, tick, id, data); } if( HPMHooks.count.HP_battle_delay_damage_sub_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_battle_delay_damage_sub_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_battle_delay_damage_sub_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -2061,13 +2138,13 @@ int HP_battle_damage_area(struct block_list *bl, va_list ap) { return retVal___; } /* bg */ -void HP_bg_init(void) { +void HP_bg_init(bool minimal) { int hIndex = 0; if( HPMHooks.count.HP_bg_init_pre ) { - void (*preHookFunc) (void); + void (*preHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_bg_init_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_bg_init_pre[hIndex].func; - preHookFunc(); + preHookFunc(&minimal); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -2075,13 +2152,13 @@ void HP_bg_init(void) { } } { - HPMHooks.source.bg.init(); + HPMHooks.source.bg.init(minimal); } if( HPMHooks.count.HP_bg_init_post ) { - void (*postHookFunc) (void); + void (*postHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_bg_init_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_bg_init_post[hIndex].func; - postHookFunc(); + postHookFunc(&minimal); } } return; @@ -2264,11 +2341,11 @@ void HP_bg_begin(struct bg_arena *arena) { } return; } -int HP_bg_begin_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_bg_begin_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_bg_begin_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_bg_begin_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_bg_begin_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -2282,7 +2359,7 @@ int HP_bg_begin_timer(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.bg.begin_timer(tid, tick, id, data); } if( HPMHooks.count.HP_bg_begin_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_bg_begin_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_bg_begin_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -2315,11 +2392,11 @@ void HP_bg_queue_pregame(struct bg_arena *arena) { } return; } -int HP_bg_fillup_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_bg_fillup_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_bg_fillup_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_bg_fillup_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_bg_fillup_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -2333,7 +2410,7 @@ int HP_bg_fillup_timer(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.bg.fillup_timer(tid, tick, id, data); } if( HPMHooks.count.HP_bg_fillup_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_bg_fillup_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_bg_fillup_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -2468,11 +2545,11 @@ struct map_session_data* HP_bg_getavailablesd(struct battleground_data *bgd) { } return retVal___; } -int HP_bg_team_delete(int bg_id) { +bool HP_bg_team_delete(int bg_id) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_bg_team_delete_pre ) { - int (*preHookFunc) (int *bg_id); + bool (*preHookFunc) (int *bg_id); for(hIndex = 0; hIndex < HPMHooks.count.HP_bg_team_delete_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_bg_team_delete_pre[hIndex].func; retVal___ = preHookFunc(&bg_id); @@ -2486,7 +2563,7 @@ int HP_bg_team_delete(int bg_id) { retVal___ = HPMHooks.source.bg.team_delete(bg_id); } if( HPMHooks.count.HP_bg_team_delete_post ) { - int (*postHookFunc) (int retVal___, int *bg_id); + bool (*postHookFunc) (bool retVal___, int *bg_id); for(hIndex = 0; hIndex < HPMHooks.count.HP_bg_team_delete_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_bg_team_delete_post[hIndex].func; retVal___ = postHookFunc(retVal___, &bg_id); @@ -2494,14 +2571,14 @@ int HP_bg_team_delete(int bg_id) { } return retVal___; } -int HP_bg_team_warp(int bg_id, unsigned short mapindex, short x, short y) { +bool HP_bg_team_warp(int bg_id, unsigned short map_index, short x, short y) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_bg_team_warp_pre ) { - int (*preHookFunc) (int *bg_id, unsigned short *mapindex, short *x, short *y); + bool (*preHookFunc) (int *bg_id, unsigned short *map_index, short *x, short *y); for(hIndex = 0; hIndex < HPMHooks.count.HP_bg_team_warp_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_bg_team_warp_pre[hIndex].func; - retVal___ = preHookFunc(&bg_id, &mapindex, &x, &y); + retVal___ = preHookFunc(&bg_id, &map_index, &x, &y); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -2509,48 +2586,47 @@ int HP_bg_team_warp(int bg_id, unsigned short mapindex, short x, short y) { } } { - retVal___ = HPMHooks.source.bg.team_warp(bg_id, mapindex, x, y); + retVal___ = HPMHooks.source.bg.team_warp(bg_id, map_index, x, y); } if( HPMHooks.count.HP_bg_team_warp_post ) { - int (*postHookFunc) (int retVal___, int *bg_id, unsigned short *mapindex, short *x, short *y); + bool (*postHookFunc) (bool retVal___, int *bg_id, unsigned short *map_index, short *x, short *y); for(hIndex = 0; hIndex < HPMHooks.count.HP_bg_team_warp_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_bg_team_warp_post[hIndex].func; - retVal___ = postHookFunc(retVal___, &bg_id, &mapindex, &x, &y); + retVal___ = postHookFunc(retVal___, &bg_id, &map_index, &x, &y); } } return retVal___; } -int HP_bg_send_dot_remove(struct map_session_data *sd) { +void HP_bg_send_dot_remove(struct map_session_data *sd) { int hIndex = 0; - int retVal___ = 0; if( HPMHooks.count.HP_bg_send_dot_remove_pre ) { - int (*preHookFunc) (struct map_session_data *sd); + void (*preHookFunc) (struct map_session_data *sd); for(hIndex = 0; hIndex < HPMHooks.count.HP_bg_send_dot_remove_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_bg_send_dot_remove_pre[hIndex].func; - retVal___ = preHookFunc(sd); + preHookFunc(sd); } if( *HPMforce_return ) { *HPMforce_return = false; - return retVal___; + return; } } { - retVal___ = HPMHooks.source.bg.send_dot_remove(sd); + HPMHooks.source.bg.send_dot_remove(sd); } if( HPMHooks.count.HP_bg_send_dot_remove_post ) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd); + void (*postHookFunc) (struct map_session_data *sd); for(hIndex = 0; hIndex < HPMHooks.count.HP_bg_send_dot_remove_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_bg_send_dot_remove_post[hIndex].func; - retVal___ = postHookFunc(retVal___, sd); + postHookFunc(sd); } } - return retVal___; + return; } -int HP_bg_team_join(int bg_id, struct map_session_data *sd) { +bool HP_bg_team_join(int bg_id, struct map_session_data *sd) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_bg_team_join_pre ) { - int (*preHookFunc) (int *bg_id, struct map_session_data *sd); + bool (*preHookFunc) (int *bg_id, struct map_session_data *sd); for(hIndex = 0; hIndex < HPMHooks.count.HP_bg_team_join_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_bg_team_join_pre[hIndex].func; retVal___ = preHookFunc(&bg_id, sd); @@ -2564,7 +2640,7 @@ int HP_bg_team_join(int bg_id, struct map_session_data *sd) { retVal___ = HPMHooks.source.bg.team_join(bg_id, sd); } if( HPMHooks.count.HP_bg_team_join_post ) { - int (*postHookFunc) (int retVal___, int *bg_id, struct map_session_data *sd); + bool (*postHookFunc) (bool retVal___, int *bg_id, struct map_session_data *sd); for(hIndex = 0; hIndex < HPMHooks.count.HP_bg_team_join_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_bg_team_join_post[hIndex].func; retVal___ = postHookFunc(retVal___, &bg_id, sd); @@ -2598,11 +2674,11 @@ int HP_bg_team_leave(struct map_session_data *sd, int flag) { } return retVal___; } -int HP_bg_member_respawn(struct map_session_data *sd) { +bool HP_bg_member_respawn(struct map_session_data *sd) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_bg_member_respawn_pre ) { - int (*preHookFunc) (struct map_session_data *sd); + bool (*preHookFunc) (struct map_session_data *sd); for(hIndex = 0; hIndex < HPMHooks.count.HP_bg_member_respawn_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_bg_member_respawn_pre[hIndex].func; retVal___ = preHookFunc(sd); @@ -2616,7 +2692,7 @@ int HP_bg_member_respawn(struct map_session_data *sd) { retVal___ = HPMHooks.source.bg.member_respawn(sd); } if( HPMHooks.count.HP_bg_member_respawn_post ) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd); + bool (*postHookFunc) (bool retVal___, struct map_session_data *sd); for(hIndex = 0; hIndex < HPMHooks.count.HP_bg_member_respawn_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_bg_member_respawn_post[hIndex].func; retVal___ = postHookFunc(retVal___, sd); @@ -2624,14 +2700,14 @@ int HP_bg_member_respawn(struct map_session_data *sd) { } return retVal___; } -int HP_bg_create(unsigned short mapindex, short rx, short ry, const char *ev, const char *dev) { +int HP_bg_create(unsigned short map_index, short rx, short ry, const char *ev, const char *dev) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_bg_create_pre ) { - int (*preHookFunc) (unsigned short *mapindex, short *rx, short *ry, const char *ev, const char *dev); + int (*preHookFunc) (unsigned short *map_index, short *rx, short *ry, const char *ev, const char *dev); for(hIndex = 0; hIndex < HPMHooks.count.HP_bg_create_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_bg_create_pre[hIndex].func; - retVal___ = preHookFunc(&mapindex, &rx, &ry, ev, dev); + retVal___ = preHookFunc(&map_index, &rx, &ry, ev, dev); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -2639,13 +2715,13 @@ int HP_bg_create(unsigned short mapindex, short rx, short ry, const char *ev, co } } { - retVal___ = HPMHooks.source.bg.create(mapindex, rx, ry, ev, dev); + retVal___ = HPMHooks.source.bg.create(map_index, rx, ry, ev, dev); } if( HPMHooks.count.HP_bg_create_post ) { - int (*postHookFunc) (int retVal___, unsigned short *mapindex, short *rx, short *ry, const char *ev, const char *dev); + int (*postHookFunc) (int retVal___, unsigned short *map_index, short *rx, short *ry, const char *ev, const char *dev); for(hIndex = 0; hIndex < HPMHooks.count.HP_bg_create_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_bg_create_post[hIndex].func; - retVal___ = postHookFunc(retVal___, &mapindex, &rx, &ry, ev, dev); + retVal___ = postHookFunc(retVal___, &map_index, &rx, &ry, ev, dev); } } return retVal___; @@ -2676,11 +2752,11 @@ int HP_bg_team_get_id(struct block_list *bl) { } return retVal___; } -int HP_bg_send_message(struct map_session_data *sd, const char *mes, int len) { +bool HP_bg_send_message(struct map_session_data *sd, const char *mes, int len) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_bg_send_message_pre ) { - int (*preHookFunc) (struct map_session_data *sd, const char *mes, int *len); + bool (*preHookFunc) (struct map_session_data *sd, const char *mes, int *len); for(hIndex = 0; hIndex < HPMHooks.count.HP_bg_send_message_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_bg_send_message_pre[hIndex].func; retVal___ = preHookFunc(sd, mes, &len); @@ -2694,7 +2770,7 @@ int HP_bg_send_message(struct map_session_data *sd, const char *mes, int len) { retVal___ = HPMHooks.source.bg.send_message(sd, mes, len); } if( HPMHooks.count.HP_bg_send_message_post ) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd, const char *mes, int *len); + bool (*postHookFunc) (bool retVal___, struct map_session_data *sd, const char *mes, int *len); for(hIndex = 0; hIndex < HPMHooks.count.HP_bg_send_message_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_bg_send_message_post[hIndex].func; retVal___ = postHookFunc(retVal___, sd, mes, &len); @@ -2734,11 +2810,11 @@ int HP_bg_send_xy_timer_sub(DBKey key, DBData *data, va_list ap) { } return retVal___; } -int HP_bg_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_bg_send_xy_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_bg_send_xy_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_bg_send_xy_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_bg_send_xy_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -2752,7 +2828,7 @@ int HP_bg_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.bg.send_xy_timer(tid, tick, id, data); } if( HPMHooks.count.HP_bg_send_xy_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_bg_send_xy_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_bg_send_xy_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -2991,11 +3067,11 @@ unsigned int HP_buyingstore_getuid(void) { return retVal___; } /* chat */ -int HP_chat_create_pc_chat(struct map_session_data *sd, const char *title, const char *pass, int limit, bool pub) { +bool HP_chat_create_pc_chat(struct map_session_data *sd, const char *title, const char *pass, int limit, bool pub) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_chat_create_pc_chat_pre ) { - int (*preHookFunc) (struct map_session_data *sd, const char *title, const char *pass, int *limit, bool *pub); + bool (*preHookFunc) (struct map_session_data *sd, const char *title, const char *pass, int *limit, bool *pub); for(hIndex = 0; hIndex < HPMHooks.count.HP_chat_create_pc_chat_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chat_create_pc_chat_pre[hIndex].func; retVal___ = preHookFunc(sd, title, pass, &limit, &pub); @@ -3009,7 +3085,7 @@ int HP_chat_create_pc_chat(struct map_session_data *sd, const char *title, const retVal___ = HPMHooks.source.chat.create_pc_chat(sd, title, pass, limit, pub); } if( HPMHooks.count.HP_chat_create_pc_chat_post ) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd, const char *title, const char *pass, int *limit, bool *pub); + bool (*postHookFunc) (bool retVal___, struct map_session_data *sd, const char *title, const char *pass, int *limit, bool *pub); for(hIndex = 0; hIndex < HPMHooks.count.HP_chat_create_pc_chat_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chat_create_pc_chat_post[hIndex].func; retVal___ = postHookFunc(retVal___, sd, title, pass, &limit, &pub); @@ -3017,11 +3093,11 @@ int HP_chat_create_pc_chat(struct map_session_data *sd, const char *title, const } return retVal___; } -int HP_chat_join(struct map_session_data *sd, int chatid, const char *pass) { +bool HP_chat_join(struct map_session_data *sd, int chatid, const char *pass) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_chat_join_pre ) { - int (*preHookFunc) (struct map_session_data *sd, int *chatid, const char *pass); + bool (*preHookFunc) (struct map_session_data *sd, int *chatid, const char *pass); for(hIndex = 0; hIndex < HPMHooks.count.HP_chat_join_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chat_join_pre[hIndex].func; retVal___ = preHookFunc(sd, &chatid, pass); @@ -3035,7 +3111,7 @@ int HP_chat_join(struct map_session_data *sd, int chatid, const char *pass) { retVal___ = HPMHooks.source.chat.join(sd, chatid, pass); } if( HPMHooks.count.HP_chat_join_post ) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd, int *chatid, const char *pass); + bool (*postHookFunc) (bool retVal___, struct map_session_data *sd, int *chatid, const char *pass); for(hIndex = 0; hIndex < HPMHooks.count.HP_chat_join_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chat_join_post[hIndex].func; retVal___ = postHookFunc(retVal___, sd, &chatid, pass); @@ -3069,11 +3145,11 @@ int HP_chat_leave(struct map_session_data *sd, bool kicked) { } return retVal___; } -int HP_chat_change_owner(struct map_session_data *sd, const char *nextownername) { +bool HP_chat_change_owner(struct map_session_data *sd, const char *nextownername) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_chat_change_owner_pre ) { - int (*preHookFunc) (struct map_session_data *sd, const char *nextownername); + bool (*preHookFunc) (struct map_session_data *sd, const char *nextownername); for(hIndex = 0; hIndex < HPMHooks.count.HP_chat_change_owner_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chat_change_owner_pre[hIndex].func; retVal___ = preHookFunc(sd, nextownername); @@ -3087,7 +3163,7 @@ int HP_chat_change_owner(struct map_session_data *sd, const char *nextownername) retVal___ = HPMHooks.source.chat.change_owner(sd, nextownername); } if( HPMHooks.count.HP_chat_change_owner_post ) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd, const char *nextownername); + bool (*postHookFunc) (bool retVal___, struct map_session_data *sd, const char *nextownername); for(hIndex = 0; hIndex < HPMHooks.count.HP_chat_change_owner_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chat_change_owner_post[hIndex].func; retVal___ = postHookFunc(retVal___, sd, nextownername); @@ -3095,11 +3171,11 @@ int HP_chat_change_owner(struct map_session_data *sd, const char *nextownername) } return retVal___; } -int HP_chat_change_status(struct map_session_data *sd, const char *title, const char *pass, int limit, bool pub) { +bool HP_chat_change_status(struct map_session_data *sd, const char *title, const char *pass, int limit, bool pub) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_chat_change_status_pre ) { - int (*preHookFunc) (struct map_session_data *sd, const char *title, const char *pass, int *limit, bool *pub); + bool (*preHookFunc) (struct map_session_data *sd, const char *title, const char *pass, int *limit, bool *pub); for(hIndex = 0; hIndex < HPMHooks.count.HP_chat_change_status_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chat_change_status_pre[hIndex].func; retVal___ = preHookFunc(sd, title, pass, &limit, &pub); @@ -3113,7 +3189,7 @@ int HP_chat_change_status(struct map_session_data *sd, const char *title, const retVal___ = HPMHooks.source.chat.change_status(sd, title, pass, limit, pub); } if( HPMHooks.count.HP_chat_change_status_post ) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd, const char *title, const char *pass, int *limit, bool *pub); + bool (*postHookFunc) (bool retVal___, struct map_session_data *sd, const char *title, const char *pass, int *limit, bool *pub); for(hIndex = 0; hIndex < HPMHooks.count.HP_chat_change_status_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chat_change_status_post[hIndex].func; retVal___ = postHookFunc(retVal___, sd, title, pass, &limit, &pub); @@ -3121,11 +3197,11 @@ int HP_chat_change_status(struct map_session_data *sd, const char *title, const } return retVal___; } -int HP_chat_kick(struct map_session_data *sd, const char *kickusername) { +bool HP_chat_kick(struct map_session_data *sd, const char *kickusername) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_chat_kick_pre ) { - int (*preHookFunc) (struct map_session_data *sd, const char *kickusername); + bool (*preHookFunc) (struct map_session_data *sd, const char *kickusername); for(hIndex = 0; hIndex < HPMHooks.count.HP_chat_kick_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chat_kick_pre[hIndex].func; retVal___ = preHookFunc(sd, kickusername); @@ -3139,7 +3215,7 @@ int HP_chat_kick(struct map_session_data *sd, const char *kickusername) { retVal___ = HPMHooks.source.chat.kick(sd, kickusername); } if( HPMHooks.count.HP_chat_kick_post ) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd, const char *kickusername); + bool (*postHookFunc) (bool retVal___, struct map_session_data *sd, const char *kickusername); for(hIndex = 0; hIndex < HPMHooks.count.HP_chat_kick_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chat_kick_post[hIndex].func; retVal___ = postHookFunc(retVal___, sd, kickusername); @@ -3147,11 +3223,11 @@ int HP_chat_kick(struct map_session_data *sd, const char *kickusername) { } return retVal___; } -int HP_chat_create_npc_chat(struct npc_data *nd, const char *title, int limit, bool pub, int trigger, const char *ev, int zeny, int minLvl, int maxLvl) { +bool HP_chat_create_npc_chat(struct npc_data *nd, const char *title, int limit, bool pub, int trigger, const char *ev, int zeny, int minLvl, int maxLvl) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_chat_create_npc_chat_pre ) { - int (*preHookFunc) (struct npc_data *nd, const char *title, int *limit, bool *pub, int *trigger, const char *ev, int *zeny, int *minLvl, int *maxLvl); + bool (*preHookFunc) (struct npc_data *nd, const char *title, int *limit, bool *pub, int *trigger, const char *ev, int *zeny, int *minLvl, int *maxLvl); for(hIndex = 0; hIndex < HPMHooks.count.HP_chat_create_npc_chat_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chat_create_npc_chat_pre[hIndex].func; retVal___ = preHookFunc(nd, title, &limit, &pub, &trigger, ev, &zeny, &minLvl, &maxLvl); @@ -3165,7 +3241,7 @@ int HP_chat_create_npc_chat(struct npc_data *nd, const char *title, int limit, b retVal___ = HPMHooks.source.chat.create_npc_chat(nd, title, limit, pub, trigger, ev, zeny, minLvl, maxLvl); } if( HPMHooks.count.HP_chat_create_npc_chat_post ) { - int (*postHookFunc) (int retVal___, struct npc_data *nd, const char *title, int *limit, bool *pub, int *trigger, const char *ev, int *zeny, int *minLvl, int *maxLvl); + bool (*postHookFunc) (bool retVal___, struct npc_data *nd, const char *title, int *limit, bool *pub, int *trigger, const char *ev, int *zeny, int *minLvl, int *maxLvl); for(hIndex = 0; hIndex < HPMHooks.count.HP_chat_create_npc_chat_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chat_create_npc_chat_post[hIndex].func; retVal___ = postHookFunc(retVal___, nd, title, &limit, &pub, &trigger, ev, &zeny, &minLvl, &maxLvl); @@ -3173,11 +3249,11 @@ int HP_chat_create_npc_chat(struct npc_data *nd, const char *title, int limit, b } return retVal___; } -int HP_chat_delete_npc_chat(struct npc_data *nd) { +bool HP_chat_delete_npc_chat(struct npc_data *nd) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_chat_delete_npc_chat_pre ) { - int (*preHookFunc) (struct npc_data *nd); + bool (*preHookFunc) (struct npc_data *nd); for(hIndex = 0; hIndex < HPMHooks.count.HP_chat_delete_npc_chat_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chat_delete_npc_chat_pre[hIndex].func; retVal___ = preHookFunc(nd); @@ -3191,7 +3267,7 @@ int HP_chat_delete_npc_chat(struct npc_data *nd) { retVal___ = HPMHooks.source.chat.delete_npc_chat(nd); } if( HPMHooks.count.HP_chat_delete_npc_chat_post ) { - int (*postHookFunc) (int retVal___, struct npc_data *nd); + bool (*postHookFunc) (bool retVal___, struct npc_data *nd); for(hIndex = 0; hIndex < HPMHooks.count.HP_chat_delete_npc_chat_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chat_delete_npc_chat_post[hIndex].func; retVal___ = postHookFunc(retVal___, nd); @@ -3199,11 +3275,11 @@ int HP_chat_delete_npc_chat(struct npc_data *nd) { } return retVal___; } -int HP_chat_enable_event(struct chat_data *cd) { +bool HP_chat_enable_event(struct chat_data *cd) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_chat_enable_event_pre ) { - int (*preHookFunc) (struct chat_data *cd); + bool (*preHookFunc) (struct chat_data *cd); for(hIndex = 0; hIndex < HPMHooks.count.HP_chat_enable_event_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chat_enable_event_pre[hIndex].func; retVal___ = preHookFunc(cd); @@ -3217,7 +3293,7 @@ int HP_chat_enable_event(struct chat_data *cd) { retVal___ = HPMHooks.source.chat.enable_event(cd); } if( HPMHooks.count.HP_chat_enable_event_post ) { - int (*postHookFunc) (int retVal___, struct chat_data *cd); + bool (*postHookFunc) (bool retVal___, struct chat_data *cd); for(hIndex = 0; hIndex < HPMHooks.count.HP_chat_enable_event_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chat_enable_event_post[hIndex].func; retVal___ = postHookFunc(retVal___, cd); @@ -3225,11 +3301,11 @@ int HP_chat_enable_event(struct chat_data *cd) { } return retVal___; } -int HP_chat_disable_event(struct chat_data *cd) { +bool HP_chat_disable_event(struct chat_data *cd) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_chat_disable_event_pre ) { - int (*preHookFunc) (struct chat_data *cd); + bool (*preHookFunc) (struct chat_data *cd); for(hIndex = 0; hIndex < HPMHooks.count.HP_chat_disable_event_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chat_disable_event_pre[hIndex].func; retVal___ = preHookFunc(cd); @@ -3243,7 +3319,7 @@ int HP_chat_disable_event(struct chat_data *cd) { retVal___ = HPMHooks.source.chat.disable_event(cd); } if( HPMHooks.count.HP_chat_disable_event_post ) { - int (*postHookFunc) (int retVal___, struct chat_data *cd); + bool (*postHookFunc) (bool retVal___, struct chat_data *cd); for(hIndex = 0; hIndex < HPMHooks.count.HP_chat_disable_event_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chat_disable_event_post[hIndex].func; retVal___ = postHookFunc(retVal___, cd); @@ -3251,11 +3327,11 @@ int HP_chat_disable_event(struct chat_data *cd) { } return retVal___; } -int HP_chat_npc_kick_all(struct chat_data *cd) { +bool HP_chat_npc_kick_all(struct chat_data *cd) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_chat_npc_kick_all_pre ) { - int (*preHookFunc) (struct chat_data *cd); + bool (*preHookFunc) (struct chat_data *cd); for(hIndex = 0; hIndex < HPMHooks.count.HP_chat_npc_kick_all_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chat_npc_kick_all_pre[hIndex].func; retVal___ = preHookFunc(cd); @@ -3269,7 +3345,7 @@ int HP_chat_npc_kick_all(struct chat_data *cd) { retVal___ = HPMHooks.source.chat.npc_kick_all(cd); } if( HPMHooks.count.HP_chat_npc_kick_all_post ) { - int (*postHookFunc) (int retVal___, struct chat_data *cd); + bool (*postHookFunc) (bool retVal___, struct chat_data *cd); for(hIndex = 0; hIndex < HPMHooks.count.HP_chat_npc_kick_all_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chat_npc_kick_all_post[hIndex].func; retVal___ = postHookFunc(retVal___, cd); @@ -3277,11 +3353,11 @@ int HP_chat_npc_kick_all(struct chat_data *cd) { } return retVal___; } -int HP_chat_trigger_event(struct chat_data *cd) { +bool HP_chat_trigger_event(struct chat_data *cd) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_chat_trigger_event_pre ) { - int (*preHookFunc) (struct chat_data *cd); + bool (*preHookFunc) (struct chat_data *cd); for(hIndex = 0; hIndex < HPMHooks.count.HP_chat_trigger_event_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chat_trigger_event_pre[hIndex].func; retVal___ = preHookFunc(cd); @@ -3295,7 +3371,7 @@ int HP_chat_trigger_event(struct chat_data *cd) { retVal___ = HPMHooks.source.chat.trigger_event(cd); } if( HPMHooks.count.HP_chat_trigger_event_post ) { - int (*postHookFunc) (int retVal___, struct chat_data *cd); + bool (*postHookFunc) (bool retVal___, struct chat_data *cd); for(hIndex = 0; hIndex < HPMHooks.count.HP_chat_trigger_event_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chat_trigger_event_post[hIndex].func; retVal___ = postHookFunc(retVal___, cd); @@ -3330,57 +3406,55 @@ struct chat_data* HP_chat_create(struct block_list *bl, const char *title, const return retVal___; } /* chrif */ -int HP_chrif_final(void) { +void HP_chrif_init(bool minimal) { int hIndex = 0; - int retVal___ = 0; - if( HPMHooks.count.HP_chrif_final_pre ) { - int (*preHookFunc) (void); - for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_final_pre; hIndex++ ) { - preHookFunc = HPMHooks.list.HP_chrif_final_pre[hIndex].func; - retVal___ = preHookFunc(); + if( HPMHooks.count.HP_chrif_init_pre ) { + void (*preHookFunc) (bool *minimal); + for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_init_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_chrif_init_pre[hIndex].func; + preHookFunc(&minimal); } if( *HPMforce_return ) { *HPMforce_return = false; - return retVal___; + return; } } { - retVal___ = HPMHooks.source.chrif.final(); + HPMHooks.source.chrif.init(minimal); } - if( HPMHooks.count.HP_chrif_final_post ) { - int (*postHookFunc) (int retVal___); - for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_final_post; hIndex++ ) { - postHookFunc = HPMHooks.list.HP_chrif_final_post[hIndex].func; - retVal___ = postHookFunc(retVal___); + if( HPMHooks.count.HP_chrif_init_post ) { + void (*postHookFunc) (bool *minimal); + for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_init_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_chrif_init_post[hIndex].func; + postHookFunc(&minimal); } } - return retVal___; + return; } -int HP_chrif_init(void) { +void HP_chrif_final(void) { int hIndex = 0; - int retVal___ = 0; - if( HPMHooks.count.HP_chrif_init_pre ) { - int (*preHookFunc) (void); - for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_init_pre; hIndex++ ) { - preHookFunc = HPMHooks.list.HP_chrif_init_pre[hIndex].func; - retVal___ = preHookFunc(); + if( HPMHooks.count.HP_chrif_final_pre ) { + void (*preHookFunc) (void); + for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_final_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_chrif_final_pre[hIndex].func; + preHookFunc(); } if( *HPMforce_return ) { *HPMforce_return = false; - return retVal___; + return; } } { - retVal___ = HPMHooks.source.chrif.init(); + HPMHooks.source.chrif.final(); } - if( HPMHooks.count.HP_chrif_init_post ) { - int (*postHookFunc) (int retVal___); - for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_init_post; hIndex++ ) { - postHookFunc = HPMHooks.list.HP_chrif_init_post[hIndex].func; - retVal___ = postHookFunc(retVal___); + if( HPMHooks.count.HP_chrif_final_post ) { + void (*postHookFunc) (void); + for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_final_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_chrif_final_post[hIndex].func; + postHookFunc(); } } - return retVal___; + return; } void HP_chrif_setuserid(char *id) { int hIndex = 0; @@ -3457,11 +3531,11 @@ void HP_chrif_checkdefaultlogin(void) { } return; } -int HP_chrif_setip(const char *ip) { +bool HP_chrif_setip(const char *ip) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_chrif_setip_pre ) { - int (*preHookFunc) (const char *ip); + bool (*preHookFunc) (const char *ip); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_setip_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chrif_setip_pre[hIndex].func; retVal___ = preHookFunc(ip); @@ -3475,7 +3549,7 @@ int HP_chrif_setip(const char *ip) { retVal___ = HPMHooks.source.chrif.setip(ip); } if( HPMHooks.count.HP_chrif_setip_post ) { - int (*postHookFunc) (int retVal___, const char *ip); + bool (*postHookFunc) (bool retVal___, const char *ip); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_setip_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chrif_setip_post[hIndex].func; retVal___ = postHookFunc(retVal___, ip); @@ -3663,13 +3737,13 @@ bool HP_chrif_auth_finished(struct map_session_data *sd) { } return retVal___; } -void HP_chrif_authreq(struct map_session_data *sd) { +void HP_chrif_authreq(struct map_session_data *sd, bool hstandalone) { int hIndex = 0; if( HPMHooks.count.HP_chrif_authreq_pre ) { - void (*preHookFunc) (struct map_session_data *sd); + void (*preHookFunc) (struct map_session_data *sd, bool *hstandalone); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_authreq_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chrif_authreq_pre[hIndex].func; - preHookFunc(sd); + preHookFunc(sd, &hstandalone); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -3677,13 +3751,13 @@ void HP_chrif_authreq(struct map_session_data *sd) { } } { - HPMHooks.source.chrif.authreq(sd); + HPMHooks.source.chrif.authreq(sd, hstandalone); } if( HPMHooks.count.HP_chrif_authreq_post ) { - void (*postHookFunc) (struct map_session_data *sd); + void (*postHookFunc) (struct map_session_data *sd, bool *hstandalone); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_authreq_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chrif_authreq_post[hIndex].func; - postHookFunc(sd); + postHookFunc(sd, &hstandalone); } } return; @@ -3713,11 +3787,11 @@ void HP_chrif_authok(int fd) { } return; } -int HP_chrif_scdata_request(int account_id, int char_id) { +bool HP_chrif_scdata_request(int account_id, int char_id) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_chrif_scdata_request_pre ) { - int (*preHookFunc) (int *account_id, int *char_id); + bool (*preHookFunc) (int *account_id, int *char_id); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_scdata_request_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chrif_scdata_request_pre[hIndex].func; retVal___ = preHookFunc(&account_id, &char_id); @@ -3731,7 +3805,7 @@ int HP_chrif_scdata_request(int account_id, int char_id) { retVal___ = HPMHooks.source.chrif.scdata_request(account_id, char_id); } if( HPMHooks.count.HP_chrif_scdata_request_post ) { - int (*postHookFunc) (int retVal___, int *account_id, int *char_id); + bool (*postHookFunc) (bool retVal___, int *account_id, int *char_id); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_scdata_request_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chrif_scdata_request_post[hIndex].func; retVal___ = postHookFunc(retVal___, &account_id, &char_id); @@ -3739,11 +3813,11 @@ int HP_chrif_scdata_request(int account_id, int char_id) { } return retVal___; } -int HP_chrif_save(struct map_session_data *sd, int flag) { +bool HP_chrif_save(struct map_session_data *sd, int flag) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_chrif_save_pre ) { - int (*preHookFunc) (struct map_session_data *sd, int *flag); + bool (*preHookFunc) (struct map_session_data *sd, int *flag); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_save_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chrif_save_pre[hIndex].func; retVal___ = preHookFunc(sd, &flag); @@ -3757,7 +3831,7 @@ int HP_chrif_save(struct map_session_data *sd, int flag) { retVal___ = HPMHooks.source.chrif.save(sd, flag); } if( HPMHooks.count.HP_chrif_save_post ) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd, int *flag); + bool (*postHookFunc) (bool retVal___, struct map_session_data *sd, int *flag); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_save_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chrif_save_post[hIndex].func; retVal___ = postHookFunc(retVal___, sd, &flag); @@ -3765,11 +3839,11 @@ int HP_chrif_save(struct map_session_data *sd, int flag) { } return retVal___; } -int HP_chrif_charselectreq(struct map_session_data *sd, uint32 s_ip) { +bool HP_chrif_charselectreq(struct map_session_data *sd, uint32 s_ip) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_chrif_charselectreq_pre ) { - int (*preHookFunc) (struct map_session_data *sd, uint32 *s_ip); + bool (*preHookFunc) (struct map_session_data *sd, uint32 *s_ip); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_charselectreq_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chrif_charselectreq_pre[hIndex].func; retVal___ = preHookFunc(sd, &s_ip); @@ -3783,7 +3857,7 @@ int HP_chrif_charselectreq(struct map_session_data *sd, uint32 s_ip) { retVal___ = HPMHooks.source.chrif.charselectreq(sd, s_ip); } if( HPMHooks.count.HP_chrif_charselectreq_post ) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd, uint32 *s_ip); + bool (*postHookFunc) (bool retVal___, struct map_session_data *sd, uint32 *s_ip); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_charselectreq_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chrif_charselectreq_post[hIndex].func; retVal___ = postHookFunc(retVal___, sd, &s_ip); @@ -3791,11 +3865,11 @@ int HP_chrif_charselectreq(struct map_session_data *sd, uint32 s_ip) { } return retVal___; } -int HP_chrif_changemapserver(struct map_session_data *sd, uint32 ip, uint16 port) { +bool HP_chrif_changemapserver(struct map_session_data *sd, uint32 ip, uint16 port) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_chrif_changemapserver_pre ) { - int (*preHookFunc) (struct map_session_data *sd, uint32 *ip, uint16 *port); + bool (*preHookFunc) (struct map_session_data *sd, uint32 *ip, uint16 *port); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_changemapserver_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chrif_changemapserver_pre[hIndex].func; retVal___ = preHookFunc(sd, &ip, &port); @@ -3809,7 +3883,7 @@ int HP_chrif_changemapserver(struct map_session_data *sd, uint32 ip, uint16 port retVal___ = HPMHooks.source.chrif.changemapserver(sd, ip, port); } if( HPMHooks.count.HP_chrif_changemapserver_post ) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd, uint32 *ip, uint16 *port); + bool (*postHookFunc) (bool retVal___, struct map_session_data *sd, uint32 *ip, uint16 *port); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_changemapserver_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chrif_changemapserver_post[hIndex].func; retVal___ = postHookFunc(retVal___, sd, &ip, &port); @@ -3817,11 +3891,11 @@ int HP_chrif_changemapserver(struct map_session_data *sd, uint32 ip, uint16 port } return retVal___; } -int HP_chrif_searchcharid(int char_id) { +bool HP_chrif_searchcharid(int char_id) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_chrif_searchcharid_pre ) { - int (*preHookFunc) (int *char_id); + bool (*preHookFunc) (int *char_id); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_searchcharid_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chrif_searchcharid_pre[hIndex].func; retVal___ = preHookFunc(&char_id); @@ -3835,7 +3909,7 @@ int HP_chrif_searchcharid(int char_id) { retVal___ = HPMHooks.source.chrif.searchcharid(char_id); } if( HPMHooks.count.HP_chrif_searchcharid_post ) { - int (*postHookFunc) (int retVal___, int *char_id); + bool (*postHookFunc) (bool retVal___, int *char_id); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_searchcharid_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chrif_searchcharid_post[hIndex].func; retVal___ = postHookFunc(retVal___, &char_id); @@ -3843,11 +3917,11 @@ int HP_chrif_searchcharid(int char_id) { } return retVal___; } -int HP_chrif_changeemail(int id, const char *actual_email, const char *new_email) { +bool HP_chrif_changeemail(int id, const char *actual_email, const char *new_email) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_chrif_changeemail_pre ) { - int (*preHookFunc) (int *id, const char *actual_email, const char *new_email); + bool (*preHookFunc) (int *id, const char *actual_email, const char *new_email); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_changeemail_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chrif_changeemail_pre[hIndex].func; retVal___ = preHookFunc(&id, actual_email, new_email); @@ -3861,7 +3935,7 @@ int HP_chrif_changeemail(int id, const char *actual_email, const char *new_email retVal___ = HPMHooks.source.chrif.changeemail(id, actual_email, new_email); } if( HPMHooks.count.HP_chrif_changeemail_post ) { - int (*postHookFunc) (int retVal___, int *id, const char *actual_email, const char *new_email); + bool (*postHookFunc) (bool retVal___, int *id, const char *actual_email, const char *new_email); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_changeemail_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chrif_changeemail_post[hIndex].func; retVal___ = postHookFunc(retVal___, &id, actual_email, new_email); @@ -3869,11 +3943,11 @@ int HP_chrif_changeemail(int id, const char *actual_email, const char *new_email } return retVal___; } -int HP_chrif_char_ask_name(int acc, const char *character_name, unsigned short operation_type, int year, int month, int day, int hour, int minute, int second) { +bool HP_chrif_char_ask_name(int acc, const char *character_name, unsigned short operation_type, int year, int month, int day, int hour, int minute, int second) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_chrif_char_ask_name_pre ) { - int (*preHookFunc) (int *acc, const char *character_name, unsigned short *operation_type, int *year, int *month, int *day, int *hour, int *minute, int *second); + bool (*preHookFunc) (int *acc, const char *character_name, unsigned short *operation_type, int *year, int *month, int *day, int *hour, int *minute, int *second); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_char_ask_name_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chrif_char_ask_name_pre[hIndex].func; retVal___ = preHookFunc(&acc, character_name, &operation_type, &year, &month, &day, &hour, &minute, &second); @@ -3887,7 +3961,7 @@ int HP_chrif_char_ask_name(int acc, const char *character_name, unsigned short o retVal___ = HPMHooks.source.chrif.char_ask_name(acc, character_name, operation_type, year, month, day, hour, minute, second); } if( HPMHooks.count.HP_chrif_char_ask_name_post ) { - int (*postHookFunc) (int retVal___, int *acc, const char *character_name, unsigned short *operation_type, int *year, int *month, int *day, int *hour, int *minute, int *second); + bool (*postHookFunc) (bool retVal___, int *acc, const char *character_name, unsigned short *operation_type, int *year, int *month, int *day, int *hour, int *minute, int *second); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_char_ask_name_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chrif_char_ask_name_post[hIndex].func; retVal___ = postHookFunc(retVal___, &acc, character_name, &operation_type, &year, &month, &day, &hour, &minute, &second); @@ -3921,11 +3995,11 @@ int HP_chrif_updatefamelist(struct map_session_data *sd) { } return retVal___; } -int HP_chrif_buildfamelist(void) { +bool HP_chrif_buildfamelist(void) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_chrif_buildfamelist_pre ) { - int (*preHookFunc) (void); + bool (*preHookFunc) (void); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_buildfamelist_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chrif_buildfamelist_pre[hIndex].func; retVal___ = preHookFunc(); @@ -3939,7 +4013,7 @@ int HP_chrif_buildfamelist(void) { retVal___ = HPMHooks.source.chrif.buildfamelist(); } if( HPMHooks.count.HP_chrif_buildfamelist_post ) { - int (*postHookFunc) (int retVal___); + bool (*postHookFunc) (bool retVal___); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_buildfamelist_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chrif_buildfamelist_post[hIndex].func; retVal___ = postHookFunc(retVal___); @@ -3947,11 +4021,11 @@ int HP_chrif_buildfamelist(void) { } return retVal___; } -int HP_chrif_save_scdata(struct map_session_data *sd) { +bool HP_chrif_save_scdata(struct map_session_data *sd) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_chrif_save_scdata_pre ) { - int (*preHookFunc) (struct map_session_data *sd); + bool (*preHookFunc) (struct map_session_data *sd); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_save_scdata_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chrif_save_scdata_pre[hIndex].func; retVal___ = preHookFunc(sd); @@ -3965,7 +4039,7 @@ int HP_chrif_save_scdata(struct map_session_data *sd) { retVal___ = HPMHooks.source.chrif.save_scdata(sd); } if( HPMHooks.count.HP_chrif_save_scdata_post ) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd); + bool (*postHookFunc) (bool retVal___, struct map_session_data *sd); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_save_scdata_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chrif_save_scdata_post[hIndex].func; retVal___ = postHookFunc(retVal___, sd); @@ -3973,11 +4047,11 @@ int HP_chrif_save_scdata(struct map_session_data *sd) { } return retVal___; } -int HP_chrif_ragsrvinfo(int base_rate, int job_rate, int drop_rate) { +bool HP_chrif_ragsrvinfo(int base_rate, int job_rate, int drop_rate) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_chrif_ragsrvinfo_pre ) { - int (*preHookFunc) (int *base_rate, int *job_rate, int *drop_rate); + bool (*preHookFunc) (int *base_rate, int *job_rate, int *drop_rate); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_ragsrvinfo_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chrif_ragsrvinfo_pre[hIndex].func; retVal___ = preHookFunc(&base_rate, &job_rate, &drop_rate); @@ -3991,7 +4065,7 @@ int HP_chrif_ragsrvinfo(int base_rate, int job_rate, int drop_rate) { retVal___ = HPMHooks.source.chrif.ragsrvinfo(base_rate, job_rate, drop_rate); } if( HPMHooks.count.HP_chrif_ragsrvinfo_post ) { - int (*postHookFunc) (int retVal___, int *base_rate, int *job_rate, int *drop_rate); + bool (*postHookFunc) (bool retVal___, int *base_rate, int *job_rate, int *drop_rate); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_ragsrvinfo_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chrif_ragsrvinfo_post[hIndex].func; retVal___ = postHookFunc(retVal___, &base_rate, &job_rate, &drop_rate); @@ -3999,37 +4073,11 @@ int HP_chrif_ragsrvinfo(int base_rate, int job_rate, int drop_rate) { } return retVal___; } -int HP_chrif_char_offline(struct map_session_data *sd) { - int hIndex = 0; - int retVal___ = 0; - if( HPMHooks.count.HP_chrif_char_offline_pre ) { - int (*preHookFunc) (struct map_session_data *sd); - for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_char_offline_pre; hIndex++ ) { - preHookFunc = HPMHooks.list.HP_chrif_char_offline_pre[hIndex].func; - retVal___ = preHookFunc(sd); - } - if( *HPMforce_return ) { - *HPMforce_return = false; - return retVal___; - } - } - { - retVal___ = HPMHooks.source.chrif.char_offline(sd); - } - if( HPMHooks.count.HP_chrif_char_offline_post ) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd); - for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_char_offline_post; hIndex++ ) { - postHookFunc = HPMHooks.list.HP_chrif_char_offline_post[hIndex].func; - retVal___ = postHookFunc(retVal___, sd); - } - } - return retVal___; -} -int HP_chrif_char_offline_nsd(int account_id, int char_id) { +bool HP_chrif_char_offline_nsd(int account_id, int char_id) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_chrif_char_offline_nsd_pre ) { - int (*preHookFunc) (int *account_id, int *char_id); + bool (*preHookFunc) (int *account_id, int *char_id); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_char_offline_nsd_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chrif_char_offline_nsd_pre[hIndex].func; retVal___ = preHookFunc(&account_id, &char_id); @@ -4043,7 +4091,7 @@ int HP_chrif_char_offline_nsd(int account_id, int char_id) { retVal___ = HPMHooks.source.chrif.char_offline_nsd(account_id, char_id); } if( HPMHooks.count.HP_chrif_char_offline_nsd_post ) { - int (*postHookFunc) (int retVal___, int *account_id, int *char_id); + bool (*postHookFunc) (bool retVal___, int *account_id, int *char_id); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_char_offline_nsd_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chrif_char_offline_nsd_post[hIndex].func; retVal___ = postHookFunc(retVal___, &account_id, &char_id); @@ -4051,11 +4099,11 @@ int HP_chrif_char_offline_nsd(int account_id, int char_id) { } return retVal___; } -int HP_chrif_char_reset_offline(void) { +bool HP_chrif_char_reset_offline(void) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_chrif_char_reset_offline_pre ) { - int (*preHookFunc) (void); + bool (*preHookFunc) (void); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_char_reset_offline_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chrif_char_reset_offline_pre[hIndex].func; retVal___ = preHookFunc(); @@ -4069,7 +4117,7 @@ int HP_chrif_char_reset_offline(void) { retVal___ = HPMHooks.source.chrif.char_reset_offline(); } if( HPMHooks.count.HP_chrif_char_reset_offline_post ) { - int (*postHookFunc) (int retVal___); + bool (*postHookFunc) (bool retVal___); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_char_reset_offline_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chrif_char_reset_offline_post[hIndex].func; retVal___ = postHookFunc(retVal___); @@ -4077,11 +4125,11 @@ int HP_chrif_char_reset_offline(void) { } return retVal___; } -int HP_chrif_send_users_tochar(void) { +bool HP_chrif_send_users_tochar(void) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_chrif_send_users_tochar_pre ) { - int (*preHookFunc) (void); + bool (*preHookFunc) (void); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_send_users_tochar_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chrif_send_users_tochar_pre[hIndex].func; retVal___ = preHookFunc(); @@ -4095,7 +4143,7 @@ int HP_chrif_send_users_tochar(void) { retVal___ = HPMHooks.source.chrif.send_users_tochar(); } if( HPMHooks.count.HP_chrif_send_users_tochar_post ) { - int (*postHookFunc) (int retVal___); + bool (*postHookFunc) (bool retVal___); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_send_users_tochar_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chrif_send_users_tochar_post[hIndex].func; retVal___ = postHookFunc(retVal___); @@ -4103,11 +4151,11 @@ int HP_chrif_send_users_tochar(void) { } return retVal___; } -int HP_chrif_char_online(struct map_session_data *sd) { +bool HP_chrif_char_online(struct map_session_data *sd) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_chrif_char_online_pre ) { - int (*preHookFunc) (struct map_session_data *sd); + bool (*preHookFunc) (struct map_session_data *sd); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_char_online_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chrif_char_online_pre[hIndex].func; retVal___ = preHookFunc(sd); @@ -4121,7 +4169,7 @@ int HP_chrif_char_online(struct map_session_data *sd) { retVal___ = HPMHooks.source.chrif.char_online(sd); } if( HPMHooks.count.HP_chrif_char_online_post ) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd); + bool (*postHookFunc) (bool retVal___, struct map_session_data *sd); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_char_online_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chrif_char_online_post[hIndex].func; retVal___ = postHookFunc(retVal___, sd); @@ -4129,11 +4177,11 @@ int HP_chrif_char_online(struct map_session_data *sd) { } return retVal___; } -int HP_chrif_changesex(struct map_session_data *sd) { +bool HP_chrif_changesex(struct map_session_data *sd) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_chrif_changesex_pre ) { - int (*preHookFunc) (struct map_session_data *sd); + bool (*preHookFunc) (struct map_session_data *sd); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_changesex_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chrif_changesex_pre[hIndex].func; retVal___ = preHookFunc(sd); @@ -4147,7 +4195,7 @@ int HP_chrif_changesex(struct map_session_data *sd) { retVal___ = HPMHooks.source.chrif.changesex(sd); } if( HPMHooks.count.HP_chrif_changesex_post ) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd); + bool (*postHookFunc) (bool retVal___, struct map_session_data *sd); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_changesex_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chrif_changesex_post[hIndex].func; retVal___ = postHookFunc(retVal___, sd); @@ -4155,11 +4203,11 @@ int HP_chrif_changesex(struct map_session_data *sd) { } return retVal___; } -int HP_chrif_divorce(int partner_id1, int partner_id2) { +bool HP_chrif_divorce(int partner_id1, int partner_id2) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_chrif_divorce_pre ) { - int (*preHookFunc) (int *partner_id1, int *partner_id2); + bool (*preHookFunc) (int *partner_id1, int *partner_id2); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_divorce_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chrif_divorce_pre[hIndex].func; retVal___ = preHookFunc(&partner_id1, &partner_id2); @@ -4173,7 +4221,7 @@ int HP_chrif_divorce(int partner_id1, int partner_id2) { retVal___ = HPMHooks.source.chrif.divorce(partner_id1, partner_id2); } if( HPMHooks.count.HP_chrif_divorce_post ) { - int (*postHookFunc) (int retVal___, int *partner_id1, int *partner_id2); + bool (*postHookFunc) (bool retVal___, int *partner_id1, int *partner_id2); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_divorce_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chrif_divorce_post[hIndex].func; retVal___ = postHookFunc(retVal___, &partner_id1, &partner_id2); @@ -4181,11 +4229,11 @@ int HP_chrif_divorce(int partner_id1, int partner_id2) { } return retVal___; } -int HP_chrif_removefriend(int char_id, int friend_id) { +bool HP_chrif_removefriend(int char_id, int friend_id) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_chrif_removefriend_pre ) { - int (*preHookFunc) (int *char_id, int *friend_id); + bool (*preHookFunc) (int *char_id, int *friend_id); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_removefriend_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chrif_removefriend_pre[hIndex].func; retVal___ = preHookFunc(&char_id, &friend_id); @@ -4199,7 +4247,7 @@ int HP_chrif_removefriend(int char_id, int friend_id) { retVal___ = HPMHooks.source.chrif.removefriend(char_id, friend_id); } if( HPMHooks.count.HP_chrif_removefriend_post ) { - int (*postHookFunc) (int retVal___, int *char_id, int *friend_id); + bool (*postHookFunc) (bool retVal___, int *char_id, int *friend_id); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_removefriend_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chrif_removefriend_post[hIndex].func; retVal___ = postHookFunc(retVal___, &char_id, &friend_id); @@ -4232,13 +4280,13 @@ void HP_chrif_send_report(char *buf, int len) { } return; } -int HP_chrif_flush_fifo(void) { +bool HP_chrif_flush(void) { int hIndex = 0; - int retVal___ = 0; - if( HPMHooks.count.HP_chrif_flush_fifo_pre ) { - int (*preHookFunc) (void); - for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_flush_fifo_pre; hIndex++ ) { - preHookFunc = HPMHooks.list.HP_chrif_flush_fifo_pre[hIndex].func; + bool retVal___ = false; + if( HPMHooks.count.HP_chrif_flush_pre ) { + bool (*preHookFunc) (void); + for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_flush_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_chrif_flush_pre[hIndex].func; retVal___ = preHookFunc(); } if( *HPMforce_return ) { @@ -4247,12 +4295,12 @@ int HP_chrif_flush_fifo(void) { } } { - retVal___ = HPMHooks.source.chrif.flush_fifo(); + retVal___ = HPMHooks.source.chrif.flush(); } - if( HPMHooks.count.HP_chrif_flush_fifo_post ) { - int (*postHookFunc) (int retVal___); - for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_flush_fifo_post; hIndex++ ) { - postHookFunc = HPMHooks.list.HP_chrif_flush_fifo_post[hIndex].func; + if( HPMHooks.count.HP_chrif_flush_post ) { + bool (*postHookFunc) (bool retVal___); + for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_flush_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_chrif_flush_post[hIndex].func; retVal___ = postHookFunc(retVal___); } } @@ -4309,11 +4357,11 @@ bool HP_chrif_sd_to_auth(TBL_PC *sd, enum sd_state state) { } return retVal___; } -int HP_chrif_check_connect_char_server(int tid, unsigned int tick, int id, intptr_t data) { +int HP_chrif_check_connect_char_server(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_chrif_check_connect_char_server_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_check_connect_char_server_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chrif_check_connect_char_server_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -4327,7 +4375,7 @@ int HP_chrif_check_connect_char_server(int tid, unsigned int tick, int id, intpt retVal___ = HPMHooks.source.chrif.check_connect_char_server(tid, tick, id, data); } if( HPMHooks.count.HP_chrif_check_connect_char_server_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_check_connect_char_server_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chrif_check_connect_char_server_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -4450,30 +4498,31 @@ int HP_chrif_auth_db_cleanup_sub(DBKey key, DBData *data, va_list ap) { } return retVal___; } -void HP_chrif_char_ask_name_answer(int acc, const char *player_name, uint16 type, uint16 answer) { +bool HP_chrif_char_ask_name_answer(int acc, const char *player_name, uint16 type, uint16 answer) { int hIndex = 0; + bool retVal___ = false; if( HPMHooks.count.HP_chrif_char_ask_name_answer_pre ) { - void (*preHookFunc) (int *acc, const char *player_name, uint16 *type, uint16 *answer); + bool (*preHookFunc) (int *acc, const char *player_name, uint16 *type, uint16 *answer); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_char_ask_name_answer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chrif_char_ask_name_answer_pre[hIndex].func; - preHookFunc(&acc, player_name, &type, &answer); + retVal___ = preHookFunc(&acc, player_name, &type, &answer); } if( *HPMforce_return ) { *HPMforce_return = false; - return; + return retVal___; } } { - HPMHooks.source.chrif.char_ask_name_answer(acc, player_name, type, answer); + retVal___ = HPMHooks.source.chrif.char_ask_name_answer(acc, player_name, type, answer); } if( HPMHooks.count.HP_chrif_char_ask_name_answer_post ) { - void (*postHookFunc) (int *acc, const char *player_name, uint16 *type, uint16 *answer); + bool (*postHookFunc) (bool retVal___, int *acc, const char *player_name, uint16 *type, uint16 *answer); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_char_ask_name_answer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chrif_char_ask_name_answer_post[hIndex].func; - postHookFunc(&acc, player_name, &type, &answer); + retVal___ = postHookFunc(retVal___, &acc, player_name, &type, &answer); } } - return; + return retVal___; } int HP_chrif_auth_db_final(DBKey key, DBData *data, va_list ap) { int hIndex = 0; @@ -4507,11 +4556,11 @@ int HP_chrif_auth_db_final(DBKey key, DBData *data, va_list ap) { } return retVal___; } -int HP_chrif_send_usercount_tochar(int tid, unsigned int tick, int id, intptr_t data) { +int HP_chrif_send_usercount_tochar(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_chrif_send_usercount_tochar_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_send_usercount_tochar_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chrif_send_usercount_tochar_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -4525,7 +4574,7 @@ int HP_chrif_send_usercount_tochar(int tid, unsigned int tick, int id, intptr_t retVal___ = HPMHooks.source.chrif.send_usercount_tochar(tid, tick, id, data); } if( HPMHooks.count.HP_chrif_send_usercount_tochar_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_send_usercount_tochar_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chrif_send_usercount_tochar_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -4533,11 +4582,11 @@ int HP_chrif_send_usercount_tochar(int tid, unsigned int tick, int id, intptr_t } return retVal___; } -int HP_chrif_auth_db_cleanup(int tid, unsigned int tick, int id, intptr_t data) { +int HP_chrif_auth_db_cleanup(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_chrif_auth_db_cleanup_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_auth_db_cleanup_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chrif_auth_db_cleanup_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -4551,7 +4600,7 @@ int HP_chrif_auth_db_cleanup(int tid, unsigned int tick, int id, intptr_t data) retVal___ = HPMHooks.source.chrif.auth_db_cleanup(tid, tick, id, data); } if( HPMHooks.count.HP_chrif_auth_db_cleanup_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_auth_db_cleanup_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chrif_auth_db_cleanup_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -4559,141 +4608,136 @@ int HP_chrif_auth_db_cleanup(int tid, unsigned int tick, int id, intptr_t data) } return retVal___; } -int HP_chrif_connect(int fd) { +void HP_chrif_connect(int fd) { int hIndex = 0; - int retVal___ = 0; if( HPMHooks.count.HP_chrif_connect_pre ) { - int (*preHookFunc) (int *fd); + void (*preHookFunc) (int *fd); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_connect_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chrif_connect_pre[hIndex].func; - retVal___ = preHookFunc(&fd); + preHookFunc(&fd); } if( *HPMforce_return ) { *HPMforce_return = false; - return retVal___; + return; } } { - retVal___ = HPMHooks.source.chrif.connect(fd); + HPMHooks.source.chrif.connect(fd); } if( HPMHooks.count.HP_chrif_connect_post ) { - int (*postHookFunc) (int retVal___, int *fd); + void (*postHookFunc) (int *fd); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_connect_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chrif_connect_post[hIndex].func; - retVal___ = postHookFunc(retVal___, &fd); + postHookFunc(&fd); } } - return retVal___; + return; } -int HP_chrif_connectack(int fd) { +void HP_chrif_connectack(int fd) { int hIndex = 0; - int retVal___ = 0; if( HPMHooks.count.HP_chrif_connectack_pre ) { - int (*preHookFunc) (int *fd); + void (*preHookFunc) (int *fd); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_connectack_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chrif_connectack_pre[hIndex].func; - retVal___ = preHookFunc(&fd); + preHookFunc(&fd); } if( *HPMforce_return ) { *HPMforce_return = false; - return retVal___; + return; } } { - retVal___ = HPMHooks.source.chrif.connectack(fd); + HPMHooks.source.chrif.connectack(fd); } if( HPMHooks.count.HP_chrif_connectack_post ) { - int (*postHookFunc) (int retVal___, int *fd); + void (*postHookFunc) (int *fd); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_connectack_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chrif_connectack_post[hIndex].func; - retVal___ = postHookFunc(retVal___, &fd); + postHookFunc(&fd); } } - return retVal___; + return; } -int HP_chrif_sendmap(int fd) { +void HP_chrif_sendmap(int fd) { int hIndex = 0; - int retVal___ = 0; if( HPMHooks.count.HP_chrif_sendmap_pre ) { - int (*preHookFunc) (int *fd); + void (*preHookFunc) (int *fd); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_sendmap_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chrif_sendmap_pre[hIndex].func; - retVal___ = preHookFunc(&fd); + preHookFunc(&fd); } if( *HPMforce_return ) { *HPMforce_return = false; - return retVal___; + return; } } { - retVal___ = HPMHooks.source.chrif.sendmap(fd); + HPMHooks.source.chrif.sendmap(fd); } if( HPMHooks.count.HP_chrif_sendmap_post ) { - int (*postHookFunc) (int retVal___, int *fd); + void (*postHookFunc) (int *fd); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_sendmap_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chrif_sendmap_post[hIndex].func; - retVal___ = postHookFunc(retVal___, &fd); + postHookFunc(&fd); } } - return retVal___; + return; } -int HP_chrif_sendmapack(int fd) { +void HP_chrif_sendmapack(int fd) { int hIndex = 0; - int retVal___ = 0; if( HPMHooks.count.HP_chrif_sendmapack_pre ) { - int (*preHookFunc) (int *fd); + void (*preHookFunc) (int *fd); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_sendmapack_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chrif_sendmapack_pre[hIndex].func; - retVal___ = preHookFunc(&fd); + preHookFunc(&fd); } if( *HPMforce_return ) { *HPMforce_return = false; - return retVal___; + return; } } { - retVal___ = HPMHooks.source.chrif.sendmapack(fd); + HPMHooks.source.chrif.sendmapack(fd); } if( HPMHooks.count.HP_chrif_sendmapack_post ) { - int (*postHookFunc) (int retVal___, int *fd); + void (*postHookFunc) (int *fd); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_sendmapack_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chrif_sendmapack_post[hIndex].func; - retVal___ = postHookFunc(retVal___, &fd); + postHookFunc(&fd); } } - return retVal___; + return; } -int HP_chrif_recvmap(int fd) { +void HP_chrif_recvmap(int fd) { int hIndex = 0; - int retVal___ = 0; if( HPMHooks.count.HP_chrif_recvmap_pre ) { - int (*preHookFunc) (int *fd); + void (*preHookFunc) (int *fd); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_recvmap_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chrif_recvmap_pre[hIndex].func; - retVal___ = preHookFunc(&fd); + preHookFunc(&fd); } if( *HPMforce_return ) { *HPMforce_return = false; - return retVal___; + return; } } { - retVal___ = HPMHooks.source.chrif.recvmap(fd); + HPMHooks.source.chrif.recvmap(fd); } if( HPMHooks.count.HP_chrif_recvmap_post ) { - int (*postHookFunc) (int retVal___, int *fd); + void (*postHookFunc) (int *fd); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_recvmap_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chrif_recvmap_post[hIndex].func; - retVal___ = postHookFunc(retVal___, &fd); + postHookFunc(&fd); } } - return retVal___; + return; } -int HP_chrif_changemapserverack(int account_id, int login_id1, int login_id2, int char_id, short map_index, short x, short y, uint32 ip, uint16 port) { +bool HP_chrif_changemapserverack(int account_id, int login_id1, int login_id2, int char_id, short map_index, short x, short y, uint32 ip, uint16 port) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_chrif_changemapserverack_pre ) { - int (*preHookFunc) (int *account_id, int *login_id1, int *login_id2, int *char_id, short *map_index, short *x, short *y, uint32 *ip, uint16 *port); + bool (*preHookFunc) (int *account_id, int *login_id1, int *login_id2, int *char_id, short *map_index, short *x, short *y, uint32 *ip, uint16 *port); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_changemapserverack_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chrif_changemapserverack_pre[hIndex].func; retVal___ = preHookFunc(&account_id, &login_id1, &login_id2, &char_id, &map_index, &x, &y, &ip, &port); @@ -4707,7 +4751,7 @@ int HP_chrif_changemapserverack(int account_id, int login_id1, int login_id2, in retVal___ = HPMHooks.source.chrif.changemapserverack(account_id, login_id1, login_id2, char_id, map_index, x, y, ip, port); } if( HPMHooks.count.HP_chrif_changemapserverack_post ) { - int (*postHookFunc) (int retVal___, int *account_id, int *login_id1, int *login_id2, int *char_id, short *map_index, short *x, short *y, uint32 *ip, uint16 *port); + bool (*postHookFunc) (bool retVal___, int *account_id, int *login_id1, int *login_id2, int *char_id, short *map_index, short *x, short *y, uint32 *ip, uint16 *port); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_changemapserverack_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chrif_changemapserverack_post[hIndex].func; retVal___ = postHookFunc(retVal___, &account_id, &login_id1, &login_id2, &char_id, &map_index, &x, &y, &ip, &port); @@ -4715,37 +4759,36 @@ int HP_chrif_changemapserverack(int account_id, int login_id1, int login_id2, in } return retVal___; } -int HP_chrif_changedsex(int fd) { +void HP_chrif_changedsex(int fd) { int hIndex = 0; - int retVal___ = 0; if( HPMHooks.count.HP_chrif_changedsex_pre ) { - int (*preHookFunc) (int *fd); + void (*preHookFunc) (int *fd); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_changedsex_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chrif_changedsex_pre[hIndex].func; - retVal___ = preHookFunc(&fd); + preHookFunc(&fd); } if( *HPMforce_return ) { *HPMforce_return = false; - return retVal___; + return; } } { - retVal___ = HPMHooks.source.chrif.changedsex(fd); + HPMHooks.source.chrif.changedsex(fd); } if( HPMHooks.count.HP_chrif_changedsex_post ) { - int (*postHookFunc) (int retVal___, int *fd); + void (*postHookFunc) (int *fd); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_changedsex_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chrif_changedsex_post[hIndex].func; - retVal___ = postHookFunc(retVal___, &fd); + postHookFunc(&fd); } } - return retVal___; + return; } -int HP_chrif_divorceack(int char_id, int partner_id) { +bool HP_chrif_divorceack(int char_id, int partner_id) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_chrif_divorceack_pre ) { - int (*preHookFunc) (int *char_id, int *partner_id); + bool (*preHookFunc) (int *char_id, int *partner_id); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_divorceack_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chrif_divorceack_pre[hIndex].func; retVal___ = preHookFunc(&char_id, &partner_id); @@ -4759,7 +4802,7 @@ int HP_chrif_divorceack(int char_id, int partner_id) { retVal___ = HPMHooks.source.chrif.divorceack(char_id, partner_id); } if( HPMHooks.count.HP_chrif_divorceack_post ) { - int (*postHookFunc) (int retVal___, int *char_id, int *partner_id); + bool (*postHookFunc) (bool retVal___, int *char_id, int *partner_id); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_divorceack_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chrif_divorceack_post[hIndex].func; retVal___ = postHookFunc(retVal___, &char_id, &partner_id); @@ -4767,63 +4810,61 @@ int HP_chrif_divorceack(int char_id, int partner_id) { } return retVal___; } -int HP_chrif_accountban(int fd) { +void HP_chrif_idbanned(int fd) { int hIndex = 0; - int retVal___ = 0; - if( HPMHooks.count.HP_chrif_accountban_pre ) { - int (*preHookFunc) (int *fd); - for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_accountban_pre; hIndex++ ) { - preHookFunc = HPMHooks.list.HP_chrif_accountban_pre[hIndex].func; - retVal___ = preHookFunc(&fd); + if( HPMHooks.count.HP_chrif_idbanned_pre ) { + void (*preHookFunc) (int *fd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_idbanned_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_chrif_idbanned_pre[hIndex].func; + preHookFunc(&fd); } if( *HPMforce_return ) { *HPMforce_return = false; - return retVal___; + return; } } { - retVal___ = HPMHooks.source.chrif.accountban(fd); + HPMHooks.source.chrif.idbanned(fd); } - if( HPMHooks.count.HP_chrif_accountban_post ) { - int (*postHookFunc) (int retVal___, int *fd); - for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_accountban_post; hIndex++ ) { - postHookFunc = HPMHooks.list.HP_chrif_accountban_post[hIndex].func; - retVal___ = postHookFunc(retVal___, &fd); + if( HPMHooks.count.HP_chrif_idbanned_post ) { + void (*postHookFunc) (int *fd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_idbanned_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_chrif_idbanned_post[hIndex].func; + postHookFunc(&fd); } } - return retVal___; + return; } -int HP_chrif_recvfamelist(int fd) { +void HP_chrif_recvfamelist(int fd) { int hIndex = 0; - int retVal___ = 0; if( HPMHooks.count.HP_chrif_recvfamelist_pre ) { - int (*preHookFunc) (int *fd); + void (*preHookFunc) (int *fd); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_recvfamelist_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chrif_recvfamelist_pre[hIndex].func; - retVal___ = preHookFunc(&fd); + preHookFunc(&fd); } if( *HPMforce_return ) { *HPMforce_return = false; - return retVal___; + return; } } { - retVal___ = HPMHooks.source.chrif.recvfamelist(fd); + HPMHooks.source.chrif.recvfamelist(fd); } if( HPMHooks.count.HP_chrif_recvfamelist_post ) { - int (*postHookFunc) (int retVal___, int *fd); + void (*postHookFunc) (int *fd); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_recvfamelist_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chrif_recvfamelist_post[hIndex].func; - retVal___ = postHookFunc(retVal___, &fd); + postHookFunc(&fd); } } - return retVal___; + return; } -int HP_chrif_load_scdata(int fd) { +bool HP_chrif_load_scdata(int fd) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_chrif_load_scdata_pre ) { - int (*preHookFunc) (int *fd); + bool (*preHookFunc) (int *fd); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_load_scdata_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chrif_load_scdata_pre[hIndex].func; retVal___ = preHookFunc(&fd); @@ -4837,7 +4878,7 @@ int HP_chrif_load_scdata(int fd) { retVal___ = HPMHooks.source.chrif.load_scdata(fd); } if( HPMHooks.count.HP_chrif_load_scdata_post ) { - int (*postHookFunc) (int retVal___, int *fd); + bool (*postHookFunc) (bool retVal___, int *fd); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_load_scdata_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chrif_load_scdata_post[hIndex].func; retVal___ = postHookFunc(retVal___, &fd); @@ -4896,31 +4937,30 @@ int HP_chrif_disconnectplayer(int fd) { } return retVal___; } -int HP_chrif_removemap(int fd) { +void HP_chrif_removemap(int fd) { int hIndex = 0; - int retVal___ = 0; if( HPMHooks.count.HP_chrif_removemap_pre ) { - int (*preHookFunc) (int *fd); + void (*preHookFunc) (int *fd); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_removemap_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chrif_removemap_pre[hIndex].func; - retVal___ = preHookFunc(&fd); + preHookFunc(&fd); } if( *HPMforce_return ) { *HPMforce_return = false; - return retVal___; + return; } } { - retVal___ = HPMHooks.source.chrif.removemap(fd); + HPMHooks.source.chrif.removemap(fd); } if( HPMHooks.count.HP_chrif_removemap_post ) { - int (*postHookFunc) (int retVal___, int *fd); + void (*postHookFunc) (int *fd); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_removemap_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chrif_removemap_post[hIndex].func; - retVal___ = postHookFunc(retVal___, &fd); + postHookFunc(&fd); } } - return retVal___; + return; } int HP_chrif_updatefamelist_ack(int fd) { int hIndex = 0; @@ -4998,31 +5038,30 @@ void HP_chrif_keepalive_ack(int fd) { } return; } -int HP_chrif_deadopt(int father_id, int mother_id, int child_id) { +void HP_chrif_deadopt(int father_id, int mother_id, int child_id) { int hIndex = 0; - int retVal___ = 0; if( HPMHooks.count.HP_chrif_deadopt_pre ) { - int (*preHookFunc) (int *father_id, int *mother_id, int *child_id); + void (*preHookFunc) (int *father_id, int *mother_id, int *child_id); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_deadopt_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_chrif_deadopt_pre[hIndex].func; - retVal___ = preHookFunc(&father_id, &mother_id, &child_id); + preHookFunc(&father_id, &mother_id, &child_id); } if( *HPMforce_return ) { *HPMforce_return = false; - return retVal___; + return; } } { - retVal___ = HPMHooks.source.chrif.deadopt(father_id, mother_id, child_id); + HPMHooks.source.chrif.deadopt(father_id, mother_id, child_id); } if( HPMHooks.count.HP_chrif_deadopt_post ) { - int (*postHookFunc) (int retVal___, int *father_id, int *mother_id, int *child_id); + void (*postHookFunc) (int *father_id, int *mother_id, int *child_id); for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_deadopt_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_chrif_deadopt_post[hIndex].func; - retVal___ = postHookFunc(retVal___, &father_id, &mother_id, &child_id); + postHookFunc(&father_id, &mother_id, &child_id); } } - return retVal___; + return; } void HP_chrif_authfail(int fd) { int hIndex = 0; @@ -5125,15 +5164,65 @@ int HP_chrif_parse(int fd) { } return retVal___; } +void HP_chrif_save_scdata_single(int account_id, int char_id, short type, struct status_change_entry *sce) { + int hIndex = 0; + if( HPMHooks.count.HP_chrif_save_scdata_single_pre ) { + void (*preHookFunc) (int *account_id, int *char_id, short *type, struct status_change_entry *sce); + for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_save_scdata_single_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_chrif_save_scdata_single_pre[hIndex].func; + preHookFunc(&account_id, &char_id, &type, sce); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.chrif.save_scdata_single(account_id, char_id, type, sce); + } + if( HPMHooks.count.HP_chrif_save_scdata_single_post ) { + void (*postHookFunc) (int *account_id, int *char_id, short *type, struct status_change_entry *sce); + for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_save_scdata_single_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_chrif_save_scdata_single_post[hIndex].func; + postHookFunc(&account_id, &char_id, &type, sce); + } + } + return; +} +void HP_chrif_del_scdata_single(int account_id, int char_id, short type) { + int hIndex = 0; + if( HPMHooks.count.HP_chrif_del_scdata_single_pre ) { + void (*preHookFunc) (int *account_id, int *char_id, short *type); + for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_del_scdata_single_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_chrif_del_scdata_single_pre[hIndex].func; + preHookFunc(&account_id, &char_id, &type); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.chrif.del_scdata_single(account_id, char_id, type); + } + if( HPMHooks.count.HP_chrif_del_scdata_single_post ) { + void (*postHookFunc) (int *account_id, int *char_id, short *type); + for(hIndex = 0; hIndex < HPMHooks.count.HP_chrif_del_scdata_single_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_chrif_del_scdata_single_post[hIndex].func; + postHookFunc(&account_id, &char_id, &type); + } + } + return; +} /* clif */ -int HP_clif_init(void) { +int HP_clif_init(bool minimal) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_clif_init_pre ) { - int (*preHookFunc) (void); + int (*preHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_init_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_clif_init_pre[hIndex].func; - retVal___ = preHookFunc(); + retVal___ = preHookFunc(&minimal); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -5141,13 +5230,13 @@ int HP_clif_init(void) { } } { - retVal___ = HPMHooks.source.clif.init(); + retVal___ = HPMHooks.source.clif.init(minimal); } if( HPMHooks.count.HP_clif_init_post ) { - int (*postHookFunc) (int retVal___); + int (*postHookFunc) (int retVal___, bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_init_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_clif_init_post[hIndex].func; - retVal___ = postHookFunc(retVal___); + retVal___ = postHookFunc(retVal___, &minimal); } } return retVal___; @@ -5177,11 +5266,11 @@ void HP_clif_final(void) { } return; } -int HP_clif_setip(const char *ip) { +bool HP_clif_setip(const char *ip) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_clif_setip_pre ) { - int (*preHookFunc) (const char *ip); + bool (*preHookFunc) (const char *ip); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_setip_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_clif_setip_pre[hIndex].func; retVal___ = preHookFunc(ip); @@ -5195,7 +5284,7 @@ int HP_clif_setip(const char *ip) { retVal___ = HPMHooks.source.clif.setip(ip); } if( HPMHooks.count.HP_clif_setip_post ) { - int (*postHookFunc) (int retVal___, const char *ip); + bool (*postHookFunc) (bool retVal___, const char *ip); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_setip_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_clif_setip_post[hIndex].func; retVal___ = postHookFunc(retVal___, ip); @@ -5203,30 +5292,31 @@ int HP_clif_setip(const char *ip) { } return retVal___; } -void HP_clif_setbindip(const char *ip) { +bool HP_clif_setbindip(const char *ip) { int hIndex = 0; + bool retVal___ = false; if( HPMHooks.count.HP_clif_setbindip_pre ) { - void (*preHookFunc) (const char *ip); + bool (*preHookFunc) (const char *ip); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_setbindip_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_clif_setbindip_pre[hIndex].func; - preHookFunc(ip); + retVal___ = preHookFunc(ip); } if( *HPMforce_return ) { *HPMforce_return = false; - return; + return retVal___; } } { - HPMHooks.source.clif.setbindip(ip); + retVal___ = HPMHooks.source.clif.setbindip(ip); } if( HPMHooks.count.HP_clif_setbindip_post ) { - void (*postHookFunc) (const char *ip); + bool (*postHookFunc) (bool retVal___, const char *ip); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_setbindip_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_clif_setbindip_post[hIndex].func; - postHookFunc(ip); + retVal___ = postHookFunc(retVal___, ip); } } - return; + return retVal___; } void HP_clif_setport(uint16 port) { int hIndex = 0; @@ -5279,11 +5369,11 @@ uint32 HP_clif_refresh_ip(void) { } return retVal___; } -int HP_clif_send(const void *buf, int len, struct block_list *bl, enum send_target type) { +bool HP_clif_send(const void *buf, int len, struct block_list *bl, enum send_target type) { int hIndex = 0; - int retVal___ = 0; + bool retVal___ = false; if( HPMHooks.count.HP_clif_send_pre ) { - int (*preHookFunc) (const void *buf, int *len, struct block_list *bl, enum send_target *type); + bool (*preHookFunc) (const void *buf, int *len, struct block_list *bl, enum send_target *type); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_send_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_clif_send_pre[hIndex].func; retVal___ = preHookFunc(buf, &len, bl, &type); @@ -5297,7 +5387,7 @@ int HP_clif_send(const void *buf, int len, struct block_list *bl, enum send_targ retVal___ = HPMHooks.source.clif.send(buf, len, bl, type); } if( HPMHooks.count.HP_clif_send_post ) { - int (*postHookFunc) (int retVal___, const void *buf, int *len, struct block_list *bl, enum send_target *type); + bool (*postHookFunc) (bool retVal___, const void *buf, int *len, struct block_list *bl, enum send_target *type); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_send_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_clif_send_post[hIndex].func; retVal___ = postHookFunc(retVal___, buf, &len, bl, &type); @@ -5790,13 +5880,13 @@ void HP_clif_cart_delitem(struct map_session_data *sd, int n, int amount) { } return; } -void HP_clif_equipitemack(struct map_session_data *sd, int n, int pos, int ok) { +void HP_clif_equipitemack(struct map_session_data *sd, int n, int pos, enum e_EQUIP_ITEM_ACK result) { int hIndex = 0; if( HPMHooks.count.HP_clif_equipitemack_pre ) { - void (*preHookFunc) (struct map_session_data *sd, int *n, int *pos, int *ok); + void (*preHookFunc) (struct map_session_data *sd, int *n, int *pos, enum e_EQUIP_ITEM_ACK *result); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_equipitemack_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_clif_equipitemack_pre[hIndex].func; - preHookFunc(sd, &n, &pos, &ok); + preHookFunc(sd, &n, &pos, &result); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -5804,24 +5894,24 @@ void HP_clif_equipitemack(struct map_session_data *sd, int n, int pos, int ok) { } } { - HPMHooks.source.clif.equipitemack(sd, n, pos, ok); + HPMHooks.source.clif.equipitemack(sd, n, pos, result); } if( HPMHooks.count.HP_clif_equipitemack_post ) { - void (*postHookFunc) (struct map_session_data *sd, int *n, int *pos, int *ok); + void (*postHookFunc) (struct map_session_data *sd, int *n, int *pos, enum e_EQUIP_ITEM_ACK *result); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_equipitemack_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_clif_equipitemack_post[hIndex].func; - postHookFunc(sd, &n, &pos, &ok); + postHookFunc(sd, &n, &pos, &result); } } return; } -void HP_clif_unequipitemack(struct map_session_data *sd, int n, int pos, int ok) { +void HP_clif_unequipitemack(struct map_session_data *sd, int n, int pos, enum e_UNEQUIP_ITEM_ACK result) { int hIndex = 0; if( HPMHooks.count.HP_clif_unequipitemack_pre ) { - void (*preHookFunc) (struct map_session_data *sd, int *n, int *pos, int *ok); + void (*preHookFunc) (struct map_session_data *sd, int *n, int *pos, enum e_UNEQUIP_ITEM_ACK *result); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_unequipitemack_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_clif_unequipitemack_pre[hIndex].func; - preHookFunc(sd, &n, &pos, &ok); + preHookFunc(sd, &n, &pos, &result); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -5829,13 +5919,13 @@ void HP_clif_unequipitemack(struct map_session_data *sd, int n, int pos, int ok) } } { - HPMHooks.source.clif.unequipitemack(sd, n, pos, ok); + HPMHooks.source.clif.unequipitemack(sd, n, pos, result); } if( HPMHooks.count.HP_clif_unequipitemack_post ) { - void (*postHookFunc) (struct map_session_data *sd, int *n, int *pos, int *ok); + void (*postHookFunc) (struct map_session_data *sd, int *n, int *pos, enum e_UNEQUIP_ITEM_ACK *result); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_unequipitemack_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_clif_unequipitemack_post[hIndex].func; - postHookFunc(sd, &n, &pos, &ok); + postHookFunc(sd, &n, &pos, &result); } } return; @@ -6040,6 +6130,31 @@ void HP_clif_package_announce(struct map_session_data *sd, unsigned short nameid } return; } +void HP_clif_item_drop_announce(struct map_session_data *sd, unsigned short nameid, char *monsterName) { + int hIndex = 0; + if( HPMHooks.count.HP_clif_item_drop_announce_pre ) { + void (*preHookFunc) (struct map_session_data *sd, unsigned short *nameid, char *monsterName); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_item_drop_announce_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_clif_item_drop_announce_pre[hIndex].func; + preHookFunc(sd, &nameid, monsterName); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.clif.item_drop_announce(sd, nameid, monsterName); + } + if( HPMHooks.count.HP_clif_item_drop_announce_post ) { + void (*postHookFunc) (struct map_session_data *sd, unsigned short *nameid, char *monsterName); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_item_drop_announce_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_clif_item_drop_announce_post[hIndex].func; + postHookFunc(sd, &nameid, monsterName); + } + } + return; +} void HP_clif_clearunit_single(int id, clr_type type, int fd) { int hIndex = 0; if( HPMHooks.count.HP_clif_clearunit_single_pre ) { @@ -6090,10 +6205,10 @@ void HP_clif_clearunit_area(struct block_list *bl, clr_type type) { } return; } -void HP_clif_clearunit_delayed(struct block_list *bl, clr_type type, unsigned int tick) { +void HP_clif_clearunit_delayed(struct block_list *bl, clr_type type, int64 tick) { int hIndex = 0; if( HPMHooks.count.HP_clif_clearunit_delayed_pre ) { - void (*preHookFunc) (struct block_list *bl, clr_type *type, unsigned int *tick); + void (*preHookFunc) (struct block_list *bl, clr_type *type, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_clearunit_delayed_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_clif_clearunit_delayed_pre[hIndex].func; preHookFunc(bl, &type, &tick); @@ -6107,7 +6222,7 @@ void HP_clif_clearunit_delayed(struct block_list *bl, clr_type type, unsigned in HPMHooks.source.clif.clearunit_delayed(bl, type, tick); } if( HPMHooks.count.HP_clif_clearunit_delayed_post ) { - void (*postHookFunc) (struct block_list *bl, clr_type *type, unsigned int *tick); + void (*postHookFunc) (struct block_list *bl, clr_type *type, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_clearunit_delayed_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_clif_clearunit_delayed_post[hIndex].func; postHookFunc(bl, &type, &tick); @@ -6365,31 +6480,6 @@ void HP_clif_class_change(struct block_list *bl, int class_, int type) { } return; } -void HP_clif_skill_setunit(struct skill_unit *su) { - int hIndex = 0; - if( HPMHooks.count.HP_clif_skill_setunit_pre ) { - void (*preHookFunc) (struct skill_unit *su); - for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_skill_setunit_pre; hIndex++ ) { - preHookFunc = HPMHooks.list.HP_clif_skill_setunit_pre[hIndex].func; - preHookFunc(su); - } - if( *HPMforce_return ) { - *HPMforce_return = false; - return; - } - } - { - HPMHooks.source.clif.skill_setunit(su); - } - if( HPMHooks.count.HP_clif_skill_setunit_post ) { - void (*postHookFunc) (struct skill_unit *su); - for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_skill_setunit_post; hIndex++ ) { - postHookFunc = HPMHooks.list.HP_clif_skill_setunit_post[hIndex].func; - postHookFunc(su); - } - } - return; -} void HP_clif_skill_delunit(struct skill_unit *su) { int hIndex = 0; if( HPMHooks.count.HP_clif_skill_delunit_pre ) { @@ -6440,11 +6530,11 @@ void HP_clif_skillunit_update(struct block_list *bl) { } return; } -int HP_clif_clearunit_delayed_sub(int tid, unsigned int tick, int id, intptr_t data) { +int HP_clif_clearunit_delayed_sub(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_clif_clearunit_delayed_sub_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_clearunit_delayed_sub_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_clif_clearunit_delayed_sub_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -6458,7 +6548,7 @@ int HP_clif_clearunit_delayed_sub(int tid, unsigned int tick, int id, intptr_t d retVal___ = HPMHooks.source.clif.clearunit_delayed_sub(tid, tick, id, data); } if( HPMHooks.count.HP_clif_clearunit_delayed_sub_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_clearunit_delayed_sub_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_clif_clearunit_delayed_sub_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -6617,13 +6707,13 @@ int HP_clif_calc_walkdelay(struct block_list *bl, int delay, int type, int damag } return retVal___; } -void HP_clif_getareachar_skillunit(struct map_session_data *sd, struct skill_unit *su) { +void HP_clif_getareachar_skillunit(struct block_list *bl, struct skill_unit *su, enum send_target target) { int hIndex = 0; if( HPMHooks.count.HP_clif_getareachar_skillunit_pre ) { - void (*preHookFunc) (struct map_session_data *sd, struct skill_unit *su); + void (*preHookFunc) (struct block_list *bl, struct skill_unit *su, enum send_target *target); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_getareachar_skillunit_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_clif_getareachar_skillunit_pre[hIndex].func; - preHookFunc(sd, su); + preHookFunc(bl, su, &target); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -6631,13 +6721,13 @@ void HP_clif_getareachar_skillunit(struct map_session_data *sd, struct skill_uni } } { - HPMHooks.source.clif.getareachar_skillunit(sd, su); + HPMHooks.source.clif.getareachar_skillunit(bl, su, target); } if( HPMHooks.count.HP_clif_getareachar_skillunit_post ) { - void (*postHookFunc) (struct map_session_data *sd, struct skill_unit *su); + void (*postHookFunc) (struct block_list *bl, struct skill_unit *su, enum send_target *target); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_getareachar_skillunit_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_clif_getareachar_skillunit_post[hIndex].func; - postHookFunc(sd, su); + postHookFunc(bl, su, &target); } } return; @@ -6724,11 +6814,36 @@ int HP_clif_getareachar(struct block_list *bl, va_list ap) { } return retVal___; } -int HP_clif_spawn(struct block_list *bl) { +void HP_clif_graffiti_entry(struct block_list *bl, struct skill_unit *su, enum send_target target) { int hIndex = 0; - int retVal___ = 0; + if( HPMHooks.count.HP_clif_graffiti_entry_pre ) { + void (*preHookFunc) (struct block_list *bl, struct skill_unit *su, enum send_target *target); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_graffiti_entry_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_clif_graffiti_entry_pre[hIndex].func; + preHookFunc(bl, su, &target); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.clif.graffiti_entry(bl, su, target); + } + if( HPMHooks.count.HP_clif_graffiti_entry_post ) { + void (*postHookFunc) (struct block_list *bl, struct skill_unit *su, enum send_target *target); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_graffiti_entry_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_clif_graffiti_entry_post[hIndex].func; + postHookFunc(bl, su, &target); + } + } + return; +} +bool HP_clif_spawn(struct block_list *bl) { + int hIndex = 0; + bool retVal___ = false; if( HPMHooks.count.HP_clif_spawn_pre ) { - int (*preHookFunc) (struct block_list *bl); + bool (*preHookFunc) (struct block_list *bl); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_spawn_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_clif_spawn_pre[hIndex].func; retVal___ = preHookFunc(bl); @@ -6742,7 +6857,7 @@ int HP_clif_spawn(struct block_list *bl) { retVal___ = HPMHooks.source.clif.spawn(bl); } if( HPMHooks.count.HP_clif_spawn_post ) { - int (*postHookFunc) (int retVal___, struct block_list *bl); + bool (*postHookFunc) (bool retVal___, struct block_list *bl); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_spawn_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_clif_spawn_post[hIndex].func; retVal___ = postHookFunc(retVal___, bl); @@ -7400,14 +7515,14 @@ void HP_clif_viewpoint(struct map_session_data *sd, int npc_id, int type, int x, } return; } -int HP_clif_damage(struct block_list *src, struct block_list *dst, unsigned int tick, int sdelay, int ddelay, int64 damage, int div, int type, int64 damage2) { +int HP_clif_damage(struct block_list *src, struct block_list *dst, int sdelay, int ddelay, int64 damage, short div, unsigned char type, int64 damage2) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_clif_damage_pre ) { - int (*preHookFunc) (struct block_list *src, struct block_list *dst, unsigned int *tick, int *sdelay, int *ddelay, int64 *damage, int *div, int *type, int64 *damage2); + int (*preHookFunc) (struct block_list *src, struct block_list *dst, int *sdelay, int *ddelay, int64 *damage, short *div, unsigned char *type, int64 *damage2); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_damage_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_clif_damage_pre[hIndex].func; - retVal___ = preHookFunc(src, dst, &tick, &sdelay, &ddelay, &damage, &div, &type, &damage2); + retVal___ = preHookFunc(src, dst, &sdelay, &ddelay, &damage, &div, &type, &damage2); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -7415,13 +7530,13 @@ int HP_clif_damage(struct block_list *src, struct block_list *dst, unsigned int } } { - retVal___ = HPMHooks.source.clif.damage(src, dst, tick, sdelay, ddelay, damage, div, type, damage2); + retVal___ = HPMHooks.source.clif.damage(src, dst, sdelay, ddelay, damage, div, type, damage2); } if( HPMHooks.count.HP_clif_damage_post ) { - int (*postHookFunc) (int retVal___, struct block_list *src, struct block_list *dst, unsigned int *tick, int *sdelay, int *ddelay, int64 *damage, int *div, int *type, int64 *damage2); + int (*postHookFunc) (int retVal___, struct block_list *src, struct block_list *dst, int *sdelay, int *ddelay, int64 *damage, short *div, unsigned char *type, int64 *damage2); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_damage_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_clif_damage_post[hIndex].func; - retVal___ = postHookFunc(retVal___, src, dst, &tick, &sdelay, &ddelay, &damage, &div, &type, &damage2); + retVal___ = postHookFunc(retVal___, src, dst, &sdelay, &ddelay, &damage, &div, &type, &damage2); } } return retVal___; @@ -7815,13 +7930,13 @@ void HP_clif_skill_fail(struct map_session_data *sd, uint16 skill_id, enum usesk } return; } -void HP_clif_skill_cooldown(struct map_session_data *sd, uint16 skill_id, unsigned int tick) { +void HP_clif_skill_cooldown(struct map_session_data *sd, uint16 skill_id, unsigned int duration) { int hIndex = 0; if( HPMHooks.count.HP_clif_skill_cooldown_pre ) { - void (*preHookFunc) (struct map_session_data *sd, uint16 *skill_id, unsigned int *tick); + void (*preHookFunc) (struct map_session_data *sd, uint16 *skill_id, unsigned int *duration); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_skill_cooldown_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_clif_skill_cooldown_pre[hIndex].func; - preHookFunc(sd, &skill_id, &tick); + preHookFunc(sd, &skill_id, &duration); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -7829,13 +7944,13 @@ void HP_clif_skill_cooldown(struct map_session_data *sd, uint16 skill_id, unsign } } { - HPMHooks.source.clif.skill_cooldown(sd, skill_id, tick); + HPMHooks.source.clif.skill_cooldown(sd, skill_id, duration); } if( HPMHooks.count.HP_clif_skill_cooldown_post ) { - void (*postHookFunc) (struct map_session_data *sd, uint16 *skill_id, unsigned int *tick); + void (*postHookFunc) (struct map_session_data *sd, uint16 *skill_id, unsigned int *duration); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_skill_cooldown_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_clif_skill_cooldown_post[hIndex].func; - postHookFunc(sd, &skill_id, &tick); + postHookFunc(sd, &skill_id, &duration); } } return; @@ -8873,31 +8988,6 @@ void HP_clif_viewequip_ack(struct map_session_data *sd, struct map_session_data } return; } -void HP_clif_viewequip_fail(struct map_session_data *sd) { - int hIndex = 0; - if( HPMHooks.count.HP_clif_viewequip_fail_pre ) { - void (*preHookFunc) (struct map_session_data *sd); - for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_viewequip_fail_pre; hIndex++ ) { - preHookFunc = HPMHooks.list.HP_clif_viewequip_fail_pre[hIndex].func; - preHookFunc(sd); - } - if( *HPMforce_return ) { - *HPMforce_return = false; - return; - } - } - { - HPMHooks.source.clif.viewequip_fail(sd); - } - if( HPMHooks.count.HP_clif_viewequip_fail_post ) { - void (*postHookFunc) (struct map_session_data *sd); - for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_viewequip_fail_post; hIndex++ ) { - postHookFunc = HPMHooks.list.HP_clif_viewequip_fail_post[hIndex].func; - postHookFunc(sd); - } - } - return; -} void HP_clif_equpcheckbox(struct map_session_data *sd) { int hIndex = 0; if( HPMHooks.count.HP_clif_equpcheckbox_pre ) { @@ -8973,10 +9063,10 @@ void HP_clif_font(struct map_session_data *sd) { } return; } -void HP_clif_progressbar(struct map_session_data *sd, unsigned long color, unsigned int second) { +void HP_clif_progressbar(struct map_session_data *sd, unsigned int color, unsigned int second) { int hIndex = 0; if( HPMHooks.count.HP_clif_progressbar_pre ) { - void (*preHookFunc) (struct map_session_data *sd, unsigned long *color, unsigned int *second); + void (*preHookFunc) (struct map_session_data *sd, unsigned int *color, unsigned int *second); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_progressbar_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_clif_progressbar_pre[hIndex].func; preHookFunc(sd, &color, &second); @@ -8990,7 +9080,7 @@ void HP_clif_progressbar(struct map_session_data *sd, unsigned long color, unsig HPMHooks.source.clif.progressbar(sd, color, second); } if( HPMHooks.count.HP_clif_progressbar_post ) { - void (*postHookFunc) (struct map_session_data *sd, unsigned long *color, unsigned int *second); + void (*postHookFunc) (struct map_session_data *sd, unsigned int *color, unsigned int *second); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_progressbar_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_clif_progressbar_post[hIndex].func; postHookFunc(sd, &color, &second); @@ -9454,11 +9544,11 @@ void HP_clif_charnameupdate(struct map_session_data *ssd) { } return; } -int HP_clif_delayquit(int tid, unsigned int tick, int id, intptr_t data) { +int HP_clif_delayquit(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_clif_delayquit_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_delayquit_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_clif_delayquit_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -9472,7 +9562,7 @@ int HP_clif_delayquit(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.clif.delayquit(tid, tick, id, data); } if( HPMHooks.count.HP_clif_delayquit_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_delayquit_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_clif_delayquit_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -9880,11 +9970,11 @@ void HP_clif_callpartner(struct map_session_data *sd) { } return; } -int HP_clif_skill_damage(struct block_list *src, struct block_list *dst, unsigned int tick, int sdelay, int ddelay, int64 damage, int div, uint16 skill_id, uint16 skill_lv, int type) { +int HP_clif_skill_damage(struct block_list *src, struct block_list *dst, int64 tick, int sdelay, int ddelay, int64 damage, int div, uint16 skill_id, uint16 skill_lv, int type) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_clif_skill_damage_pre ) { - int (*preHookFunc) (struct block_list *src, struct block_list *dst, unsigned int *tick, int *sdelay, int *ddelay, int64 *damage, int *div, uint16 *skill_id, uint16 *skill_lv, int *type); + int (*preHookFunc) (struct block_list *src, struct block_list *dst, int64 *tick, int *sdelay, int *ddelay, int64 *damage, int *div, uint16 *skill_id, uint16 *skill_lv, int *type); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_skill_damage_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_clif_skill_damage_pre[hIndex].func; retVal___ = preHookFunc(src, dst, &tick, &sdelay, &ddelay, &damage, &div, &skill_id, &skill_lv, &type); @@ -9898,7 +9988,7 @@ int HP_clif_skill_damage(struct block_list *src, struct block_list *dst, unsigne retVal___ = HPMHooks.source.clif.skill_damage(src, dst, tick, sdelay, ddelay, damage, div, skill_id, skill_lv, type); } if( HPMHooks.count.HP_clif_skill_damage_post ) { - int (*postHookFunc) (int retVal___, struct block_list *src, struct block_list *dst, unsigned int *tick, int *sdelay, int *ddelay, int64 *damage, int *div, uint16 *skill_id, uint16 *skill_lv, int *type); + int (*postHookFunc) (int retVal___, struct block_list *src, struct block_list *dst, int64 *tick, int *sdelay, int *ddelay, int64 *damage, int *div, uint16 *skill_id, uint16 *skill_lv, int *type); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_skill_damage_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_clif_skill_damage_post[hIndex].func; retVal___ = postHookFunc(retVal___, src, dst, &tick, &sdelay, &ddelay, &damage, &div, &skill_id, &skill_lv, &type); @@ -9932,10 +10022,10 @@ int HP_clif_skill_nodamage(struct block_list *src, struct block_list *dst, uint1 } return retVal___; } -void HP_clif_skill_poseffect(struct block_list *src, uint16 skill_id, int val, int x, int y, int tick) { +void HP_clif_skill_poseffect(struct block_list *src, uint16 skill_id, int val, int x, int y, int64 tick) { int hIndex = 0; if( HPMHooks.count.HP_clif_skill_poseffect_pre ) { - void (*preHookFunc) (struct block_list *src, uint16 *skill_id, int *val, int *x, int *y, int *tick); + void (*preHookFunc) (struct block_list *src, uint16 *skill_id, int *val, int *x, int *y, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_skill_poseffect_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_clif_skill_poseffect_pre[hIndex].func; preHookFunc(src, &skill_id, &val, &x, &y, &tick); @@ -9949,7 +10039,7 @@ void HP_clif_skill_poseffect(struct block_list *src, uint16 skill_id, int val, i HPMHooks.source.clif.skill_poseffect(src, skill_id, val, x, y, tick); } if( HPMHooks.count.HP_clif_skill_poseffect_post ) { - void (*postHookFunc) (struct block_list *src, uint16 *skill_id, int *val, int *x, int *y, int *tick); + void (*postHookFunc) (struct block_list *src, uint16 *skill_id, int *val, int *x, int *y, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_skill_poseffect_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_clif_skill_poseffect_post[hIndex].func; postHookFunc(src, &skill_id, &val, &x, &y, &tick); @@ -10357,13 +10447,13 @@ void HP_clif_specialeffect_value(struct block_list *bl, int effect_id, int num, } return; } -void HP_clif_millenniumshield(struct map_session_data *sd, short shields) { +void HP_clif_millenniumshield(struct block_list *bl, short shields) { int hIndex = 0; if( HPMHooks.count.HP_clif_millenniumshield_pre ) { - void (*preHookFunc) (struct map_session_data *sd, short *shields); + void (*preHookFunc) (struct block_list *bl, short *shields); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_millenniumshield_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_clif_millenniumshield_pre[hIndex].func; - preHookFunc(sd, &shields); + preHookFunc(bl, &shields); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -10371,13 +10461,13 @@ void HP_clif_millenniumshield(struct map_session_data *sd, short shields) { } } { - HPMHooks.source.clif.millenniumshield(sd, shields); + HPMHooks.source.clif.millenniumshield(bl, shields); } if( HPMHooks.count.HP_clif_millenniumshield_post ) { - void (*postHookFunc) (struct map_session_data *sd, short *shields); + void (*postHookFunc) (struct block_list *bl, short *shields); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_millenniumshield_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_clif_millenniumshield_post[hIndex].func; - postHookFunc(sd, &shields); + postHookFunc(bl, &shields); } } return; @@ -10807,10 +10897,10 @@ void HP_clif_changechatstatus(struct chat_data *cd) { } return; } -void HP_clif_wis_message(int fd, const char *nick, const char *mes, int mes_len) { +void HP_clif_wis_message(int fd, const char *nick, const char *mes, size_t mes_len) { int hIndex = 0; if( HPMHooks.count.HP_clif_wis_message_pre ) { - void (*preHookFunc) (int *fd, const char *nick, const char *mes, int *mes_len); + void (*preHookFunc) (int *fd, const char *nick, const char *mes, size_t *mes_len); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_wis_message_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_clif_wis_message_pre[hIndex].func; preHookFunc(&fd, nick, mes, &mes_len); @@ -10824,7 +10914,7 @@ void HP_clif_wis_message(int fd, const char *nick, const char *mes, int mes_len) HPMHooks.source.clif.wis_message(fd, nick, mes, mes_len); } if( HPMHooks.count.HP_clif_wis_message_post ) { - void (*postHookFunc) (int *fd, const char *nick, const char *mes, int *mes_len); + void (*postHookFunc) (int *fd, const char *nick, const char *mes, size_t *mes_len); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_wis_message_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_clif_wis_message_post[hIndex].func; postHookFunc(&fd, nick, mes, &mes_len); @@ -10857,35 +10947,10 @@ void HP_clif_wis_end(int fd, int flag) { } return; } -void HP_clif_disp_onlyself(struct map_session_data *sd, const char *mes, int len) { - int hIndex = 0; - if( HPMHooks.count.HP_clif_disp_onlyself_pre ) { - void (*preHookFunc) (struct map_session_data *sd, const char *mes, int *len); - for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_disp_onlyself_pre; hIndex++ ) { - preHookFunc = HPMHooks.list.HP_clif_disp_onlyself_pre[hIndex].func; - preHookFunc(sd, mes, &len); - } - if( *HPMforce_return ) { - *HPMforce_return = false; - return; - } - } - { - HPMHooks.source.clif.disp_onlyself(sd, mes, len); - } - if( HPMHooks.count.HP_clif_disp_onlyself_post ) { - void (*postHookFunc) (struct map_session_data *sd, const char *mes, int *len); - for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_disp_onlyself_post; hIndex++ ) { - postHookFunc = HPMHooks.list.HP_clif_disp_onlyself_post[hIndex].func; - postHookFunc(sd, mes, &len); - } - } - return; -} -void HP_clif_disp_message(struct block_list *src, const char *mes, int len, enum send_target target) { +void HP_clif_disp_message(struct block_list *src, const char *mes, size_t len, enum send_target target) { int hIndex = 0; if( HPMHooks.count.HP_clif_disp_message_pre ) { - void (*preHookFunc) (struct block_list *src, const char *mes, int *len, enum send_target *target); + void (*preHookFunc) (struct block_list *src, const char *mes, size_t *len, enum send_target *target); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_disp_message_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_clif_disp_message_pre[hIndex].func; preHookFunc(src, mes, &len, &target); @@ -10899,7 +10964,7 @@ void HP_clif_disp_message(struct block_list *src, const char *mes, int len, enum HPMHooks.source.clif.disp_message(src, mes, len, target); } if( HPMHooks.count.HP_clif_disp_message_post ) { - void (*postHookFunc) (struct block_list *src, const char *mes, int *len, enum send_target *target); + void (*postHookFunc) (struct block_list *src, const char *mes, size_t *len, enum send_target *target); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_disp_message_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_clif_disp_message_post[hIndex].func; postHookFunc(src, mes, &len, &target); @@ -10907,10 +10972,10 @@ void HP_clif_disp_message(struct block_list *src, const char *mes, int len, enum } return; } -void HP_clif_broadcast(struct block_list *bl, const char *mes, int len, int type, enum send_target target) { +void HP_clif_broadcast(struct block_list *bl, const char *mes, size_t len, int type, enum send_target target) { int hIndex = 0; if( HPMHooks.count.HP_clif_broadcast_pre ) { - void (*preHookFunc) (struct block_list *bl, const char *mes, int *len, int *type, enum send_target *target); + void (*preHookFunc) (struct block_list *bl, const char *mes, size_t *len, int *type, enum send_target *target); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_broadcast_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_clif_broadcast_pre[hIndex].func; preHookFunc(bl, mes, &len, &type, &target); @@ -10924,7 +10989,7 @@ void HP_clif_broadcast(struct block_list *bl, const char *mes, int len, int type HPMHooks.source.clif.broadcast(bl, mes, len, type, target); } if( HPMHooks.count.HP_clif_broadcast_post ) { - void (*postHookFunc) (struct block_list *bl, const char *mes, int *len, int *type, enum send_target *target); + void (*postHookFunc) (struct block_list *bl, const char *mes, size_t *len, int *type, enum send_target *target); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_broadcast_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_clif_broadcast_post[hIndex].func; postHookFunc(bl, mes, &len, &type, &target); @@ -10932,10 +10997,10 @@ void HP_clif_broadcast(struct block_list *bl, const char *mes, int len, int type } return; } -void HP_clif_broadcast2(struct block_list *bl, const char *mes, int len, unsigned long fontColor, short fontType, short fontSize, short fontAlign, short fontY, enum send_target target) { +void HP_clif_broadcast2(struct block_list *bl, const char *mes, size_t len, unsigned int fontColor, short fontType, short fontSize, short fontAlign, short fontY, enum send_target target) { int hIndex = 0; if( HPMHooks.count.HP_clif_broadcast2_pre ) { - void (*preHookFunc) (struct block_list *bl, const char *mes, int *len, unsigned long *fontColor, short *fontType, short *fontSize, short *fontAlign, short *fontY, enum send_target *target); + void (*preHookFunc) (struct block_list *bl, const char *mes, size_t *len, unsigned int *fontColor, short *fontType, short *fontSize, short *fontAlign, short *fontY, enum send_target *target); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_broadcast2_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_clif_broadcast2_pre[hIndex].func; preHookFunc(bl, mes, &len, &fontColor, &fontType, &fontSize, &fontAlign, &fontY, &target); @@ -10949,7 +11014,7 @@ void HP_clif_broadcast2(struct block_list *bl, const char *mes, int len, unsigne HPMHooks.source.clif.broadcast2(bl, mes, len, fontColor, fontType, fontSize, fontAlign, fontY, target); } if( HPMHooks.count.HP_clif_broadcast2_post ) { - void (*postHookFunc) (struct block_list *bl, const char *mes, int *len, unsigned long *fontColor, short *fontType, short *fontSize, short *fontAlign, short *fontY, enum send_target *target); + void (*postHookFunc) (struct block_list *bl, const char *mes, size_t *len, unsigned int *fontColor, short *fontType, short *fontSize, short *fontAlign, short *fontY, enum send_target *target); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_broadcast2_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_clif_broadcast2_post[hIndex].func; postHookFunc(bl, mes, &len, &fontColor, &fontType, &fontSize, &fontAlign, &fontY, &target); @@ -10957,10 +11022,10 @@ void HP_clif_broadcast2(struct block_list *bl, const char *mes, int len, unsigne } return; } -void HP_clif_messagecolor(struct block_list *bl, unsigned long color, const char *msg) { +void HP_clif_messagecolor(struct block_list *bl, unsigned int color, const char *msg) { int hIndex = 0; if( HPMHooks.count.HP_clif_messagecolor_pre ) { - void (*preHookFunc) (struct block_list *bl, unsigned long *color, const char *msg); + void (*preHookFunc) (struct block_list *bl, unsigned int *color, const char *msg); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_messagecolor_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_clif_messagecolor_pre[hIndex].func; preHookFunc(bl, &color, msg); @@ -10974,7 +11039,7 @@ void HP_clif_messagecolor(struct block_list *bl, unsigned long color, const char HPMHooks.source.clif.messagecolor(bl, color, msg); } if( HPMHooks.count.HP_clif_messagecolor_post ) { - void (*postHookFunc) (struct block_list *bl, unsigned long *color, const char *msg); + void (*postHookFunc) (struct block_list *bl, unsigned int *color, const char *msg); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_messagecolor_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_clif_messagecolor_post[hIndex].func; postHookFunc(bl, &color, msg); @@ -11208,11 +11273,11 @@ int HP_clif_colormes(int fd, enum clif_colors color, const char *msg) { } return retVal___; } -bool HP_clif_process_message(struct map_session_data *sd, int format, char **name_, int *namelen_, char **message_, int *messagelen_) { +bool HP_clif_process_message(struct map_session_data *sd, int format, char **name_, size_t *namelen_, char **message_, size_t *messagelen_) { int hIndex = 0; bool retVal___ = false; if( HPMHooks.count.HP_clif_process_message_pre ) { - bool (*preHookFunc) (struct map_session_data *sd, int *format, char **name_, int *namelen_, char **message_, int *messagelen_); + bool (*preHookFunc) (struct map_session_data *sd, int *format, char **name_, size_t *namelen_, char **message_, size_t *messagelen_); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_process_message_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_clif_process_message_pre[hIndex].func; retVal___ = preHookFunc(sd, &format, name_, namelen_, message_, messagelen_); @@ -11226,7 +11291,7 @@ bool HP_clif_process_message(struct map_session_data *sd, int format, char **nam retVal___ = HPMHooks.source.clif.process_message(sd, format, name_, namelen_, message_, messagelen_); } if( HPMHooks.count.HP_clif_process_message_post ) { - bool (*postHookFunc) (bool retVal___, struct map_session_data *sd, int *format, char **name_, int *namelen_, char **message_, int *messagelen_); + bool (*postHookFunc) (bool retVal___, struct map_session_data *sd, int *format, char **name_, size_t *namelen_, char **message_, size_t *messagelen_); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_process_message_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_clif_process_message_post[hIndex].func; retVal___ = postHookFunc(retVal___, sd, &format, name_, namelen_, message_, messagelen_); @@ -11309,6 +11374,31 @@ void HP_clif_PMIgnoreList(struct map_session_data *sd) { } return; } +void HP_clif_ShowScript(struct block_list *bl, const char *message) { + int hIndex = 0; + if( HPMHooks.count.HP_clif_ShowScript_pre ) { + void (*preHookFunc) (struct block_list *bl, const char *message); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_ShowScript_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_clif_ShowScript_pre[hIndex].func; + preHookFunc(bl, message); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.clif.ShowScript(bl, message); + } + if( HPMHooks.count.HP_clif_ShowScript_post ) { + void (*postHookFunc) (struct block_list *bl, const char *message); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_ShowScript_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_clif_ShowScript_post[hIndex].func; + postHookFunc(bl, message); + } + } + return; +} void HP_clif_traderequest(struct map_session_data *sd, const char *name) { int hIndex = 0; if( HPMHooks.count.HP_clif_traderequest_pre ) { @@ -11834,13 +11924,13 @@ void HP_clif_skillinfoblock(struct map_session_data *sd) { } return; } -void HP_clif_skillup(struct map_session_data *sd, uint16 skill_id) { +void HP_clif_skillup(struct map_session_data *sd, uint16 skill_id, int skill_lv, int flag) { int hIndex = 0; if( HPMHooks.count.HP_clif_skillup_pre ) { - void (*preHookFunc) (struct map_session_data *sd, uint16 *skill_id); + void (*preHookFunc) (struct map_session_data *sd, uint16 *skill_id, int *skill_lv, int *flag); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_skillup_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_clif_skillup_pre[hIndex].func; - preHookFunc(sd, &skill_id); + preHookFunc(sd, &skill_id, &skill_lv, &flag); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -11848,13 +11938,13 @@ void HP_clif_skillup(struct map_session_data *sd, uint16 skill_id) { } } { - HPMHooks.source.clif.skillup(sd, skill_id); + HPMHooks.source.clif.skillup(sd, skill_id, skill_lv, flag); } if( HPMHooks.count.HP_clif_skillup_post ) { - void (*postHookFunc) (struct map_session_data *sd, uint16 *skill_id); + void (*postHookFunc) (struct map_session_data *sd, uint16 *skill_id, int *skill_lv, int *flag); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_skillup_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_clif_skillup_post[hIndex].func; - postHookFunc(sd, &skill_id); + postHookFunc(sd, &skill_id, &skill_lv, &flag); } } return; @@ -12759,32 +12849,6 @@ void HP_clif_guild_message(struct guild *g, int account_id, const char *mes, int } return; } -int HP_clif_guild_skillup(struct map_session_data *sd, uint16 skill_id, int lv) { - int hIndex = 0; - int retVal___ = 0; - if( HPMHooks.count.HP_clif_guild_skillup_pre ) { - int (*preHookFunc) (struct map_session_data *sd, uint16 *skill_id, int *lv); - for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_guild_skillup_pre; hIndex++ ) { - preHookFunc = HPMHooks.list.HP_clif_guild_skillup_pre[hIndex].func; - retVal___ = preHookFunc(sd, &skill_id, &lv); - } - if( *HPMforce_return ) { - *HPMforce_return = false; - return retVal___; - } - } - { - retVal___ = HPMHooks.source.clif.guild_skillup(sd, skill_id, lv); - } - if( HPMHooks.count.HP_clif_guild_skillup_post ) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd, uint16 *skill_id, int *lv); - for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_guild_skillup_post; hIndex++ ) { - postHookFunc = HPMHooks.list.HP_clif_guild_skillup_post[hIndex].func; - retVal___ = postHookFunc(retVal___, sd, &skill_id, &lv); - } - } - return retVal___; -} void HP_clif_guild_reqalliance(struct map_session_data *sd, int account_id, const char *name) { int hIndex = 0; if( HPMHooks.count.HP_clif_guild_reqalliance_pre ) { @@ -13161,10 +13225,10 @@ void HP_clif_bg_xy_remove(struct map_session_data *sd) { } return; } -void HP_clif_bg_message(struct battleground_data *bgd, int src_id, const char *name, const char *mes, int len) { +void HP_clif_bg_message(struct battleground_data *bgd, int src_id, const char *name, const char *mes, size_t len) { int hIndex = 0; if( HPMHooks.count.HP_clif_bg_message_pre ) { - void (*preHookFunc) (struct battleground_data *bgd, int *src_id, const char *name, const char *mes, int *len); + void (*preHookFunc) (struct battleground_data *bgd, int *src_id, const char *name, const char *mes, size_t *len); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_bg_message_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_clif_bg_message_pre[hIndex].func; preHookFunc(bgd, &src_id, name, mes, &len); @@ -13178,7 +13242,7 @@ void HP_clif_bg_message(struct battleground_data *bgd, int src_id, const char *n HPMHooks.source.clif.bg_message(bgd, src_id, name, mes, len); } if( HPMHooks.count.HP_clif_bg_message_post ) { - void (*postHookFunc) (struct battleground_data *bgd, int *src_id, const char *name, const char *mes, int *len); + void (*postHookFunc) (struct battleground_data *bgd, int *src_id, const char *name, const char *mes, size_t *len); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_bg_message_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_clif_bg_message_post[hIndex].func; postHookFunc(bgd, &src_id, name, mes, &len); @@ -13844,31 +13908,30 @@ void HP_clif_hominfo(struct map_session_data *sd, struct homun_data *hd, int fla } return; } -int HP_clif_homskillinfoblock(struct map_session_data *sd) { +void HP_clif_homskillinfoblock(struct map_session_data *sd) { int hIndex = 0; - int retVal___ = 0; if( HPMHooks.count.HP_clif_homskillinfoblock_pre ) { - int (*preHookFunc) (struct map_session_data *sd); + void (*preHookFunc) (struct map_session_data *sd); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_homskillinfoblock_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_clif_homskillinfoblock_pre[hIndex].func; - retVal___ = preHookFunc(sd); + preHookFunc(sd); } if( *HPMforce_return ) { *HPMforce_return = false; - return retVal___; + return; } } { - retVal___ = HPMHooks.source.clif.homskillinfoblock(sd); + HPMHooks.source.clif.homskillinfoblock(sd); } if( HPMHooks.count.HP_clif_homskillinfoblock_post ) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd); + void (*postHookFunc) (struct map_session_data *sd); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_homskillinfoblock_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_clif_homskillinfoblock_post[hIndex].func; - retVal___ = postHookFunc(retVal___, sd); + postHookFunc(sd); } } - return retVal___; + return; } void HP_clif_homskillup(struct map_session_data *sd, uint16 skill_id) { int hIndex = 0; @@ -13895,31 +13958,30 @@ void HP_clif_homskillup(struct map_session_data *sd, uint16 skill_id) { } return; } -int HP_clif_hom_food(struct map_session_data *sd, int foodid, int fail) { +void HP_clif_hom_food(struct map_session_data *sd, int foodid, int fail) { int hIndex = 0; - int retVal___ = 0; if( HPMHooks.count.HP_clif_hom_food_pre ) { - int (*preHookFunc) (struct map_session_data *sd, int *foodid, int *fail); + void (*preHookFunc) (struct map_session_data *sd, int *foodid, int *fail); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_hom_food_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_clif_hom_food_pre[hIndex].func; - retVal___ = preHookFunc(sd, &foodid, &fail); + preHookFunc(sd, &foodid, &fail); } if( *HPMforce_return ) { *HPMforce_return = false; - return retVal___; + return; } } { - retVal___ = HPMHooks.source.clif.hom_food(sd, foodid, fail); + HPMHooks.source.clif.hom_food(sd, foodid, fail); } if( HPMHooks.count.HP_clif_hom_food_post ) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd, int *foodid, int *fail); + void (*postHookFunc) (struct map_session_data *sd, int *foodid, int *fail); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_hom_food_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_clif_hom_food_post[hIndex].func; - retVal___ = postHookFunc(retVal___, sd, &foodid, &fail); + postHookFunc(sd, &foodid, &fail); } } - return retVal___; + return; } void HP_clif_send_homdata(struct map_session_data *sd, int state, int param) { int hIndex = 0; @@ -13996,13 +14058,13 @@ void HP_clif_quest_send_mission(struct map_session_data *sd) { } return; } -void HP_clif_quest_add(struct map_session_data *sd, struct quest *qd, int index) { +void HP_clif_quest_add(struct map_session_data *sd, struct quest *qd) { int hIndex = 0; if( HPMHooks.count.HP_clif_quest_add_pre ) { - void (*preHookFunc) (struct map_session_data *sd, struct quest *qd, int *index); + void (*preHookFunc) (struct map_session_data *sd, struct quest *qd); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_quest_add_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_clif_quest_add_pre[hIndex].func; - preHookFunc(sd, qd, &index); + preHookFunc(sd, qd); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -14010,13 +14072,13 @@ void HP_clif_quest_add(struct map_session_data *sd, struct quest *qd, int index) } } { - HPMHooks.source.clif.quest_add(sd, qd, index); + HPMHooks.source.clif.quest_add(sd, qd); } if( HPMHooks.count.HP_clif_quest_add_post ) { - void (*postHookFunc) (struct map_session_data *sd, struct quest *qd, int *index); + void (*postHookFunc) (struct map_session_data *sd, struct quest *qd); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_quest_add_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_clif_quest_add_post[hIndex].func; - postHookFunc(sd, qd, &index); + postHookFunc(sd, qd); } } return; @@ -14071,13 +14133,13 @@ void HP_clif_quest_update_status(struct map_session_data *sd, int quest_id, bool } return; } -void HP_clif_quest_update_objective(struct map_session_data *sd, struct quest *qd, int index) { +void HP_clif_quest_update_objective(struct map_session_data *sd, struct quest *qd) { int hIndex = 0; if( HPMHooks.count.HP_clif_quest_update_objective_pre ) { - void (*preHookFunc) (struct map_session_data *sd, struct quest *qd, int *index); + void (*preHookFunc) (struct map_session_data *sd, struct quest *qd); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_quest_update_objective_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_clif_quest_update_objective_pre[hIndex].func; - preHookFunc(sd, qd, &index); + preHookFunc(sd, qd); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -14085,13 +14147,13 @@ void HP_clif_quest_update_objective(struct map_session_data *sd, struct quest *q } } { - HPMHooks.source.clif.quest_update_objective(sd, qd, index); + HPMHooks.source.clif.quest_update_objective(sd, qd); } if( HPMHooks.count.HP_clif_quest_update_objective_post ) { - void (*postHookFunc) (struct map_session_data *sd, struct quest *qd, int *index); + void (*postHookFunc) (struct map_session_data *sd, struct quest *qd); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_quest_update_objective_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_clif_quest_update_objective_post[hIndex].func; - postHookFunc(sd, qd, &index); + postHookFunc(sd, qd); } } return; @@ -14946,10 +15008,10 @@ void HP_clif_PartyBookingVolunteerInfo(int index, struct map_session_data *sd) { } return; } -void HP_clif_PartyBookingRefuseVolunteer(unsigned long aid, struct map_session_data *sd) { +void HP_clif_PartyBookingRefuseVolunteer(unsigned int aid, struct map_session_data *sd) { int hIndex = 0; if( HPMHooks.count.HP_clif_PartyBookingRefuseVolunteer_pre ) { - void (*preHookFunc) (unsigned long *aid, struct map_session_data *sd); + void (*preHookFunc) (unsigned int *aid, struct map_session_data *sd); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_PartyBookingRefuseVolunteer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_clif_PartyBookingRefuseVolunteer_pre[hIndex].func; preHookFunc(&aid, sd); @@ -14963,7 +15025,7 @@ void HP_clif_PartyBookingRefuseVolunteer(unsigned long aid, struct map_session_d HPMHooks.source.clif.PartyBookingRefuseVolunteer(aid, sd); } if( HPMHooks.count.HP_clif_PartyBookingRefuseVolunteer_post ) { - void (*postHookFunc) (unsigned long *aid, struct map_session_data *sd); + void (*postHookFunc) (unsigned int *aid, struct map_session_data *sd); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_PartyBookingRefuseVolunteer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_clif_PartyBookingRefuseVolunteer_post[hIndex].func; postHookFunc(&aid, sd); @@ -15721,10 +15783,10 @@ void HP_clif_readbook(int fd, int book_id, int page) { } return; } -void HP_clif_notify_time(struct map_session_data *sd, unsigned long time) { +void HP_clif_notify_time(struct map_session_data *sd, int64 time) { int hIndex = 0; if( HPMHooks.count.HP_clif_notify_time_pre ) { - void (*preHookFunc) (struct map_session_data *sd, unsigned long *time); + void (*preHookFunc) (struct map_session_data *sd, int64 *time); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_notify_time_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_clif_notify_time_pre[hIndex].func; preHookFunc(sd, &time); @@ -15738,7 +15800,7 @@ void HP_clif_notify_time(struct map_session_data *sd, unsigned long time) { HPMHooks.source.clif.notify_time(sd, time); } if( HPMHooks.count.HP_clif_notify_time_post ) { - void (*postHookFunc) (struct map_session_data *sd, unsigned long *time); + void (*postHookFunc) (struct map_session_data *sd, int64 *time); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_notify_time_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_clif_notify_time_post[hIndex].func; postHookFunc(sd, &time); @@ -15821,11 +15883,11 @@ void HP_clif_bc_ready(void) { } return; } -int HP_clif_undisguise_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_clif_undisguise_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_clif_undisguise_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_undisguise_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_clif_undisguise_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -15839,7 +15901,7 @@ int HP_clif_undisguise_timer(int tid, unsigned int tick, int id, intptr_t data) retVal___ = HPMHooks.source.clif.undisguise_timer(tid, tick, id, data); } if( HPMHooks.count.HP_clif_undisguise_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_undisguise_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_clif_undisguise_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -16147,6 +16209,208 @@ void HP_clif_chsys_gleave(struct guild *g1, struct guild *g2) { } return; } +void HP_clif_bank_deposit(struct map_session_data *sd, enum e_BANKING_DEPOSIT_ACK reason) { + int hIndex = 0; + if( HPMHooks.count.HP_clif_bank_deposit_pre ) { + void (*preHookFunc) (struct map_session_data *sd, enum e_BANKING_DEPOSIT_ACK *reason); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_bank_deposit_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_clif_bank_deposit_pre[hIndex].func; + preHookFunc(sd, &reason); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.clif.bank_deposit(sd, reason); + } + if( HPMHooks.count.HP_clif_bank_deposit_post ) { + void (*postHookFunc) (struct map_session_data *sd, enum e_BANKING_DEPOSIT_ACK *reason); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_bank_deposit_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_clif_bank_deposit_post[hIndex].func; + postHookFunc(sd, &reason); + } + } + return; +} +void HP_clif_bank_withdraw(struct map_session_data *sd, enum e_BANKING_WITHDRAW_ACK reason) { + int hIndex = 0; + if( HPMHooks.count.HP_clif_bank_withdraw_pre ) { + void (*preHookFunc) (struct map_session_data *sd, enum e_BANKING_WITHDRAW_ACK *reason); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_bank_withdraw_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_clif_bank_withdraw_pre[hIndex].func; + preHookFunc(sd, &reason); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.clif.bank_withdraw(sd, reason); + } + if( HPMHooks.count.HP_clif_bank_withdraw_post ) { + void (*postHookFunc) (struct map_session_data *sd, enum e_BANKING_WITHDRAW_ACK *reason); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_bank_withdraw_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_clif_bank_withdraw_post[hIndex].func; + postHookFunc(sd, &reason); + } + } + return; +} +void HP_clif_show_modifiers(struct map_session_data *sd) { + int hIndex = 0; + if( HPMHooks.count.HP_clif_show_modifiers_pre ) { + void (*preHookFunc) (struct map_session_data *sd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_show_modifiers_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_clif_show_modifiers_pre[hIndex].func; + preHookFunc(sd); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.clif.show_modifiers(sd); + } + if( HPMHooks.count.HP_clif_show_modifiers_post ) { + void (*postHookFunc) (struct map_session_data *sd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_show_modifiers_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_clif_show_modifiers_post[hIndex].func; + postHookFunc(sd); + } + } + return; +} +void HP_clif_notify_bounditem(struct map_session_data *sd, unsigned short index) { + int hIndex = 0; + if( HPMHooks.count.HP_clif_notify_bounditem_pre ) { + void (*preHookFunc) (struct map_session_data *sd, unsigned short *index); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_notify_bounditem_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_clif_notify_bounditem_pre[hIndex].func; + preHookFunc(sd, &index); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.clif.notify_bounditem(sd, index); + } + if( HPMHooks.count.HP_clif_notify_bounditem_post ) { + void (*postHookFunc) (struct map_session_data *sd, unsigned short *index); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_notify_bounditem_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_clif_notify_bounditem_post[hIndex].func; + postHookFunc(sd, &index); + } + } + return; +} +int HP_clif_delay_damage(int64 tick, struct block_list *src, struct block_list *dst, int sdelay, int ddelay, int64 in_damage, short div, unsigned char type) { + int hIndex = 0; + int retVal___ = 0; + if( HPMHooks.count.HP_clif_delay_damage_pre ) { + int (*preHookFunc) (int64 *tick, struct block_list *src, struct block_list *dst, int *sdelay, int *ddelay, int64 *in_damage, short *div, unsigned char *type); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_delay_damage_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_clif_delay_damage_pre[hIndex].func; + retVal___ = preHookFunc(&tick, src, dst, &sdelay, &ddelay, &in_damage, &div, &type); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.clif.delay_damage(tick, src, dst, sdelay, ddelay, in_damage, div, type); + } + if( HPMHooks.count.HP_clif_delay_damage_post ) { + int (*postHookFunc) (int retVal___, int64 *tick, struct block_list *src, struct block_list *dst, int *sdelay, int *ddelay, int64 *in_damage, short *div, unsigned char *type); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_delay_damage_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_clif_delay_damage_post[hIndex].func; + retVal___ = postHookFunc(retVal___, &tick, src, dst, &sdelay, &ddelay, &in_damage, &div, &type); + } + } + return retVal___; +} +int HP_clif_delay_damage_sub(int tid, int64 tick, int id, intptr_t data) { + int hIndex = 0; + int retVal___ = 0; + if( HPMHooks.count.HP_clif_delay_damage_sub_pre ) { + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_delay_damage_sub_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_clif_delay_damage_sub_pre[hIndex].func; + retVal___ = preHookFunc(&tid, &tick, &id, &data); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.clif.delay_damage_sub(tid, tick, id, data); + } + if( HPMHooks.count.HP_clif_delay_damage_sub_post ) { + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_delay_damage_sub_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_clif_delay_damage_sub_post[hIndex].func; + retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); + } + } + return retVal___; +} +void HP_clif_npc_market_open(struct map_session_data *sd, struct npc_data *nd) { + int hIndex = 0; + if( HPMHooks.count.HP_clif_npc_market_open_pre ) { + void (*preHookFunc) (struct map_session_data *sd, struct npc_data *nd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_npc_market_open_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_clif_npc_market_open_pre[hIndex].func; + preHookFunc(sd, nd); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.clif.npc_market_open(sd, nd); + } + if( HPMHooks.count.HP_clif_npc_market_open_post ) { + void (*postHookFunc) (struct map_session_data *sd, struct npc_data *nd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_npc_market_open_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_clif_npc_market_open_post[hIndex].func; + postHookFunc(sd, nd); + } + } + return; +} +void HP_clif_npc_market_purchase_ack(struct map_session_data *sd, struct packet_npc_market_purchase *req, unsigned char response) { + int hIndex = 0; + if( HPMHooks.count.HP_clif_npc_market_purchase_ack_pre ) { + void (*preHookFunc) (struct map_session_data *sd, struct packet_npc_market_purchase *req, unsigned char *response); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_npc_market_purchase_ack_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_clif_npc_market_purchase_ack_pre[hIndex].func; + preHookFunc(sd, req, &response); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.clif.npc_market_purchase_ack(sd, req, response); + } + if( HPMHooks.count.HP_clif_npc_market_purchase_ack_post ) { + void (*postHookFunc) (struct map_session_data *sd, struct packet_npc_market_purchase *req, unsigned char *response); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_npc_market_purchase_ack_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_clif_npc_market_purchase_ack_post[hIndex].func; + postHookFunc(sd, req, &response); + } + } + return; +} void HP_clif_pWantToConnection(int fd, struct map_session_data *sd) { int hIndex = 0; if( HPMHooks.count.HP_clif_pWantToConnection_pre ) { @@ -16497,10 +16761,10 @@ void HP_clif_pActionRequest(int fd, struct map_session_data *sd) { } return; } -void HP_clif_pActionRequest_sub(struct map_session_data *sd, int action_type, int target_id, unsigned int tick) { +void HP_clif_pActionRequest_sub(struct map_session_data *sd, int action_type, int target_id, int64 tick) { int hIndex = 0; if( HPMHooks.count.HP_clif_pActionRequest_sub_pre ) { - void (*preHookFunc) (struct map_session_data *sd, int *action_type, int *target_id, unsigned int *tick); + void (*preHookFunc) (struct map_session_data *sd, int *action_type, int *target_id, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_pActionRequest_sub_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_clif_pActionRequest_sub_pre[hIndex].func; preHookFunc(sd, &action_type, &target_id, &tick); @@ -16514,7 +16778,7 @@ void HP_clif_pActionRequest_sub(struct map_session_data *sd, int action_type, in HPMHooks.source.clif.pActionRequest_sub(sd, action_type, target_id, tick); } if( HPMHooks.count.HP_clif_pActionRequest_sub_post ) { - void (*postHookFunc) (struct map_session_data *sd, int *action_type, int *target_id, unsigned int *tick); + void (*postHookFunc) (struct map_session_data *sd, int *action_type, int *target_id, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_pActionRequest_sub_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_clif_pActionRequest_sub_post[hIndex].func; postHookFunc(sd, &action_type, &target_id, &tick); @@ -17347,10 +17611,10 @@ void HP_clif_pUseSkillToId(int fd, struct map_session_data *sd) { } return; } -void HP_clif_pUseSkillToId_homun(struct homun_data *hd, struct map_session_data *sd, unsigned int tick, uint16 skill_id, uint16 skill_lv, int target_id) { +void HP_clif_pUseSkillToId_homun(struct homun_data *hd, struct map_session_data *sd, int64 tick, uint16 skill_id, uint16 skill_lv, int target_id) { int hIndex = 0; if( HPMHooks.count.HP_clif_pUseSkillToId_homun_pre ) { - void (*preHookFunc) (struct homun_data *hd, struct map_session_data *sd, unsigned int *tick, uint16 *skill_id, uint16 *skill_lv, int *target_id); + void (*preHookFunc) (struct homun_data *hd, struct map_session_data *sd, int64 *tick, uint16 *skill_id, uint16 *skill_lv, int *target_id); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_pUseSkillToId_homun_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_clif_pUseSkillToId_homun_pre[hIndex].func; preHookFunc(hd, sd, &tick, &skill_id, &skill_lv, &target_id); @@ -17364,7 +17628,7 @@ void HP_clif_pUseSkillToId_homun(struct homun_data *hd, struct map_session_data HPMHooks.source.clif.pUseSkillToId_homun(hd, sd, tick, skill_id, skill_lv, target_id); } if( HPMHooks.count.HP_clif_pUseSkillToId_homun_post ) { - void (*postHookFunc) (struct homun_data *hd, struct map_session_data *sd, unsigned int *tick, uint16 *skill_id, uint16 *skill_lv, int *target_id); + void (*postHookFunc) (struct homun_data *hd, struct map_session_data *sd, int64 *tick, uint16 *skill_id, uint16 *skill_lv, int *target_id); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_pUseSkillToId_homun_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_clif_pUseSkillToId_homun_post[hIndex].func; postHookFunc(hd, sd, &tick, &skill_id, &skill_lv, &target_id); @@ -17372,10 +17636,10 @@ void HP_clif_pUseSkillToId_homun(struct homun_data *hd, struct map_session_data } return; } -void HP_clif_pUseSkillToId_mercenary(struct mercenary_data *md, struct map_session_data *sd, unsigned int tick, uint16 skill_id, uint16 skill_lv, int target_id) { +void HP_clif_pUseSkillToId_mercenary(struct mercenary_data *md, struct map_session_data *sd, int64 tick, uint16 skill_id, uint16 skill_lv, int target_id) { int hIndex = 0; if( HPMHooks.count.HP_clif_pUseSkillToId_mercenary_pre ) { - void (*preHookFunc) (struct mercenary_data *md, struct map_session_data *sd, unsigned int *tick, uint16 *skill_id, uint16 *skill_lv, int *target_id); + void (*preHookFunc) (struct mercenary_data *md, struct map_session_data *sd, int64 *tick, uint16 *skill_id, uint16 *skill_lv, int *target_id); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_pUseSkillToId_mercenary_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_clif_pUseSkillToId_mercenary_pre[hIndex].func; preHookFunc(md, sd, &tick, &skill_id, &skill_lv, &target_id); @@ -17389,7 +17653,7 @@ void HP_clif_pUseSkillToId_mercenary(struct mercenary_data *md, struct map_sessi HPMHooks.source.clif.pUseSkillToId_mercenary(md, sd, tick, skill_id, skill_lv, target_id); } if( HPMHooks.count.HP_clif_pUseSkillToId_mercenary_post ) { - void (*postHookFunc) (struct mercenary_data *md, struct map_session_data *sd, unsigned int *tick, uint16 *skill_id, uint16 *skill_lv, int *target_id); + void (*postHookFunc) (struct mercenary_data *md, struct map_session_data *sd, int64 *tick, uint16 *skill_id, uint16 *skill_lv, int *target_id); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_pUseSkillToId_mercenary_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_clif_pUseSkillToId_mercenary_post[hIndex].func; postHookFunc(md, sd, &tick, &skill_id, &skill_lv, &target_id); @@ -17447,10 +17711,10 @@ void HP_clif_pUseSkillToPosSub(int fd, struct map_session_data *sd, uint16 skill } return; } -void HP_clif_pUseSkillToPos_homun(struct homun_data *hd, struct map_session_data *sd, unsigned int tick, uint16 skill_id, uint16 skill_lv, short x, short y, int skillmoreinfo) { +void HP_clif_pUseSkillToPos_homun(struct homun_data *hd, struct map_session_data *sd, int64 tick, uint16 skill_id, uint16 skill_lv, short x, short y, int skillmoreinfo) { int hIndex = 0; if( HPMHooks.count.HP_clif_pUseSkillToPos_homun_pre ) { - void (*preHookFunc) (struct homun_data *hd, struct map_session_data *sd, unsigned int *tick, uint16 *skill_id, uint16 *skill_lv, short *x, short *y, int *skillmoreinfo); + void (*preHookFunc) (struct homun_data *hd, struct map_session_data *sd, int64 *tick, uint16 *skill_id, uint16 *skill_lv, short *x, short *y, int *skillmoreinfo); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_pUseSkillToPos_homun_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_clif_pUseSkillToPos_homun_pre[hIndex].func; preHookFunc(hd, sd, &tick, &skill_id, &skill_lv, &x, &y, &skillmoreinfo); @@ -17464,7 +17728,7 @@ void HP_clif_pUseSkillToPos_homun(struct homun_data *hd, struct map_session_data HPMHooks.source.clif.pUseSkillToPos_homun(hd, sd, tick, skill_id, skill_lv, x, y, skillmoreinfo); } if( HPMHooks.count.HP_clif_pUseSkillToPos_homun_post ) { - void (*postHookFunc) (struct homun_data *hd, struct map_session_data *sd, unsigned int *tick, uint16 *skill_id, uint16 *skill_lv, short *x, short *y, int *skillmoreinfo); + void (*postHookFunc) (struct homun_data *hd, struct map_session_data *sd, int64 *tick, uint16 *skill_id, uint16 *skill_lv, short *x, short *y, int *skillmoreinfo); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_pUseSkillToPos_homun_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_clif_pUseSkillToPos_homun_post[hIndex].func; postHookFunc(hd, sd, &tick, &skill_id, &skill_lv, &x, &y, &skillmoreinfo); @@ -17472,10 +17736,10 @@ void HP_clif_pUseSkillToPos_homun(struct homun_data *hd, struct map_session_data } return; } -void HP_clif_pUseSkillToPos_mercenary(struct mercenary_data *md, struct map_session_data *sd, unsigned int tick, uint16 skill_id, uint16 skill_lv, short x, short y, int skillmoreinfo) { +void HP_clif_pUseSkillToPos_mercenary(struct mercenary_data *md, struct map_session_data *sd, int64 tick, uint16 skill_id, uint16 skill_lv, short x, short y, int skillmoreinfo) { int hIndex = 0; if( HPMHooks.count.HP_clif_pUseSkillToPos_mercenary_pre ) { - void (*preHookFunc) (struct mercenary_data *md, struct map_session_data *sd, unsigned int *tick, uint16 *skill_id, uint16 *skill_lv, short *x, short *y, int *skillmoreinfo); + void (*preHookFunc) (struct mercenary_data *md, struct map_session_data *sd, int64 *tick, uint16 *skill_id, uint16 *skill_lv, short *x, short *y, int *skillmoreinfo); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_pUseSkillToPos_mercenary_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_clif_pUseSkillToPos_mercenary_pre[hIndex].func; preHookFunc(md, sd, &tick, &skill_id, &skill_lv, &x, &y, &skillmoreinfo); @@ -17489,7 +17753,7 @@ void HP_clif_pUseSkillToPos_mercenary(struct mercenary_data *md, struct map_sess HPMHooks.source.clif.pUseSkillToPos_mercenary(md, sd, tick, skill_id, skill_lv, x, y, skillmoreinfo); } if( HPMHooks.count.HP_clif_pUseSkillToPos_mercenary_post ) { - void (*postHookFunc) (struct mercenary_data *md, struct map_session_data *sd, unsigned int *tick, uint16 *skill_id, uint16 *skill_lv, short *x, short *y, int *skillmoreinfo); + void (*postHookFunc) (struct mercenary_data *md, struct map_session_data *sd, int64 *tick, uint16 *skill_id, uint16 *skill_lv, short *x, short *y, int *skillmoreinfo); for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_pUseSkillToPos_mercenary_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_clif_pUseSkillToPos_mercenary_post[hIndex].func; postHookFunc(md, sd, &tick, &skill_id, &skill_lv, &x, &y, &skillmoreinfo); @@ -19622,6 +19886,31 @@ void HP_clif_pGMChangeMapType(int fd, struct map_session_data *sd) { } return; } +void HP_clif_pGMFullStrip(int fd, struct map_session_data *sd) { + int hIndex = 0; + if( HPMHooks.count.HP_clif_pGMFullStrip_pre ) { + void (*preHookFunc) (int *fd, struct map_session_data *sd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_pGMFullStrip_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_clif_pGMFullStrip_pre[hIndex].func; + preHookFunc(&fd, sd); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.clif.pGMFullStrip(fd, sd); + } + if( HPMHooks.count.HP_clif_pGMFullStrip_post ) { + void (*postHookFunc) (int *fd, struct map_session_data *sd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_pGMFullStrip_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_clif_pGMFullStrip_post[hIndex].func; + postHookFunc(&fd, sd); + } + } + return; +} void HP_clif_pPMIgnore(int fd, struct map_session_data *sd) { int hIndex = 0; if( HPMHooks.count.HP_clif_pPMIgnore_pre ) { @@ -21497,6 +21786,206 @@ void HP_clif_pPartyBookingCancelVolunteer(int fd, struct map_session_data *sd) { } return; } +void HP_clif_pBankDeposit(int fd, struct map_session_data *sd) { + int hIndex = 0; + if( HPMHooks.count.HP_clif_pBankDeposit_pre ) { + void (*preHookFunc) (int *fd, struct map_session_data *sd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_pBankDeposit_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_clif_pBankDeposit_pre[hIndex].func; + preHookFunc(&fd, sd); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.clif.pBankDeposit(fd, sd); + } + if( HPMHooks.count.HP_clif_pBankDeposit_post ) { + void (*postHookFunc) (int *fd, struct map_session_data *sd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_pBankDeposit_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_clif_pBankDeposit_post[hIndex].func; + postHookFunc(&fd, sd); + } + } + return; +} +void HP_clif_pBankWithdraw(int fd, struct map_session_data *sd) { + int hIndex = 0; + if( HPMHooks.count.HP_clif_pBankWithdraw_pre ) { + void (*preHookFunc) (int *fd, struct map_session_data *sd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_pBankWithdraw_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_clif_pBankWithdraw_pre[hIndex].func; + preHookFunc(&fd, sd); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.clif.pBankWithdraw(fd, sd); + } + if( HPMHooks.count.HP_clif_pBankWithdraw_post ) { + void (*postHookFunc) (int *fd, struct map_session_data *sd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_pBankWithdraw_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_clif_pBankWithdraw_post[hIndex].func; + postHookFunc(&fd, sd); + } + } + return; +} +void HP_clif_pBankCheck(int fd, struct map_session_data *sd) { + int hIndex = 0; + if( HPMHooks.count.HP_clif_pBankCheck_pre ) { + void (*preHookFunc) (int *fd, struct map_session_data *sd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_pBankCheck_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_clif_pBankCheck_pre[hIndex].func; + preHookFunc(&fd, sd); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.clif.pBankCheck(fd, sd); + } + if( HPMHooks.count.HP_clif_pBankCheck_post ) { + void (*postHookFunc) (int *fd, struct map_session_data *sd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_pBankCheck_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_clif_pBankCheck_post[hIndex].func; + postHookFunc(&fd, sd); + } + } + return; +} +void HP_clif_pBankOpen(int fd, struct map_session_data *sd) { + int hIndex = 0; + if( HPMHooks.count.HP_clif_pBankOpen_pre ) { + void (*preHookFunc) (int *fd, struct map_session_data *sd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_pBankOpen_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_clif_pBankOpen_pre[hIndex].func; + preHookFunc(&fd, sd); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.clif.pBankOpen(fd, sd); + } + if( HPMHooks.count.HP_clif_pBankOpen_post ) { + void (*postHookFunc) (int *fd, struct map_session_data *sd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_pBankOpen_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_clif_pBankOpen_post[hIndex].func; + postHookFunc(&fd, sd); + } + } + return; +} +void HP_clif_pBankClose(int fd, struct map_session_data *sd) { + int hIndex = 0; + if( HPMHooks.count.HP_clif_pBankClose_pre ) { + void (*preHookFunc) (int *fd, struct map_session_data *sd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_pBankClose_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_clif_pBankClose_pre[hIndex].func; + preHookFunc(&fd, sd); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.clif.pBankClose(fd, sd); + } + if( HPMHooks.count.HP_clif_pBankClose_post ) { + void (*postHookFunc) (int *fd, struct map_session_data *sd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_pBankClose_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_clif_pBankClose_post[hIndex].func; + postHookFunc(&fd, sd); + } + } + return; +} +void HP_clif_pNPCShopClosed(int fd, struct map_session_data *sd) { + int hIndex = 0; + if( HPMHooks.count.HP_clif_pNPCShopClosed_pre ) { + void (*preHookFunc) (int *fd, struct map_session_data *sd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_pNPCShopClosed_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_clif_pNPCShopClosed_pre[hIndex].func; + preHookFunc(&fd, sd); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.clif.pNPCShopClosed(fd, sd); + } + if( HPMHooks.count.HP_clif_pNPCShopClosed_post ) { + void (*postHookFunc) (int *fd, struct map_session_data *sd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_pNPCShopClosed_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_clif_pNPCShopClosed_post[hIndex].func; + postHookFunc(&fd, sd); + } + } + return; +} +void HP_clif_pNPCMarketClosed(int fd, struct map_session_data *sd) { + int hIndex = 0; + if( HPMHooks.count.HP_clif_pNPCMarketClosed_pre ) { + void (*preHookFunc) (int *fd, struct map_session_data *sd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_pNPCMarketClosed_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_clif_pNPCMarketClosed_pre[hIndex].func; + preHookFunc(&fd, sd); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.clif.pNPCMarketClosed(fd, sd); + } + if( HPMHooks.count.HP_clif_pNPCMarketClosed_post ) { + void (*postHookFunc) (int *fd, struct map_session_data *sd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_pNPCMarketClosed_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_clif_pNPCMarketClosed_post[hIndex].func; + postHookFunc(&fd, sd); + } + } + return; +} +void HP_clif_pNPCMarketPurchase(int fd, struct map_session_data *sd) { + int hIndex = 0; + if( HPMHooks.count.HP_clif_pNPCMarketPurchase_pre ) { + void (*preHookFunc) (int *fd, struct map_session_data *sd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_pNPCMarketPurchase_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_clif_pNPCMarketPurchase_pre[hIndex].func; + preHookFunc(&fd, sd); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.clif.pNPCMarketPurchase(fd, sd); + } + if( HPMHooks.count.HP_clif_pNPCMarketPurchase_post ) { + void (*postHookFunc) (int *fd, struct map_session_data *sd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_pNPCMarketPurchase_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_clif_pNPCMarketPurchase_post[hIndex].func; + postHookFunc(&fd, sd); + } + } + return; +} /* duel */ int HP_duel_create(struct map_session_data *sd, const unsigned int maxpl) { int hIndex = 0; @@ -21675,13 +22164,13 @@ int HP_duel_checktime(struct map_session_data *sd) { } return retVal___; } -void HP_duel_init(void) { +void HP_duel_init(bool minimal) { int hIndex = 0; if( HPMHooks.count.HP_duel_init_pre ) { - void (*preHookFunc) (void); + void (*preHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_duel_init_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_duel_init_pre[hIndex].func; - preHookFunc(); + preHookFunc(&minimal); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -21689,13 +22178,13 @@ void HP_duel_init(void) { } } { - HPMHooks.source.duel.init(); + HPMHooks.source.duel.init(minimal); } if( HPMHooks.count.HP_duel_init_post ) { - void (*postHookFunc) (void); + void (*postHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_duel_init_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_duel_init_post[hIndex].func; - postHookFunc(); + postHookFunc(&minimal); } } return; @@ -21726,14 +22215,14 @@ void HP_duel_final(void) { return; } /* elemental */ -int HP_elemental_init(void) { +int HP_elemental_init(bool minimal) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_elemental_init_pre ) { - int (*preHookFunc) (void); + int (*preHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_elemental_init_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_elemental_init_pre[hIndex].func; - retVal___ = preHookFunc(); + retVal___ = preHookFunc(&minimal); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -21741,13 +22230,13 @@ int HP_elemental_init(void) { } } { - retVal___ = HPMHooks.source.elemental.init(); + retVal___ = HPMHooks.source.elemental.init(minimal); } if( HPMHooks.count.HP_elemental_init_post ) { - int (*postHookFunc) (int retVal___); + int (*postHookFunc) (int retVal___, bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_elemental_init_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_elemental_init_post[hIndex].func; - retVal___ = postHookFunc(retVal___); + retVal___ = postHookFunc(retVal___, &minimal); } } return retVal___; @@ -22217,11 +22706,11 @@ int HP_elemental_clean_effect(struct elemental_data *ed) { } return retVal___; } -int HP_elemental_action(struct elemental_data *ed, struct block_list *bl, unsigned int tick) { +int HP_elemental_action(struct elemental_data *ed, struct block_list *bl, int64 tick) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_elemental_action_pre ) { - int (*preHookFunc) (struct elemental_data *ed, struct block_list *bl, unsigned int *tick); + int (*preHookFunc) (struct elemental_data *ed, struct block_list *bl, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_elemental_action_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_elemental_action_pre[hIndex].func; retVal___ = preHookFunc(ed, bl, &tick); @@ -22235,7 +22724,7 @@ int HP_elemental_action(struct elemental_data *ed, struct block_list *bl, unsign retVal___ = HPMHooks.source.elemental.action(ed, bl, tick); } if( HPMHooks.count.HP_elemental_action_post ) { - int (*postHookFunc) (int retVal___, struct elemental_data *ed, struct block_list *bl, unsigned int *tick); + int (*postHookFunc) (int retVal___, struct elemental_data *ed, struct block_list *bl, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_elemental_action_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_elemental_action_post[hIndex].func; retVal___ = postHookFunc(retVal___, ed, bl, &tick); @@ -22397,11 +22886,11 @@ void HP_elemental_summon_init(struct elemental_data *ed) { } return; } -int HP_elemental_summon_end_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_elemental_summon_end_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_elemental_summon_end_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_elemental_summon_end_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_elemental_summon_end_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -22415,7 +22904,7 @@ int HP_elemental_summon_end_timer(int tid, unsigned int tick, int id, intptr_t d retVal___ = HPMHooks.source.elemental.summon_end_timer(tid, tick, id, data); } if( HPMHooks.count.HP_elemental_summon_end_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_elemental_summon_end_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_elemental_summon_end_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -22455,11 +22944,11 @@ int HP_elemental_ai_sub_timer_activesearch(struct block_list *bl, va_list ap) { } return retVal___; } -int HP_elemental_ai_sub_timer(struct elemental_data *ed, struct map_session_data *sd, unsigned int tick) { +int HP_elemental_ai_sub_timer(struct elemental_data *ed, struct map_session_data *sd, int64 tick) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_elemental_ai_sub_timer_pre ) { - int (*preHookFunc) (struct elemental_data *ed, struct map_session_data *sd, unsigned int *tick); + int (*preHookFunc) (struct elemental_data *ed, struct map_session_data *sd, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_elemental_ai_sub_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_elemental_ai_sub_timer_pre[hIndex].func; retVal___ = preHookFunc(ed, sd, &tick); @@ -22473,7 +22962,7 @@ int HP_elemental_ai_sub_timer(struct elemental_data *ed, struct map_session_data retVal___ = HPMHooks.source.elemental.ai_sub_timer(ed, sd, tick); } if( HPMHooks.count.HP_elemental_ai_sub_timer_post ) { - int (*postHookFunc) (int retVal___, struct elemental_data *ed, struct map_session_data *sd, unsigned int *tick); + int (*postHookFunc) (int retVal___, struct elemental_data *ed, struct map_session_data *sd, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_elemental_ai_sub_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_elemental_ai_sub_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, ed, sd, &tick); @@ -22513,11 +23002,11 @@ int HP_elemental_ai_sub_foreachclient(struct map_session_data *sd, va_list ap) { } return retVal___; } -int HP_elemental_ai_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_elemental_ai_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_elemental_ai_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_elemental_ai_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_elemental_ai_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -22531,7 +23020,7 @@ int HP_elemental_ai_timer(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.elemental.ai_timer(tid, tick, id, data); } if( HPMHooks.count.HP_elemental_ai_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_elemental_ai_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_elemental_ai_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -22566,13 +23055,13 @@ int HP_elemental_read_db(void) { return retVal___; } /* guild */ -void HP_guild_init(void) { +void HP_guild_init(bool minimal) { int hIndex = 0; if( HPMHooks.count.HP_guild_init_pre ) { - void (*preHookFunc) (void); + void (*preHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_guild_init_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_guild_init_pre[hIndex].func; - preHookFunc(); + preHookFunc(&minimal); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -22580,13 +23069,13 @@ void HP_guild_init(void) { } } { - HPMHooks.source.guild.init(); + HPMHooks.source.guild.init(minimal); } if( HPMHooks.count.HP_guild_init_post ) { - void (*postHookFunc) (void); + void (*postHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_guild_init_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_guild_init_post[hIndex].func; - postHookFunc(); + postHookFunc(&minimal); } } return; @@ -22850,14 +23339,14 @@ struct guild_castle* HP_guild_mapname2gc(const char *mapname) { } return retVal___; } -struct guild_castle* HP_guild_mapindex2gc(short mapindex) { +struct guild_castle* HP_guild_mapindex2gc(short map_index) { int hIndex = 0; struct guild_castle* retVal___ = NULL; if( HPMHooks.count.HP_guild_mapindex2gc_pre ) { - struct guild_castle* (*preHookFunc) (short *mapindex); + struct guild_castle* (*preHookFunc) (short *map_index); for(hIndex = 0; hIndex < HPMHooks.count.HP_guild_mapindex2gc_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_guild_mapindex2gc_pre[hIndex].func; - retVal___ = preHookFunc(&mapindex); + retVal___ = preHookFunc(&map_index); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -22865,13 +23354,13 @@ struct guild_castle* HP_guild_mapindex2gc(short mapindex) { } } { - retVal___ = HPMHooks.source.guild.mapindex2gc(mapindex); + retVal___ = HPMHooks.source.guild.mapindex2gc(map_index); } if( HPMHooks.count.HP_guild_mapindex2gc_post ) { - struct guild_castle* (*postHookFunc) (struct guild_castle* retVal___, short *mapindex); + struct guild_castle* (*postHookFunc) (struct guild_castle* retVal___, short *map_index); for(hIndex = 0; hIndex < HPMHooks.count.HP_guild_mapindex2gc_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_guild_mapindex2gc_post[hIndex].func; - retVal___ = postHookFunc(retVal___, &mapindex); + retVal___ = postHookFunc(retVal___, &map_index); } } return retVal___; @@ -24320,11 +24809,36 @@ void HP_guild_aura_refresh(struct map_session_data *sd, uint16 skill_id, uint16 } return; } -int HP_guild_payexp_timer(int tid, unsigned int tick, int id, intptr_t data) { +void HP_guild_retrieveitembound(int char_id, int aid, int guild_id) { + int hIndex = 0; + if( HPMHooks.count.HP_guild_retrieveitembound_pre ) { + void (*preHookFunc) (int *char_id, int *aid, int *guild_id); + for(hIndex = 0; hIndex < HPMHooks.count.HP_guild_retrieveitembound_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_guild_retrieveitembound_pre[hIndex].func; + preHookFunc(&char_id, &aid, &guild_id); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.guild.retrieveitembound(char_id, aid, guild_id); + } + if( HPMHooks.count.HP_guild_retrieveitembound_post ) { + void (*postHookFunc) (int *char_id, int *aid, int *guild_id); + for(hIndex = 0; hIndex < HPMHooks.count.HP_guild_retrieveitembound_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_guild_retrieveitembound_post[hIndex].func; + postHookFunc(&char_id, &aid, &guild_id); + } + } + return; +} +int HP_guild_payexp_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_guild_payexp_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_guild_payexp_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_guild_payexp_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -24338,7 +24852,7 @@ int HP_guild_payexp_timer(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.guild.payexp_timer(tid, tick, id, data); } if( HPMHooks.count.HP_guild_payexp_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_guild_payexp_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_guild_payexp_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -24488,11 +25002,11 @@ int HP_guild_send_xy_timer_sub(DBKey key, DBData *data, va_list ap) { } return retVal___; } -int HP_guild_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_guild_send_xy_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_guild_send_xy_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_guild_send_xy_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_guild_send_xy_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -24506,7 +25020,7 @@ int HP_guild_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.guild.send_xy_timer(tid, tick, id, data); } if( HPMHooks.count.HP_guild_send_xy_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_guild_send_xy_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_guild_send_xy_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -24868,13 +25382,13 @@ struct guild_storage* HP_gstorage_id2storage2(int guild_id) { } return retVal___; } -void HP_gstorage_init(void) { +void HP_gstorage_init(bool minimal) { int hIndex = 0; if( HPMHooks.count.HP_gstorage_init_pre ) { - void (*preHookFunc) (void); + void (*preHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_gstorage_init_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_gstorage_init_pre[hIndex].func; - preHookFunc(); + preHookFunc(&minimal); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -24882,13 +25396,13 @@ void HP_gstorage_init(void) { } } { - HPMHooks.source.gstorage.init(); + HPMHooks.source.gstorage.init(minimal); } if( HPMHooks.count.HP_gstorage_init_post ) { - void (*postHookFunc) (void); + void (*postHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_gstorage_init_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_gstorage_init_post[hIndex].func; - postHookFunc(); + postHookFunc(&minimal); } } return; @@ -25264,13 +25778,13 @@ DBData HP_gstorage_create(DBKey key, va_list args) { return retVal___; } /* homun */ -void HP_homun_init(void) { +void HP_homun_init(bool minimal) { int hIndex = 0; if( HPMHooks.count.HP_homun_init_pre ) { - void (*preHookFunc) (void); + void (*preHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_homun_init_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_homun_init_pre[hIndex].func; - preHookFunc(); + preHookFunc(&minimal); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -25278,13 +25792,13 @@ void HP_homun_init(void) { } } { - HPMHooks.source.homun.init(); + HPMHooks.source.homun.init(minimal); } if( HPMHooks.count.HP_homun_init_post ) { - void (*postHookFunc) (void); + void (*postHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_homun_init_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_homun_init_post[hIndex].func; - postHookFunc(); + postHookFunc(&minimal); } } return; @@ -25467,11 +25981,11 @@ int HP_homun_dead(struct homun_data *hd) { } return retVal___; } -int HP_homun_vaporize(struct map_session_data *sd, int flag) { +int HP_homun_vaporize(struct map_session_data *sd, enum homun_state flag) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_homun_vaporize_pre ) { - int (*preHookFunc) (struct map_session_data *sd, int *flag); + int (*preHookFunc) (struct map_session_data *sd, enum homun_state *flag); for(hIndex = 0; hIndex < HPMHooks.count.HP_homun_vaporize_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_homun_vaporize_pre[hIndex].func; retVal___ = preHookFunc(sd, &flag); @@ -25485,7 +25999,7 @@ int HP_homun_vaporize(struct map_session_data *sd, int flag) { retVal___ = HPMHooks.source.homun.vaporize(sd, flag); } if( HPMHooks.count.HP_homun_vaporize_post ) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd, int *flag); + int (*postHookFunc) (int retVal___, struct map_session_data *sd, enum homun_state *flag); for(hIndex = 0; hIndex < HPMHooks.count.HP_homun_vaporize_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_homun_vaporize_post[hIndex].func; retVal___ = postHookFunc(retVal___, sd, &flag); @@ -25906,11 +26420,11 @@ bool HP_homun_feed(struct map_session_data *sd, struct homun_data *hd) { } return retVal___; } -int HP_homun_hunger_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_homun_hunger_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_homun_hunger_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_homun_hunger_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_homun_hunger_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -25924,7 +26438,7 @@ int HP_homun_hunger_timer(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.homun.hunger_timer(tid, tick, id, data); } if( HPMHooks.count.HP_homun_hunger_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_homun_hunger_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_homun_hunger_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -26444,13 +26958,13 @@ void HP_homun_delspiritball(struct homun_data *hd, int count, int type) { return; } /* instance */ -void HP_instance_init(void) { +void HP_instance_init(bool minimal) { int hIndex = 0; if( HPMHooks.count.HP_instance_init_pre ) { - void (*preHookFunc) (void); + void (*preHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_instance_init_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_instance_init_pre[hIndex].func; - preHookFunc(); + preHookFunc(&minimal); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -26458,13 +26972,13 @@ void HP_instance_init(void) { } } { - HPMHooks.source.instance.init(); + HPMHooks.source.instance.init(minimal); } if( HPMHooks.count.HP_instance_init_post ) { - void (*postHookFunc) (void); + void (*postHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_instance_init_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_instance_init_post[hIndex].func; - postHookFunc(); + postHookFunc(&minimal); } } return; @@ -26494,6 +27008,31 @@ void HP_instance_final(void) { } return; } +void HP_instance_reload(void) { + int hIndex = 0; + if( HPMHooks.count.HP_instance_reload_pre ) { + void (*preHookFunc) (void); + for(hIndex = 0; hIndex < HPMHooks.count.HP_instance_reload_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_instance_reload_pre[hIndex].func; + preHookFunc(); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.instance.reload(); + } + if( HPMHooks.count.HP_instance_reload_post ) { + void (*postHookFunc) (void); + for(hIndex = 0; hIndex < HPMHooks.count.HP_instance_reload_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_instance_reload_post[hIndex].func; + postHookFunc(); + } + } + return; +} int HP_instance_create(int party_id, const char *name, enum instance_owner_type type) { int hIndex = 0; int retVal___ = 0; @@ -26623,6 +27162,96 @@ int HP_instance_mapid2imapid(int16 m, int instance_id) { } return retVal___; } +int HP_instance_mapname2imap(const char *map_name, int instance_id) { + int hIndex = 0; + int retVal___ = 0; + if( HPMHooks.count.HP_instance_mapname2imap_pre ) { + int (*preHookFunc) (const char *map_name, int *instance_id); + for(hIndex = 0; hIndex < HPMHooks.count.HP_instance_mapname2imap_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_instance_mapname2imap_pre[hIndex].func; + retVal___ = preHookFunc(map_name, &instance_id); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.instance.mapname2imap(map_name, instance_id); + } + if( HPMHooks.count.HP_instance_mapname2imap_post ) { + int (*postHookFunc) (int retVal___, const char *map_name, int *instance_id); + for(hIndex = 0; hIndex < HPMHooks.count.HP_instance_mapname2imap_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_instance_mapname2imap_post[hIndex].func; + retVal___ = postHookFunc(retVal___, map_name, &instance_id); + } + } + return retVal___; +} +int HP_instance_map_npcsub(struct block_list *bl, va_list args) { + int hIndex = 0; + int retVal___ = 0; + if( HPMHooks.count.HP_instance_map_npcsub_pre ) { + int (*preHookFunc) (struct block_list *bl, va_list args); + for(hIndex = 0; hIndex < HPMHooks.count.HP_instance_map_npcsub_pre; hIndex++ ) { + va_list args___copy; va_copy(args___copy, args); + preHookFunc = HPMHooks.list.HP_instance_map_npcsub_pre[hIndex].func; + retVal___ = preHookFunc(bl, args___copy); + va_end(args___copy); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + va_list args___copy; va_copy(args___copy, args); + retVal___ = HPMHooks.source.instance.map_npcsub(bl, args___copy); + va_end(args___copy); + } + if( HPMHooks.count.HP_instance_map_npcsub_post ) { + int (*postHookFunc) (int retVal___, struct block_list *bl, va_list args); + for(hIndex = 0; hIndex < HPMHooks.count.HP_instance_map_npcsub_post; hIndex++ ) { + va_list args___copy; va_copy(args___copy, args); + postHookFunc = HPMHooks.list.HP_instance_map_npcsub_post[hIndex].func; + retVal___ = postHookFunc(retVal___, bl, args___copy); + va_end(args___copy); + } + } + return retVal___; +} +int HP_instance_init_npc(struct block_list *bl, va_list args) { + int hIndex = 0; + int retVal___ = 0; + if( HPMHooks.count.HP_instance_init_npc_pre ) { + int (*preHookFunc) (struct block_list *bl, va_list args); + for(hIndex = 0; hIndex < HPMHooks.count.HP_instance_init_npc_pre; hIndex++ ) { + va_list args___copy; va_copy(args___copy, args); + preHookFunc = HPMHooks.list.HP_instance_init_npc_pre[hIndex].func; + retVal___ = preHookFunc(bl, args___copy); + va_end(args___copy); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + va_list args___copy; va_copy(args___copy, args); + retVal___ = HPMHooks.source.instance.init_npc(bl, args___copy); + va_end(args___copy); + } + if( HPMHooks.count.HP_instance_init_npc_post ) { + int (*postHookFunc) (int retVal___, struct block_list *bl, va_list args); + for(hIndex = 0; hIndex < HPMHooks.count.HP_instance_init_npc_post; hIndex++ ) { + va_list args___copy; va_copy(args___copy, args); + postHookFunc = HPMHooks.list.HP_instance_init_npc_post[hIndex].func; + retVal___ = postHookFunc(retVal___, bl, args___copy); + va_end(args___copy); + } + } + return retVal___; +} void HP_instance_destroy(int instance_id) { int hIndex = 0; if( HPMHooks.count.HP_instance_destroy_pre ) { @@ -26774,11 +27403,11 @@ bool HP_instance_valid(int instance_id) { } return retVal___; } -int HP_instance_destroy_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_instance_destroy_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_instance_destroy_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_instance_destroy_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_instance_destroy_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -26792,7 +27421,7 @@ int HP_instance_destroy_timer(int tid, unsigned int tick, int id, intptr_t data) retVal___ = HPMHooks.source.instance.destroy_timer(tid, tick, id, data); } if( HPMHooks.count.HP_instance_destroy_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_instance_destroy_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_instance_destroy_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -26853,11 +27482,11 @@ int HP_intif_create_pet(int account_id, int char_id, short pet_type, short pet_l } return retVal___; } -int HP_intif_broadcast(const char *mes, int len, int type) { +int HP_intif_broadcast(const char *mes, size_t len, int type) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_intif_broadcast_pre ) { - int (*preHookFunc) (const char *mes, int *len, int *type); + int (*preHookFunc) (const char *mes, size_t *len, int *type); for(hIndex = 0; hIndex < HPMHooks.count.HP_intif_broadcast_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_intif_broadcast_pre[hIndex].func; retVal___ = preHookFunc(mes, &len, &type); @@ -26871,7 +27500,7 @@ int HP_intif_broadcast(const char *mes, int len, int type) { retVal___ = HPMHooks.source.intif.broadcast(mes, len, type); } if( HPMHooks.count.HP_intif_broadcast_post ) { - int (*postHookFunc) (int retVal___, const char *mes, int *len, int *type); + int (*postHookFunc) (int retVal___, const char *mes, size_t *len, int *type); for(hIndex = 0; hIndex < HPMHooks.count.HP_intif_broadcast_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_intif_broadcast_post[hIndex].func; retVal___ = postHookFunc(retVal___, mes, &len, &type); @@ -26879,11 +27508,11 @@ int HP_intif_broadcast(const char *mes, int len, int type) { } return retVal___; } -int HP_intif_broadcast2(const char *mes, int len, unsigned long fontColor, short fontType, short fontSize, short fontAlign, short fontY) { +int HP_intif_broadcast2(const char *mes, size_t len, unsigned int fontColor, short fontType, short fontSize, short fontAlign, short fontY) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_intif_broadcast2_pre ) { - int (*preHookFunc) (const char *mes, int *len, unsigned long *fontColor, short *fontType, short *fontSize, short *fontAlign, short *fontY); + int (*preHookFunc) (const char *mes, size_t *len, unsigned int *fontColor, short *fontType, short *fontSize, short *fontAlign, short *fontY); for(hIndex = 0; hIndex < HPMHooks.count.HP_intif_broadcast2_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_intif_broadcast2_pre[hIndex].func; retVal___ = preHookFunc(mes, &len, &fontColor, &fontType, &fontSize, &fontAlign, &fontY); @@ -26897,7 +27526,7 @@ int HP_intif_broadcast2(const char *mes, int len, unsigned long fontColor, short retVal___ = HPMHooks.source.intif.broadcast2(mes, len, fontColor, fontType, fontSize, fontAlign, fontY); } if( HPMHooks.count.HP_intif_broadcast2_post ) { - int (*postHookFunc) (int retVal___, const char *mes, int *len, unsigned long *fontColor, short *fontType, short *fontSize, short *fontAlign, short *fontY); + int (*postHookFunc) (int retVal___, const char *mes, size_t *len, unsigned int *fontColor, short *fontType, short *fontSize, short *fontAlign, short *fontY); for(hIndex = 0; hIndex < HPMHooks.count.HP_intif_broadcast2_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_intif_broadcast2_post[hIndex].func; retVal___ = postHookFunc(retVal___, mes, &len, &fontColor, &fontType, &fontSize, &fontAlign, &fontY); @@ -26931,11 +27560,11 @@ int HP_intif_main_message(struct map_session_data *sd, const char *message) { } return retVal___; } -int HP_intif_wis_message(struct map_session_data *sd, char *nick, char *mes, int mes_len) { +int HP_intif_wis_message(struct map_session_data *sd, char *nick, char *mes, size_t mes_len) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_intif_wis_message_pre ) { - int (*preHookFunc) (struct map_session_data *sd, char *nick, char *mes, int *mes_len); + int (*preHookFunc) (struct map_session_data *sd, char *nick, char *mes, size_t *mes_len); for(hIndex = 0; hIndex < HPMHooks.count.HP_intif_wis_message_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_intif_wis_message_pre[hIndex].func; retVal___ = preHookFunc(sd, nick, mes, &mes_len); @@ -26949,7 +27578,7 @@ int HP_intif_wis_message(struct map_session_data *sd, char *nick, char *mes, int retVal___ = HPMHooks.source.intif.wis_message(sd, nick, mes, mes_len); } if( HPMHooks.count.HP_intif_wis_message_post ) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd, char *nick, char *mes, int *mes_len); + int (*postHookFunc) (int retVal___, struct map_session_data *sd, char *nick, char *mes, size_t *mes_len); for(hIndex = 0; hIndex < HPMHooks.count.HP_intif_wis_message_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_intif_wis_message_post[hIndex].func; retVal___ = postHookFunc(retVal___, sd, nick, mes, &mes_len); @@ -26983,14 +27612,14 @@ int HP_intif_wis_message_to_gm(char *Wisp_name, int permission, char *mes) { } return retVal___; } -int HP_intif_saveregistry(struct map_session_data *sd, int type) { +int HP_intif_saveregistry(struct map_session_data *sd) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_intif_saveregistry_pre ) { - int (*preHookFunc) (struct map_session_data *sd, int *type); + int (*preHookFunc) (struct map_session_data *sd); for(hIndex = 0; hIndex < HPMHooks.count.HP_intif_saveregistry_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_intif_saveregistry_pre[hIndex].func; - retVal___ = preHookFunc(sd, &type); + retVal___ = preHookFunc(sd); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -26998,13 +27627,13 @@ int HP_intif_saveregistry(struct map_session_data *sd, int type) { } } { - retVal___ = HPMHooks.source.intif.saveregistry(sd, type); + retVal___ = HPMHooks.source.intif.saveregistry(sd); } if( HPMHooks.count.HP_intif_saveregistry_post ) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd, int *type); + int (*postHookFunc) (int retVal___, struct map_session_data *sd); for(hIndex = 0; hIndex < HPMHooks.count.HP_intif_saveregistry_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_intif_saveregistry_post[hIndex].func; - retVal___ = postHookFunc(retVal___, sd, &type); + retVal___ = postHookFunc(retVal___, sd); } } return retVal___; @@ -27503,11 +28132,11 @@ int HP_intif_guild_message(int guild_id, int account_id, const char *mes, int le } return retVal___; } -int HP_intif_guild_change_gm(int guild_id, const char *name, int len) { +int HP_intif_guild_change_gm(int guild_id, const char *name, size_t len) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_intif_guild_change_gm_pre ) { - int (*preHookFunc) (int *guild_id, const char *name, int *len); + int (*preHookFunc) (int *guild_id, const char *name, size_t *len); for(hIndex = 0; hIndex < HPMHooks.count.HP_intif_guild_change_gm_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_intif_guild_change_gm_pre[hIndex].func; retVal___ = preHookFunc(&guild_id, name, &len); @@ -27521,7 +28150,7 @@ int HP_intif_guild_change_gm(int guild_id, const char *name, int len) { retVal___ = HPMHooks.source.intif.guild_change_gm(guild_id, name, len); } if( HPMHooks.count.HP_intif_guild_change_gm_post ) { - int (*postHookFunc) (int retVal___, int *guild_id, const char *name, int *len); + int (*postHookFunc) (int retVal___, int *guild_id, const char *name, size_t *len); for(hIndex = 0; hIndex < HPMHooks.count.HP_intif_guild_change_gm_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_intif_guild_change_gm_post[hIndex].func; retVal___ = postHookFunc(retVal___, &guild_id, name, &len); @@ -27763,6 +28392,31 @@ int HP_intif_guild_castle_datasave(int castle_id, int index, int value) { } return retVal___; } +void HP_intif_itembound_req(int char_id, int aid, int guild_id) { + int hIndex = 0; + if( HPMHooks.count.HP_intif_itembound_req_pre ) { + void (*preHookFunc) (int *char_id, int *aid, int *guild_id); + for(hIndex = 0; hIndex < HPMHooks.count.HP_intif_itembound_req_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_intif_itembound_req_pre[hIndex].func; + preHookFunc(&char_id, &aid, &guild_id); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.intif.itembound_req(char_id, aid, guild_id); + } + if( HPMHooks.count.HP_intif_itembound_req_post ) { + void (*postHookFunc) (int *char_id, int *aid, int *guild_id); + for(hIndex = 0; hIndex < HPMHooks.count.HP_intif_itembound_req_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_intif_itembound_req_post[hIndex].func; + postHookFunc(&char_id, &aid, &guild_id); + } + } + return; +} int HP_intif_request_petdata(int account_id, int char_id, int pet_id) { int hIndex = 0; int retVal___ = 0; @@ -27971,31 +28625,30 @@ int HP_intif_homunculus_requestdelete(int homun_id) { } return retVal___; } -int HP_intif_request_questlog(struct map_session_data *sd) { +void HP_intif_request_questlog(struct map_session_data *sd) { int hIndex = 0; - int retVal___ = 0; if( HPMHooks.count.HP_intif_request_questlog_pre ) { - int (*preHookFunc) (struct map_session_data *sd); + void (*preHookFunc) (struct map_session_data *sd); for(hIndex = 0; hIndex < HPMHooks.count.HP_intif_request_questlog_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_intif_request_questlog_pre[hIndex].func; - retVal___ = preHookFunc(sd); + preHookFunc(sd); } if( *HPMforce_return ) { *HPMforce_return = false; - return retVal___; + return; } } { - retVal___ = HPMHooks.source.intif.request_questlog(sd); + HPMHooks.source.intif.request_questlog(sd); } if( HPMHooks.count.HP_intif_request_questlog_post ) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd); + void (*postHookFunc) (struct map_session_data *sd); for(hIndex = 0; hIndex < HPMHooks.count.HP_intif_request_questlog_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_intif_request_questlog_post[hIndex].func; - retVal___ = postHookFunc(retVal___, sd); + postHookFunc(sd); } } - return retVal___; + return; } int HP_intif_quest_save(struct map_session_data *sd) { int hIndex = 0; @@ -29750,6 +30403,31 @@ void HP_intif_pAuctionBid(int fd) { } return; } +void HP_intif_pItembound_ack(int fd) { + int hIndex = 0; + if( HPMHooks.count.HP_intif_pItembound_ack_pre ) { + void (*preHookFunc) (int *fd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_intif_pItembound_ack_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_intif_pItembound_ack_pre[hIndex].func; + preHookFunc(&fd); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.intif.pItembound_ack(fd); + } + if( HPMHooks.count.HP_intif_pItembound_ack_post ) { + void (*postHookFunc) (int *fd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_intif_pItembound_ack_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_intif_pItembound_ack_post[hIndex].func; + postHookFunc(&fd); + } + } + return; +} void HP_intif_pMercenaryReceived(int fd) { int hIndex = 0; if( HPMHooks.count.HP_intif_pMercenaryReceived_pre ) { @@ -30101,13 +30779,13 @@ void HP_intif_pDeleteHomunculusOk(int fd) { return; } /* ircbot */ -void HP_ircbot_init(void) { +void HP_ircbot_init(bool minimal) { int hIndex = 0; if( HPMHooks.count.HP_ircbot_init_pre ) { - void (*preHookFunc) (void); + void (*preHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_ircbot_init_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_ircbot_init_pre[hIndex].func; - preHookFunc(); + preHookFunc(&minimal); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -30115,13 +30793,13 @@ void HP_ircbot_init(void) { } } { - HPMHooks.source.ircbot.init(); + HPMHooks.source.ircbot.init(minimal); } if( HPMHooks.count.HP_ircbot_init_post ) { - void (*postHookFunc) (void); + void (*postHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_ircbot_init_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_ircbot_init_post[hIndex].func; - postHookFunc(); + postHookFunc(&minimal); } } return; @@ -30253,11 +30931,11 @@ struct irc_func* HP_ircbot_func_search(char *function_name) { } return retVal___; } -int HP_ircbot_connect_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_ircbot_connect_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_ircbot_connect_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_ircbot_connect_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_ircbot_connect_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -30271,7 +30949,7 @@ int HP_ircbot_connect_timer(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.ircbot.connect_timer(tid, tick, id, data); } if( HPMHooks.count.HP_ircbot_connect_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_ircbot_connect_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_ircbot_connect_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -30279,11 +30957,11 @@ int HP_ircbot_connect_timer(int tid, unsigned int tick, int id, intptr_t data) { } return retVal___; } -int HP_ircbot_identify_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_ircbot_identify_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_ircbot_identify_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_ircbot_identify_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_ircbot_identify_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -30297,7 +30975,7 @@ int HP_ircbot_identify_timer(int tid, unsigned int tick, int id, intptr_t data) retVal___ = HPMHooks.source.ircbot.identify_timer(tid, tick, id, data); } if( HPMHooks.count.HP_ircbot_identify_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_ircbot_identify_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_ircbot_identify_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -30305,11 +30983,11 @@ int HP_ircbot_identify_timer(int tid, unsigned int tick, int id, intptr_t data) } return retVal___; } -int HP_ircbot_join_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_ircbot_join_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_ircbot_join_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_ircbot_join_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_ircbot_join_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -30323,7 +31001,7 @@ int HP_ircbot_join_timer(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.ircbot.join_timer(tid, tick, id, data); } if( HPMHooks.count.HP_ircbot_join_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_ircbot_join_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_ircbot_join_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -30507,13 +31185,13 @@ void HP_ircbot_usernick(int fd, char *cmd, char *source, char *target, char *msg return; } /* itemdb */ -void HP_itemdb_init(void) { +void HP_itemdb_init(bool minimal) { int hIndex = 0; if( HPMHooks.count.HP_itemdb_init_pre ) { - void (*preHookFunc) (void); + void (*preHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_init_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_itemdb_init_pre[hIndex].func; - preHookFunc(); + preHookFunc(&minimal); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -30521,13 +31199,13 @@ void HP_itemdb_init(void) { } } { - HPMHooks.source.itemdb.init(); + HPMHooks.source.itemdb.init(minimal); } if( HPMHooks.count.HP_itemdb_init_post ) { - void (*postHookFunc) (void); + void (*postHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_init_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_itemdb_init_post[hIndex].func; - postHookFunc(); + postHookFunc(&minimal); } } return; @@ -30607,31 +31285,6 @@ void HP_itemdb_name_constants(void) { } return; } -void HP_itemdb_force_name_constants(void) { - int hIndex = 0; - if( HPMHooks.count.HP_itemdb_force_name_constants_pre ) { - void (*preHookFunc) (void); - for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_force_name_constants_pre; hIndex++ ) { - preHookFunc = HPMHooks.list.HP_itemdb_force_name_constants_pre[hIndex].func; - preHookFunc(); - } - if( *HPMforce_return ) { - *HPMforce_return = false; - return; - } - } - { - HPMHooks.source.itemdb.force_name_constants(); - } - if( HPMHooks.count.HP_itemdb_force_name_constants_post ) { - void (*postHookFunc) (void); - for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_force_name_constants_post; hIndex++ ) { - postHookFunc = HPMHooks.list.HP_itemdb_force_name_constants_post[hIndex].func; - postHookFunc(); - } - } - return; -} void HP_itemdb_read_groups(void) { int hIndex = 0; if( HPMHooks.count.HP_itemdb_read_groups_pre ) { @@ -30888,32 +31541,6 @@ struct item_data* HP_itemdb_search(int nameid) { } return retVal___; } -int HP_itemdb_parse_dbrow(char **str, const char *source, int line, int scriptopt) { - int hIndex = 0; - int retVal___ = 0; - if( HPMHooks.count.HP_itemdb_parse_dbrow_pre ) { - int (*preHookFunc) (char **str, const char *source, int *line, int *scriptopt); - for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_parse_dbrow_pre; hIndex++ ) { - preHookFunc = HPMHooks.list.HP_itemdb_parse_dbrow_pre[hIndex].func; - retVal___ = preHookFunc(str, source, &line, &scriptopt); - } - if( *HPMforce_return ) { - *HPMforce_return = false; - return retVal___; - } - } - { - retVal___ = HPMHooks.source.itemdb.parse_dbrow(str, source, line, scriptopt); - } - if( HPMHooks.count.HP_itemdb_parse_dbrow_post ) { - int (*postHookFunc) (int retVal___, char **str, const char *source, int *line, int *scriptopt); - for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_parse_dbrow_post; hIndex++ ) { - postHookFunc = HPMHooks.list.HP_itemdb_parse_dbrow_post[hIndex].func; - retVal___ = postHookFunc(retVal___, str, source, &line, &scriptopt); - } - } - return retVal___; -} struct item_data* HP_itemdb_exists(int nameid) { int hIndex = 0; struct item_data* retVal___ = NULL; @@ -31884,39 +32511,40 @@ int HP_itemdb_gendercheck(struct item_data *id) { } return retVal___; } -void HP_itemdb_re_split_atoi(char *str, int *atk, int *matk) { +int HP_itemdb_validate_entry(struct item_data *entry, int n, const char *source) { int hIndex = 0; - if( HPMHooks.count.HP_itemdb_re_split_atoi_pre ) { - void (*preHookFunc) (char *str, int *atk, int *matk); - for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_re_split_atoi_pre; hIndex++ ) { - preHookFunc = HPMHooks.list.HP_itemdb_re_split_atoi_pre[hIndex].func; - preHookFunc(str, atk, matk); + int retVal___ = 0; + if( HPMHooks.count.HP_itemdb_validate_entry_pre ) { + int (*preHookFunc) (struct item_data *entry, int *n, const char *source); + for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_validate_entry_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_itemdb_validate_entry_pre[hIndex].func; + retVal___ = preHookFunc(entry, &n, source); } if( *HPMforce_return ) { *HPMforce_return = false; - return; + return retVal___; } } { - HPMHooks.source.itemdb.re_split_atoi(str, atk, matk); + retVal___ = HPMHooks.source.itemdb.validate_entry(entry, n, source); } - if( HPMHooks.count.HP_itemdb_re_split_atoi_post ) { - void (*postHookFunc) (char *str, int *atk, int *matk); - for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_re_split_atoi_post; hIndex++ ) { - postHookFunc = HPMHooks.list.HP_itemdb_re_split_atoi_post[hIndex].func; - postHookFunc(str, atk, matk); + if( HPMHooks.count.HP_itemdb_validate_entry_post ) { + int (*postHookFunc) (int retVal___, struct item_data *entry, int *n, const char *source); + for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_validate_entry_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_itemdb_validate_entry_post[hIndex].func; + retVal___ = postHookFunc(retVal___, entry, &n, source); } } - return; + return retVal___; } -int HP_itemdb_readdb(void) { +int HP_itemdb_readdb_sql_sub(Sql *handle, int n, const char *source) { int hIndex = 0; int retVal___ = 0; - if( HPMHooks.count.HP_itemdb_readdb_pre ) { - int (*preHookFunc) (void); - for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_readdb_pre; hIndex++ ) { - preHookFunc = HPMHooks.list.HP_itemdb_readdb_pre[hIndex].func; - retVal___ = preHookFunc(); + if( HPMHooks.count.HP_itemdb_readdb_sql_sub_pre ) { + int (*preHookFunc) (Sql *handle, int *n, const char *source); + for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_readdb_sql_sub_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_itemdb_readdb_sql_sub_pre[hIndex].func; + retVal___ = preHookFunc(handle, &n, source); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -31924,25 +32552,25 @@ int HP_itemdb_readdb(void) { } } { - retVal___ = HPMHooks.source.itemdb.readdb(); + retVal___ = HPMHooks.source.itemdb.readdb_sql_sub(handle, n, source); } - if( HPMHooks.count.HP_itemdb_readdb_post ) { - int (*postHookFunc) (int retVal___); - for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_readdb_post; hIndex++ ) { - postHookFunc = HPMHooks.list.HP_itemdb_readdb_post[hIndex].func; - retVal___ = postHookFunc(retVal___); + if( HPMHooks.count.HP_itemdb_readdb_sql_sub_post ) { + int (*postHookFunc) (int retVal___, Sql *handle, int *n, const char *source); + for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_readdb_sql_sub_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_itemdb_readdb_sql_sub_post[hIndex].func; + retVal___ = postHookFunc(retVal___, handle, &n, source); } } return retVal___; } -int HP_itemdb_read_sqldb(void) { +int HP_itemdb_readdb_libconfig_sub(config_setting_t *it, int n, const char *source) { int hIndex = 0; int retVal___ = 0; - if( HPMHooks.count.HP_itemdb_read_sqldb_pre ) { - int (*preHookFunc) (void); - for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_read_sqldb_pre; hIndex++ ) { - preHookFunc = HPMHooks.list.HP_itemdb_read_sqldb_pre[hIndex].func; - retVal___ = preHookFunc(); + if( HPMHooks.count.HP_itemdb_readdb_libconfig_sub_pre ) { + int (*preHookFunc) (config_setting_t *it, int *n, const char *source); + for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_readdb_libconfig_sub_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_itemdb_readdb_libconfig_sub_pre[hIndex].func; + retVal___ = preHookFunc(it, &n, source); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -31950,13 +32578,65 @@ int HP_itemdb_read_sqldb(void) { } } { - retVal___ = HPMHooks.source.itemdb.read_sqldb(); + retVal___ = HPMHooks.source.itemdb.readdb_libconfig_sub(it, n, source); } - if( HPMHooks.count.HP_itemdb_read_sqldb_post ) { - int (*postHookFunc) (int retVal___); - for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_read_sqldb_post; hIndex++ ) { - postHookFunc = HPMHooks.list.HP_itemdb_read_sqldb_post[hIndex].func; - retVal___ = postHookFunc(retVal___); + if( HPMHooks.count.HP_itemdb_readdb_libconfig_sub_post ) { + int (*postHookFunc) (int retVal___, config_setting_t *it, int *n, const char *source); + for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_readdb_libconfig_sub_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_itemdb_readdb_libconfig_sub_post[hIndex].func; + retVal___ = postHookFunc(retVal___, it, &n, source); + } + } + return retVal___; +} +int HP_itemdb_readdb_libconfig(const char *filename) { + int hIndex = 0; + int retVal___ = 0; + if( HPMHooks.count.HP_itemdb_readdb_libconfig_pre ) { + int (*preHookFunc) (const char *filename); + for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_readdb_libconfig_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_itemdb_readdb_libconfig_pre[hIndex].func; + retVal___ = preHookFunc(filename); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.itemdb.readdb_libconfig(filename); + } + if( HPMHooks.count.HP_itemdb_readdb_libconfig_post ) { + int (*postHookFunc) (int retVal___, const char *filename); + for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_readdb_libconfig_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_itemdb_readdb_libconfig_post[hIndex].func; + retVal___ = postHookFunc(retVal___, filename); + } + } + return retVal___; +} +int HP_itemdb_readdb_sql(const char *tablename) { + int hIndex = 0; + int retVal___ = 0; + if( HPMHooks.count.HP_itemdb_readdb_sql_pre ) { + int (*preHookFunc) (const char *tablename); + for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_readdb_sql_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_itemdb_readdb_sql_pre[hIndex].func; + retVal___ = preHookFunc(tablename); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.itemdb.readdb_sql(tablename); + } + if( HPMHooks.count.HP_itemdb_readdb_sql_post ) { + int (*postHookFunc) (int retVal___, const char *tablename); + for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_readdb_sql_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_itemdb_readdb_sql_post[hIndex].func; + retVal___ = postHookFunc(retVal___, tablename); } } return retVal___; @@ -32013,13 +32693,13 @@ int HP_itemdb_uid_load(void) { } return retVal___; } -void HP_itemdb_read(void) { +void HP_itemdb_read(bool minimal) { int hIndex = 0; if( HPMHooks.count.HP_itemdb_read_pre ) { - void (*preHookFunc) (void); + void (*preHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_read_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_itemdb_read_pre[hIndex].func; - preHookFunc(); + preHookFunc(&minimal); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -32027,13 +32707,13 @@ void HP_itemdb_read(void) { } } { - HPMHooks.source.itemdb.read(); + HPMHooks.source.itemdb.read(minimal); } if( HPMHooks.count.HP_itemdb_read_post ) { - void (*postHookFunc) (void); + void (*postHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_read_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_itemdb_read_post[hIndex].func; - postHookFunc(); + postHookFunc(&minimal); } } return; @@ -32095,6 +32775,57 @@ int HP_itemdb_final_sub(DBKey key, DBData *data, va_list ap) { } return retVal___; } +void HP_itemdb_clear(bool total) { + int hIndex = 0; + if( HPMHooks.count.HP_itemdb_clear_pre ) { + void (*preHookFunc) (bool *total); + for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_clear_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_itemdb_clear_pre[hIndex].func; + preHookFunc(&total); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.itemdb.clear(total); + } + if( HPMHooks.count.HP_itemdb_clear_post ) { + void (*postHookFunc) (bool *total); + for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_clear_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_itemdb_clear_post[hIndex].func; + postHookFunc(&total); + } + } + return; +} +struct item_combo* HP_itemdb_id2combo(unsigned short id) { + int hIndex = 0; + struct item_combo* retVal___ = NULL; + if( HPMHooks.count.HP_itemdb_id2combo_pre ) { + struct item_combo* (*preHookFunc) (unsigned short *id); + for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_id2combo_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_itemdb_id2combo_pre[hIndex].func; + retVal___ = preHookFunc(&id); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.itemdb.id2combo(id); + } + if( HPMHooks.count.HP_itemdb_id2combo_post ) { + struct item_combo* (*postHookFunc) (struct item_combo* retVal___, unsigned short *id); + for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_id2combo_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_itemdb_id2combo_post[hIndex].func; + retVal___ = postHookFunc(retVal___, &id); + } + } + return retVal___; +} /* logs */ void HP_logs_pick_pc(struct map_session_data *sd, e_log_pick_type type, int amount, struct item *itm, struct item_data *data) { int hIndex = 0; @@ -33291,11 +34022,11 @@ int HP_map_delblock(struct block_list *bl) { } return retVal___; } -int HP_map_moveblock(struct block_list *bl, int x1, int y1, unsigned int tick) { +int HP_map_moveblock(struct block_list *bl, int x1, int y1, int64 tick) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_map_moveblock_pre ) { - int (*preHookFunc) (struct block_list *bl, int *x1, int *y1, unsigned int *tick); + int (*preHookFunc) (struct block_list *bl, int *x1, int *y1, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_map_moveblock_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_map_moveblock_pre[hIndex].func; retVal___ = preHookFunc(bl, &x1, &y1, &tick); @@ -33309,7 +34040,7 @@ int HP_map_moveblock(struct block_list *bl, int x1, int y1, unsigned int tick) { retVal___ = HPMHooks.source.map.moveblock(bl, x1, y1, tick); } if( HPMHooks.count.HP_map_moveblock_post ) { - int (*postHookFunc) (int retVal___, struct block_list *bl, int *x1, int *y1, unsigned int *tick); + int (*postHookFunc) (int retVal___, struct block_list *bl, int *x1, int *y1, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_map_moveblock_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_map_moveblock_post[hIndex].func; retVal___ = postHookFunc(retVal___, bl, &x1, &y1, &tick); @@ -33473,11 +34204,11 @@ bool HP_map_addnpc(int16 m, struct npc_data *nd) { } return retVal___; } -int HP_map_clearflooritem_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_map_clearflooritem_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_map_clearflooritem_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_map_clearflooritem_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_map_clearflooritem_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -33491,7 +34222,7 @@ int HP_map_clearflooritem_timer(int tid, unsigned int tick, int id, intptr_t dat retVal___ = HPMHooks.source.map.clearflooritem_timer(tid, tick, id, data); } if( HPMHooks.count.HP_map_clearflooritem_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_map_clearflooritem_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_map_clearflooritem_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -33499,11 +34230,11 @@ int HP_map_clearflooritem_timer(int tid, unsigned int tick, int id, intptr_t dat } return retVal___; } -int HP_map_removemobs_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_map_removemobs_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_map_removemobs_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_map_removemobs_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_map_removemobs_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -33517,7 +34248,7 @@ int HP_map_removemobs_timer(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.map.removemobs_timer(tid, tick, id, data); } if( HPMHooks.count.HP_map_removemobs_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_map_removemobs_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_map_removemobs_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -34386,14 +35117,14 @@ bool HP_map_blid_exists(int id) { } return retVal___; } -int16 HP_map_mapindex2mapid(unsigned short mapindex) { +int16 HP_map_mapindex2mapid(unsigned short map_index) { int hIndex = 0; int16 retVal___ = 0; if( HPMHooks.count.HP_map_mapindex2mapid_pre ) { - int16 (*preHookFunc) (unsigned short *mapindex); + int16 (*preHookFunc) (unsigned short *map_index); for(hIndex = 0; hIndex < HPMHooks.count.HP_map_mapindex2mapid_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_map_mapindex2mapid_pre[hIndex].func; - retVal___ = preHookFunc(&mapindex); + retVal___ = preHookFunc(&map_index); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -34401,13 +35132,13 @@ int16 HP_map_mapindex2mapid(unsigned short mapindex) { } } { - retVal___ = HPMHooks.source.map.mapindex2mapid(mapindex); + retVal___ = HPMHooks.source.map.mapindex2mapid(map_index); } if( HPMHooks.count.HP_map_mapindex2mapid_post ) { - int16 (*postHookFunc) (int16 retVal___, unsigned short *mapindex); + int16 (*postHookFunc) (int16 retVal___, unsigned short *map_index); for(hIndex = 0; hIndex < HPMHooks.count.HP_map_mapindex2mapid_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_map_mapindex2mapid_post[hIndex].func; - retVal___ = postHookFunc(retVal___, &mapindex); + retVal___ = postHookFunc(retVal___, &map_index); } } return retVal___; @@ -34464,14 +35195,14 @@ int HP_map_mapname2ipport(unsigned short name, uint32 *ip, uint16 *port) { } return retVal___; } -int HP_map_setipport(unsigned short mapindex, uint32 ip, uint16 port) { +int HP_map_setipport(unsigned short map_index, uint32 ip, uint16 port) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_map_setipport_pre ) { - int (*preHookFunc) (unsigned short *mapindex, uint32 *ip, uint16 *port); + int (*preHookFunc) (unsigned short *map_index, uint32 *ip, uint16 *port); for(hIndex = 0; hIndex < HPMHooks.count.HP_map_setipport_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_map_setipport_pre[hIndex].func; - retVal___ = preHookFunc(&mapindex, &ip, &port); + retVal___ = preHookFunc(&map_index, &ip, &port); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -34479,25 +35210,25 @@ int HP_map_setipport(unsigned short mapindex, uint32 ip, uint16 port) { } } { - retVal___ = HPMHooks.source.map.setipport(mapindex, ip, port); + retVal___ = HPMHooks.source.map.setipport(map_index, ip, port); } if( HPMHooks.count.HP_map_setipport_post ) { - int (*postHookFunc) (int retVal___, unsigned short *mapindex, uint32 *ip, uint16 *port); + int (*postHookFunc) (int retVal___, unsigned short *map_index, uint32 *ip, uint16 *port); for(hIndex = 0; hIndex < HPMHooks.count.HP_map_setipport_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_map_setipport_post[hIndex].func; - retVal___ = postHookFunc(retVal___, &mapindex, &ip, &port); + retVal___ = postHookFunc(retVal___, &map_index, &ip, &port); } } return retVal___; } -int HP_map_eraseipport(unsigned short mapindex, uint32 ip, uint16 port) { +int HP_map_eraseipport(unsigned short map_index, uint32 ip, uint16 port) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_map_eraseipport_pre ) { - int (*preHookFunc) (unsigned short *mapindex, uint32 *ip, uint16 *port); + int (*preHookFunc) (unsigned short *map_index, uint32 *ip, uint16 *port); for(hIndex = 0; hIndex < HPMHooks.count.HP_map_eraseipport_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_map_eraseipport_pre[hIndex].func; - retVal___ = preHookFunc(&mapindex, &ip, &port); + retVal___ = preHookFunc(&map_index, &ip, &port); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -34505,13 +35236,13 @@ int HP_map_eraseipport(unsigned short mapindex, uint32 ip, uint16 port) { } } { - retVal___ = HPMHooks.source.map.eraseipport(mapindex, ip, port); + retVal___ = HPMHooks.source.map.eraseipport(map_index, ip, port); } if( HPMHooks.count.HP_map_eraseipport_post ) { - int (*postHookFunc) (int retVal___, unsigned short *mapindex, uint32 *ip, uint16 *port); + int (*postHookFunc) (int retVal___, unsigned short *map_index, uint32 *ip, uint16 *port); for(hIndex = 0; hIndex < HPMHooks.count.HP_map_eraseipport_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_map_eraseipport_post[hIndex].func; - retVal___ = postHookFunc(retVal___, &mapindex, &ip, &port); + retVal___ = postHookFunc(retVal___, &map_index, &ip, &port); } } return retVal___; @@ -35108,11 +35839,11 @@ void HP_map_do_shutdown(void) { } return; } -int HP_map_freeblock_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_map_freeblock_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_map_freeblock_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_map_freeblock_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_map_freeblock_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -35126,7 +35857,7 @@ int HP_map_freeblock_timer(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.map.freeblock_timer(tid, tick, id, data); } if( HPMHooks.count.HP_map_freeblock_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_map_freeblock_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_map_freeblock_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -35554,11 +36285,11 @@ int HP_map_readfromcache(struct map_data *m, char *buffer) { } return retVal___; } -int HP_map_addmap(char *mapname) { +int HP_map_addmap(const char *mapname) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_map_addmap_pre ) { - int (*preHookFunc) (char *mapname); + int (*preHookFunc) (const char *mapname); for(hIndex = 0; hIndex < HPMHooks.count.HP_map_addmap_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_map_addmap_pre[hIndex].func; retVal___ = preHookFunc(mapname); @@ -35572,7 +36303,7 @@ int HP_map_addmap(char *mapname) { retVal___ = HPMHooks.source.map.addmap(mapname); } if( HPMHooks.count.HP_map_addmap_post ) { - int (*postHookFunc) (int retVal___, char *mapname); + int (*postHookFunc) (int retVal___, const char *mapname); for(hIndex = 0; hIndex < HPMHooks.count.HP_map_addmap_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_map_addmap_post[hIndex].func; retVal___ = postHookFunc(retVal___, mapname); @@ -36195,14 +36926,14 @@ void HP_map_versionscreen(bool do_exit) { } return; } -bool HP_map_arg_next_value(const char *option, int i, int argc) { +bool HP_map_arg_next_value(const char *option, int i, int argc, bool must) { int hIndex = 0; bool retVal___ = false; if( HPMHooks.count.HP_map_arg_next_value_pre ) { - bool (*preHookFunc) (const char *option, int *i, int *argc); + bool (*preHookFunc) (const char *option, int *i, int *argc, bool *must); for(hIndex = 0; hIndex < HPMHooks.count.HP_map_arg_next_value_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_map_arg_next_value_pre[hIndex].func; - retVal___ = preHookFunc(option, &i, &argc); + retVal___ = preHookFunc(option, &i, &argc, &must); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -36210,13 +36941,13 @@ bool HP_map_arg_next_value(const char *option, int i, int argc) { } } { - retVal___ = HPMHooks.source.map.arg_next_value(option, i, argc); + retVal___ = HPMHooks.source.map.arg_next_value(option, i, argc, must); } if( HPMHooks.count.HP_map_arg_next_value_post ) { - bool (*postHookFunc) (bool retVal___, const char *option, int *i, int *argc); + bool (*postHookFunc) (bool retVal___, const char *option, int *i, int *argc, bool *must); for(hIndex = 0; hIndex < HPMHooks.count.HP_map_arg_next_value_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_map_arg_next_value_post[hIndex].func; - retVal___ = postHookFunc(retVal___, option, &i, &argc); + retVal___ = postHookFunc(retVal___, option, &i, &argc, &must); } } return retVal___; @@ -36271,6 +37002,109 @@ void HP_map_delblcell(struct block_list *bl) { } return; } +int HP_map_get_new_bonus_id(void) { + int hIndex = 0; + int retVal___ = 0; + if( HPMHooks.count.HP_map_get_new_bonus_id_pre ) { + int (*preHookFunc) (void); + for(hIndex = 0; hIndex < HPMHooks.count.HP_map_get_new_bonus_id_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_map_get_new_bonus_id_pre[hIndex].func; + retVal___ = preHookFunc(); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.map.get_new_bonus_id(); + } + if( HPMHooks.count.HP_map_get_new_bonus_id_post ) { + int (*postHookFunc) (int retVal___); + for(hIndex = 0; hIndex < HPMHooks.count.HP_map_get_new_bonus_id_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_map_get_new_bonus_id_post[hIndex].func; + retVal___ = postHookFunc(retVal___); + } + } + return retVal___; +} +void HP_map_add_questinfo(int m, struct questinfo *qi) { + int hIndex = 0; + if( HPMHooks.count.HP_map_add_questinfo_pre ) { + void (*preHookFunc) (int *m, struct questinfo *qi); + for(hIndex = 0; hIndex < HPMHooks.count.HP_map_add_questinfo_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_map_add_questinfo_pre[hIndex].func; + preHookFunc(&m, qi); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.map.add_questinfo(m, qi); + } + if( HPMHooks.count.HP_map_add_questinfo_post ) { + void (*postHookFunc) (int *m, struct questinfo *qi); + for(hIndex = 0; hIndex < HPMHooks.count.HP_map_add_questinfo_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_map_add_questinfo_post[hIndex].func; + postHookFunc(&m, qi); + } + } + return; +} +bool HP_map_remove_questinfo(int m, struct npc_data *nd) { + int hIndex = 0; + bool retVal___ = false; + if( HPMHooks.count.HP_map_remove_questinfo_pre ) { + bool (*preHookFunc) (int *m, struct npc_data *nd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_map_remove_questinfo_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_map_remove_questinfo_pre[hIndex].func; + retVal___ = preHookFunc(&m, nd); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.map.remove_questinfo(m, nd); + } + if( HPMHooks.count.HP_map_remove_questinfo_post ) { + bool (*postHookFunc) (bool retVal___, int *m, struct npc_data *nd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_map_remove_questinfo_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_map_remove_questinfo_post[hIndex].func; + retVal___ = postHookFunc(retVal___, &m, nd); + } + } + return retVal___; +} +struct map_zone_data* HP_map_merge_zone(struct map_zone_data *main, struct map_zone_data *other) { + int hIndex = 0; + struct map_zone_data* retVal___ = NULL; + if( HPMHooks.count.HP_map_merge_zone_pre ) { + struct map_zone_data* (*preHookFunc) (struct map_zone_data *main, struct map_zone_data *other); + for(hIndex = 0; hIndex < HPMHooks.count.HP_map_merge_zone_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_map_merge_zone_pre[hIndex].func; + retVal___ = preHookFunc(main, other); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.map.merge_zone(main, other); + } + if( HPMHooks.count.HP_map_merge_zone_post ) { + struct map_zone_data* (*postHookFunc) (struct map_zone_data* retVal___, struct map_zone_data *main, struct map_zone_data *other); + for(hIndex = 0; hIndex < HPMHooks.count.HP_map_merge_zone_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_map_merge_zone_post[hIndex].func; + retVal___ = postHookFunc(retVal___, main, other); + } + } + return retVal___; +} /* mapit */ struct s_mapiterator* HP_mapit_alloc(enum e_mapitflags flags, enum bl_type types) { int hIndex = 0; @@ -36504,11 +37338,11 @@ void HP_mapreg_final(void) { } return; } -int HP_mapreg_readreg(int uid) { +int HP_mapreg_readreg(int64 uid) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_mapreg_readreg_pre ) { - int (*preHookFunc) (int *uid); + int (*preHookFunc) (int64 *uid); for(hIndex = 0; hIndex < HPMHooks.count.HP_mapreg_readreg_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_mapreg_readreg_pre[hIndex].func; retVal___ = preHookFunc(&uid); @@ -36522,7 +37356,7 @@ int HP_mapreg_readreg(int uid) { retVal___ = HPMHooks.source.mapreg.readreg(uid); } if( HPMHooks.count.HP_mapreg_readreg_post ) { - int (*postHookFunc) (int retVal___, int *uid); + int (*postHookFunc) (int retVal___, int64 *uid); for(hIndex = 0; hIndex < HPMHooks.count.HP_mapreg_readreg_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_mapreg_readreg_post[hIndex].func; retVal___ = postHookFunc(retVal___, &uid); @@ -36530,11 +37364,11 @@ int HP_mapreg_readreg(int uid) { } return retVal___; } -char* HP_mapreg_readregstr(int uid) { +char* HP_mapreg_readregstr(int64 uid) { int hIndex = 0; char* retVal___ = NULL; if( HPMHooks.count.HP_mapreg_readregstr_pre ) { - char* (*preHookFunc) (int *uid); + char* (*preHookFunc) (int64 *uid); for(hIndex = 0; hIndex < HPMHooks.count.HP_mapreg_readregstr_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_mapreg_readregstr_pre[hIndex].func; retVal___ = preHookFunc(&uid); @@ -36548,7 +37382,7 @@ char* HP_mapreg_readregstr(int uid) { retVal___ = HPMHooks.source.mapreg.readregstr(uid); } if( HPMHooks.count.HP_mapreg_readregstr_post ) { - char* (*postHookFunc) (char* retVal___, int *uid); + char* (*postHookFunc) (char* retVal___, int64 *uid); for(hIndex = 0; hIndex < HPMHooks.count.HP_mapreg_readregstr_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_mapreg_readregstr_post[hIndex].func; retVal___ = postHookFunc(retVal___, &uid); @@ -36556,11 +37390,11 @@ char* HP_mapreg_readregstr(int uid) { } return retVal___; } -bool HP_mapreg_setreg(int uid, int val) { +bool HP_mapreg_setreg(int64 uid, int val) { int hIndex = 0; bool retVal___ = false; if( HPMHooks.count.HP_mapreg_setreg_pre ) { - bool (*preHookFunc) (int *uid, int *val); + bool (*preHookFunc) (int64 *uid, int *val); for(hIndex = 0; hIndex < HPMHooks.count.HP_mapreg_setreg_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_mapreg_setreg_pre[hIndex].func; retVal___ = preHookFunc(&uid, &val); @@ -36574,7 +37408,7 @@ bool HP_mapreg_setreg(int uid, int val) { retVal___ = HPMHooks.source.mapreg.setreg(uid, val); } if( HPMHooks.count.HP_mapreg_setreg_post ) { - bool (*postHookFunc) (bool retVal___, int *uid, int *val); + bool (*postHookFunc) (bool retVal___, int64 *uid, int *val); for(hIndex = 0; hIndex < HPMHooks.count.HP_mapreg_setreg_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_mapreg_setreg_post[hIndex].func; retVal___ = postHookFunc(retVal___, &uid, &val); @@ -36582,11 +37416,11 @@ bool HP_mapreg_setreg(int uid, int val) { } return retVal___; } -bool HP_mapreg_setregstr(int uid, const char *str) { +bool HP_mapreg_setregstr(int64 uid, const char *str) { int hIndex = 0; bool retVal___ = false; if( HPMHooks.count.HP_mapreg_setregstr_pre ) { - bool (*preHookFunc) (int *uid, const char *str); + bool (*preHookFunc) (int64 *uid, const char *str); for(hIndex = 0; hIndex < HPMHooks.count.HP_mapreg_setregstr_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_mapreg_setregstr_pre[hIndex].func; retVal___ = preHookFunc(&uid, str); @@ -36600,7 +37434,7 @@ bool HP_mapreg_setregstr(int uid, const char *str) { retVal___ = HPMHooks.source.mapreg.setregstr(uid, str); } if( HPMHooks.count.HP_mapreg_setregstr_post ) { - bool (*postHookFunc) (bool retVal___, int *uid, const char *str); + bool (*postHookFunc) (bool retVal___, int64 *uid, const char *str); for(hIndex = 0; hIndex < HPMHooks.count.HP_mapreg_setregstr_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_mapreg_setregstr_post[hIndex].func; retVal___ = postHookFunc(retVal___, &uid, str); @@ -36658,11 +37492,11 @@ void HP_mapreg_save(void) { } return; } -int HP_mapreg_save_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_mapreg_save_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_mapreg_save_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_mapreg_save_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_mapreg_save_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -36676,7 +37510,7 @@ int HP_mapreg_save_timer(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.mapreg.save_timer(tid, tick, id, data); } if( HPMHooks.count.HP_mapreg_save_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_mapreg_save_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_mapreg_save_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -36736,13 +37570,13 @@ bool HP_mapreg_config_read(const char *w1, const char *w2) { return retVal___; } /* mercenary */ -void HP_mercenary_init(void) { +void HP_mercenary_init(bool minimal) { int hIndex = 0; if( HPMHooks.count.HP_mercenary_init_pre ) { - void (*preHookFunc) (void); + void (*preHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_mercenary_init_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_mercenary_init_pre[hIndex].func; - preHookFunc(); + preHookFunc(&minimal); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -36750,13 +37584,13 @@ void HP_mercenary_init(void) { } } { - HPMHooks.source.mercenary.init(); + HPMHooks.source.mercenary.init(minimal); } if( HPMHooks.count.HP_mercenary_init_post ) { - void (*postHookFunc) (void); + void (*postHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_mercenary_init_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_mercenary_init_post[hIndex].func; - postHookFunc(); + postHookFunc(&minimal); } } return; @@ -37305,11 +38139,11 @@ int HP_mercenary_search_index(int class_) { } return retVal___; } -int HP_mercenary_contract_end_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_mercenary_contract_end_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_mercenary_contract_end_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_mercenary_contract_end_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_mercenary_contract_end_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -37323,7 +38157,7 @@ int HP_mercenary_contract_end_timer(int tid, unsigned int tick, int id, intptr_t retVal___ = HPMHooks.source.mercenary.contract_end_timer(tid, tick, id, data); } if( HPMHooks.count.HP_mercenary_contract_end_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_mercenary_contract_end_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_mercenary_contract_end_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -37384,14 +38218,14 @@ bool HP_mercenary_read_skill_db_sub(char *str[], int columns, int current) { return retVal___; } /* mob */ -int HP_mob_init(void) { +int HP_mob_init(bool mimimal) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_mob_init_pre ) { - int (*preHookFunc) (void); + int (*preHookFunc) (bool *mimimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_init_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_mob_init_pre[hIndex].func; - retVal___ = preHookFunc(); + retVal___ = preHookFunc(&mimimal); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -37399,13 +38233,13 @@ int HP_mob_init(void) { } } { - retVal___ = HPMHooks.source.mob.init(); + retVal___ = HPMHooks.source.mob.init(mimimal); } if( HPMHooks.count.HP_mob_init_post ) { - int (*postHookFunc) (int retVal___); + int (*postHookFunc) (int retVal___, bool *mimimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_init_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_mob_init_post[hIndex].func; - retVal___ = postHookFunc(retVal___); + retVal___ = postHookFunc(retVal___, &mimimal); } } return retVal___; @@ -37539,11 +38373,11 @@ int HP_mob_makedummymobdb(int p1) { } return retVal___; } -int HP_mob_spawn_guardian_sub(int tid, unsigned int tick, int id, intptr_t data) { +int HP_mob_spawn_guardian_sub(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_mob_spawn_guardian_sub_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_spawn_guardian_sub_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_mob_spawn_guardian_sub_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -37557,7 +38391,7 @@ int HP_mob_spawn_guardian_sub(int tid, unsigned int tick, int id, intptr_t data) retVal___ = HPMHooks.source.mob.spawn_guardian_sub(tid, tick, id, data); } if( HPMHooks.count.HP_mob_spawn_guardian_sub_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_spawn_guardian_sub_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_mob_spawn_guardian_sub_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -37617,14 +38451,14 @@ int HP_mob_db_searchname(const char *str) { } return retVal___; } -int HP_mob_db_searchname_array_sub(struct mob_db *mob, const char *str, int flag) { +int HP_mob_db_searchname_array_sub(struct mob_db *monster, const char *str, int flag) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_mob_db_searchname_array_sub_pre ) { - int (*preHookFunc) (struct mob_db *mob, const char *str, int *flag); + int (*preHookFunc) (struct mob_db *monster, const char *str, int *flag); for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_db_searchname_array_sub_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_mob_db_searchname_array_sub_pre[hIndex].func; - retVal___ = preHookFunc(mob, str, &flag); + retVal___ = preHookFunc(monster, str, &flag); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -37632,13 +38466,13 @@ int HP_mob_db_searchname_array_sub(struct mob_db *mob, const char *str, int flag } } { - retVal___ = HPMHooks.source.mob.db_searchname_array_sub(mob, str, flag); + retVal___ = HPMHooks.source.mob.db_searchname_array_sub(monster, str, flag); } if( HPMHooks.count.HP_mob_db_searchname_array_sub_post ) { - int (*postHookFunc) (int retVal___, struct mob_db *mob, const char *str, int *flag); + int (*postHookFunc) (int retVal___, struct mob_db *monster, const char *str, int *flag); for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_db_searchname_array_sub_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_mob_db_searchname_array_sub_post[hIndex].func; - retVal___ = postHookFunc(retVal___, mob, str, &flag); + retVal___ = postHookFunc(retVal___, monster, str, &flag); } } return retVal___; @@ -38063,11 +38897,11 @@ int HP_mob_linksearch(struct block_list *bl, va_list ap) { } return retVal___; } -int HP_mob_delayspawn(int tid, unsigned int tick, int id, intptr_t data) { +int HP_mob_delayspawn(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_mob_delayspawn_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_delayspawn_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_mob_delayspawn_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -38081,7 +38915,7 @@ int HP_mob_delayspawn(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.mob.delayspawn(tid, tick, id, data); } if( HPMHooks.count.HP_mob_delayspawn_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_delayspawn_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_mob_delayspawn_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -38385,11 +39219,11 @@ int HP_mob_warpchase_sub(struct block_list *bl, va_list ap) { } return retVal___; } -int HP_mob_ai_sub_hard_slavemob(struct mob_data *md, unsigned int tick) { +int HP_mob_ai_sub_hard_slavemob(struct mob_data *md, int64 tick) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_mob_ai_sub_hard_slavemob_pre ) { - int (*preHookFunc) (struct mob_data *md, unsigned int *tick); + int (*preHookFunc) (struct mob_data *md, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_ai_sub_hard_slavemob_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_mob_ai_sub_hard_slavemob_pre[hIndex].func; retVal___ = preHookFunc(md, &tick); @@ -38403,7 +39237,7 @@ int HP_mob_ai_sub_hard_slavemob(struct mob_data *md, unsigned int tick) { retVal___ = HPMHooks.source.mob.ai_sub_hard_slavemob(md, tick); } if( HPMHooks.count.HP_mob_ai_sub_hard_slavemob_post ) { - int (*postHookFunc) (int retVal___, struct mob_data *md, unsigned int *tick); + int (*postHookFunc) (int retVal___, struct mob_data *md, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_ai_sub_hard_slavemob_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_mob_ai_sub_hard_slavemob_post[hIndex].func; retVal___ = postHookFunc(retVal___, md, &tick); @@ -38411,11 +39245,11 @@ int HP_mob_ai_sub_hard_slavemob(struct mob_data *md, unsigned int tick) { } return retVal___; } -int HP_mob_unlocktarget(struct mob_data *md, unsigned int tick) { +int HP_mob_unlocktarget(struct mob_data *md, int64 tick) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_mob_unlocktarget_pre ) { - int (*preHookFunc) (struct mob_data *md, unsigned int *tick); + int (*preHookFunc) (struct mob_data *md, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_unlocktarget_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_mob_unlocktarget_pre[hIndex].func; retVal___ = preHookFunc(md, &tick); @@ -38429,7 +39263,7 @@ int HP_mob_unlocktarget(struct mob_data *md, unsigned int tick) { retVal___ = HPMHooks.source.mob.unlocktarget(md, tick); } if( HPMHooks.count.HP_mob_unlocktarget_post ) { - int (*postHookFunc) (int retVal___, struct mob_data *md, unsigned int *tick); + int (*postHookFunc) (int retVal___, struct mob_data *md, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_unlocktarget_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_mob_unlocktarget_post[hIndex].func; retVal___ = postHookFunc(retVal___, md, &tick); @@ -38437,11 +39271,11 @@ int HP_mob_unlocktarget(struct mob_data *md, unsigned int tick) { } return retVal___; } -int HP_mob_randomwalk(struct mob_data *md, unsigned int tick) { +int HP_mob_randomwalk(struct mob_data *md, int64 tick) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_mob_randomwalk_pre ) { - int (*preHookFunc) (struct mob_data *md, unsigned int *tick); + int (*preHookFunc) (struct mob_data *md, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_randomwalk_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_mob_randomwalk_pre[hIndex].func; retVal___ = preHookFunc(md, &tick); @@ -38455,7 +39289,7 @@ int HP_mob_randomwalk(struct mob_data *md, unsigned int tick) { retVal___ = HPMHooks.source.mob.randomwalk(md, tick); } if( HPMHooks.count.HP_mob_randomwalk_post ) { - int (*postHookFunc) (int retVal___, struct mob_data *md, unsigned int *tick); + int (*postHookFunc) (int retVal___, struct mob_data *md, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_randomwalk_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_mob_randomwalk_post[hIndex].func; retVal___ = postHookFunc(retVal___, md, &tick); @@ -38489,11 +39323,11 @@ int HP_mob_warpchase(struct mob_data *md, struct block_list *target) { } return retVal___; } -bool HP_mob_ai_sub_hard(struct mob_data *md, unsigned int tick) { +bool HP_mob_ai_sub_hard(struct mob_data *md, int64 tick) { int hIndex = 0; bool retVal___ = false; if( HPMHooks.count.HP_mob_ai_sub_hard_pre ) { - bool (*preHookFunc) (struct mob_data *md, unsigned int *tick); + bool (*preHookFunc) (struct mob_data *md, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_ai_sub_hard_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_mob_ai_sub_hard_pre[hIndex].func; retVal___ = preHookFunc(md, &tick); @@ -38507,7 +39341,7 @@ bool HP_mob_ai_sub_hard(struct mob_data *md, unsigned int tick) { retVal___ = HPMHooks.source.mob.ai_sub_hard(md, tick); } if( HPMHooks.count.HP_mob_ai_sub_hard_post ) { - bool (*postHookFunc) (bool retVal___, struct mob_data *md, unsigned int *tick); + bool (*postHookFunc) (bool retVal___, struct mob_data *md, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_ai_sub_hard_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_mob_ai_sub_hard_post[hIndex].func; retVal___ = postHookFunc(retVal___, md, &tick); @@ -38611,11 +39445,11 @@ int HP_mob_ai_sub_lazy(struct mob_data *md, va_list args) { } return retVal___; } -int HP_mob_ai_lazy(int tid, unsigned int tick, int id, intptr_t data) { +int HP_mob_ai_lazy(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_mob_ai_lazy_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_ai_lazy_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_mob_ai_lazy_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -38629,7 +39463,7 @@ int HP_mob_ai_lazy(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.mob.ai_lazy(tid, tick, id, data); } if( HPMHooks.count.HP_mob_ai_lazy_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_ai_lazy_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_mob_ai_lazy_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -38637,11 +39471,11 @@ int HP_mob_ai_lazy(int tid, unsigned int tick, int id, intptr_t data) { } return retVal___; } -int HP_mob_ai_hard(int tid, unsigned int tick, int id, intptr_t data) { +int HP_mob_ai_hard(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_mob_ai_hard_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_ai_hard_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_mob_ai_hard_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -38655,7 +39489,7 @@ int HP_mob_ai_hard(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.mob.ai_hard(tid, tick, id, data); } if( HPMHooks.count.HP_mob_ai_hard_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_ai_hard_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_mob_ai_hard_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -38715,11 +39549,11 @@ struct item_drop* HP_mob_setlootitem(struct item *item) { } return retVal___; } -int HP_mob_delay_item_drop(int tid, unsigned int tick, int id, intptr_t data) { +int HP_mob_delay_item_drop(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_mob_delay_item_drop_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_delay_item_drop_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_mob_delay_item_drop_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -38733,7 +39567,7 @@ int HP_mob_delay_item_drop(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.mob.delay_item_drop(tid, tick, id, data); } if( HPMHooks.count.HP_mob_delay_item_drop_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_delay_item_drop_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_mob_delay_item_drop_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -38766,11 +39600,11 @@ void HP_mob_item_drop(struct mob_data *md, struct item_drop_list *dlist, struct } return; } -int HP_mob_timer_delete(int tid, unsigned int tick, int id, intptr_t data) { +int HP_mob_timer_delete(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_mob_timer_delete_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_timer_delete_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_mob_timer_delete_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -38784,7 +39618,7 @@ int HP_mob_timer_delete(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.mob.timer_delete(tid, tick, id, data); } if( HPMHooks.count.HP_mob_timer_delete_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_timer_delete_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_mob_timer_delete_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -38850,11 +39684,11 @@ int HP_mob_deleteslave(struct mob_data *md) { } return retVal___; } -int HP_mob_respawn(int tid, unsigned int tick, int id, intptr_t data) { +int HP_mob_respawn(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_mob_respawn_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_respawn_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_mob_respawn_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -38868,7 +39702,7 @@ int HP_mob_respawn(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.mob.respawn(tid, tick, id, data); } if( HPMHooks.count.HP_mob_respawn_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_respawn_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_mob_respawn_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -39364,11 +40198,11 @@ struct mob_data* HP_mob_getfriendstatus(struct mob_data *md, int cond1, int cond } return retVal___; } -int HP_mob_skill_use(struct mob_data *md, unsigned int tick, int event) { +int HP_mob_skill_use(struct mob_data *md, int64 tick, int event) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_mob_skill_use_pre ) { - int (*preHookFunc) (struct mob_data *md, unsigned int *tick, int *event); + int (*preHookFunc) (struct mob_data *md, int64 *tick, int *event); for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_skill_use_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_mob_skill_use_pre[hIndex].func; retVal___ = preHookFunc(md, &tick, &event); @@ -39382,7 +40216,7 @@ int HP_mob_skill_use(struct mob_data *md, unsigned int tick, int event) { retVal___ = HPMHooks.source.mob.skill_use(md, tick, event); } if( HPMHooks.count.HP_mob_skill_use_post ) { - int (*postHookFunc) (int retVal___, struct mob_data *md, unsigned int *tick, int *event); + int (*postHookFunc) (int retVal___, struct mob_data *md, int64 *tick, int *event); for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_skill_use_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_mob_skill_use_post[hIndex].func; retVal___ = postHookFunc(retVal___, md, &tick, &event); @@ -39390,11 +40224,11 @@ int HP_mob_skill_use(struct mob_data *md, unsigned int tick, int event) { } return retVal___; } -int HP_mob_skill_event(struct mob_data *md, struct block_list *src, unsigned int tick, int flag) { +int HP_mob_skill_event(struct mob_data *md, struct block_list *src, int64 tick, int flag) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_mob_skill_event_pre ) { - int (*preHookFunc) (struct mob_data *md, struct block_list *src, unsigned int *tick, int *flag); + int (*preHookFunc) (struct mob_data *md, struct block_list *src, int64 *tick, int *flag); for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_skill_event_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_mob_skill_event_pre[hIndex].func; retVal___ = preHookFunc(md, src, &tick, &flag); @@ -39408,7 +40242,7 @@ int HP_mob_skill_event(struct mob_data *md, struct block_list *src, unsigned int retVal___ = HPMHooks.source.mob.skill_event(md, src, tick, flag); } if( HPMHooks.count.HP_mob_skill_event_post ) { - int (*postHookFunc) (int retVal___, struct mob_data *md, struct block_list *src, unsigned int *tick, int *flag); + int (*postHookFunc) (int retVal___, struct mob_data *md, struct block_list *src, int64 *tick, int *flag); for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_skill_event_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_mob_skill_event_post[hIndex].func; retVal___ = postHookFunc(retVal___, md, src, &tick, &flag); @@ -39648,6 +40482,31 @@ int HP_mob_read_sqldb(void) { } return retVal___; } +void HP_mob_name_constants(void) { + int hIndex = 0; + if( HPMHooks.count.HP_mob_name_constants_pre ) { + void (*preHookFunc) (void); + for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_name_constants_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_mob_name_constants_pre[hIndex].func; + preHookFunc(); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.mob.name_constants(); + } + if( HPMHooks.count.HP_mob_name_constants_post ) { + void (*postHookFunc) (void); + for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_name_constants_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_mob_name_constants_post[hIndex].func; + postHookFunc(); + } + } + return; +} bool HP_mob_readdb_mobavail(char *str[], int columns, int current) { int hIndex = 0; bool retVal___ = false; @@ -39880,13 +40739,13 @@ bool HP_mob_readdb_itemratio(char *str[], int columns, int current) { } return retVal___; } -void HP_mob_load(void) { +void HP_mob_load(bool minimal) { int hIndex = 0; if( HPMHooks.count.HP_mob_load_pre ) { - void (*preHookFunc) (void); + void (*preHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_load_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_mob_load_pre[hIndex].func; - preHookFunc(); + preHookFunc(&minimal); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -39894,13 +40753,13 @@ void HP_mob_load(void) { } } { - HPMHooks.source.mob.load(); + HPMHooks.source.mob.load(minimal); } if( HPMHooks.count.HP_mob_load_post ) { - void (*postHookFunc) (void); + void (*postHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_mob_load_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_mob_load_post[hIndex].func; - postHookFunc(); + postHookFunc(&minimal); } } return; @@ -39931,14 +40790,14 @@ void HP_mob_clear_spawninfo(void) { return; } /* npc */ -int HP_npc_init(void) { +int HP_npc_init(bool minimal) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_npc_init_pre ) { - int (*preHookFunc) (void); + int (*preHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_init_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_npc_init_pre[hIndex].func; - retVal___ = preHookFunc(); + retVal___ = preHookFunc(&minimal); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -39946,13 +40805,13 @@ int HP_npc_init(void) { } } { - retVal___ = HPMHooks.source.npc.init(); + retVal___ = HPMHooks.source.npc.init(minimal); } if( HPMHooks.count.HP_npc_init_post ) { - int (*postHookFunc) (int retVal___); + int (*postHookFunc) (int retVal___, bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_init_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_npc_init_post[hIndex].func; - retVal___ = postHookFunc(retVal___); + retVal___ = postHookFunc(retVal___, &minimal); } } return retVal___; @@ -40449,11 +41308,11 @@ int HP_npc_event_doall(const char *name) { } return retVal___; } -int HP_npc_event_do_clock(int tid, unsigned int tick, int id, intptr_t data) { +int HP_npc_event_do_clock(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_npc_event_do_clock_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_event_do_clock_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_npc_event_do_clock_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -40467,7 +41326,7 @@ int HP_npc_event_do_clock(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.npc.event_do_clock(tid, tick, id, data); } if( HPMHooks.count.HP_npc_event_do_clock_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_event_do_clock_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_npc_event_do_clock_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -40526,11 +41385,11 @@ int HP_npc_timerevent_export(struct npc_data *nd, int i) { } return retVal___; } -int HP_npc_timerevent(int tid, unsigned int tick, int id, intptr_t data) { +int HP_npc_timerevent(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_npc_timerevent_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_timerevent_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_npc_timerevent_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -40544,7 +41403,7 @@ int HP_npc_timerevent(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.npc.timerevent(tid, tick, id, data); } if( HPMHooks.count.HP_npc_timerevent_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_timerevent_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_npc_timerevent_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -40629,11 +41488,11 @@ void HP_npc_timerevent_quit(struct map_session_data *sd) { } return; } -int HP_npc_gettimerevent_tick(struct npc_data *nd) { +int64 HP_npc_gettimerevent_tick(struct npc_data *nd) { int hIndex = 0; - int retVal___ = 0; + int64 retVal___ = 0; if( HPMHooks.count.HP_npc_gettimerevent_tick_pre ) { - int (*preHookFunc) (struct npc_data *nd); + int64 (*preHookFunc) (struct npc_data *nd); for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_gettimerevent_tick_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_npc_gettimerevent_tick_pre[hIndex].func; retVal___ = preHookFunc(nd); @@ -40647,7 +41506,7 @@ int HP_npc_gettimerevent_tick(struct npc_data *nd) { retVal___ = HPMHooks.source.npc.gettimerevent_tick(nd); } if( HPMHooks.count.HP_npc_gettimerevent_tick_post ) { - int (*postHookFunc) (int retVal___, struct npc_data *nd); + int64 (*postHookFunc) (int64 retVal___, struct npc_data *nd); for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_gettimerevent_tick_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_npc_gettimerevent_tick_post[hIndex].func; retVal___ = postHookFunc(retVal___, nd); @@ -41427,6 +42286,58 @@ void HP_npc_parsename(struct npc_data *nd, const char *name, const char *start, } return; } +int HP_npc_parseview(const char *w4, const char *start, const char *buffer, const char *filepath) { + int hIndex = 0; + int retVal___ = 0; + if( HPMHooks.count.HP_npc_parseview_pre ) { + int (*preHookFunc) (const char *w4, const char *start, const char *buffer, const char *filepath); + for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_parseview_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_npc_parseview_pre[hIndex].func; + retVal___ = preHookFunc(w4, start, buffer, filepath); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.npc.parseview(w4, start, buffer, filepath); + } + if( HPMHooks.count.HP_npc_parseview_post ) { + int (*postHookFunc) (int retVal___, const char *w4, const char *start, const char *buffer, const char *filepath); + for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_parseview_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_npc_parseview_post[hIndex].func; + retVal___ = postHookFunc(retVal___, w4, start, buffer, filepath); + } + } + return retVal___; +} +bool HP_npc_viewisid(const char *viewid) { + int hIndex = 0; + bool retVal___ = false; + if( HPMHooks.count.HP_npc_viewisid_pre ) { + bool (*preHookFunc) (const char *viewid); + for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_viewisid_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_npc_viewisid_pre[hIndex].func; + retVal___ = preHookFunc(viewid); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.npc.viewisid(viewid); + } + if( HPMHooks.count.HP_npc_viewisid_post ) { + bool (*postHookFunc) (bool retVal___, const char *viewid); + for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_viewisid_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_npc_viewisid_post[hIndex].func; + retVal___ = postHookFunc(retVal___, viewid); + } + } + return retVal___; +} struct npc_data* HP_npc_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) { int hIndex = 0; struct npc_data* retVal___ = NULL; @@ -41556,14 +42467,14 @@ const char* HP_npc_skip_script(const char *start, const char *buffer, const char } return retVal___; } -const char* HP_npc_parse_script(char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath, bool runOnInit) { +const char* HP_npc_parse_script(char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath, int options) { int hIndex = 0; const char* retVal___ = NULL; if( HPMHooks.count.HP_npc_parse_script_pre ) { - const char* (*preHookFunc) (char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath, bool *runOnInit); + const char* (*preHookFunc) (char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath, int *options); for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_parse_script_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_npc_parse_script_pre[hIndex].func; - retVal___ = preHookFunc(w1, w2, w3, w4, start, buffer, filepath, &runOnInit); + retVal___ = preHookFunc(w1, w2, w3, w4, start, buffer, filepath, &options); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -41571,13 +42482,13 @@ const char* HP_npc_parse_script(char *w1, char *w2, char *w3, char *w4, const ch } } { - retVal___ = HPMHooks.source.npc.parse_script(w1, w2, w3, w4, start, buffer, filepath, runOnInit); + retVal___ = HPMHooks.source.npc.parse_script(w1, w2, w3, w4, start, buffer, filepath, options); } if( HPMHooks.count.HP_npc_parse_script_post ) { - const char* (*postHookFunc) (const char* retVal___, char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath, bool *runOnInit); + const char* (*postHookFunc) (const char* retVal___, char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath, int *options); for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_parse_script_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_npc_parse_script_post[hIndex].func; - retVal___ = postHookFunc(retVal___, w1, w2, w3, w4, start, buffer, filepath, &runOnInit); + retVal___ = postHookFunc(retVal___, w1, w2, w3, w4, start, buffer, filepath, &options); } } return retVal___; @@ -41920,30 +42831,31 @@ const char* HP_npc_parse_mapflag(char *w1, char *w2, char *w3, char *w4, const c } return retVal___; } -void HP_npc_parsesrcfile(const char *filepath, bool runOnInit) { +int HP_npc_parsesrcfile(const char *filepath, bool runOnInit) { int hIndex = 0; + int retVal___ = 0; if( HPMHooks.count.HP_npc_parsesrcfile_pre ) { - void (*preHookFunc) (const char *filepath, bool *runOnInit); + int (*preHookFunc) (const char *filepath, bool *runOnInit); for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_parsesrcfile_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_npc_parsesrcfile_pre[hIndex].func; - preHookFunc(filepath, &runOnInit); + retVal___ = preHookFunc(filepath, &runOnInit); } if( *HPMforce_return ) { *HPMforce_return = false; - return; + return retVal___; } } { - HPMHooks.source.npc.parsesrcfile(filepath, runOnInit); + retVal___ = HPMHooks.source.npc.parsesrcfile(filepath, runOnInit); } if( HPMHooks.count.HP_npc_parsesrcfile_post ) { - void (*postHookFunc) (const char *filepath, bool *runOnInit); + int (*postHookFunc) (int retVal___, const char *filepath, bool *runOnInit); for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_parsesrcfile_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_npc_parsesrcfile_post[hIndex].func; - postHookFunc(filepath, &runOnInit); + retVal___ = postHookFunc(retVal___, filepath, &runOnInit); } } - return; + return retVal___; } int HP_npc_script_event(struct map_session_data *sd, enum npce_event type) { int hIndex = 0; @@ -42187,11 +43099,239 @@ void HP_npc_debug_warps(void) { } return; } -int HP_npc_secure_timeout_timer(int tid, unsigned int tick, int id, intptr_t data) { +void HP_npc_trader_count_funds(struct npc_data *nd, struct map_session_data *sd) { + int hIndex = 0; + if( HPMHooks.count.HP_npc_trader_count_funds_pre ) { + void (*preHookFunc) (struct npc_data *nd, struct map_session_data *sd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_trader_count_funds_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_npc_trader_count_funds_pre[hIndex].func; + preHookFunc(nd, sd); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.npc.trader_count_funds(nd, sd); + } + if( HPMHooks.count.HP_npc_trader_count_funds_post ) { + void (*postHookFunc) (struct npc_data *nd, struct map_session_data *sd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_trader_count_funds_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_npc_trader_count_funds_post[hIndex].func; + postHookFunc(nd, sd); + } + } + return; +} +bool HP_npc_trader_pay(struct npc_data *nd, struct map_session_data *sd, int price, int points) { + int hIndex = 0; + bool retVal___ = false; + if( HPMHooks.count.HP_npc_trader_pay_pre ) { + bool (*preHookFunc) (struct npc_data *nd, struct map_session_data *sd, int *price, int *points); + for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_trader_pay_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_npc_trader_pay_pre[hIndex].func; + retVal___ = preHookFunc(nd, sd, &price, &points); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.npc.trader_pay(nd, sd, price, points); + } + if( HPMHooks.count.HP_npc_trader_pay_post ) { + bool (*postHookFunc) (bool retVal___, struct npc_data *nd, struct map_session_data *sd, int *price, int *points); + for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_trader_pay_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_npc_trader_pay_post[hIndex].func; + retVal___ = postHookFunc(retVal___, nd, sd, &price, &points); + } + } + return retVal___; +} +void HP_npc_trader_update(int master) { + int hIndex = 0; + if( HPMHooks.count.HP_npc_trader_update_pre ) { + void (*preHookFunc) (int *master); + for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_trader_update_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_npc_trader_update_pre[hIndex].func; + preHookFunc(&master); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.npc.trader_update(master); + } + if( HPMHooks.count.HP_npc_trader_update_post ) { + void (*postHookFunc) (int *master); + for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_trader_update_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_npc_trader_update_post[hIndex].func; + postHookFunc(&master); + } + } + return; +} +int HP_npc_market_buylist(struct map_session_data *sd, unsigned short list_size, struct packet_npc_market_purchase *p) { + int hIndex = 0; + int retVal___ = 0; + if( HPMHooks.count.HP_npc_market_buylist_pre ) { + int (*preHookFunc) (struct map_session_data *sd, unsigned short *list_size, struct packet_npc_market_purchase *p); + for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_market_buylist_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_npc_market_buylist_pre[hIndex].func; + retVal___ = preHookFunc(sd, &list_size, p); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.npc.market_buylist(sd, list_size, p); + } + if( HPMHooks.count.HP_npc_market_buylist_post ) { + int (*postHookFunc) (int retVal___, struct map_session_data *sd, unsigned short *list_size, struct packet_npc_market_purchase *p); + for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_market_buylist_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_npc_market_buylist_post[hIndex].func; + retVal___ = postHookFunc(retVal___, sd, &list_size, p); + } + } + return retVal___; +} +bool HP_npc_trader_open(struct map_session_data *sd, struct npc_data *nd) { + int hIndex = 0; + bool retVal___ = false; + if( HPMHooks.count.HP_npc_trader_open_pre ) { + bool (*preHookFunc) (struct map_session_data *sd, struct npc_data *nd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_trader_open_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_npc_trader_open_pre[hIndex].func; + retVal___ = preHookFunc(sd, nd); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.npc.trader_open(sd, nd); + } + if( HPMHooks.count.HP_npc_trader_open_post ) { + bool (*postHookFunc) (bool retVal___, struct map_session_data *sd, struct npc_data *nd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_trader_open_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_npc_trader_open_post[hIndex].func; + retVal___ = postHookFunc(retVal___, sd, nd); + } + } + return retVal___; +} +void HP_npc_market_fromsql(void) { + int hIndex = 0; + if( HPMHooks.count.HP_npc_market_fromsql_pre ) { + void (*preHookFunc) (void); + for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_market_fromsql_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_npc_market_fromsql_pre[hIndex].func; + preHookFunc(); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.npc.market_fromsql(); + } + if( HPMHooks.count.HP_npc_market_fromsql_post ) { + void (*postHookFunc) (void); + for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_market_fromsql_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_npc_market_fromsql_post[hIndex].func; + postHookFunc(); + } + } + return; +} +void HP_npc_market_tosql(struct npc_data *nd, unsigned short index) { + int hIndex = 0; + if( HPMHooks.count.HP_npc_market_tosql_pre ) { + void (*preHookFunc) (struct npc_data *nd, unsigned short *index); + for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_market_tosql_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_npc_market_tosql_pre[hIndex].func; + preHookFunc(nd, &index); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.npc.market_tosql(nd, index); + } + if( HPMHooks.count.HP_npc_market_tosql_post ) { + void (*postHookFunc) (struct npc_data *nd, unsigned short *index); + for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_market_tosql_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_npc_market_tosql_post[hIndex].func; + postHookFunc(nd, &index); + } + } + return; +} +void HP_npc_market_delfromsql(struct npc_data *nd, unsigned short index) { + int hIndex = 0; + if( HPMHooks.count.HP_npc_market_delfromsql_pre ) { + void (*preHookFunc) (struct npc_data *nd, unsigned short *index); + for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_market_delfromsql_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_npc_market_delfromsql_pre[hIndex].func; + preHookFunc(nd, &index); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.npc.market_delfromsql(nd, index); + } + if( HPMHooks.count.HP_npc_market_delfromsql_post ) { + void (*postHookFunc) (struct npc_data *nd, unsigned short *index); + for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_market_delfromsql_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_npc_market_delfromsql_post[hIndex].func; + postHookFunc(nd, &index); + } + } + return; +} +void HP_npc_market_delfromsql_sub(const char *npcname, unsigned short index) { + int hIndex = 0; + if( HPMHooks.count.HP_npc_market_delfromsql_sub_pre ) { + void (*preHookFunc) (const char *npcname, unsigned short *index); + for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_market_delfromsql_sub_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_npc_market_delfromsql_sub_pre[hIndex].func; + preHookFunc(npcname, &index); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.npc.market_delfromsql_sub(npcname, index); + } + if( HPMHooks.count.HP_npc_market_delfromsql_sub_post ) { + void (*postHookFunc) (const char *npcname, unsigned short *index); + for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_market_delfromsql_sub_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_npc_market_delfromsql_sub_post[hIndex].func; + postHookFunc(npcname, &index); + } + } + return; +} +int HP_npc_secure_timeout_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_npc_secure_timeout_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_secure_timeout_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_npc_secure_timeout_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -42205,7 +43345,7 @@ int HP_npc_secure_timeout_timer(int tid, unsigned int tick, int id, intptr_t dat retVal___ = HPMHooks.source.npc.secure_timeout_timer(tid, tick, id, data); } if( HPMHooks.count.HP_npc_secure_timeout_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_secure_timeout_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_npc_secure_timeout_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -42214,13 +43354,13 @@ int HP_npc_secure_timeout_timer(int tid, unsigned int tick, int id, intptr_t dat return retVal___; } /* party */ -void HP_party_init(void) { +void HP_party_init(bool minimal) { int hIndex = 0; if( HPMHooks.count.HP_party_init_pre ) { - void (*preHookFunc) (void); + void (*preHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_party_init_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_party_init_pre[hIndex].func; - preHookFunc(); + preHookFunc(&minimal); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -42228,13 +43368,13 @@ void HP_party_init(void) { } } { - HPMHooks.source.party.init(); + HPMHooks.source.party.init(minimal); } if( HPMHooks.count.HP_party_init_post ) { - void (*postHookFunc) (void); + void (*postHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_party_init_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_party_init_post[hIndex].func; - postHookFunc(); + postHookFunc(&minimal); } } return; @@ -43097,6 +44237,38 @@ int HP_party_sub_count(struct block_list *bl, va_list ap) { } return retVal___; } +int HP_party_sub_count_chorus(struct block_list *bl, va_list ap) { + int hIndex = 0; + int retVal___ = 0; + if( HPMHooks.count.HP_party_sub_count_chorus_pre ) { + int (*preHookFunc) (struct block_list *bl, va_list ap); + for(hIndex = 0; hIndex < HPMHooks.count.HP_party_sub_count_chorus_pre; hIndex++ ) { + va_list ap___copy; va_copy(ap___copy, ap); + preHookFunc = HPMHooks.list.HP_party_sub_count_chorus_pre[hIndex].func; + retVal___ = preHookFunc(bl, ap___copy); + va_end(ap___copy); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + va_list ap___copy; va_copy(ap___copy, ap); + retVal___ = HPMHooks.source.party.sub_count_chorus(bl, ap___copy); + va_end(ap___copy); + } + if( HPMHooks.count.HP_party_sub_count_chorus_post ) { + int (*postHookFunc) (int retVal___, struct block_list *bl, va_list ap); + for(hIndex = 0; hIndex < HPMHooks.count.HP_party_sub_count_chorus_post; hIndex++ ) { + va_list ap___copy; va_copy(ap___copy, ap); + postHookFunc = HPMHooks.list.HP_party_sub_count_chorus_post[hIndex].func; + retVal___ = postHookFunc(retVal___, bl, ap___copy); + va_end(ap___copy); + } + } + return retVal___; +} void HP_party_booking_register(struct map_session_data *sd, short level, short mapid, short *job) { int hIndex = 0; if( HPMHooks.count.HP_party_booking_register_pre ) { @@ -43305,11 +44477,11 @@ int HP_party_vforeachsamemap(int ( *func ) (struct block_list *, va_list), struc } return retVal___; } -int HP_party_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_party_send_xy_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_party_send_xy_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_party_send_xy_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_party_send_xy_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -43323,7 +44495,7 @@ int HP_party_send_xy_timer(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.party.send_xy_timer(tid, tick, id, data); } if( HPMHooks.count.HP_party_send_xy_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_party_send_xy_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_party_send_xy_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -43596,14 +44768,298 @@ unsigned int HP_path_distance(int dx, int dy) { } return retVal___; } +/* pcg */ +void HP_pcg_init(void) { + int hIndex = 0; + if( HPMHooks.count.HP_pcg_init_pre ) { + void (*preHookFunc) (void); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pcg_init_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_pcg_init_pre[hIndex].func; + preHookFunc(); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.pcg.init(); + } + if( HPMHooks.count.HP_pcg_init_post ) { + void (*postHookFunc) (void); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pcg_init_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_pcg_init_post[hIndex].func; + postHookFunc(); + } + } + return; +} +void HP_pcg_final(void) { + int hIndex = 0; + if( HPMHooks.count.HP_pcg_final_pre ) { + void (*preHookFunc) (void); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pcg_final_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_pcg_final_pre[hIndex].func; + preHookFunc(); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.pcg.final(); + } + if( HPMHooks.count.HP_pcg_final_post ) { + void (*postHookFunc) (void); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pcg_final_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_pcg_final_post[hIndex].func; + postHookFunc(); + } + } + return; +} +void HP_pcg_reload(void) { + int hIndex = 0; + if( HPMHooks.count.HP_pcg_reload_pre ) { + void (*preHookFunc) (void); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pcg_reload_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_pcg_reload_pre[hIndex].func; + preHookFunc(); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.pcg.reload(); + } + if( HPMHooks.count.HP_pcg_reload_post ) { + void (*postHookFunc) (void); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pcg_reload_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_pcg_reload_post[hIndex].func; + postHookFunc(); + } + } + return; +} +GroupSettings* HP_pcg_get_dummy_group(void) { + int hIndex = 0; + GroupSettings* retVal___ = NULL; + if( HPMHooks.count.HP_pcg_get_dummy_group_pre ) { + GroupSettings* (*preHookFunc) (void); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pcg_get_dummy_group_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_pcg_get_dummy_group_pre[hIndex].func; + retVal___ = preHookFunc(); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.pcg.get_dummy_group(); + } + if( HPMHooks.count.HP_pcg_get_dummy_group_post ) { + GroupSettings* (*postHookFunc) (GroupSettings* retVal___); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pcg_get_dummy_group_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_pcg_get_dummy_group_post[hIndex].func; + retVal___ = postHookFunc(retVal___); + } + } + return retVal___; +} +bool HP_pcg_exists(int group_id) { + int hIndex = 0; + bool retVal___ = false; + if( HPMHooks.count.HP_pcg_exists_pre ) { + bool (*preHookFunc) (int *group_id); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pcg_exists_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_pcg_exists_pre[hIndex].func; + retVal___ = preHookFunc(&group_id); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.pcg.exists(group_id); + } + if( HPMHooks.count.HP_pcg_exists_post ) { + bool (*postHookFunc) (bool retVal___, int *group_id); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pcg_exists_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_pcg_exists_post[hIndex].func; + retVal___ = postHookFunc(retVal___, &group_id); + } + } + return retVal___; +} +GroupSettings* HP_pcg_id2group(int group_id) { + int hIndex = 0; + GroupSettings* retVal___ = NULL; + if( HPMHooks.count.HP_pcg_id2group_pre ) { + GroupSettings* (*preHookFunc) (int *group_id); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pcg_id2group_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_pcg_id2group_pre[hIndex].func; + retVal___ = preHookFunc(&group_id); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.pcg.id2group(group_id); + } + if( HPMHooks.count.HP_pcg_id2group_post ) { + GroupSettings* (*postHookFunc) (GroupSettings* retVal___, int *group_id); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pcg_id2group_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_pcg_id2group_post[hIndex].func; + retVal___ = postHookFunc(retVal___, &group_id); + } + } + return retVal___; +} +bool HP_pcg_has_permission(GroupSettings *group, unsigned int permission) { + int hIndex = 0; + bool retVal___ = false; + if( HPMHooks.count.HP_pcg_has_permission_pre ) { + bool (*preHookFunc) (GroupSettings *group, unsigned int *permission); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pcg_has_permission_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_pcg_has_permission_pre[hIndex].func; + retVal___ = preHookFunc(group, &permission); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.pcg.has_permission(group, permission); + } + if( HPMHooks.count.HP_pcg_has_permission_post ) { + bool (*postHookFunc) (bool retVal___, GroupSettings *group, unsigned int *permission); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pcg_has_permission_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_pcg_has_permission_post[hIndex].func; + retVal___ = postHookFunc(retVal___, group, &permission); + } + } + return retVal___; +} +bool HP_pcg_should_log_commands(GroupSettings *group) { + int hIndex = 0; + bool retVal___ = false; + if( HPMHooks.count.HP_pcg_should_log_commands_pre ) { + bool (*preHookFunc) (GroupSettings *group); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pcg_should_log_commands_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_pcg_should_log_commands_pre[hIndex].func; + retVal___ = preHookFunc(group); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.pcg.should_log_commands(group); + } + if( HPMHooks.count.HP_pcg_should_log_commands_post ) { + bool (*postHookFunc) (bool retVal___, GroupSettings *group); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pcg_should_log_commands_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_pcg_should_log_commands_post[hIndex].func; + retVal___ = postHookFunc(retVal___, group); + } + } + return retVal___; +} +const char* HP_pcg_get_name(GroupSettings *group) { + int hIndex = 0; + const char* retVal___ = NULL; + if( HPMHooks.count.HP_pcg_get_name_pre ) { + const char* (*preHookFunc) (GroupSettings *group); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pcg_get_name_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_pcg_get_name_pre[hIndex].func; + retVal___ = preHookFunc(group); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.pcg.get_name(group); + } + if( HPMHooks.count.HP_pcg_get_name_post ) { + const char* (*postHookFunc) (const char* retVal___, GroupSettings *group); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pcg_get_name_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_pcg_get_name_post[hIndex].func; + retVal___ = postHookFunc(retVal___, group); + } + } + return retVal___; +} +int HP_pcg_get_level(GroupSettings *group) { + int hIndex = 0; + int retVal___ = 0; + if( HPMHooks.count.HP_pcg_get_level_pre ) { + int (*preHookFunc) (GroupSettings *group); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pcg_get_level_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_pcg_get_level_pre[hIndex].func; + retVal___ = preHookFunc(group); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.pcg.get_level(group); + } + if( HPMHooks.count.HP_pcg_get_level_post ) { + int (*postHookFunc) (int retVal___, GroupSettings *group); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pcg_get_level_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_pcg_get_level_post[hIndex].func; + retVal___ = postHookFunc(retVal___, group); + } + } + return retVal___; +} +int HP_pcg_get_idx(GroupSettings *group) { + int hIndex = 0; + int retVal___ = 0; + if( HPMHooks.count.HP_pcg_get_idx_pre ) { + int (*preHookFunc) (GroupSettings *group); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pcg_get_idx_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_pcg_get_idx_pre[hIndex].func; + retVal___ = preHookFunc(group); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.pcg.get_idx(group); + } + if( HPMHooks.count.HP_pcg_get_idx_post ) { + int (*postHookFunc) (int retVal___, GroupSettings *group); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pcg_get_idx_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_pcg_get_idx_post[hIndex].func; + retVal___ = postHookFunc(retVal___, group); + } + } + return retVal___; +} /* pc */ -void HP_pc_init(void) { +void HP_pc_init(bool minimal) { int hIndex = 0; if( HPMHooks.count.HP_pc_init_pre ) { - void (*preHookFunc) (void); + void (*preHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_init_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_pc_init_pre[hIndex].func; - preHookFunc(); + preHookFunc(&minimal); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -43611,13 +45067,13 @@ void HP_pc_init(void) { } } { - HPMHooks.source.pc.init(); + HPMHooks.source.pc.init(minimal); } if( HPMHooks.count.HP_pc_init_post ) { - void (*postHookFunc) (void); + void (*postHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_init_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_pc_init_post[hIndex].func; - postHookFunc(); + postHookFunc(&minimal); } } return; @@ -43699,13 +45155,13 @@ int HP_pc_class2idx(int class_) { } return retVal___; } -int HP_pc_get_group_level(struct map_session_data *sd) { +bool HP_pc_can_give_items(struct map_session_data *sd) { int hIndex = 0; - int retVal___ = 0; - if( HPMHooks.count.HP_pc_get_group_level_pre ) { - int (*preHookFunc) (struct map_session_data *sd); - for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_get_group_level_pre; hIndex++ ) { - preHookFunc = HPMHooks.list.HP_pc_get_group_level_pre[hIndex].func; + bool retVal___ = false; + if( HPMHooks.count.HP_pc_can_give_items_pre ) { + bool (*preHookFunc) (struct map_session_data *sd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_can_give_items_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_pc_can_give_items_pre[hIndex].func; retVal___ = preHookFunc(sd); } if( *HPMforce_return ) { @@ -43714,24 +45170,24 @@ int HP_pc_get_group_level(struct map_session_data *sd) { } } { - retVal___ = HPMHooks.source.pc.get_group_level(sd); + retVal___ = HPMHooks.source.pc.can_give_items(sd); } - if( HPMHooks.count.HP_pc_get_group_level_post ) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd); - for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_get_group_level_post; hIndex++ ) { - postHookFunc = HPMHooks.list.HP_pc_get_group_level_post[hIndex].func; + if( HPMHooks.count.HP_pc_can_give_items_post ) { + bool (*postHookFunc) (bool retVal___, struct map_session_data *sd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_can_give_items_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_pc_can_give_items_post[hIndex].func; retVal___ = postHookFunc(retVal___, sd); } } return retVal___; } -bool HP_pc_can_give_items(struct map_session_data *sd) { +bool HP_pc_can_give_bound_items(struct map_session_data *sd) { int hIndex = 0; bool retVal___ = false; - if( HPMHooks.count.HP_pc_can_give_items_pre ) { + if( HPMHooks.count.HP_pc_can_give_bound_items_pre ) { bool (*preHookFunc) (struct map_session_data *sd); - for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_can_give_items_pre; hIndex++ ) { - preHookFunc = HPMHooks.list.HP_pc_can_give_items_pre[hIndex].func; + for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_can_give_bound_items_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_pc_can_give_bound_items_pre[hIndex].func; retVal___ = preHookFunc(sd); } if( *HPMforce_return ) { @@ -43740,12 +45196,12 @@ bool HP_pc_can_give_items(struct map_session_data *sd) { } } { - retVal___ = HPMHooks.source.pc.can_give_items(sd); + retVal___ = HPMHooks.source.pc.can_give_bound_items(sd); } - if( HPMHooks.count.HP_pc_can_give_items_post ) { + if( HPMHooks.count.HP_pc_can_give_bound_items_post ) { bool (*postHookFunc) (bool retVal___, struct map_session_data *sd); - for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_can_give_items_post; hIndex++ ) { - postHookFunc = HPMHooks.list.HP_pc_can_give_items_post[hIndex].func; + for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_can_give_bound_items_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_pc_can_give_bound_items_post[hIndex].func; retVal___ = postHookFunc(retVal___, sd); } } @@ -43777,32 +45233,6 @@ bool HP_pc_can_use_command(struct map_session_data *sd, const char *command) { } return retVal___; } -bool HP_pc_has_permission(struct map_session_data *sd, enum e_pc_permission permission) { - int hIndex = 0; - bool retVal___ = false; - if( HPMHooks.count.HP_pc_has_permission_pre ) { - bool (*preHookFunc) (struct map_session_data *sd, enum e_pc_permission *permission); - for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_has_permission_pre; hIndex++ ) { - preHookFunc = HPMHooks.list.HP_pc_has_permission_pre[hIndex].func; - retVal___ = preHookFunc(sd, &permission); - } - if( *HPMforce_return ) { - *HPMforce_return = false; - return retVal___; - } - } - { - retVal___ = HPMHooks.source.pc.has_permission(sd, permission); - } - if( HPMHooks.count.HP_pc_has_permission_post ) { - bool (*postHookFunc) (bool retVal___, struct map_session_data *sd, enum e_pc_permission *permission); - for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_has_permission_post; hIndex++ ) { - postHookFunc = HPMHooks.list.HP_pc_has_permission_post[hIndex].func; - retVal___ = postHookFunc(retVal___, sd, &permission); - } - } - return retVal___; -} int HP_pc_set_group(struct map_session_data *sd, int group_id) { int hIndex = 0; int retVal___ = 0; @@ -44295,14 +45725,14 @@ int HP_pc_clean_skilltree(struct map_session_data *sd) { } return retVal___; } -int HP_pc_setpos(struct map_session_data *sd, unsigned short mapindex, int x, int y, clr_type clrtype) { +int HP_pc_setpos(struct map_session_data *sd, unsigned short map_index, int x, int y, clr_type clrtype) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_pc_setpos_pre ) { - int (*preHookFunc) (struct map_session_data *sd, unsigned short *mapindex, int *x, int *y, clr_type *clrtype); + int (*preHookFunc) (struct map_session_data *sd, unsigned short *map_index, int *x, int *y, clr_type *clrtype); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_setpos_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_pc_setpos_pre[hIndex].func; - retVal___ = preHookFunc(sd, &mapindex, &x, &y, &clrtype); + retVal___ = preHookFunc(sd, &map_index, &x, &y, &clrtype); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -44310,25 +45740,25 @@ int HP_pc_setpos(struct map_session_data *sd, unsigned short mapindex, int x, in } } { - retVal___ = HPMHooks.source.pc.setpos(sd, mapindex, x, y, clrtype); + retVal___ = HPMHooks.source.pc.setpos(sd, map_index, x, y, clrtype); } if( HPMHooks.count.HP_pc_setpos_post ) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd, unsigned short *mapindex, int *x, int *y, clr_type *clrtype); + int (*postHookFunc) (int retVal___, struct map_session_data *sd, unsigned short *map_index, int *x, int *y, clr_type *clrtype); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_setpos_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_pc_setpos_post[hIndex].func; - retVal___ = postHookFunc(retVal___, sd, &mapindex, &x, &y, &clrtype); + retVal___ = postHookFunc(retVal___, sd, &map_index, &x, &y, &clrtype); } } return retVal___; } -int HP_pc_setsavepoint(struct map_session_data *sd, short mapindex, int x, int y) { +int HP_pc_setsavepoint(struct map_session_data *sd, short map_index, int x, int y) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_pc_setsavepoint_pre ) { - int (*preHookFunc) (struct map_session_data *sd, short *mapindex, int *x, int *y); + int (*preHookFunc) (struct map_session_data *sd, short *map_index, int *x, int *y); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_setsavepoint_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_pc_setsavepoint_pre[hIndex].func; - retVal___ = preHookFunc(sd, &mapindex, &x, &y); + retVal___ = preHookFunc(sd, &map_index, &x, &y); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -44336,13 +45766,13 @@ int HP_pc_setsavepoint(struct map_session_data *sd, short mapindex, int x, int y } } { - retVal___ = HPMHooks.source.pc.setsavepoint(sd, mapindex, x, y); + retVal___ = HPMHooks.source.pc.setsavepoint(sd, map_index, x, y); } if( HPMHooks.count.HP_pc_setsavepoint_post ) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd, short *mapindex, int *x, int *y); + int (*postHookFunc) (int retVal___, struct map_session_data *sd, short *map_index, int *x, int *y); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_setsavepoint_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_pc_setsavepoint_post[hIndex].func; - retVal___ = postHookFunc(retVal___, sd, &mapindex, &x, &y); + retVal___ = postHookFunc(retVal___, sd, &map_index, &x, &y); } } return retVal___; @@ -44971,11 +46401,11 @@ int HP_pc_exeautobonus(struct map_session_data *sd, struct s_autobonus *bonus) { } return retVal___; } -int HP_pc_endautobonus(int tid, unsigned int tick, int id, intptr_t data) { +int HP_pc_endautobonus(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_pc_endautobonus_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_endautobonus_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_pc_endautobonus_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -44989,7 +46419,7 @@ int HP_pc_endautobonus(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.pc.endautobonus(tid, tick, id, data); } if( HPMHooks.count.HP_pc_endautobonus_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_endautobonus_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_pc_endautobonus_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -45647,14 +47077,40 @@ int HP_pc_need_status_point(struct map_session_data *sd, int type, int val) { } return retVal___; } -int HP_pc_statusup(struct map_session_data *sd, int type) { +int HP_pc_maxparameterincrease(struct map_session_data *sd, int type) { int hIndex = 0; int retVal___ = 0; - if( HPMHooks.count.HP_pc_statusup_pre ) { + if( HPMHooks.count.HP_pc_maxparameterincrease_pre ) { int (*preHookFunc) (struct map_session_data *sd, int *type); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_maxparameterincrease_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_pc_maxparameterincrease_pre[hIndex].func; + retVal___ = preHookFunc(sd, &type); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.pc.maxparameterincrease(sd, type); + } + if( HPMHooks.count.HP_pc_maxparameterincrease_post ) { + int (*postHookFunc) (int retVal___, struct map_session_data *sd, int *type); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_maxparameterincrease_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_pc_maxparameterincrease_post[hIndex].func; + retVal___ = postHookFunc(retVal___, sd, &type); + } + } + return retVal___; +} +bool HP_pc_statusup(struct map_session_data *sd, int type, int increase) { + int hIndex = 0; + bool retVal___ = false; + if( HPMHooks.count.HP_pc_statusup_pre ) { + bool (*preHookFunc) (struct map_session_data *sd, int *type, int *increase); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_statusup_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_pc_statusup_pre[hIndex].func; - retVal___ = preHookFunc(sd, &type); + retVal___ = preHookFunc(sd, &type, &increase); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -45662,13 +47118,13 @@ int HP_pc_statusup(struct map_session_data *sd, int type) { } } { - retVal___ = HPMHooks.source.pc.statusup(sd, type); + retVal___ = HPMHooks.source.pc.statusup(sd, type, increase); } if( HPMHooks.count.HP_pc_statusup_post ) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd, int *type); + bool (*postHookFunc) (bool retVal___, struct map_session_data *sd, int *type, int *increase); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_statusup_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_pc_statusup_post[hIndex].func; - retVal___ = postHookFunc(retVal___, sd, &type); + retVal___ = postHookFunc(retVal___, sd, &type, &increase); } } return retVal___; @@ -46476,11 +47932,11 @@ int HP_pc_setparam(struct map_session_data *sd, int type, int val) { } return retVal___; } -int HP_pc_readreg(struct map_session_data *sd, int reg) { +int HP_pc_readreg(struct map_session_data *sd, int64 reg) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_pc_readreg_pre ) { - int (*preHookFunc) (struct map_session_data *sd, int *reg); + int (*preHookFunc) (struct map_session_data *sd, int64 *reg); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_readreg_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_pc_readreg_pre[hIndex].func; retVal___ = preHookFunc(sd, ®); @@ -46494,7 +47950,7 @@ int HP_pc_readreg(struct map_session_data *sd, int reg) { retVal___ = HPMHooks.source.pc.readreg(sd, reg); } if( HPMHooks.count.HP_pc_readreg_post ) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd, int *reg); + int (*postHookFunc) (int retVal___, struct map_session_data *sd, int64 *reg); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_readreg_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_pc_readreg_post[hIndex].func; retVal___ = postHookFunc(retVal___, sd, ®); @@ -46502,37 +47958,36 @@ int HP_pc_readreg(struct map_session_data *sd, int reg) { } return retVal___; } -int HP_pc_setreg(struct map_session_data *sd, int reg, int val) { +void HP_pc_setreg(struct map_session_data *sd, int64 reg, int val) { int hIndex = 0; - int retVal___ = 0; if( HPMHooks.count.HP_pc_setreg_pre ) { - int (*preHookFunc) (struct map_session_data *sd, int *reg, int *val); + void (*preHookFunc) (struct map_session_data *sd, int64 *reg, int *val); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_setreg_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_pc_setreg_pre[hIndex].func; - retVal___ = preHookFunc(sd, ®, &val); + preHookFunc(sd, ®, &val); } if( *HPMforce_return ) { *HPMforce_return = false; - return retVal___; + return; } } { - retVal___ = HPMHooks.source.pc.setreg(sd, reg, val); + HPMHooks.source.pc.setreg(sd, reg, val); } if( HPMHooks.count.HP_pc_setreg_post ) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd, int *reg, int *val); + void (*postHookFunc) (struct map_session_data *sd, int64 *reg, int *val); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_setreg_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_pc_setreg_post[hIndex].func; - retVal___ = postHookFunc(retVal___, sd, ®, &val); + postHookFunc(sd, ®, &val); } } - return retVal___; + return; } -char* HP_pc_readregstr(struct map_session_data *sd, int reg) { +char* HP_pc_readregstr(struct map_session_data *sd, int64 reg) { int hIndex = 0; char* retVal___ = NULL; if( HPMHooks.count.HP_pc_readregstr_pre ) { - char* (*preHookFunc) (struct map_session_data *sd, int *reg); + char* (*preHookFunc) (struct map_session_data *sd, int64 *reg); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_readregstr_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_pc_readregstr_pre[hIndex].func; retVal___ = preHookFunc(sd, ®); @@ -46546,7 +48001,7 @@ char* HP_pc_readregstr(struct map_session_data *sd, int reg) { retVal___ = HPMHooks.source.pc.readregstr(sd, reg); } if( HPMHooks.count.HP_pc_readregstr_post ) { - char* (*postHookFunc) (char* retVal___, struct map_session_data *sd, int *reg); + char* (*postHookFunc) (char* retVal___, struct map_session_data *sd, int64 *reg); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_readregstr_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_pc_readregstr_post[hIndex].func; retVal___ = postHookFunc(retVal___, sd, ®); @@ -46554,40 +48009,39 @@ char* HP_pc_readregstr(struct map_session_data *sd, int reg) { } return retVal___; } -int HP_pc_setregstr(struct map_session_data *sd, int reg, const char *str) { +void HP_pc_setregstr(struct map_session_data *sd, int64 reg, const char *str) { int hIndex = 0; - int retVal___ = 0; if( HPMHooks.count.HP_pc_setregstr_pre ) { - int (*preHookFunc) (struct map_session_data *sd, int *reg, const char *str); + void (*preHookFunc) (struct map_session_data *sd, int64 *reg, const char *str); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_setregstr_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_pc_setregstr_pre[hIndex].func; - retVal___ = preHookFunc(sd, ®, str); + preHookFunc(sd, ®, str); } if( *HPMforce_return ) { *HPMforce_return = false; - return retVal___; + return; } } { - retVal___ = HPMHooks.source.pc.setregstr(sd, reg, str); + HPMHooks.source.pc.setregstr(sd, reg, str); } if( HPMHooks.count.HP_pc_setregstr_post ) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd, int *reg, const char *str); + void (*postHookFunc) (struct map_session_data *sd, int64 *reg, const char *str); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_setregstr_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_pc_setregstr_post[hIndex].func; - retVal___ = postHookFunc(retVal___, sd, ®, str); + postHookFunc(sd, ®, str); } } - return retVal___; + return; } -int HP_pc_readregistry(struct map_session_data *sd, const char *reg, int type) { +int HP_pc_readregistry(struct map_session_data *sd, int64 reg) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_pc_readregistry_pre ) { - int (*preHookFunc) (struct map_session_data *sd, const char *reg, int *type); + int (*preHookFunc) (struct map_session_data *sd, int64 *reg); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_readregistry_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_pc_readregistry_pre[hIndex].func; - retVal___ = preHookFunc(sd, reg, &type); + retVal___ = preHookFunc(sd, ®); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -46595,25 +48049,25 @@ int HP_pc_readregistry(struct map_session_data *sd, const char *reg, int type) { } } { - retVal___ = HPMHooks.source.pc.readregistry(sd, reg, type); + retVal___ = HPMHooks.source.pc.readregistry(sd, reg); } if( HPMHooks.count.HP_pc_readregistry_post ) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd, const char *reg, int *type); + int (*postHookFunc) (int retVal___, struct map_session_data *sd, int64 *reg); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_readregistry_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_pc_readregistry_post[hIndex].func; - retVal___ = postHookFunc(retVal___, sd, reg, &type); + retVal___ = postHookFunc(retVal___, sd, ®); } } return retVal___; } -int HP_pc_setregistry(struct map_session_data *sd, const char *reg, int val, int type) { +int HP_pc_setregistry(struct map_session_data *sd, int64 reg, int val) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_pc_setregistry_pre ) { - int (*preHookFunc) (struct map_session_data *sd, const char *reg, int *val, int *type); + int (*preHookFunc) (struct map_session_data *sd, int64 *reg, int *val); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_setregistry_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_pc_setregistry_pre[hIndex].func; - retVal___ = preHookFunc(sd, reg, &val, &type); + retVal___ = preHookFunc(sd, ®, &val); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -46621,25 +48075,25 @@ int HP_pc_setregistry(struct map_session_data *sd, const char *reg, int val, int } } { - retVal___ = HPMHooks.source.pc.setregistry(sd, reg, val, type); + retVal___ = HPMHooks.source.pc.setregistry(sd, reg, val); } if( HPMHooks.count.HP_pc_setregistry_post ) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd, const char *reg, int *val, int *type); + int (*postHookFunc) (int retVal___, struct map_session_data *sd, int64 *reg, int *val); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_setregistry_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_pc_setregistry_post[hIndex].func; - retVal___ = postHookFunc(retVal___, sd, reg, &val, &type); + retVal___ = postHookFunc(retVal___, sd, ®, &val); } } return retVal___; } -char* HP_pc_readregistry_str(struct map_session_data *sd, const char *reg, int type) { +char* HP_pc_readregistry_str(struct map_session_data *sd, int64 reg) { int hIndex = 0; char* retVal___ = NULL; if( HPMHooks.count.HP_pc_readregistry_str_pre ) { - char* (*preHookFunc) (struct map_session_data *sd, const char *reg, int *type); + char* (*preHookFunc) (struct map_session_data *sd, int64 *reg); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_readregistry_str_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_pc_readregistry_str_pre[hIndex].func; - retVal___ = preHookFunc(sd, reg, &type); + retVal___ = preHookFunc(sd, ®); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -46647,25 +48101,25 @@ char* HP_pc_readregistry_str(struct map_session_data *sd, const char *reg, int t } } { - retVal___ = HPMHooks.source.pc.readregistry_str(sd, reg, type); + retVal___ = HPMHooks.source.pc.readregistry_str(sd, reg); } if( HPMHooks.count.HP_pc_readregistry_str_post ) { - char* (*postHookFunc) (char* retVal___, struct map_session_data *sd, const char *reg, int *type); + char* (*postHookFunc) (char* retVal___, struct map_session_data *sd, int64 *reg); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_readregistry_str_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_pc_readregistry_str_post[hIndex].func; - retVal___ = postHookFunc(retVal___, sd, reg, &type); + retVal___ = postHookFunc(retVal___, sd, ®); } } return retVal___; } -int HP_pc_setregistry_str(struct map_session_data *sd, const char *reg, const char *val, int type) { +int HP_pc_setregistry_str(struct map_session_data *sd, int64 reg, const char *val) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_pc_setregistry_str_pre ) { - int (*preHookFunc) (struct map_session_data *sd, const char *reg, const char *val, int *type); + int (*preHookFunc) (struct map_session_data *sd, int64 *reg, const char *val); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_setregistry_str_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_pc_setregistry_str_pre[hIndex].func; - retVal___ = preHookFunc(sd, reg, val, &type); + retVal___ = preHookFunc(sd, ®, val); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -46673,13 +48127,13 @@ int HP_pc_setregistry_str(struct map_session_data *sd, const char *reg, const ch } } { - retVal___ = HPMHooks.source.pc.setregistry_str(sd, reg, val, type); + retVal___ = HPMHooks.source.pc.setregistry_str(sd, reg, val); } if( HPMHooks.count.HP_pc_setregistry_str_post ) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd, const char *reg, const char *val, int *type); + int (*postHookFunc) (int retVal___, struct map_session_data *sd, int64 *reg, const char *val); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_setregistry_str_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_pc_setregistry_str_post[hIndex].func; - retVal___ = postHookFunc(retVal___, sd, reg, val, &type); + retVal___ = postHookFunc(retVal___, sd, ®, val); } } return retVal___; @@ -46814,11 +48268,11 @@ int HP_pc_calc_pvprank(struct map_session_data *sd) { } return retVal___; } -int HP_pc_calc_pvprank_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_pc_calc_pvprank_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_pc_calc_pvprank_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_calc_pvprank_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_pc_calc_pvprank_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -46832,7 +48286,7 @@ int HP_pc_calc_pvprank_timer(int tid, unsigned int tick, int id, intptr_t data) retVal___ = HPMHooks.source.pc.calc_pvprank_timer(tid, tick, id, data); } if( HPMHooks.count.HP_pc_calc_pvprank_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_calc_pvprank_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_pc_calc_pvprank_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -47406,11 +48860,11 @@ int HP_pc_readdb(void) { } return retVal___; } -int HP_pc_map_day_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_pc_map_day_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_pc_map_day_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_map_day_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_pc_map_day_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -47424,7 +48878,7 @@ int HP_pc_map_day_timer(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.pc.map_day_timer(tid, tick, id, data); } if( HPMHooks.count.HP_pc_map_day_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_map_day_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_pc_map_day_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -47432,11 +48886,11 @@ int HP_pc_map_day_timer(int tid, unsigned int tick, int id, intptr_t data) { } return retVal___; } -int HP_pc_map_night_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_pc_map_night_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_pc_map_night_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_map_night_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_pc_map_night_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -47450,7 +48904,7 @@ int HP_pc_map_night_timer(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.pc.map_night_timer(tid, tick, id, data); } if( HPMHooks.count.HP_pc_map_night_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_map_night_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_pc_map_night_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -47817,11 +49271,11 @@ int HP_pc_calc_skillpoint(struct map_session_data *sd) { } return retVal___; } -int HP_pc_invincible_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_pc_invincible_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_pc_invincible_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_invincible_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_pc_invincible_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -47835,7 +49289,7 @@ int HP_pc_invincible_timer(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.pc.invincible_timer(tid, tick, id, data); } if( HPMHooks.count.HP_pc_invincible_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_invincible_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_pc_invincible_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -47843,11 +49297,11 @@ int HP_pc_invincible_timer(int tid, unsigned int tick, int id, intptr_t data) { } return retVal___; } -int HP_pc_spiritball_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_pc_spiritball_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_pc_spiritball_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_spiritball_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_pc_spiritball_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -47861,7 +49315,7 @@ int HP_pc_spiritball_timer(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.pc.spiritball_timer(tid, tick, id, data); } if( HPMHooks.count.HP_pc_spiritball_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_spiritball_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_pc_spiritball_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -47901,11 +49355,11 @@ int HP_pc_check_banding(struct block_list *bl, va_list ap) { } return retVal___; } -int HP_pc_inventory_rental_end(int tid, unsigned int tick, int id, intptr_t data) { +int HP_pc_inventory_rental_end(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_pc_inventory_rental_end_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_inventory_rental_end_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_pc_inventory_rental_end_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -47919,7 +49373,7 @@ int HP_pc_inventory_rental_end(int tid, unsigned int tick, int id, intptr_t data retVal___ = HPMHooks.source.pc.inventory_rental_end(tid, tick, id, data); } if( HPMHooks.count.HP_pc_inventory_rental_end_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_inventory_rental_end_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_pc_inventory_rental_end_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -48107,11 +49561,11 @@ void HP_pc_calcexp(struct map_session_data *sd, unsigned int *base_exp, unsigned } return; } -int HP_pc_respawn_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_pc_respawn_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_pc_respawn_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_respawn_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_pc_respawn_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -48125,7 +49579,7 @@ int HP_pc_respawn_timer(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.pc.respawn_timer(tid, tick, id, data); } if( HPMHooks.count.HP_pc_respawn_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_respawn_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_pc_respawn_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -48217,11 +49671,11 @@ int HP_pc_setstat(struct map_session_data *sd, int type, int val) { } return retVal___; } -int HP_pc_eventtimer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_pc_eventtimer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_pc_eventtimer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_eventtimer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_pc_eventtimer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -48235,7 +49689,7 @@ int HP_pc_eventtimer(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.pc.eventtimer(tid, tick, id, data); } if( HPMHooks.count.HP_pc_eventtimer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_eventtimer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_pc_eventtimer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -48275,11 +49729,11 @@ int HP_pc_daynight_timer_sub(struct map_session_data *sd, va_list ap) { } return retVal___; } -int HP_pc_charm_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_pc_charm_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_pc_charm_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_charm_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_pc_charm_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -48293,7 +49747,7 @@ int HP_pc_charm_timer(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.pc.charm_timer(tid, tick, id, data); } if( HPMHooks.count.HP_pc_charm_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_charm_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_pc_charm_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -48327,11 +49781,11 @@ bool HP_pc_readdb_levelpenalty(char *fields[], int columns, int current) { } return retVal___; } -int HP_pc_autosave(int tid, unsigned int tick, int id, intptr_t data) { +int HP_pc_autosave(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_pc_autosave_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_autosave_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_pc_autosave_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -48345,7 +49799,7 @@ int HP_pc_autosave(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.pc.autosave(tid, tick, id, data); } if( HPMHooks.count.HP_pc_autosave_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_autosave_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_pc_autosave_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -48353,11 +49807,11 @@ int HP_pc_autosave(int tid, unsigned int tick, int id, intptr_t data) { } return retVal___; } -int HP_pc_follow_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_pc_follow_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_pc_follow_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_follow_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_pc_follow_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -48371,7 +49825,7 @@ int HP_pc_follow_timer(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.pc.follow_timer(tid, tick, id, data); } if( HPMHooks.count.HP_pc_follow_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_follow_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_pc_follow_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -48540,15 +49994,342 @@ int HP_pc_removecombo(struct map_session_data *sd, struct item_data *data) { } return retVal___; } +void HP_pc_bank_deposit(struct map_session_data *sd, int money) { + int hIndex = 0; + if( HPMHooks.count.HP_pc_bank_deposit_pre ) { + void (*preHookFunc) (struct map_session_data *sd, int *money); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_bank_deposit_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_pc_bank_deposit_pre[hIndex].func; + preHookFunc(sd, &money); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.pc.bank_deposit(sd, money); + } + if( HPMHooks.count.HP_pc_bank_deposit_post ) { + void (*postHookFunc) (struct map_session_data *sd, int *money); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_bank_deposit_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_pc_bank_deposit_post[hIndex].func; + postHookFunc(sd, &money); + } + } + return; +} +void HP_pc_bank_withdraw(struct map_session_data *sd, int money) { + int hIndex = 0; + if( HPMHooks.count.HP_pc_bank_withdraw_pre ) { + void (*preHookFunc) (struct map_session_data *sd, int *money); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_bank_withdraw_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_pc_bank_withdraw_pre[hIndex].func; + preHookFunc(sd, &money); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.pc.bank_withdraw(sd, money); + } + if( HPMHooks.count.HP_pc_bank_withdraw_post ) { + void (*postHookFunc) (struct map_session_data *sd, int *money); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_bank_withdraw_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_pc_bank_withdraw_post[hIndex].func; + postHookFunc(sd, &money); + } + } + return; +} +void HP_pc_rental_expire(struct map_session_data *sd, int i) { + int hIndex = 0; + if( HPMHooks.count.HP_pc_rental_expire_pre ) { + void (*preHookFunc) (struct map_session_data *sd, int *i); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_rental_expire_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_pc_rental_expire_pre[hIndex].func; + preHookFunc(sd, &i); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.pc.rental_expire(sd, i); + } + if( HPMHooks.count.HP_pc_rental_expire_post ) { + void (*postHookFunc) (struct map_session_data *sd, int *i); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_rental_expire_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_pc_rental_expire_post[hIndex].func; + postHookFunc(sd, &i); + } + } + return; +} +void HP_pc_scdata_received(struct map_session_data *sd) { + int hIndex = 0; + if( HPMHooks.count.HP_pc_scdata_received_pre ) { + void (*preHookFunc) (struct map_session_data *sd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_scdata_received_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_pc_scdata_received_pre[hIndex].func; + preHookFunc(sd); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.pc.scdata_received(sd); + } + if( HPMHooks.count.HP_pc_scdata_received_post ) { + void (*postHookFunc) (struct map_session_data *sd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_scdata_received_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_pc_scdata_received_post[hIndex].func; + postHookFunc(sd); + } + } + return; +} +void HP_pc_bound_clear(struct map_session_data *sd, enum e_item_bound_type type) { + int hIndex = 0; + if( HPMHooks.count.HP_pc_bound_clear_pre ) { + void (*preHookFunc) (struct map_session_data *sd, enum e_item_bound_type *type); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_bound_clear_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_pc_bound_clear_pre[hIndex].func; + preHookFunc(sd, &type); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.pc.bound_clear(sd, type); + } + if( HPMHooks.count.HP_pc_bound_clear_post ) { + void (*postHookFunc) (struct map_session_data *sd, enum e_item_bound_type *type); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_bound_clear_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_pc_bound_clear_post[hIndex].func; + postHookFunc(sd, &type); + } + } + return; +} +int HP_pc_expiration_timer(int tid, int64 tick, int id, intptr_t data) { + int hIndex = 0; + int retVal___ = 0; + if( HPMHooks.count.HP_pc_expiration_timer_pre ) { + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_expiration_timer_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_pc_expiration_timer_pre[hIndex].func; + retVal___ = preHookFunc(&tid, &tick, &id, &data); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.pc.expiration_timer(tid, tick, id, data); + } + if( HPMHooks.count.HP_pc_expiration_timer_post ) { + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_expiration_timer_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_pc_expiration_timer_post[hIndex].func; + retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); + } + } + return retVal___; +} +int HP_pc_global_expiration_timer(int tid, int64 tick, int id, intptr_t data) { + int hIndex = 0; + int retVal___ = 0; + if( HPMHooks.count.HP_pc_global_expiration_timer_pre ) { + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_global_expiration_timer_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_pc_global_expiration_timer_pre[hIndex].func; + retVal___ = preHookFunc(&tid, &tick, &id, &data); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.pc.global_expiration_timer(tid, tick, id, data); + } + if( HPMHooks.count.HP_pc_global_expiration_timer_post ) { + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_global_expiration_timer_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_pc_global_expiration_timer_post[hIndex].func; + retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); + } + } + return retVal___; +} +void HP_pc_expire_check(struct map_session_data *sd) { + int hIndex = 0; + if( HPMHooks.count.HP_pc_expire_check_pre ) { + void (*preHookFunc) (struct map_session_data *sd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_expire_check_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_pc_expire_check_pre[hIndex].func; + preHookFunc(sd); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.pc.expire_check(sd); + } + if( HPMHooks.count.HP_pc_expire_check_post ) { + void (*postHookFunc) (struct map_session_data *sd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_expire_check_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_pc_expire_check_post[hIndex].func; + postHookFunc(sd); + } + } + return; +} +void HP_pc_autotrade_load(void) { + int hIndex = 0; + if( HPMHooks.count.HP_pc_autotrade_load_pre ) { + void (*preHookFunc) (void); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_autotrade_load_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_pc_autotrade_load_pre[hIndex].func; + preHookFunc(); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.pc.autotrade_load(); + } + if( HPMHooks.count.HP_pc_autotrade_load_post ) { + void (*postHookFunc) (void); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_autotrade_load_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_pc_autotrade_load_post[hIndex].func; + postHookFunc(); + } + } + return; +} +void HP_pc_autotrade_update(struct map_session_data *sd, enum e_pc_autotrade_update_action action) { + int hIndex = 0; + if( HPMHooks.count.HP_pc_autotrade_update_pre ) { + void (*preHookFunc) (struct map_session_data *sd, enum e_pc_autotrade_update_action *action); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_autotrade_update_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_pc_autotrade_update_pre[hIndex].func; + preHookFunc(sd, &action); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.pc.autotrade_update(sd, action); + } + if( HPMHooks.count.HP_pc_autotrade_update_post ) { + void (*postHookFunc) (struct map_session_data *sd, enum e_pc_autotrade_update_action *action); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_autotrade_update_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_pc_autotrade_update_post[hIndex].func; + postHookFunc(sd, &action); + } + } + return; +} +void HP_pc_autotrade_start(struct map_session_data *sd) { + int hIndex = 0; + if( HPMHooks.count.HP_pc_autotrade_start_pre ) { + void (*preHookFunc) (struct map_session_data *sd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_autotrade_start_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_pc_autotrade_start_pre[hIndex].func; + preHookFunc(sd); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.pc.autotrade_start(sd); + } + if( HPMHooks.count.HP_pc_autotrade_start_post ) { + void (*postHookFunc) (struct map_session_data *sd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_autotrade_start_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_pc_autotrade_start_post[hIndex].func; + postHookFunc(sd); + } + } + return; +} +void HP_pc_autotrade_prepare(struct map_session_data *sd) { + int hIndex = 0; + if( HPMHooks.count.HP_pc_autotrade_prepare_pre ) { + void (*preHookFunc) (struct map_session_data *sd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_autotrade_prepare_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_pc_autotrade_prepare_pre[hIndex].func; + preHookFunc(sd); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.pc.autotrade_prepare(sd); + } + if( HPMHooks.count.HP_pc_autotrade_prepare_post ) { + void (*postHookFunc) (struct map_session_data *sd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_autotrade_prepare_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_pc_autotrade_prepare_post[hIndex].func; + postHookFunc(sd); + } + } + return; +} +void HP_pc_autotrade_populate(struct map_session_data *sd) { + int hIndex = 0; + if( HPMHooks.count.HP_pc_autotrade_populate_pre ) { + void (*preHookFunc) (struct map_session_data *sd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_autotrade_populate_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_pc_autotrade_populate_pre[hIndex].func; + preHookFunc(sd); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.pc.autotrade_populate(sd); + } + if( HPMHooks.count.HP_pc_autotrade_populate_post ) { + void (*postHookFunc) (struct map_session_data *sd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_pc_autotrade_populate_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_pc_autotrade_populate_post[hIndex].func; + postHookFunc(sd); + } + } + return; +} /* pet */ -int HP_pet_init(void) { +int HP_pet_init(bool minimal) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_pet_init_pre ) { - int (*preHookFunc) (void); + int (*preHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_pet_init_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_pet_init_pre[hIndex].func; - retVal___ = preHookFunc(); + retVal___ = preHookFunc(&minimal); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -48556,13 +50337,13 @@ int HP_pet_init(void) { } } { - retVal___ = HPMHooks.source.pet.init(); + retVal___ = HPMHooks.source.pet.init(minimal); } if( HPMHooks.count.HP_pet_init_post ) { - int (*postHookFunc) (int retVal___); + int (*postHookFunc) (int retVal___, bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_pet_init_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_pet_init_post[hIndex].func; - retVal___ = postHookFunc(retVal___); + retVal___ = postHookFunc(retVal___, &minimal); } } return retVal___; @@ -48774,11 +50555,11 @@ int HP_pet_sc_check(struct map_session_data *sd, int type) { } return retVal___; } -int HP_pet_hungry(int tid, unsigned int tick, int id, intptr_t data) { +int HP_pet_hungry(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_pet_hungry_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pet_hungry_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_pet_hungry_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -48792,7 +50573,7 @@ int HP_pet_hungry(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.pet.hungry(tid, tick, id, data); } if( HPMHooks.count.HP_pet_hungry_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pet_hungry_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_pet_hungry_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -49274,11 +51055,11 @@ int HP_pet_equipitem(struct map_session_data *sd, int index) { } return retVal___; } -int HP_pet_randomwalk(struct pet_data *pd, unsigned int tick) { +int HP_pet_randomwalk(struct pet_data *pd, int64 tick) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_pet_randomwalk_pre ) { - int (*preHookFunc) (struct pet_data *pd, unsigned int *tick); + int (*preHookFunc) (struct pet_data *pd, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_pet_randomwalk_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_pet_randomwalk_pre[hIndex].func; retVal___ = preHookFunc(pd, &tick); @@ -49292,7 +51073,7 @@ int HP_pet_randomwalk(struct pet_data *pd, unsigned int tick) { retVal___ = HPMHooks.source.pet.randomwalk(pd, tick); } if( HPMHooks.count.HP_pet_randomwalk_post ) { - int (*postHookFunc) (int retVal___, struct pet_data *pd, unsigned int *tick); + int (*postHookFunc) (int retVal___, struct pet_data *pd, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_pet_randomwalk_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_pet_randomwalk_post[hIndex].func; retVal___ = postHookFunc(retVal___, pd, &tick); @@ -49300,11 +51081,11 @@ int HP_pet_randomwalk(struct pet_data *pd, unsigned int tick) { } return retVal___; } -int HP_pet_ai_sub_hard(struct pet_data *pd, struct map_session_data *sd, unsigned int tick) { +int HP_pet_ai_sub_hard(struct pet_data *pd, struct map_session_data *sd, int64 tick) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_pet_ai_sub_hard_pre ) { - int (*preHookFunc) (struct pet_data *pd, struct map_session_data *sd, unsigned int *tick); + int (*preHookFunc) (struct pet_data *pd, struct map_session_data *sd, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_pet_ai_sub_hard_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_pet_ai_sub_hard_pre[hIndex].func; retVal___ = preHookFunc(pd, sd, &tick); @@ -49318,7 +51099,7 @@ int HP_pet_ai_sub_hard(struct pet_data *pd, struct map_session_data *sd, unsigne retVal___ = HPMHooks.source.pet.ai_sub_hard(pd, sd, tick); } if( HPMHooks.count.HP_pet_ai_sub_hard_post ) { - int (*postHookFunc) (int retVal___, struct pet_data *pd, struct map_session_data *sd, unsigned int *tick); + int (*postHookFunc) (int retVal___, struct pet_data *pd, struct map_session_data *sd, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_pet_ai_sub_hard_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_pet_ai_sub_hard_post[hIndex].func; retVal___ = postHookFunc(retVal___, pd, sd, &tick); @@ -49358,11 +51139,11 @@ int HP_pet_ai_sub_foreachclient(struct map_session_data *sd, va_list ap) { } return retVal___; } -int HP_pet_ai_hard(int tid, unsigned int tick, int id, intptr_t data) { +int HP_pet_ai_hard(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_pet_ai_hard_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pet_ai_hard_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_pet_ai_hard_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -49376,7 +51157,7 @@ int HP_pet_ai_hard(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.pet.ai_hard(tid, tick, id, data); } if( HPMHooks.count.HP_pet_ai_hard_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pet_ai_hard_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_pet_ai_hard_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -49384,11 +51165,11 @@ int HP_pet_ai_hard(int tid, unsigned int tick, int id, intptr_t data) { } return retVal___; } -int HP_pet_delay_item_drop(int tid, unsigned int tick, int id, intptr_t data) { +int HP_pet_delay_item_drop(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_pet_delay_item_drop_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pet_delay_item_drop_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_pet_delay_item_drop_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -49402,7 +51183,7 @@ int HP_pet_delay_item_drop(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.pet.delay_item_drop(tid, tick, id, data); } if( HPMHooks.count.HP_pet_delay_item_drop_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pet_delay_item_drop_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_pet_delay_item_drop_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -49436,11 +51217,11 @@ int HP_pet_lootitem_drop(struct pet_data *pd, struct map_session_data *sd) { } return retVal___; } -int HP_pet_skill_bonus_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_pet_skill_bonus_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_pet_skill_bonus_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pet_skill_bonus_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_pet_skill_bonus_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -49454,7 +51235,7 @@ int HP_pet_skill_bonus_timer(int tid, unsigned int tick, int id, intptr_t data) retVal___ = HPMHooks.source.pet.skill_bonus_timer(tid, tick, id, data); } if( HPMHooks.count.HP_pet_skill_bonus_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pet_skill_bonus_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_pet_skill_bonus_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -49462,11 +51243,11 @@ int HP_pet_skill_bonus_timer(int tid, unsigned int tick, int id, intptr_t data) } return retVal___; } -int HP_pet_recovery_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_pet_recovery_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_pet_recovery_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pet_recovery_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_pet_recovery_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -49480,7 +51261,7 @@ int HP_pet_recovery_timer(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.pet.recovery_timer(tid, tick, id, data); } if( HPMHooks.count.HP_pet_recovery_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pet_recovery_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_pet_recovery_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -49488,11 +51269,11 @@ int HP_pet_recovery_timer(int tid, unsigned int tick, int id, intptr_t data) { } return retVal___; } -int HP_pet_heal_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_pet_heal_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_pet_heal_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pet_heal_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_pet_heal_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -49506,7 +51287,7 @@ int HP_pet_heal_timer(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.pet.heal_timer(tid, tick, id, data); } if( HPMHooks.count.HP_pet_heal_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pet_heal_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_pet_heal_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -49514,11 +51295,11 @@ int HP_pet_heal_timer(int tid, unsigned int tick, int id, intptr_t data) { } return retVal___; } -int HP_pet_skill_support_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_pet_skill_support_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_pet_skill_support_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pet_skill_support_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_pet_skill_support_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -49532,7 +51313,7 @@ int HP_pet_skill_support_timer(int tid, unsigned int tick, int id, intptr_t data retVal___ = HPMHooks.source.pet.skill_support_timer(tid, tick, id, data); } if( HPMHooks.count.HP_pet_skill_support_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_pet_skill_support_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_pet_skill_support_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -49567,13 +51348,13 @@ int HP_pet_read_db(void) { return retVal___; } /* quest */ -void HP_quest_init(void) { +void HP_quest_init(bool minimal) { int hIndex = 0; if( HPMHooks.count.HP_quest_init_pre ) { - void (*preHookFunc) (void); + void (*preHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_quest_init_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_quest_init_pre[hIndex].func; - preHookFunc(); + preHookFunc(&minimal); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -49581,12 +51362,37 @@ void HP_quest_init(void) { } } { - HPMHooks.source.quest.init(); + HPMHooks.source.quest.init(minimal); } if( HPMHooks.count.HP_quest_init_post ) { - void (*postHookFunc) (void); + void (*postHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_quest_init_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_quest_init_post[hIndex].func; + postHookFunc(&minimal); + } + } + return; +} +void HP_quest_final(void) { + int hIndex = 0; + if( HPMHooks.count.HP_quest_final_pre ) { + void (*preHookFunc) (void); + for(hIndex = 0; hIndex < HPMHooks.count.HP_quest_final_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_quest_final_pre[hIndex].func; + preHookFunc(); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.quest.final(); + } + if( HPMHooks.count.HP_quest_final_post ) { + void (*postHookFunc) (void); + for(hIndex = 0; hIndex < HPMHooks.count.HP_quest_final_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_quest_final_post[hIndex].func; postHookFunc(); } } @@ -49617,13 +51423,13 @@ void HP_quest_reload(void) { } return; } -int HP_quest_search_db(int quest_id) { +struct quest_db* HP_quest_db(int quest_id) { int hIndex = 0; - int retVal___ = 0; - if( HPMHooks.count.HP_quest_search_db_pre ) { - int (*preHookFunc) (int *quest_id); - for(hIndex = 0; hIndex < HPMHooks.count.HP_quest_search_db_pre; hIndex++ ) { - preHookFunc = HPMHooks.list.HP_quest_search_db_pre[hIndex].func; + struct quest_db* retVal___ = NULL; + if( HPMHooks.count.HP_quest_db_pre ) { + struct quest_db* (*preHookFunc) (int *quest_id); + for(hIndex = 0; hIndex < HPMHooks.count.HP_quest_db_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_quest_db_pre[hIndex].func; retVal___ = preHookFunc(&quest_id); } if( *HPMforce_return ) { @@ -49632,12 +51438,12 @@ int HP_quest_search_db(int quest_id) { } } { - retVal___ = HPMHooks.source.quest.search_db(quest_id); + retVal___ = HPMHooks.source.quest.db(quest_id); } - if( HPMHooks.count.HP_quest_search_db_post ) { - int (*postHookFunc) (int retVal___, int *quest_id); - for(hIndex = 0; hIndex < HPMHooks.count.HP_quest_search_db_post; hIndex++ ) { - postHookFunc = HPMHooks.list.HP_quest_search_db_post[hIndex].func; + if( HPMHooks.count.HP_quest_db_post ) { + struct quest_db* (*postHookFunc) (struct quest_db* retVal___, int *quest_id); + for(hIndex = 0; hIndex < HPMHooks.count.HP_quest_db_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_quest_db_post[hIndex].func; retVal___ = postHookFunc(retVal___, &quest_id); } } @@ -49804,11 +51610,11 @@ void HP_quest_update_objective(TBL_PC *sd, int mob_id) { } return; } -int HP_quest_update_status(TBL_PC *sd, int quest_id, quest_state qs) { +int HP_quest_update_status(TBL_PC *sd, int quest_id, enum quest_state qs) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_quest_update_status_pre ) { - int (*preHookFunc) (TBL_PC *sd, int *quest_id, quest_state *qs); + int (*preHookFunc) (TBL_PC *sd, int *quest_id, enum quest_state *qs); for(hIndex = 0; hIndex < HPMHooks.count.HP_quest_update_status_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_quest_update_status_pre[hIndex].func; retVal___ = preHookFunc(sd, &quest_id, &qs); @@ -49822,7 +51628,7 @@ int HP_quest_update_status(TBL_PC *sd, int quest_id, quest_state qs) { retVal___ = HPMHooks.source.quest.update_status(sd, quest_id, qs); } if( HPMHooks.count.HP_quest_update_status_post ) { - int (*postHookFunc) (int retVal___, TBL_PC *sd, int *quest_id, quest_state *qs); + int (*postHookFunc) (int retVal___, TBL_PC *sd, int *quest_id, enum quest_state *qs); for(hIndex = 0; hIndex < HPMHooks.count.HP_quest_update_status_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_quest_update_status_post[hIndex].func; retVal___ = postHookFunc(retVal___, sd, &quest_id, &qs); @@ -49830,11 +51636,11 @@ int HP_quest_update_status(TBL_PC *sd, int quest_id, quest_state qs) { } return retVal___; } -int HP_quest_check(TBL_PC *sd, int quest_id, quest_check_type type) { +int HP_quest_check(TBL_PC *sd, int quest_id, enum quest_check_type type) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_quest_check_pre ) { - int (*preHookFunc) (TBL_PC *sd, int *quest_id, quest_check_type *type); + int (*preHookFunc) (TBL_PC *sd, int *quest_id, enum quest_check_type *type); for(hIndex = 0; hIndex < HPMHooks.count.HP_quest_check_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_quest_check_pre[hIndex].func; retVal___ = preHookFunc(sd, &quest_id, &type); @@ -49848,7 +51654,7 @@ int HP_quest_check(TBL_PC *sd, int quest_id, quest_check_type type) { retVal___ = HPMHooks.source.quest.check(sd, quest_id, type); } if( HPMHooks.count.HP_quest_check_post ) { - int (*postHookFunc) (int retVal___, TBL_PC *sd, int *quest_id, quest_check_type *type); + int (*postHookFunc) (int retVal___, TBL_PC *sd, int *quest_id, enum quest_check_type *type); for(hIndex = 0; hIndex < HPMHooks.count.HP_quest_check_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_quest_check_post[hIndex].func; retVal___ = postHookFunc(retVal___, sd, &quest_id, &type); @@ -49856,6 +51662,31 @@ int HP_quest_check(TBL_PC *sd, int quest_id, quest_check_type type) { } return retVal___; } +void HP_quest_clear(void) { + int hIndex = 0; + if( HPMHooks.count.HP_quest_clear_pre ) { + void (*preHookFunc) (void); + for(hIndex = 0; hIndex < HPMHooks.count.HP_quest_clear_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_quest_clear_pre[hIndex].func; + preHookFunc(); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.quest.clear(); + } + if( HPMHooks.count.HP_quest_clear_post ) { + void (*postHookFunc) (void); + for(hIndex = 0; hIndex < HPMHooks.count.HP_quest_clear_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_quest_clear_post[hIndex].func; + postHookFunc(); + } + } + return; +} int HP_quest_read_db(void) { int hIndex = 0; int retVal___ = 0; @@ -49883,13 +51714,13 @@ int HP_quest_read_db(void) { return retVal___; } /* script */ -void HP_script_init(void) { +void HP_script_init(bool minimal) { int hIndex = 0; if( HPMHooks.count.HP_script_init_pre ) { - void (*preHookFunc) (void); + void (*preHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_script_init_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_script_init_pre[hIndex].func; - preHookFunc(); + preHookFunc(&minimal); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -49897,13 +51728,13 @@ void HP_script_init(void) { } } { - HPMHooks.source.script.init(); + HPMHooks.source.script.init(minimal); } if( HPMHooks.count.HP_script_init_post ) { - void (*postHookFunc) (void); + void (*postHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_script_init_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_script_init_post[hIndex].func; - postHookFunc(); + postHookFunc(&minimal); } } return; @@ -49985,6 +51816,32 @@ struct script_code* HP_script_parse(const char *src, const char *file, int line, } return retVal___; } +bool HP_script_add_builtin(const struct script_function *buildin, bool override) { + int hIndex = 0; + bool retVal___ = false; + if( HPMHooks.count.HP_script_add_builtin_pre ) { + bool (*preHookFunc) (const struct script_function *buildin, bool *override); + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_add_builtin_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_script_add_builtin_pre[hIndex].func; + retVal___ = preHookFunc(buildin, &override); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.script.add_builtin(buildin, override); + } + if( HPMHooks.count.HP_script_add_builtin_post ) { + bool (*postHookFunc) (bool retVal___, const struct script_function *buildin, bool *override); + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_add_builtin_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_script_add_builtin_post[hIndex].func; + retVal___ = postHookFunc(retVal___, buildin, &override); + } + } + return retVal___; +} void HP_script_parse_builtin(void) { int hIndex = 0; if( HPMHooks.count.HP_script_parse_builtin_pre ) { @@ -50241,11 +52098,11 @@ void HP_script_detach_rid(struct script_state *st) { } return; } -struct script_data* HP_script_push_val(struct script_stack *stack, enum c_op type, int val, struct DBMap **ref) { +struct script_data* HP_script_push_val(struct script_stack *stack, enum c_op type, int64 val, struct DBMap **ref) { int hIndex = 0; struct script_data* retVal___ = NULL; if( HPMHooks.count.HP_script_push_val_pre ) { - struct script_data* (*preHookFunc) (struct script_stack *stack, enum c_op *type, int *val, struct DBMap **ref); + struct script_data* (*preHookFunc) (struct script_stack *stack, enum c_op *type, int64 *val, struct DBMap **ref); for(hIndex = 0; hIndex < HPMHooks.count.HP_script_push_val_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_script_push_val_pre[hIndex].func; retVal___ = preHookFunc(stack, &type, &val, ref); @@ -50259,7 +52116,7 @@ struct script_data* HP_script_push_val(struct script_stack *stack, enum c_op typ retVal___ = HPMHooks.source.script.push_val(stack, type, val, ref); } if( HPMHooks.count.HP_script_push_val_post ) { - struct script_data* (*postHookFunc) (struct script_data* retVal___, struct script_stack *stack, enum c_op *type, int *val, struct DBMap **ref); + struct script_data* (*postHookFunc) (struct script_data* retVal___, struct script_stack *stack, enum c_op *type, int64 *val, struct DBMap **ref); for(hIndex = 0; hIndex < HPMHooks.count.HP_script_push_val_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_script_push_val_post[hIndex].func; retVal___ = postHookFunc(retVal___, stack, &type, &val, ref); @@ -50267,36 +52124,37 @@ struct script_data* HP_script_push_val(struct script_stack *stack, enum c_op typ } return retVal___; } -void HP_script_get_val(struct script_state *st, struct script_data *data) { +struct script_data* HP_script_get_val(struct script_state *st, struct script_data *data) { int hIndex = 0; + struct script_data* retVal___ = NULL; if( HPMHooks.count.HP_script_get_val_pre ) { - void (*preHookFunc) (struct script_state *st, struct script_data *data); + struct script_data* (*preHookFunc) (struct script_state *st, struct script_data *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_script_get_val_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_script_get_val_pre[hIndex].func; - preHookFunc(st, data); + retVal___ = preHookFunc(st, data); } if( *HPMforce_return ) { *HPMforce_return = false; - return; + return retVal___; } } { - HPMHooks.source.script.get_val(st, data); + retVal___ = HPMHooks.source.script.get_val(st, data); } if( HPMHooks.count.HP_script_get_val_post ) { - void (*postHookFunc) (struct script_state *st, struct script_data *data); + struct script_data* (*postHookFunc) (struct script_data* retVal___, struct script_state *st, struct script_data *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_script_get_val_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_script_get_val_post[hIndex].func; - postHookFunc(st, data); + retVal___ = postHookFunc(retVal___, st, data); } } - return; + return retVal___; } -void* HP_script_get_val2(struct script_state *st, int uid, struct DBMap **ref) { +void* HP_script_get_val2(struct script_state *st, int64 uid, struct DBMap **ref) { int hIndex = 0; void* retVal___ = NULL; if( HPMHooks.count.HP_script_get_val2_pre ) { - void* (*preHookFunc) (struct script_state *st, int *uid, struct DBMap **ref); + void* (*preHookFunc) (struct script_state *st, int64 *uid, struct DBMap **ref); for(hIndex = 0; hIndex < HPMHooks.count.HP_script_get_val2_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_script_get_val2_pre[hIndex].func; retVal___ = preHookFunc(st, &uid, ref); @@ -50310,7 +52168,7 @@ void* HP_script_get_val2(struct script_state *st, int uid, struct DBMap **ref) { retVal___ = HPMHooks.source.script.get_val2(st, uid, ref); } if( HPMHooks.count.HP_script_get_val2_post ) { - void* (*postHookFunc) (void* retVal___, struct script_state *st, int *uid, struct DBMap **ref); + void* (*postHookFunc) (void* retVal___, struct script_state *st, int64 *uid, struct DBMap **ref); for(hIndex = 0; hIndex < HPMHooks.count.HP_script_get_val2_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_script_get_val2_post[hIndex].func; retVal___ = postHookFunc(retVal___, st, &uid, ref); @@ -50445,31 +52303,6 @@ void HP_script_set_constant2(const char *name, int value, bool isparameter) { } return; } -void HP_script_set_constant_force(const char *name, int value, bool isparameter) { - int hIndex = 0; - if( HPMHooks.count.HP_script_set_constant_force_pre ) { - void (*preHookFunc) (const char *name, int *value, bool *isparameter); - for(hIndex = 0; hIndex < HPMHooks.count.HP_script_set_constant_force_pre; hIndex++ ) { - preHookFunc = HPMHooks.list.HP_script_set_constant_force_pre[hIndex].func; - preHookFunc(name, &value, &isparameter); - } - if( *HPMforce_return ) { - *HPMforce_return = false; - return; - } - } - { - HPMHooks.source.script.set_constant_force(name, value, isparameter); - } - if( HPMHooks.count.HP_script_set_constant_force_post ) { - void (*postHookFunc) (const char *name, int *value, bool *isparameter); - for(hIndex = 0; hIndex < HPMHooks.count.HP_script_set_constant_force_post; hIndex++ ) { - postHookFunc = HPMHooks.list.HP_script_set_constant_force_post[hIndex].func; - postHookFunc(name, &value, &isparameter); - } - } - return; -} bool HP_script_get_constant(const char *name, int *value) { int hIndex = 0; bool retVal___ = false; @@ -50571,11 +52404,11 @@ void HP_script_run_main(struct script_state *st) { } return; } -int HP_script_run_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_script_run_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_script_run_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_script_run_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_script_run_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -50589,7 +52422,7 @@ int HP_script_run_timer(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.script.run_timer(tid, tick, id, data); } if( HPMHooks.count.HP_script_run_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_script_run_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_script_run_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -50799,10 +52632,10 @@ void HP_script_cleararray_pc(struct map_session_data *sd, const char *varname, v } return; } -void HP_script_setarray_pc(struct map_session_data *sd, const char *varname, uint8 idx, void *value, int *refcache) { +void HP_script_setarray_pc(struct map_session_data *sd, const char *varname, uint32 idx, void *value, int *refcache) { int hIndex = 0; if( HPMHooks.count.HP_script_setarray_pc_pre ) { - void (*preHookFunc) (struct map_session_data *sd, const char *varname, uint8 *idx, void *value, int *refcache); + void (*preHookFunc) (struct map_session_data *sd, const char *varname, uint32 *idx, void *value, int *refcache); for(hIndex = 0; hIndex < HPMHooks.count.HP_script_setarray_pc_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_script_setarray_pc_pre[hIndex].func; preHookFunc(sd, varname, &idx, value, refcache); @@ -50816,7 +52649,7 @@ void HP_script_setarray_pc(struct map_session_data *sd, const char *varname, uin HPMHooks.source.script.setarray_pc(sd, varname, idx, value, refcache); } if( HPMHooks.count.HP_script_setarray_pc_post ) { - void (*postHookFunc) (struct map_session_data *sd, const char *varname, uint8 *idx, void *value, int *refcache); + void (*postHookFunc) (struct map_session_data *sd, const char *varname, uint32 *idx, void *value, int *refcache); for(hIndex = 0; hIndex < HPMHooks.count.HP_script_setarray_pc_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_script_setarray_pc_post[hIndex].func; postHookFunc(sd, varname, &idx, value, refcache); @@ -51390,31 +53223,6 @@ void HP_script_reportfunc(struct script_state *st) { } return; } -void HP_script_disp_error_message2(const char *mes, const char *pos, int report) { - int hIndex = 0; - if( HPMHooks.count.HP_script_disp_error_message2_pre ) { - void (*preHookFunc) (const char *mes, const char *pos, int *report); - for(hIndex = 0; hIndex < HPMHooks.count.HP_script_disp_error_message2_pre; hIndex++ ) { - preHookFunc = HPMHooks.list.HP_script_disp_error_message2_pre[hIndex].func; - preHookFunc(mes, pos, &report); - } - if( *HPMforce_return ) { - *HPMforce_return = false; - return; - } - } - { - HPMHooks.source.script.disp_error_message2(mes, pos, report); - } - if( HPMHooks.count.HP_script_disp_error_message2_post ) { - void (*postHookFunc) (const char *mes, const char *pos, int *report); - for(hIndex = 0; hIndex < HPMHooks.count.HP_script_disp_error_message2_post; hIndex++ ) { - postHookFunc = HPMHooks.list.HP_script_disp_error_message2_post[hIndex].func; - postHookFunc(mes, pos, &report); - } - } - return; -} void HP_script_disp_warning_message(const char *mes, const char *pos) { int hIndex = 0; if( HPMHooks.count.HP_script_disp_warning_message_pre ) { @@ -51899,11 +53707,11 @@ void HP_script_errorwarning_sub(StringBuf *buf, const char *src, const char *fil } return; } -int HP_script_set_reg(struct script_state *st, TBL_PC *sd, int num, const char *name, const void *value, struct DBMap **ref) { +int HP_script_set_reg(struct script_state *st, TBL_PC *sd, int64 num, const char *name, const void *value, struct DBMap **ref) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_script_set_reg_pre ) { - int (*preHookFunc) (struct script_state *st, TBL_PC *sd, int *num, const char *name, const void *value, struct DBMap **ref); + int (*preHookFunc) (struct script_state *st, TBL_PC *sd, int64 *num, const char *name, const void *value, struct DBMap **ref); for(hIndex = 0; hIndex < HPMHooks.count.HP_script_set_reg_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_script_set_reg_pre[hIndex].func; retVal___ = preHookFunc(st, sd, &num, name, value, ref); @@ -51917,7 +53725,7 @@ int HP_script_set_reg(struct script_state *st, TBL_PC *sd, int num, const char * retVal___ = HPMHooks.source.script.set_reg(st, sd, num, name, value, ref); } if( HPMHooks.count.HP_script_set_reg_post ) { - int (*postHookFunc) (int retVal___, struct script_state *st, TBL_PC *sd, int *num, const char *name, const void *value, struct DBMap **ref); + int (*postHookFunc) (int retVal___, struct script_state *st, TBL_PC *sd, int64 *num, const char *name, const void *value, struct DBMap **ref); for(hIndex = 0; hIndex < HPMHooks.count.HP_script_set_reg_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_script_set_reg_post[hIndex].func; retVal___ = postHookFunc(retVal___, st, sd, &num, name, value, ref); @@ -51976,32 +53784,6 @@ struct script_data* HP_script_push_retinfo(struct script_stack *stack, struct sc } return retVal___; } -int HP_script_pop_val(struct script_state *st) { - int hIndex = 0; - int retVal___ = 0; - if( HPMHooks.count.HP_script_pop_val_pre ) { - int (*preHookFunc) (struct script_state *st); - for(hIndex = 0; hIndex < HPMHooks.count.HP_script_pop_val_pre; hIndex++ ) { - preHookFunc = HPMHooks.list.HP_script_pop_val_pre[hIndex].func; - retVal___ = preHookFunc(st); - } - if( *HPMforce_return ) { - *HPMforce_return = false; - return retVal___; - } - } - { - retVal___ = HPMHooks.source.script.pop_val(st); - } - if( HPMHooks.count.HP_script_pop_val_post ) { - int (*postHookFunc) (int retVal___, struct script_state *st); - for(hIndex = 0; hIndex < HPMHooks.count.HP_script_pop_val_post; hIndex++ ) { - postHookFunc = HPMHooks.list.HP_script_pop_val_post[hIndex].func; - retVal___ = postHookFunc(retVal___, st); - } - } - return retVal___; -} void HP_script_op_3(struct script_state *st, int op) { int hIndex = 0; if( HPMHooks.count.HP_script_op_3_pre ) { @@ -52324,32 +54106,6 @@ int HP_script_buildin_areapercentheal_sub(struct block_list *bl, va_list ap) { } return retVal___; } -int32 HP_script_getarraysize(struct script_state *st, int32 id, int32 idx, int isstring, struct DBMap **ref) { - int hIndex = 0; - int32 retVal___ = 0; - if( HPMHooks.count.HP_script_getarraysize_pre ) { - int32 (*preHookFunc) (struct script_state *st, int32 *id, int32 *idx, int *isstring, struct DBMap **ref); - for(hIndex = 0; hIndex < HPMHooks.count.HP_script_getarraysize_pre; hIndex++ ) { - preHookFunc = HPMHooks.list.HP_script_getarraysize_pre[hIndex].func; - retVal___ = preHookFunc(st, &id, &idx, &isstring, ref); - } - if( *HPMforce_return ) { - *HPMforce_return = false; - return retVal___; - } - } - { - retVal___ = HPMHooks.source.script.getarraysize(st, id, idx, isstring, ref); - } - if( HPMHooks.count.HP_script_getarraysize_post ) { - int32 (*postHookFunc) (int32 retVal___, struct script_state *st, int32 *id, int32 *idx, int *isstring, struct DBMap **ref); - for(hIndex = 0; hIndex < HPMHooks.count.HP_script_getarraysize_post; hIndex++ ) { - postHookFunc = HPMHooks.list.HP_script_getarraysize_post[hIndex].func; - retVal___ = postHookFunc(retVal___, st, &id, &idx, &isstring, ref); - } - } - return retVal___; -} void HP_script_buildin_delitem_delete(struct map_session_data *sd, int idx, int *amount, bool delete_items) { int hIndex = 0; if( HPMHooks.count.HP_script_buildin_delitem_delete_pre ) { @@ -52785,14 +54541,14 @@ int HP_script_buildin_mobcount_sub(struct block_list *bl, va_list ap) { } return retVal___; } -int HP_script_playBGM_sub(struct block_list *bl, va_list ap) { +int HP_script_playbgm_sub(struct block_list *bl, va_list ap) { int hIndex = 0; int retVal___ = 0; - if( HPMHooks.count.HP_script_playBGM_sub_pre ) { + if( HPMHooks.count.HP_script_playbgm_sub_pre ) { int (*preHookFunc) (struct block_list *bl, va_list ap); - for(hIndex = 0; hIndex < HPMHooks.count.HP_script_playBGM_sub_pre; hIndex++ ) { + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_playbgm_sub_pre; hIndex++ ) { va_list ap___copy; va_copy(ap___copy, ap); - preHookFunc = HPMHooks.list.HP_script_playBGM_sub_pre[hIndex].func; + preHookFunc = HPMHooks.list.HP_script_playbgm_sub_pre[hIndex].func; retVal___ = preHookFunc(bl, ap___copy); va_end(ap___copy); } @@ -52803,28 +54559,28 @@ int HP_script_playBGM_sub(struct block_list *bl, va_list ap) { } { va_list ap___copy; va_copy(ap___copy, ap); - retVal___ = HPMHooks.source.script.playBGM_sub(bl, ap___copy); + retVal___ = HPMHooks.source.script.playbgm_sub(bl, ap___copy); va_end(ap___copy); } - if( HPMHooks.count.HP_script_playBGM_sub_post ) { + if( HPMHooks.count.HP_script_playbgm_sub_post ) { int (*postHookFunc) (int retVal___, struct block_list *bl, va_list ap); - for(hIndex = 0; hIndex < HPMHooks.count.HP_script_playBGM_sub_post; hIndex++ ) { + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_playbgm_sub_post; hIndex++ ) { va_list ap___copy; va_copy(ap___copy, ap); - postHookFunc = HPMHooks.list.HP_script_playBGM_sub_post[hIndex].func; + postHookFunc = HPMHooks.list.HP_script_playbgm_sub_post[hIndex].func; retVal___ = postHookFunc(retVal___, bl, ap___copy); va_end(ap___copy); } } return retVal___; } -int HP_script_playBGM_foreachpc_sub(struct map_session_data *sd, va_list args) { +int HP_script_playbgm_foreachpc_sub(struct map_session_data *sd, va_list args) { int hIndex = 0; int retVal___ = 0; - if( HPMHooks.count.HP_script_playBGM_foreachpc_sub_pre ) { + if( HPMHooks.count.HP_script_playbgm_foreachpc_sub_pre ) { int (*preHookFunc) (struct map_session_data *sd, va_list args); - for(hIndex = 0; hIndex < HPMHooks.count.HP_script_playBGM_foreachpc_sub_pre; hIndex++ ) { + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_playbgm_foreachpc_sub_pre; hIndex++ ) { va_list args___copy; va_copy(args___copy, args); - preHookFunc = HPMHooks.list.HP_script_playBGM_foreachpc_sub_pre[hIndex].func; + preHookFunc = HPMHooks.list.HP_script_playbgm_foreachpc_sub_pre[hIndex].func; retVal___ = preHookFunc(sd, args___copy); va_end(args___copy); } @@ -52835,14 +54591,14 @@ int HP_script_playBGM_foreachpc_sub(struct map_session_data *sd, va_list args) { } { va_list args___copy; va_copy(args___copy, args); - retVal___ = HPMHooks.source.script.playBGM_foreachpc_sub(sd, args___copy); + retVal___ = HPMHooks.source.script.playbgm_foreachpc_sub(sd, args___copy); va_end(args___copy); } - if( HPMHooks.count.HP_script_playBGM_foreachpc_sub_post ) { + if( HPMHooks.count.HP_script_playbgm_foreachpc_sub_post ) { int (*postHookFunc) (int retVal___, struct map_session_data *sd, va_list args); - for(hIndex = 0; hIndex < HPMHooks.count.HP_script_playBGM_foreachpc_sub_post; hIndex++ ) { + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_playbgm_foreachpc_sub_post; hIndex++ ) { va_list args___copy; va_copy(args___copy, args); - postHookFunc = HPMHooks.list.HP_script_playBGM_foreachpc_sub_post[hIndex].func; + postHookFunc = HPMHooks.list.HP_script_playbgm_foreachpc_sub_post[hIndex].func; retVal___ = postHookFunc(retVal___, sd, args___copy); va_end(args___copy); } @@ -52907,32 +54663,6 @@ int HP_script_buildin_query_sql_sub(struct script_state *st, Sql *handle) { } return retVal___; } -int HP_script_axtoi(const char *hexStg) { - int hIndex = 0; - int retVal___ = 0; - if( HPMHooks.count.HP_script_axtoi_pre ) { - int (*preHookFunc) (const char *hexStg); - for(hIndex = 0; hIndex < HPMHooks.count.HP_script_axtoi_pre; hIndex++ ) { - preHookFunc = HPMHooks.list.HP_script_axtoi_pre[hIndex].func; - retVal___ = preHookFunc(hexStg); - } - if( *HPMforce_return ) { - *HPMforce_return = false; - return retVal___; - } - } - { - retVal___ = HPMHooks.source.script.axtoi(hexStg); - } - if( HPMHooks.count.HP_script_axtoi_post ) { - int (*postHookFunc) (int retVal___, const char *hexStg); - for(hIndex = 0; hIndex < HPMHooks.count.HP_script_axtoi_post; hIndex++ ) { - postHookFunc = HPMHooks.list.HP_script_axtoi_post[hIndex].func; - retVal___ = postHookFunc(retVal___, hexStg); - } - } - return retVal___; -} int HP_script_buildin_instance_warpall_sub(struct block_list *bl, va_list ap) { int hIndex = 0; int retVal___ = 0; @@ -53055,6 +54785,401 @@ int HP_script_run_func(struct script_state *st) { } return retVal___; } +const char* HP_script_getfuncname(struct script_state *st) { + int hIndex = 0; + const char* retVal___ = NULL; + if( HPMHooks.count.HP_script_getfuncname_pre ) { + const char* (*preHookFunc) (struct script_state *st); + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_getfuncname_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_script_getfuncname_pre[hIndex].func; + retVal___ = preHookFunc(st); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.script.getfuncname(st); + } + if( HPMHooks.count.HP_script_getfuncname_post ) { + const char* (*postHookFunc) (const char* retVal___, struct script_state *st); + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_getfuncname_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_script_getfuncname_post[hIndex].func; + retVal___ = postHookFunc(retVal___, st); + } + } + return retVal___; +} +unsigned int HP_script_calc_hash_ci(const char *p) { + int hIndex = 0; + unsigned int retVal___ = 0; + if( HPMHooks.count.HP_script_calc_hash_ci_pre ) { + unsigned int (*preHookFunc) (const char *p); + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_calc_hash_ci_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_script_calc_hash_ci_pre[hIndex].func; + retVal___ = preHookFunc(p); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.script.calc_hash_ci(p); + } + if( HPMHooks.count.HP_script_calc_hash_ci_post ) { + unsigned int (*postHookFunc) (unsigned int retVal___, const char *p); + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_calc_hash_ci_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_script_calc_hash_ci_post[hIndex].func; + retVal___ = postHookFunc(retVal___, p); + } + } + return retVal___; +} +struct DBMap* HP_script_array_src(struct script_state *st, struct map_session_data *sd, const char *name, struct DBMap **ref) { + int hIndex = 0; + struct DBMap* retVal___ = NULL; + if( HPMHooks.count.HP_script_array_src_pre ) { + struct DBMap* (*preHookFunc) (struct script_state *st, struct map_session_data *sd, const char *name, struct DBMap **ref); + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_array_src_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_script_array_src_pre[hIndex].func; + retVal___ = preHookFunc(st, sd, name, ref); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.script.array_src(st, sd, name, ref); + } + if( HPMHooks.count.HP_script_array_src_post ) { + struct DBMap* (*postHookFunc) (struct DBMap* retVal___, struct script_state *st, struct map_session_data *sd, const char *name, struct DBMap **ref); + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_array_src_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_script_array_src_post[hIndex].func; + retVal___ = postHookFunc(retVal___, st, sd, name, ref); + } + } + return retVal___; +} +void HP_script_array_update(struct DBMap **src, int64 num, bool empty) { + int hIndex = 0; + if( HPMHooks.count.HP_script_array_update_pre ) { + void (*preHookFunc) (struct DBMap **src, int64 *num, bool *empty); + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_array_update_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_script_array_update_pre[hIndex].func; + preHookFunc(src, &num, &empty); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.script.array_update(src, num, empty); + } + if( HPMHooks.count.HP_script_array_update_post ) { + void (*postHookFunc) (struct DBMap **src, int64 *num, bool *empty); + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_array_update_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_script_array_update_post[hIndex].func; + postHookFunc(src, &num, &empty); + } + } + return; +} +void HP_script_array_delete(struct DBMap *src, struct script_array *sa) { + int hIndex = 0; + if( HPMHooks.count.HP_script_array_delete_pre ) { + void (*preHookFunc) (struct DBMap *src, struct script_array *sa); + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_array_delete_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_script_array_delete_pre[hIndex].func; + preHookFunc(src, sa); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.script.array_delete(src, sa); + } + if( HPMHooks.count.HP_script_array_delete_post ) { + void (*postHookFunc) (struct DBMap *src, struct script_array *sa); + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_array_delete_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_script_array_delete_post[hIndex].func; + postHookFunc(src, sa); + } + } + return; +} +void HP_script_array_remove_member(struct DBMap *src, struct script_array *sa, unsigned int idx) { + int hIndex = 0; + if( HPMHooks.count.HP_script_array_remove_member_pre ) { + void (*preHookFunc) (struct DBMap *src, struct script_array *sa, unsigned int *idx); + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_array_remove_member_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_script_array_remove_member_pre[hIndex].func; + preHookFunc(src, sa, &idx); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.script.array_remove_member(src, sa, idx); + } + if( HPMHooks.count.HP_script_array_remove_member_post ) { + void (*postHookFunc) (struct DBMap *src, struct script_array *sa, unsigned int *idx); + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_array_remove_member_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_script_array_remove_member_post[hIndex].func; + postHookFunc(src, sa, &idx); + } + } + return; +} +void HP_script_array_add_member(struct script_array *sa, unsigned int idx) { + int hIndex = 0; + if( HPMHooks.count.HP_script_array_add_member_pre ) { + void (*preHookFunc) (struct script_array *sa, unsigned int *idx); + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_array_add_member_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_script_array_add_member_pre[hIndex].func; + preHookFunc(sa, &idx); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.script.array_add_member(sa, idx); + } + if( HPMHooks.count.HP_script_array_add_member_post ) { + void (*postHookFunc) (struct script_array *sa, unsigned int *idx); + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_array_add_member_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_script_array_add_member_post[hIndex].func; + postHookFunc(sa, &idx); + } + } + return; +} +unsigned int HP_script_array_size(struct script_state *st, struct map_session_data *sd, const char *name, struct DBMap **ref) { + int hIndex = 0; + unsigned int retVal___ = 0; + if( HPMHooks.count.HP_script_array_size_pre ) { + unsigned int (*preHookFunc) (struct script_state *st, struct map_session_data *sd, const char *name, struct DBMap **ref); + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_array_size_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_script_array_size_pre[hIndex].func; + retVal___ = preHookFunc(st, sd, name, ref); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.script.array_size(st, sd, name, ref); + } + if( HPMHooks.count.HP_script_array_size_post ) { + unsigned int (*postHookFunc) (unsigned int retVal___, struct script_state *st, struct map_session_data *sd, const char *name, struct DBMap **ref); + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_array_size_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_script_array_size_post[hIndex].func; + retVal___ = postHookFunc(retVal___, st, sd, name, ref); + } + } + return retVal___; +} +unsigned int HP_script_array_highest_key(struct script_state *st, struct map_session_data *sd, const char *name, struct DBMap **ref) { + int hIndex = 0; + unsigned int retVal___ = 0; + if( HPMHooks.count.HP_script_array_highest_key_pre ) { + unsigned int (*preHookFunc) (struct script_state *st, struct map_session_data *sd, const char *name, struct DBMap **ref); + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_array_highest_key_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_script_array_highest_key_pre[hIndex].func; + retVal___ = preHookFunc(st, sd, name, ref); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.script.array_highest_key(st, sd, name, ref); + } + if( HPMHooks.count.HP_script_array_highest_key_post ) { + unsigned int (*postHookFunc) (unsigned int retVal___, struct script_state *st, struct map_session_data *sd, const char *name, struct DBMap **ref); + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_array_highest_key_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_script_array_highest_key_post[hIndex].func; + retVal___ = postHookFunc(retVal___, st, sd, name, ref); + } + } + return retVal___; +} +int HP_script_array_free_db(DBKey key, DBData *data, va_list ap) { + int hIndex = 0; + int retVal___ = 0; + if( HPMHooks.count.HP_script_array_free_db_pre ) { + int (*preHookFunc) (DBKey *key, DBData *data, va_list ap); + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_array_free_db_pre; hIndex++ ) { + va_list ap___copy; va_copy(ap___copy, ap); + preHookFunc = HPMHooks.list.HP_script_array_free_db_pre[hIndex].func; + retVal___ = preHookFunc(&key, data, ap___copy); + va_end(ap___copy); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + va_list ap___copy; va_copy(ap___copy, ap); + retVal___ = HPMHooks.source.script.array_free_db(key, data, ap___copy); + va_end(ap___copy); + } + if( HPMHooks.count.HP_script_array_free_db_post ) { + int (*postHookFunc) (int retVal___, DBKey *key, DBData *data, va_list ap); + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_array_free_db_post; hIndex++ ) { + va_list ap___copy; va_copy(ap___copy, ap); + postHookFunc = HPMHooks.list.HP_script_array_free_db_post[hIndex].func; + retVal___ = postHookFunc(retVal___, &key, data, ap___copy); + va_end(ap___copy); + } + } + return retVal___; +} +void HP_script_array_ensure_zero(struct script_state *st, struct map_session_data *sd, int64 uid, struct DBMap **ref) { + int hIndex = 0; + if( HPMHooks.count.HP_script_array_ensure_zero_pre ) { + void (*preHookFunc) (struct script_state *st, struct map_session_data *sd, int64 *uid, struct DBMap **ref); + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_array_ensure_zero_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_script_array_ensure_zero_pre[hIndex].func; + preHookFunc(st, sd, &uid, ref); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.script.array_ensure_zero(st, sd, uid, ref); + } + if( HPMHooks.count.HP_script_array_ensure_zero_post ) { + void (*postHookFunc) (struct script_state *st, struct map_session_data *sd, int64 *uid, struct DBMap **ref); + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_array_ensure_zero_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_script_array_ensure_zero_post[hIndex].func; + postHookFunc(st, sd, &uid, ref); + } + } + return; +} +void HP_script_reg_destroy_single(struct map_session_data *sd, int64 reg, struct script_reg_state *data) { + int hIndex = 0; + if( HPMHooks.count.HP_script_reg_destroy_single_pre ) { + void (*preHookFunc) (struct map_session_data *sd, int64 *reg, struct script_reg_state *data); + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_reg_destroy_single_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_script_reg_destroy_single_pre[hIndex].func; + preHookFunc(sd, ®, data); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.script.reg_destroy_single(sd, reg, data); + } + if( HPMHooks.count.HP_script_reg_destroy_single_post ) { + void (*postHookFunc) (struct map_session_data *sd, int64 *reg, struct script_reg_state *data); + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_reg_destroy_single_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_script_reg_destroy_single_post[hIndex].func; + postHookFunc(sd, ®, data); + } + } + return; +} +int HP_script_reg_destroy(DBKey key, DBData *data, va_list ap) { + int hIndex = 0; + int retVal___ = 0; + if( HPMHooks.count.HP_script_reg_destroy_pre ) { + int (*preHookFunc) (DBKey *key, DBData *data, va_list ap); + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_reg_destroy_pre; hIndex++ ) { + va_list ap___copy; va_copy(ap___copy, ap); + preHookFunc = HPMHooks.list.HP_script_reg_destroy_pre[hIndex].func; + retVal___ = preHookFunc(&key, data, ap___copy); + va_end(ap___copy); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + va_list ap___copy; va_copy(ap___copy, ap); + retVal___ = HPMHooks.source.script.reg_destroy(key, data, ap___copy); + va_end(ap___copy); + } + if( HPMHooks.count.HP_script_reg_destroy_post ) { + int (*postHookFunc) (int retVal___, DBKey *key, DBData *data, va_list ap); + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_reg_destroy_post; hIndex++ ) { + va_list ap___copy; va_copy(ap___copy, ap); + postHookFunc = HPMHooks.list.HP_script_reg_destroy_post[hIndex].func; + retVal___ = postHookFunc(retVal___, &key, data, ap___copy); + va_end(ap___copy); + } + } + return retVal___; +} +void HP_script_generic_ui_array_expand(unsigned int plus) { + int hIndex = 0; + if( HPMHooks.count.HP_script_generic_ui_array_expand_pre ) { + void (*preHookFunc) (unsigned int *plus); + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_generic_ui_array_expand_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_script_generic_ui_array_expand_pre[hIndex].func; + preHookFunc(&plus); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return; + } + } + { + HPMHooks.source.script.generic_ui_array_expand(plus); + } + if( HPMHooks.count.HP_script_generic_ui_array_expand_post ) { + void (*postHookFunc) (unsigned int *plus); + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_generic_ui_array_expand_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_script_generic_ui_array_expand_post[hIndex].func; + postHookFunc(&plus); + } + } + return; +} +unsigned int* HP_script_array_cpy_list(struct script_array *sa) { + int hIndex = 0; + unsigned int* retVal___ = NULL; + if( HPMHooks.count.HP_script_array_cpy_list_pre ) { + unsigned int* (*preHookFunc) (struct script_array *sa); + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_array_cpy_list_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_script_array_cpy_list_pre[hIndex].func; + retVal___ = preHookFunc(sa); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.script.array_cpy_list(sa); + } + if( HPMHooks.count.HP_script_array_cpy_list_post ) { + unsigned int* (*postHookFunc) (unsigned int* retVal___, struct script_array *sa); + for(hIndex = 0; hIndex < HPMHooks.count.HP_script_array_cpy_list_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_script_array_cpy_list_post[hIndex].func; + retVal___ = postHookFunc(retVal___, sa); + } + } + return retVal___; +} /* searchstore */ bool HP_searchstore_open(struct map_session_data *sd, unsigned int uses, unsigned short effect) { int hIndex = 0; @@ -53311,14 +55436,14 @@ bool HP_searchstore_result(struct map_session_data *sd, unsigned int store_id, i return retVal___; } /* skill */ -int HP_skill_init(void) { +int HP_skill_init(bool minimal) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_skill_init_pre ) { - int (*preHookFunc) (void); + int (*preHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_init_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_skill_init_pre[hIndex].func; - retVal___ = preHookFunc(); + retVal___ = preHookFunc(&minimal); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -53326,13 +55451,13 @@ int HP_skill_init(void) { } } { - retVal___ = HPMHooks.source.skill.init(); + retVal___ = HPMHooks.source.skill.init(minimal); } if( HPMHooks.count.HP_skill_init_post ) { - int (*postHookFunc) (int retVal___); + int (*postHookFunc) (int retVal___, bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_init_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_skill_init_post[hIndex].func; - retVal___ = postHookFunc(retVal___); + retVal___ = postHookFunc(retVal___, &minimal); } } return retVal___; @@ -53388,13 +55513,13 @@ void HP_skill_reload(void) { } return; } -void HP_skill_read_db(void) { +void HP_skill_read_db(bool minimal) { int hIndex = 0; if( HPMHooks.count.HP_skill_read_db_pre ) { - void (*preHookFunc) (void); + void (*preHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_read_db_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_skill_read_db_pre[hIndex].func; - preHookFunc(); + preHookFunc(&minimal); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -53402,13 +55527,13 @@ void HP_skill_read_db(void) { } } { - HPMHooks.source.skill.read_db(); + HPMHooks.source.skill.read_db(minimal); } if( HPMHooks.count.HP_skill_read_db_post ) { - void (*postHookFunc) (void); + void (*postHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_read_db_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_skill_read_db_post[hIndex].func; - postHookFunc(); + postHookFunc(&minimal); } } return; @@ -54634,14 +56759,14 @@ int HP_skill_name2id(const char *name) { } return retVal___; } -int HP_skill_isammotype(struct map_session_data *sd, int skill) { +int HP_skill_isammotype(struct map_session_data *sd, int skill_id) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_skill_isammotype_pre ) { - int (*preHookFunc) (struct map_session_data *sd, int *skill); + int (*preHookFunc) (struct map_session_data *sd, int *skill_id); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_isammotype_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_skill_isammotype_pre[hIndex].func; - retVal___ = preHookFunc(sd, &skill); + retVal___ = preHookFunc(sd, &skill_id); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -54649,22 +56774,22 @@ int HP_skill_isammotype(struct map_session_data *sd, int skill) { } } { - retVal___ = HPMHooks.source.skill.isammotype(sd, skill); + retVal___ = HPMHooks.source.skill.isammotype(sd, skill_id); } if( HPMHooks.count.HP_skill_isammotype_post ) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd, int *skill); + int (*postHookFunc) (int retVal___, struct map_session_data *sd, int *skill_id); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_isammotype_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_skill_isammotype_post[hIndex].func; - retVal___ = postHookFunc(retVal___, sd, &skill); + retVal___ = postHookFunc(retVal___, sd, &skill_id); } } return retVal___; } -int HP_skill_castend_id(int tid, unsigned int tick, int id, intptr_t data) { +int HP_skill_castend_id(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_skill_castend_id_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_castend_id_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_skill_castend_id_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -54678,7 +56803,7 @@ int HP_skill_castend_id(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.skill.castend_id(tid, tick, id, data); } if( HPMHooks.count.HP_skill_castend_id_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_castend_id_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_skill_castend_id_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -54686,11 +56811,11 @@ int HP_skill_castend_id(int tid, unsigned int tick, int id, intptr_t data) { } return retVal___; } -int HP_skill_castend_pos(int tid, unsigned int tick, int id, intptr_t data) { +int HP_skill_castend_pos(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_skill_castend_pos_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_castend_pos_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_skill_castend_pos_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -54704,7 +56829,7 @@ int HP_skill_castend_pos(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.skill.castend_pos(tid, tick, id, data); } if( HPMHooks.count.HP_skill_castend_pos_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_castend_pos_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_skill_castend_pos_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -54764,11 +56889,11 @@ int HP_skill_cleartimerskill(struct block_list *src) { } return retVal___; } -int HP_skill_addtimerskill(struct block_list *src, unsigned int tick, int target, int x, int y, uint16 skill_id, uint16 skill_lv, int type, int flag) { +int HP_skill_addtimerskill(struct block_list *src, int64 tick, int target, int x, int y, uint16 skill_id, uint16 skill_lv, int type, int flag) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_skill_addtimerskill_pre ) { - int (*preHookFunc) (struct block_list *src, unsigned int *tick, int *target, int *x, int *y, uint16 *skill_id, uint16 *skill_lv, int *type, int *flag); + int (*preHookFunc) (struct block_list *src, int64 *tick, int *target, int *x, int *y, uint16 *skill_id, uint16 *skill_lv, int *type, int *flag); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_addtimerskill_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_skill_addtimerskill_pre[hIndex].func; retVal___ = preHookFunc(src, &tick, &target, &x, &y, &skill_id, &skill_lv, &type, &flag); @@ -54782,7 +56907,7 @@ int HP_skill_addtimerskill(struct block_list *src, unsigned int tick, int target retVal___ = HPMHooks.source.skill.addtimerskill(src, tick, target, x, y, skill_id, skill_lv, type, flag); } if( HPMHooks.count.HP_skill_addtimerskill_post ) { - int (*postHookFunc) (int retVal___, struct block_list *src, unsigned int *tick, int *target, int *x, int *y, uint16 *skill_id, uint16 *skill_lv, int *type, int *flag); + int (*postHookFunc) (int retVal___, struct block_list *src, int64 *tick, int *target, int *x, int *y, uint16 *skill_id, uint16 *skill_lv, int *type, int *flag); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_addtimerskill_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_skill_addtimerskill_post[hIndex].func; retVal___ = postHookFunc(retVal___, src, &tick, &target, &x, &y, &skill_id, &skill_lv, &type, &flag); @@ -54790,11 +56915,11 @@ int HP_skill_addtimerskill(struct block_list *src, unsigned int tick, int target } return retVal___; } -int HP_skill_additional_effect(struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int attack_type, int dmg_lv, unsigned int tick) { +int HP_skill_additional_effect(struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int attack_type, int dmg_lv, int64 tick) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_skill_additional_effect_pre ) { - int (*preHookFunc) (struct block_list *src, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, int *attack_type, int *dmg_lv, unsigned int *tick); + int (*preHookFunc) (struct block_list *src, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, int *attack_type, int *dmg_lv, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_additional_effect_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_skill_additional_effect_pre[hIndex].func; retVal___ = preHookFunc(src, bl, &skill_id, &skill_lv, &attack_type, &dmg_lv, &tick); @@ -54808,7 +56933,7 @@ int HP_skill_additional_effect(struct block_list *src, struct block_list *bl, ui retVal___ = HPMHooks.source.skill.additional_effect(src, bl, skill_id, skill_lv, attack_type, dmg_lv, tick); } if( HPMHooks.count.HP_skill_additional_effect_post ) { - int (*postHookFunc) (int retVal___, struct block_list *src, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, int *attack_type, int *dmg_lv, unsigned int *tick); + int (*postHookFunc) (int retVal___, struct block_list *src, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, int *attack_type, int *dmg_lv, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_additional_effect_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_skill_additional_effect_post[hIndex].func; retVal___ = postHookFunc(retVal___, src, bl, &skill_id, &skill_lv, &attack_type, &dmg_lv, &tick); @@ -54816,11 +56941,11 @@ int HP_skill_additional_effect(struct block_list *src, struct block_list *bl, ui } return retVal___; } -int HP_skill_counter_additional_effect(struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int attack_type, unsigned int tick) { +int HP_skill_counter_additional_effect(struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int attack_type, int64 tick) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_skill_counter_additional_effect_pre ) { - int (*preHookFunc) (struct block_list *src, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, int *attack_type, unsigned int *tick); + int (*preHookFunc) (struct block_list *src, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, int *attack_type, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_counter_additional_effect_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_skill_counter_additional_effect_pre[hIndex].func; retVal___ = preHookFunc(src, bl, &skill_id, &skill_lv, &attack_type, &tick); @@ -54834,7 +56959,7 @@ int HP_skill_counter_additional_effect(struct block_list *src, struct block_list retVal___ = HPMHooks.source.skill.counter_additional_effect(src, bl, skill_id, skill_lv, attack_type, tick); } if( HPMHooks.count.HP_skill_counter_additional_effect_post ) { - int (*postHookFunc) (int retVal___, struct block_list *src, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, int *attack_type, unsigned int *tick); + int (*postHookFunc) (int retVal___, struct block_list *src, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, int *attack_type, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_counter_additional_effect_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_skill_counter_additional_effect_post[hIndex].func; retVal___ = postHookFunc(retVal___, src, bl, &skill_id, &skill_lv, &attack_type, &tick); @@ -55128,11 +57253,11 @@ int HP_skill_clear_group(struct block_list *bl, int flag) { } return retVal___; } -int HP_skill_unit_onplace(struct skill_unit *src, struct block_list *bl, unsigned int tick) { +int HP_skill_unit_onplace(struct skill_unit *src, struct block_list *bl, int64 tick) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_skill_unit_onplace_pre ) { - int (*preHookFunc) (struct skill_unit *src, struct block_list *bl, unsigned int *tick); + int (*preHookFunc) (struct skill_unit *src, struct block_list *bl, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_unit_onplace_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_skill_unit_onplace_pre[hIndex].func; retVal___ = preHookFunc(src, bl, &tick); @@ -55146,7 +57271,7 @@ int HP_skill_unit_onplace(struct skill_unit *src, struct block_list *bl, unsigne retVal___ = HPMHooks.source.skill.unit_onplace(src, bl, tick); } if( HPMHooks.count.HP_skill_unit_onplace_post ) { - int (*postHookFunc) (int retVal___, struct skill_unit *src, struct block_list *bl, unsigned int *tick); + int (*postHookFunc) (int retVal___, struct skill_unit *src, struct block_list *bl, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_unit_onplace_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_skill_unit_onplace_post[hIndex].func; retVal___ = postHookFunc(retVal___, src, bl, &tick); @@ -55154,11 +57279,11 @@ int HP_skill_unit_onplace(struct skill_unit *src, struct block_list *bl, unsigne } return retVal___; } -int HP_skill_unit_ondamaged(struct skill_unit *src, struct block_list *bl, int64 damage, unsigned int tick) { +int HP_skill_unit_ondamaged(struct skill_unit *src, struct block_list *bl, int64 damage, int64 tick) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_skill_unit_ondamaged_pre ) { - int (*preHookFunc) (struct skill_unit *src, struct block_list *bl, int64 *damage, unsigned int *tick); + int (*preHookFunc) (struct skill_unit *src, struct block_list *bl, int64 *damage, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_unit_ondamaged_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_skill_unit_ondamaged_pre[hIndex].func; retVal___ = preHookFunc(src, bl, &damage, &tick); @@ -55172,7 +57297,7 @@ int HP_skill_unit_ondamaged(struct skill_unit *src, struct block_list *bl, int64 retVal___ = HPMHooks.source.skill.unit_ondamaged(src, bl, damage, tick); } if( HPMHooks.count.HP_skill_unit_ondamaged_post ) { - int (*postHookFunc) (int retVal___, struct skill_unit *src, struct block_list *bl, int64 *damage, unsigned int *tick); + int (*postHookFunc) (int retVal___, struct skill_unit *src, struct block_list *bl, int64 *damage, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_unit_ondamaged_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_skill_unit_ondamaged_post[hIndex].func; retVal___ = postHookFunc(retVal___, src, bl, &damage, &tick); @@ -55415,11 +57540,11 @@ int HP_skill_check_pc_partner(struct map_session_data *sd, uint16 skill_id, uint } return retVal___; } -int HP_skill_unit_move(struct block_list *bl, unsigned int tick, int flag) { +int HP_skill_unit_move(struct block_list *bl, int64 tick, int flag) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_skill_unit_move_pre ) { - int (*preHookFunc) (struct block_list *bl, unsigned int *tick, int *flag); + int (*preHookFunc) (struct block_list *bl, int64 *tick, int *flag); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_unit_move_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_skill_unit_move_pre[hIndex].func; retVal___ = preHookFunc(bl, &tick, &flag); @@ -55433,7 +57558,7 @@ int HP_skill_unit_move(struct block_list *bl, unsigned int tick, int flag) { retVal___ = HPMHooks.source.skill.unit_move(bl, tick, flag); } if( HPMHooks.count.HP_skill_unit_move_post ) { - int (*postHookFunc) (int retVal___, struct block_list *bl, unsigned int *tick, int *flag); + int (*postHookFunc) (int retVal___, struct block_list *bl, int64 *tick, int *flag); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_unit_move_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_skill_unit_move_post[hIndex].func; retVal___ = postHookFunc(retVal___, bl, &tick, &flag); @@ -55441,11 +57566,11 @@ int HP_skill_unit_move(struct block_list *bl, unsigned int tick, int flag) { } return retVal___; } -int HP_skill_unit_onleft(uint16 skill_id, struct block_list *bl, unsigned int tick) { +int HP_skill_unit_onleft(uint16 skill_id, struct block_list *bl, int64 tick) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_skill_unit_onleft_pre ) { - int (*preHookFunc) (uint16 *skill_id, struct block_list *bl, unsigned int *tick); + int (*preHookFunc) (uint16 *skill_id, struct block_list *bl, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_unit_onleft_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_skill_unit_onleft_pre[hIndex].func; retVal___ = preHookFunc(&skill_id, bl, &tick); @@ -55459,7 +57584,7 @@ int HP_skill_unit_onleft(uint16 skill_id, struct block_list *bl, unsigned int ti retVal___ = HPMHooks.source.skill.unit_onleft(skill_id, bl, tick); } if( HPMHooks.count.HP_skill_unit_onleft_post ) { - int (*postHookFunc) (int retVal___, uint16 *skill_id, struct block_list *bl, unsigned int *tick); + int (*postHookFunc) (int retVal___, uint16 *skill_id, struct block_list *bl, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_unit_onleft_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_skill_unit_onleft_post[hIndex].func; retVal___ = postHookFunc(retVal___, &skill_id, bl, &tick); @@ -55467,11 +57592,11 @@ int HP_skill_unit_onleft(uint16 skill_id, struct block_list *bl, unsigned int ti } return retVal___; } -int HP_skill_unit_onout(struct skill_unit *src, struct block_list *bl, unsigned int tick) { +int HP_skill_unit_onout(struct skill_unit *src, struct block_list *bl, int64 tick) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_skill_unit_onout_pre ) { - int (*preHookFunc) (struct skill_unit *src, struct block_list *bl, unsigned int *tick); + int (*preHookFunc) (struct skill_unit *src, struct block_list *bl, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_unit_onout_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_skill_unit_onout_pre[hIndex].func; retVal___ = preHookFunc(src, bl, &tick); @@ -55485,7 +57610,7 @@ int HP_skill_unit_onout(struct skill_unit *src, struct block_list *bl, unsigned retVal___ = HPMHooks.source.skill.unit_onout(src, bl, tick); } if( HPMHooks.count.HP_skill_unit_onout_post ) { - int (*postHookFunc) (int retVal___, struct skill_unit *src, struct block_list *bl, unsigned int *tick); + int (*postHookFunc) (int retVal___, struct skill_unit *src, struct block_list *bl, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_unit_onout_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_skill_unit_onout_post[hIndex].func; retVal___ = postHookFunc(retVal___, src, bl, &tick); @@ -55545,10 +57670,10 @@ int HP_skill_sit(struct map_session_data *sd, int type) { } return retVal___; } -void HP_skill_brandishspear(struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, unsigned int tick, int flag) { +void HP_skill_brandishspear(struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag) { int hIndex = 0; if( HPMHooks.count.HP_skill_brandishspear_pre ) { - void (*preHookFunc) (struct block_list *src, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, unsigned int *tick, int *flag); + void (*preHookFunc) (struct block_list *src, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_brandishspear_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_skill_brandishspear_pre[hIndex].func; preHookFunc(src, bl, &skill_id, &skill_lv, &tick, &flag); @@ -55562,7 +57687,7 @@ void HP_skill_brandishspear(struct block_list *src, struct block_list *bl, uint1 HPMHooks.source.skill.brandishspear(src, bl, skill_id, skill_lv, tick, flag); } if( HPMHooks.count.HP_skill_brandishspear_post ) { - void (*postHookFunc) (struct block_list *src, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, unsigned int *tick, int *flag); + void (*postHookFunc) (struct block_list *src, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_brandishspear_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_skill_brandishspear_post[hIndex].func; postHookFunc(src, bl, &skill_id, &skill_lv, &tick, &flag); @@ -55937,11 +58062,11 @@ int HP_skill_arrow_create(struct map_session_data *sd, int nameid) { } return retVal___; } -int HP_skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, unsigned int tick, int flag) { +int HP_skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_skill_castend_nodamage_id_pre ) { - int (*preHookFunc) (struct block_list *src, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, unsigned int *tick, int *flag); + int (*preHookFunc) (struct block_list *src, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_castend_nodamage_id_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_skill_castend_nodamage_id_pre[hIndex].func; retVal___ = preHookFunc(src, bl, &skill_id, &skill_lv, &tick, &flag); @@ -55955,7 +58080,7 @@ int HP_skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, retVal___ = HPMHooks.source.skill.castend_nodamage_id(src, bl, skill_id, skill_lv, tick, flag); } if( HPMHooks.count.HP_skill_castend_nodamage_id_post ) { - int (*postHookFunc) (int retVal___, struct block_list *src, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, unsigned int *tick, int *flag); + int (*postHookFunc) (int retVal___, struct block_list *src, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_castend_nodamage_id_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_skill_castend_nodamage_id_post[hIndex].func; retVal___ = postHookFunc(retVal___, src, bl, &skill_id, &skill_lv, &tick, &flag); @@ -55963,11 +58088,11 @@ int HP_skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, } return retVal___; } -int HP_skill_castend_damage_id(struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, unsigned int tick, int flag) { +int HP_skill_castend_damage_id(struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_skill_castend_damage_id_pre ) { - int (*preHookFunc) (struct block_list *src, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, unsigned int *tick, int *flag); + int (*preHookFunc) (struct block_list *src, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_castend_damage_id_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_skill_castend_damage_id_pre[hIndex].func; retVal___ = preHookFunc(src, bl, &skill_id, &skill_lv, &tick, &flag); @@ -55981,7 +58106,7 @@ int HP_skill_castend_damage_id(struct block_list *src, struct block_list *bl, ui retVal___ = HPMHooks.source.skill.castend_damage_id(src, bl, skill_id, skill_lv, tick, flag); } if( HPMHooks.count.HP_skill_castend_damage_id_post ) { - int (*postHookFunc) (int retVal___, struct block_list *src, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, unsigned int *tick, int *flag); + int (*postHookFunc) (int retVal___, struct block_list *src, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_castend_damage_id_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_skill_castend_damage_id_post[hIndex].func; retVal___ = postHookFunc(retVal___, src, bl, &skill_id, &skill_lv, &tick, &flag); @@ -55989,11 +58114,11 @@ int HP_skill_castend_damage_id(struct block_list *src, struct block_list *bl, ui } return retVal___; } -int HP_skill_castend_pos2(struct block_list *src, int x, int y, uint16 skill_id, uint16 skill_lv, unsigned int tick, int flag) { +int HP_skill_castend_pos2(struct block_list *src, int x, int y, uint16 skill_id, uint16 skill_lv, int64 tick, int flag) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_skill_castend_pos2_pre ) { - int (*preHookFunc) (struct block_list *src, int *x, int *y, uint16 *skill_id, uint16 *skill_lv, unsigned int *tick, int *flag); + int (*preHookFunc) (struct block_list *src, int *x, int *y, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_castend_pos2_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_skill_castend_pos2_pre[hIndex].func; retVal___ = preHookFunc(src, &x, &y, &skill_id, &skill_lv, &tick, &flag); @@ -56007,7 +58132,7 @@ int HP_skill_castend_pos2(struct block_list *src, int x, int y, uint16 skill_id, retVal___ = HPMHooks.source.skill.castend_pos2(src, x, y, skill_id, skill_lv, tick, flag); } if( HPMHooks.count.HP_skill_castend_pos2_post ) { - int (*postHookFunc) (int retVal___, struct block_list *src, int *x, int *y, uint16 *skill_id, uint16 *skill_lv, unsigned int *tick, int *flag); + int (*postHookFunc) (int retVal___, struct block_list *src, int *x, int *y, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_castend_pos2_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_skill_castend_pos2_post[hIndex].func; retVal___ = postHookFunc(retVal___, src, &x, &y, &skill_id, &skill_lv, &tick, &flag); @@ -56015,14 +58140,14 @@ int HP_skill_castend_pos2(struct block_list *src, int x, int y, uint16 skill_id, } return retVal___; } -int HP_skill_blockpc_start(struct map_session_data *sd, uint16 skill_id, int tick, bool load) { +int HP_skill_blockpc_start(struct map_session_data *sd, uint16 skill_id, int tick) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_skill_blockpc_start_pre ) { - int (*preHookFunc) (struct map_session_data *sd, uint16 *skill_id, int *tick, bool *load); + int (*preHookFunc) (struct map_session_data *sd, uint16 *skill_id, int *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_blockpc_start_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_skill_blockpc_start_pre[hIndex].func; - retVal___ = preHookFunc(sd, &skill_id, &tick, &load); + retVal___ = preHookFunc(sd, &skill_id, &tick); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -56030,13 +58155,13 @@ int HP_skill_blockpc_start(struct map_session_data *sd, uint16 skill_id, int tic } } { - retVal___ = HPMHooks.source.skill.blockpc_start(sd, skill_id, tick, load); + retVal___ = HPMHooks.source.skill.blockpc_start(sd, skill_id, tick); } if( HPMHooks.count.HP_skill_blockpc_start_post ) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd, uint16 *skill_id, int *tick, bool *load); + int (*postHookFunc) (int retVal___, struct map_session_data *sd, uint16 *skill_id, int *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_blockpc_start_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_skill_blockpc_start_post[hIndex].func; - retVal___ = postHookFunc(retVal___, sd, &skill_id, &tick, &load); + retVal___ = postHookFunc(retVal___, sd, &skill_id, &tick); } } return retVal___; @@ -56093,11 +58218,11 @@ int HP_skill_blockmerc_start(struct mercenary_data *md, uint16 skill_id, int tic } return retVal___; } -int HP_skill_attack(int attack_type, struct block_list *src, struct block_list *dsrc, struct block_list *bl, uint16 skill_id, uint16 skill_lv, unsigned int tick, int flag) { +int HP_skill_attack(int attack_type, struct block_list *src, struct block_list *dsrc, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_skill_attack_pre ) { - int (*preHookFunc) (int *attack_type, struct block_list *src, struct block_list *dsrc, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, unsigned int *tick, int *flag); + int (*preHookFunc) (int *attack_type, struct block_list *src, struct block_list *dsrc, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_attack_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_skill_attack_pre[hIndex].func; retVal___ = preHookFunc(&attack_type, src, dsrc, bl, &skill_id, &skill_lv, &tick, &flag); @@ -56111,7 +58236,7 @@ int HP_skill_attack(int attack_type, struct block_list *src, struct block_list * retVal___ = HPMHooks.source.skill.attack(attack_type, src, dsrc, bl, skill_id, skill_lv, tick, flag); } if( HPMHooks.count.HP_skill_attack_post ) { - int (*postHookFunc) (int retVal___, int *attack_type, struct block_list *src, struct block_list *dsrc, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, unsigned int *tick, int *flag); + int (*postHookFunc) (int retVal___, int *attack_type, struct block_list *src, struct block_list *dsrc, struct block_list *bl, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_attack_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_skill_attack_post[hIndex].func; retVal___ = postHookFunc(retVal___, &attack_type, src, dsrc, bl, &skill_id, &skill_lv, &tick, &flag); @@ -56183,11 +58308,11 @@ int HP_skill_area_sub(struct block_list *bl, va_list ap) { } return retVal___; } -int HP_skill_area_sub_count(struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, unsigned int tick, int flag) { +int HP_skill_area_sub_count(struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int64 tick, int flag) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_skill_area_sub_count_pre ) { - int (*preHookFunc) (struct block_list *src, struct block_list *target, uint16 *skill_id, uint16 *skill_lv, unsigned int *tick, int *flag); + int (*preHookFunc) (struct block_list *src, struct block_list *target, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_area_sub_count_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_skill_area_sub_count_pre[hIndex].func; retVal___ = preHookFunc(src, target, &skill_id, &skill_lv, &tick, &flag); @@ -56201,7 +58326,7 @@ int HP_skill_area_sub_count(struct block_list *src, struct block_list *target, u retVal___ = HPMHooks.source.skill.area_sub_count(src, target, skill_id, skill_lv, tick, flag); } if( HPMHooks.count.HP_skill_area_sub_count_post ) { - int (*postHookFunc) (int retVal___, struct block_list *src, struct block_list *target, uint16 *skill_id, uint16 *skill_lv, unsigned int *tick, int *flag); + int (*postHookFunc) (int retVal___, struct block_list *src, struct block_list *target, uint16 *skill_id, uint16 *skill_lv, int64 *tick, int *flag); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_area_sub_count_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_skill_area_sub_count_post[hIndex].func; retVal___ = postHookFunc(retVal___, src, target, &skill_id, &skill_lv, &tick, &flag); @@ -56376,11 +58501,11 @@ int HP_skill_magic_reflect(struct block_list *src, struct block_list *bl, int ty } return retVal___; } -int HP_skill_onskillusage(struct map_session_data *sd, struct block_list *bl, uint16 skill_id, unsigned int tick) { +int HP_skill_onskillusage(struct map_session_data *sd, struct block_list *bl, uint16 skill_id, int64 tick) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_skill_onskillusage_pre ) { - int (*preHookFunc) (struct map_session_data *sd, struct block_list *bl, uint16 *skill_id, unsigned int *tick); + int (*preHookFunc) (struct map_session_data *sd, struct block_list *bl, uint16 *skill_id, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_onskillusage_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_skill_onskillusage_pre[hIndex].func; retVal___ = preHookFunc(sd, bl, &skill_id, &tick); @@ -56394,7 +58519,7 @@ int HP_skill_onskillusage(struct map_session_data *sd, struct block_list *bl, ui retVal___ = HPMHooks.source.skill.onskillusage(sd, bl, skill_id, tick); } if( HPMHooks.count.HP_skill_onskillusage_post ) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd, struct block_list *bl, uint16 *skill_id, unsigned int *tick); + int (*postHookFunc) (int retVal___, struct map_session_data *sd, struct block_list *bl, uint16 *skill_id, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_onskillusage_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_skill_onskillusage_post[hIndex].func; retVal___ = postHookFunc(retVal___, sd, bl, &skill_id, &tick); @@ -56434,11 +58559,11 @@ int HP_skill_cell_overlap(struct block_list *bl, va_list ap) { } return retVal___; } -int HP_skill_timerskill(int tid, unsigned int tick, int id, intptr_t data) { +int HP_skill_timerskill(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_skill_timerskill_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_timerskill_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_skill_timerskill_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -56452,7 +58577,7 @@ int HP_skill_timerskill(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.skill.timerskill(tid, tick, id, data); } if( HPMHooks.count.HP_skill_timerskill_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_timerskill_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_skill_timerskill_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -56820,11 +58945,11 @@ int HP_skill_icewall_block(struct block_list *bl, va_list ap) { } return retVal___; } -struct skill_unit_group_tickset* HP_skill_unitgrouptickset_search(struct block_list *bl, struct skill_unit_group *group, int tick) { +struct skill_unit_group_tickset* HP_skill_unitgrouptickset_search(struct block_list *bl, struct skill_unit_group *group, int64 tick) { int hIndex = 0; struct skill_unit_group_tickset* retVal___ = NULL; if( HPMHooks.count.HP_skill_unitgrouptickset_search_pre ) { - struct skill_unit_group_tickset* (*preHookFunc) (struct block_list *bl, struct skill_unit_group *group, int *tick); + struct skill_unit_group_tickset* (*preHookFunc) (struct block_list *bl, struct skill_unit_group *group, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_unitgrouptickset_search_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_skill_unitgrouptickset_search_pre[hIndex].func; retVal___ = preHookFunc(bl, group, &tick); @@ -56838,7 +58963,7 @@ struct skill_unit_group_tickset* HP_skill_unitgrouptickset_search(struct block_l retVal___ = HPMHooks.source.skill.unitgrouptickset_search(bl, group, tick); } if( HPMHooks.count.HP_skill_unitgrouptickset_search_post ) { - struct skill_unit_group_tickset* (*postHookFunc) (struct skill_unit_group_tickset* retVal___, struct block_list *bl, struct skill_unit_group *group, int *tick); + struct skill_unit_group_tickset* (*postHookFunc) (struct skill_unit_group_tickset* retVal___, struct block_list *bl, struct skill_unit_group *group, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_unitgrouptickset_search_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_skill_unitgrouptickset_search_post[hIndex].func; retVal___ = postHookFunc(retVal___, bl, group, &tick); @@ -57133,11 +59258,11 @@ void HP_skill_unitsetmapcell(struct skill_unit *src, uint16 skill_id, uint16 ski } return; } -int HP_skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, unsigned int tick) { +int HP_skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int64 tick) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_skill_unit_onplace_timer_pre ) { - int (*preHookFunc) (struct skill_unit *src, struct block_list *bl, unsigned int *tick); + int (*preHookFunc) (struct skill_unit *src, struct block_list *bl, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_unit_onplace_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_skill_unit_onplace_timer_pre[hIndex].func; retVal___ = preHookFunc(src, bl, &tick); @@ -57151,7 +59276,7 @@ int HP_skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, u retVal___ = HPMHooks.source.skill.unit_onplace_timer(src, bl, tick); } if( HPMHooks.count.HP_skill_unit_onplace_timer_post ) { - int (*postHookFunc) (int retVal___, struct skill_unit *src, struct block_list *bl, unsigned int *tick); + int (*postHookFunc) (int retVal___, struct skill_unit *src, struct block_list *bl, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_unit_onplace_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_skill_unit_onplace_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, src, bl, &tick); @@ -57255,11 +59380,11 @@ int HP_skill_unit_move_sub(struct block_list *bl, va_list ap) { } return retVal___; } -int HP_skill_blockpc_end(int tid, unsigned int tick, int id, intptr_t data) { +int HP_skill_blockpc_end(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_skill_blockpc_end_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_blockpc_end_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_skill_blockpc_end_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -57273,7 +59398,7 @@ int HP_skill_blockpc_end(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.skill.blockpc_end(tid, tick, id, data); } if( HPMHooks.count.HP_skill_blockpc_end_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_blockpc_end_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_skill_blockpc_end_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -57281,11 +59406,11 @@ int HP_skill_blockpc_end(int tid, unsigned int tick, int id, intptr_t data) { } return retVal___; } -int HP_skill_blockhomun_end(int tid, unsigned int tick, int id, intptr_t data) { +int HP_skill_blockhomun_end(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_skill_blockhomun_end_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_blockhomun_end_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_skill_blockhomun_end_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -57299,7 +59424,7 @@ int HP_skill_blockhomun_end(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.skill.blockhomun_end(tid, tick, id, data); } if( HPMHooks.count.HP_skill_blockhomun_end_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_blockhomun_end_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_skill_blockhomun_end_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -57307,11 +59432,11 @@ int HP_skill_blockhomun_end(int tid, unsigned int tick, int id, intptr_t data) { } return retVal___; } -int HP_skill_blockmerc_end(int tid, unsigned int tick, int id, intptr_t data) { +int HP_skill_blockmerc_end(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_skill_blockmerc_end_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_blockmerc_end_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_skill_blockmerc_end_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -57325,7 +59450,7 @@ int HP_skill_blockmerc_end(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.skill.blockmerc_end(tid, tick, id, data); } if( HPMHooks.count.HP_skill_blockmerc_end_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_blockmerc_end_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_skill_blockmerc_end_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -57359,11 +59484,11 @@ int HP_skill_split_atoi(char *str, int *val) { } return retVal___; } -int HP_skill_unit_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_skill_unit_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_skill_unit_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_unit_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_skill_unit_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -57377,7 +59502,7 @@ int HP_skill_unit_timer(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.skill.unit_timer(tid, tick, id, data); } if( HPMHooks.count.HP_skill_unit_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_unit_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_skill_unit_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -58146,16 +60271,14 @@ void HP_skill_cooldown_save(struct map_session_data *sd) { } return; } -int HP_skill_maelstrom_suction(struct block_list *bl, va_list ap) { +int HP_skill_get_new_group_id(void) { int hIndex = 0; int retVal___ = 0; - if( HPMHooks.count.HP_skill_maelstrom_suction_pre ) { - int (*preHookFunc) (struct block_list *bl, va_list ap); - for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_maelstrom_suction_pre; hIndex++ ) { - va_list ap___copy; va_copy(ap___copy, ap); - preHookFunc = HPMHooks.list.HP_skill_maelstrom_suction_pre[hIndex].func; - retVal___ = preHookFunc(bl, ap___copy); - va_end(ap___copy); + if( HPMHooks.count.HP_skill_get_new_group_id_pre ) { + int (*preHookFunc) (void); + for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_get_new_group_id_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_skill_get_new_group_id_pre[hIndex].func; + retVal___ = preHookFunc(); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -58163,29 +60286,25 @@ int HP_skill_maelstrom_suction(struct block_list *bl, va_list ap) { } } { - va_list ap___copy; va_copy(ap___copy, ap); - retVal___ = HPMHooks.source.skill.maelstrom_suction(bl, ap___copy); - va_end(ap___copy); + retVal___ = HPMHooks.source.skill.get_new_group_id(); } - if( HPMHooks.count.HP_skill_maelstrom_suction_post ) { - int (*postHookFunc) (int retVal___, struct block_list *bl, va_list ap); - for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_maelstrom_suction_post; hIndex++ ) { - va_list ap___copy; va_copy(ap___copy, ap); - postHookFunc = HPMHooks.list.HP_skill_maelstrom_suction_post[hIndex].func; - retVal___ = postHookFunc(retVal___, bl, ap___copy); - va_end(ap___copy); + if( HPMHooks.count.HP_skill_get_new_group_id_post ) { + int (*postHookFunc) (int retVal___); + for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_get_new_group_id_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_skill_get_new_group_id_post[hIndex].func; + retVal___ = postHookFunc(retVal___); } } return retVal___; } -int HP_skill_get_new_group_id(void) { +bool HP_skill_check_shadowform(struct block_list *bl, int64 damage, int hit) { int hIndex = 0; - int retVal___ = 0; - if( HPMHooks.count.HP_skill_get_new_group_id_pre ) { - int (*preHookFunc) (void); - for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_get_new_group_id_pre; hIndex++ ) { - preHookFunc = HPMHooks.list.HP_skill_get_new_group_id_pre[hIndex].func; - retVal___ = preHookFunc(); + bool retVal___ = false; + if( HPMHooks.count.HP_skill_check_shadowform_pre ) { + bool (*preHookFunc) (struct block_list *bl, int64 *damage, int *hit); + for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_check_shadowform_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_skill_check_shadowform_pre[hIndex].func; + retVal___ = preHookFunc(bl, &damage, &hit); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -58193,26 +60312,26 @@ int HP_skill_get_new_group_id(void) { } } { - retVal___ = HPMHooks.source.skill.get_new_group_id(); + retVal___ = HPMHooks.source.skill.check_shadowform(bl, damage, hit); } - if( HPMHooks.count.HP_skill_get_new_group_id_post ) { - int (*postHookFunc) (int retVal___); - for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_get_new_group_id_post; hIndex++ ) { - postHookFunc = HPMHooks.list.HP_skill_get_new_group_id_post[hIndex].func; - retVal___ = postHookFunc(retVal___); + if( HPMHooks.count.HP_skill_check_shadowform_post ) { + bool (*postHookFunc) (bool retVal___, struct block_list *bl, int64 *damage, int *hit); + for(hIndex = 0; hIndex < HPMHooks.count.HP_skill_check_shadowform_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_skill_check_shadowform_post[hIndex].func; + retVal___ = postHookFunc(retVal___, bl, &damage, &hit); } } return retVal___; } /* status */ -int HP_status_init(void) { +int HP_status_init(bool minimal) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_status_init_pre ) { - int (*preHookFunc) (void); + int (*preHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_status_init_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_status_init_pre[hIndex].func; - retVal___ = preHookFunc(); + retVal___ = preHookFunc(&minimal); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -58220,13 +60339,13 @@ int HP_status_init(void) { } } { - retVal___ = HPMHooks.source.status.init(); + retVal___ = HPMHooks.source.status.init(minimal); } if( HPMHooks.count.HP_status_init_post ) { - int (*postHookFunc) (int retVal___); + int (*postHookFunc) (int retVal___, bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_status_init_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_status_init_post[hIndex].func; - retVal___ = postHookFunc(retVal___); + retVal___ = postHookFunc(retVal___, &minimal); } } return retVal___; @@ -58594,6 +60713,32 @@ int HP_status_revive(struct block_list *bl, unsigned char per_hp, unsigned char } return retVal___; } +int HP_status_fixed_revive(struct block_list *bl, unsigned int per_hp, unsigned int per_sp) { + int hIndex = 0; + int retVal___ = 0; + if( HPMHooks.count.HP_status_fixed_revive_pre ) { + int (*preHookFunc) (struct block_list *bl, unsigned int *per_hp, unsigned int *per_sp); + for(hIndex = 0; hIndex < HPMHooks.count.HP_status_fixed_revive_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_status_fixed_revive_pre[hIndex].func; + retVal___ = preHookFunc(bl, &per_hp, &per_sp); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.status.fixed_revive(bl, per_hp, per_sp); + } + if( HPMHooks.count.HP_status_fixed_revive_post ) { + int (*postHookFunc) (int retVal___, struct block_list *bl, unsigned int *per_hp, unsigned int *per_sp); + for(hIndex = 0; hIndex < HPMHooks.count.HP_status_fixed_revive_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_status_fixed_revive_post[hIndex].func; + retVal___ = postHookFunc(retVal___, bl, &per_hp, &per_sp); + } + } + return retVal___; +} struct regen_data* HP_status_get_regen_data(struct block_list *bl) { int hIndex = 0; struct regen_data* retVal___ = NULL; @@ -59112,14 +61257,14 @@ int HP_status_isimmune(struct block_list *bl) { } return retVal___; } -int HP_status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int tick, int flag) { +int HP_status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int tick, int flag) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_status_get_sc_def_pre ) { - int (*preHookFunc) (struct block_list *bl, enum sc_type *type, int *rate, int *tick, int *flag); + int (*preHookFunc) (struct block_list *src, struct block_list *bl, enum sc_type *type, int *rate, int *tick, int *flag); for(hIndex = 0; hIndex < HPMHooks.count.HP_status_get_sc_def_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_status_get_sc_def_pre[hIndex].func; - retVal___ = preHookFunc(bl, &type, &rate, &tick, &flag); + retVal___ = preHookFunc(src, bl, &type, &rate, &tick, &flag); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -59127,25 +61272,25 @@ int HP_status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int } } { - retVal___ = HPMHooks.source.status.get_sc_def(bl, type, rate, tick, flag); + retVal___ = HPMHooks.source.status.get_sc_def(src, bl, type, rate, tick, flag); } if( HPMHooks.count.HP_status_get_sc_def_post ) { - int (*postHookFunc) (int retVal___, struct block_list *bl, enum sc_type *type, int *rate, int *tick, int *flag); + int (*postHookFunc) (int retVal___, struct block_list *src, struct block_list *bl, enum sc_type *type, int *rate, int *tick, int *flag); for(hIndex = 0; hIndex < HPMHooks.count.HP_status_get_sc_def_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_status_get_sc_def_post[hIndex].func; - retVal___ = postHookFunc(retVal___, bl, &type, &rate, &tick, &flag); + retVal___ = postHookFunc(retVal___, src, bl, &type, &rate, &tick, &flag); } } return retVal___; } -int HP_status_change_start(struct block_list *bl, enum sc_type type, int rate, int val1, int val2, int val3, int val4, int tick, int flag) { +int HP_status_change_start(struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int val1, int val2, int val3, int val4, int tick, int flag) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_status_change_start_pre ) { - int (*preHookFunc) (struct block_list *bl, enum sc_type *type, int *rate, int *val1, int *val2, int *val3, int *val4, int *tick, int *flag); + int (*preHookFunc) (struct block_list *src, struct block_list *bl, enum sc_type *type, int *rate, int *val1, int *val2, int *val3, int *val4, int *tick, int *flag); for(hIndex = 0; hIndex < HPMHooks.count.HP_status_change_start_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_status_change_start_pre[hIndex].func; - retVal___ = preHookFunc(bl, &type, &rate, &val1, &val2, &val3, &val4, &tick, &flag); + retVal___ = preHookFunc(src, bl, &type, &rate, &val1, &val2, &val3, &val4, &tick, &flag); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -59153,13 +61298,13 @@ int HP_status_change_start(struct block_list *bl, enum sc_type type, int rate, i } } { - retVal___ = HPMHooks.source.status.change_start(bl, type, rate, val1, val2, val3, val4, tick, flag); + retVal___ = HPMHooks.source.status.change_start(src, bl, type, rate, val1, val2, val3, val4, tick, flag); } if( HPMHooks.count.HP_status_change_start_post ) { - int (*postHookFunc) (int retVal___, struct block_list *bl, enum sc_type *type, int *rate, int *val1, int *val2, int *val3, int *val4, int *tick, int *flag); + int (*postHookFunc) (int retVal___, struct block_list *src, struct block_list *bl, enum sc_type *type, int *rate, int *val1, int *val2, int *val3, int *val4, int *tick, int *flag); for(hIndex = 0; hIndex < HPMHooks.count.HP_status_change_start_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_status_change_start_post[hIndex].func; - retVal___ = postHookFunc(retVal___, bl, &type, &rate, &val1, &val2, &val3, &val4, &tick, &flag); + retVal___ = postHookFunc(retVal___, src, bl, &type, &rate, &val1, &val2, &val3, &val4, &tick, &flag); } } return retVal___; @@ -59190,11 +61335,11 @@ int HP_status_change_end_(struct block_list *bl, enum sc_type type, int tid, con } return retVal___; } -int HP_status_kaahi_heal_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_status_kaahi_heal_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_status_kaahi_heal_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_status_kaahi_heal_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_status_kaahi_heal_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -59208,7 +61353,7 @@ int HP_status_kaahi_heal_timer(int tid, unsigned int tick, int id, intptr_t data retVal___ = HPMHooks.source.status.kaahi_heal_timer(tid, tick, id, data); } if( HPMHooks.count.HP_status_kaahi_heal_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_status_kaahi_heal_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_status_kaahi_heal_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -59216,11 +61361,11 @@ int HP_status_kaahi_heal_timer(int tid, unsigned int tick, int id, intptr_t data } return retVal___; } -int HP_status_change_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_status_change_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_status_change_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_status_change_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_status_change_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -59234,7 +61379,7 @@ int HP_status_change_timer(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.status.change_timer(tid, tick, id, data); } if( HPMHooks.count.HP_status_change_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_status_change_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_status_change_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -59326,13 +61471,13 @@ int HP_status_change_clear_buffs(struct block_list *bl, int type) { } return retVal___; } -void HP_status_calc_bl_(struct block_list *bl, enum scb_flag flag, bool first) { +void HP_status_calc_bl_(struct block_list *bl, enum scb_flag flag, enum e_status_calc_opt opt) { int hIndex = 0; if( HPMHooks.count.HP_status_calc_bl__pre ) { - void (*preHookFunc) (struct block_list *bl, enum scb_flag *flag, bool *first); + void (*preHookFunc) (struct block_list *bl, enum scb_flag *flag, enum e_status_calc_opt *opt); for(hIndex = 0; hIndex < HPMHooks.count.HP_status_calc_bl__pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_status_calc_bl__pre[hIndex].func; - preHookFunc(bl, &flag, &first); + preHookFunc(bl, &flag, &opt); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -59340,25 +61485,25 @@ void HP_status_calc_bl_(struct block_list *bl, enum scb_flag flag, bool first) { } } { - HPMHooks.source.status.calc_bl_(bl, flag, first); + HPMHooks.source.status.calc_bl_(bl, flag, opt); } if( HPMHooks.count.HP_status_calc_bl__post ) { - void (*postHookFunc) (struct block_list *bl, enum scb_flag *flag, bool *first); + void (*postHookFunc) (struct block_list *bl, enum scb_flag *flag, enum e_status_calc_opt *opt); for(hIndex = 0; hIndex < HPMHooks.count.HP_status_calc_bl__post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_status_calc_bl__post[hIndex].func; - postHookFunc(bl, &flag, &first); + postHookFunc(bl, &flag, &opt); } } return; } -int HP_status_calc_mob_(struct mob_data *md, bool first) { +int HP_status_calc_mob_(struct mob_data *md, enum e_status_calc_opt opt) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_status_calc_mob__pre ) { - int (*preHookFunc) (struct mob_data *md, bool *first); + int (*preHookFunc) (struct mob_data *md, enum e_status_calc_opt *opt); for(hIndex = 0; hIndex < HPMHooks.count.HP_status_calc_mob__pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_status_calc_mob__pre[hIndex].func; - retVal___ = preHookFunc(md, &first); + retVal___ = preHookFunc(md, &opt); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -59366,25 +61511,25 @@ int HP_status_calc_mob_(struct mob_data *md, bool first) { } } { - retVal___ = HPMHooks.source.status.calc_mob_(md, first); + retVal___ = HPMHooks.source.status.calc_mob_(md, opt); } if( HPMHooks.count.HP_status_calc_mob__post ) { - int (*postHookFunc) (int retVal___, struct mob_data *md, bool *first); + int (*postHookFunc) (int retVal___, struct mob_data *md, enum e_status_calc_opt *opt); for(hIndex = 0; hIndex < HPMHooks.count.HP_status_calc_mob__post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_status_calc_mob__post[hIndex].func; - retVal___ = postHookFunc(retVal___, md, &first); + retVal___ = postHookFunc(retVal___, md, &opt); } } return retVal___; } -int HP_status_calc_pet_(struct pet_data *pd, bool first) { +int HP_status_calc_pet_(struct pet_data *pd, enum e_status_calc_opt opt) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_status_calc_pet__pre ) { - int (*preHookFunc) (struct pet_data *pd, bool *first); + int (*preHookFunc) (struct pet_data *pd, enum e_status_calc_opt *opt); for(hIndex = 0; hIndex < HPMHooks.count.HP_status_calc_pet__pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_status_calc_pet__pre[hIndex].func; - retVal___ = preHookFunc(pd, &first); + retVal___ = preHookFunc(pd, &opt); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -59392,25 +61537,25 @@ int HP_status_calc_pet_(struct pet_data *pd, bool first) { } } { - retVal___ = HPMHooks.source.status.calc_pet_(pd, first); + retVal___ = HPMHooks.source.status.calc_pet_(pd, opt); } if( HPMHooks.count.HP_status_calc_pet__post ) { - int (*postHookFunc) (int retVal___, struct pet_data *pd, bool *first); + int (*postHookFunc) (int retVal___, struct pet_data *pd, enum e_status_calc_opt *opt); for(hIndex = 0; hIndex < HPMHooks.count.HP_status_calc_pet__post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_status_calc_pet__post[hIndex].func; - retVal___ = postHookFunc(retVal___, pd, &first); + retVal___ = postHookFunc(retVal___, pd, &opt); } } return retVal___; } -int HP_status_calc_pc_(struct map_session_data *sd, bool first) { +int HP_status_calc_pc_(struct map_session_data *sd, enum e_status_calc_opt opt) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_status_calc_pc__pre ) { - int (*preHookFunc) (struct map_session_data *sd, bool *first); + int (*preHookFunc) (struct map_session_data *sd, enum e_status_calc_opt *opt); for(hIndex = 0; hIndex < HPMHooks.count.HP_status_calc_pc__pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_status_calc_pc__pre[hIndex].func; - retVal___ = preHookFunc(sd, &first); + retVal___ = preHookFunc(sd, &opt); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -59418,25 +61563,25 @@ int HP_status_calc_pc_(struct map_session_data *sd, bool first) { } } { - retVal___ = HPMHooks.source.status.calc_pc_(sd, first); + retVal___ = HPMHooks.source.status.calc_pc_(sd, opt); } if( HPMHooks.count.HP_status_calc_pc__post ) { - int (*postHookFunc) (int retVal___, struct map_session_data *sd, bool *first); + int (*postHookFunc) (int retVal___, struct map_session_data *sd, enum e_status_calc_opt *opt); for(hIndex = 0; hIndex < HPMHooks.count.HP_status_calc_pc__post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_status_calc_pc__post[hIndex].func; - retVal___ = postHookFunc(retVal___, sd, &first); + retVal___ = postHookFunc(retVal___, sd, &opt); } } return retVal___; } -int HP_status_calc_homunculus_(struct homun_data *hd, bool first) { +int HP_status_calc_homunculus_(struct homun_data *hd, enum e_status_calc_opt opt) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_status_calc_homunculus__pre ) { - int (*preHookFunc) (struct homun_data *hd, bool *first); + int (*preHookFunc) (struct homun_data *hd, enum e_status_calc_opt *opt); for(hIndex = 0; hIndex < HPMHooks.count.HP_status_calc_homunculus__pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_status_calc_homunculus__pre[hIndex].func; - retVal___ = preHookFunc(hd, &first); + retVal___ = preHookFunc(hd, &opt); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -59444,25 +61589,25 @@ int HP_status_calc_homunculus_(struct homun_data *hd, bool first) { } } { - retVal___ = HPMHooks.source.status.calc_homunculus_(hd, first); + retVal___ = HPMHooks.source.status.calc_homunculus_(hd, opt); } if( HPMHooks.count.HP_status_calc_homunculus__post ) { - int (*postHookFunc) (int retVal___, struct homun_data *hd, bool *first); + int (*postHookFunc) (int retVal___, struct homun_data *hd, enum e_status_calc_opt *opt); for(hIndex = 0; hIndex < HPMHooks.count.HP_status_calc_homunculus__post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_status_calc_homunculus__post[hIndex].func; - retVal___ = postHookFunc(retVal___, hd, &first); + retVal___ = postHookFunc(retVal___, hd, &opt); } } return retVal___; } -int HP_status_calc_mercenary_(struct mercenary_data *md, bool first) { +int HP_status_calc_mercenary_(struct mercenary_data *md, enum e_status_calc_opt opt) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_status_calc_mercenary__pre ) { - int (*preHookFunc) (struct mercenary_data *md, bool *first); + int (*preHookFunc) (struct mercenary_data *md, enum e_status_calc_opt *opt); for(hIndex = 0; hIndex < HPMHooks.count.HP_status_calc_mercenary__pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_status_calc_mercenary__pre[hIndex].func; - retVal___ = preHookFunc(md, &first); + retVal___ = preHookFunc(md, &opt); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -59470,25 +61615,25 @@ int HP_status_calc_mercenary_(struct mercenary_data *md, bool first) { } } { - retVal___ = HPMHooks.source.status.calc_mercenary_(md, first); + retVal___ = HPMHooks.source.status.calc_mercenary_(md, opt); } if( HPMHooks.count.HP_status_calc_mercenary__post ) { - int (*postHookFunc) (int retVal___, struct mercenary_data *md, bool *first); + int (*postHookFunc) (int retVal___, struct mercenary_data *md, enum e_status_calc_opt *opt); for(hIndex = 0; hIndex < HPMHooks.count.HP_status_calc_mercenary__post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_status_calc_mercenary__post[hIndex].func; - retVal___ = postHookFunc(retVal___, md, &first); + retVal___ = postHookFunc(retVal___, md, &opt); } } return retVal___; } -int HP_status_calc_elemental_(struct elemental_data *ed, bool first) { +int HP_status_calc_elemental_(struct elemental_data *ed, enum e_status_calc_opt opt) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_status_calc_elemental__pre ) { - int (*preHookFunc) (struct elemental_data *ed, bool *first); + int (*preHookFunc) (struct elemental_data *ed, enum e_status_calc_opt *opt); for(hIndex = 0; hIndex < HPMHooks.count.HP_status_calc_elemental__pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_status_calc_elemental__pre[hIndex].func; - retVal___ = preHookFunc(ed, &first); + retVal___ = preHookFunc(ed, &opt); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -59496,24 +61641,24 @@ int HP_status_calc_elemental_(struct elemental_data *ed, bool first) { } } { - retVal___ = HPMHooks.source.status.calc_elemental_(ed, first); + retVal___ = HPMHooks.source.status.calc_elemental_(ed, opt); } if( HPMHooks.count.HP_status_calc_elemental__post ) { - int (*postHookFunc) (int retVal___, struct elemental_data *ed, bool *first); + int (*postHookFunc) (int retVal___, struct elemental_data *ed, enum e_status_calc_opt *opt); for(hIndex = 0; hIndex < HPMHooks.count.HP_status_calc_elemental__post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_status_calc_elemental__post[hIndex].func; - retVal___ = postHookFunc(retVal___, ed, &first); + retVal___ = postHookFunc(retVal___, ed, &opt); } } return retVal___; } -void HP_status_calc_misc(struct block_list *bl, struct status_data *status, int level) { +void HP_status_calc_misc(struct block_list *bl, struct status_data *st, int level) { int hIndex = 0; if( HPMHooks.count.HP_status_calc_misc_pre ) { - void (*preHookFunc) (struct block_list *bl, struct status_data *status, int *level); + void (*preHookFunc) (struct block_list *bl, struct status_data *st, int *level); for(hIndex = 0; hIndex < HPMHooks.count.HP_status_calc_misc_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_status_calc_misc_pre[hIndex].func; - preHookFunc(bl, status, &level); + preHookFunc(bl, st, &level); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -59521,13 +61666,13 @@ void HP_status_calc_misc(struct block_list *bl, struct status_data *status, int } } { - HPMHooks.source.status.calc_misc(bl, status, level); + HPMHooks.source.status.calc_misc(bl, st, level); } if( HPMHooks.count.HP_status_calc_misc_post ) { - void (*postHookFunc) (struct block_list *bl, struct status_data *status, int *level); + void (*postHookFunc) (struct block_list *bl, struct status_data *st, int *level); for(hIndex = 0; hIndex < HPMHooks.count.HP_status_calc_misc_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_status_calc_misc_post[hIndex].func; - postHookFunc(bl, status, &level); + postHookFunc(bl, st, &level); } } return; @@ -60125,14 +62270,14 @@ unsigned int HP_status_base_pc_maxsp(struct map_session_data *sd, struct status_ } return retVal___; } -int HP_status_calc_npc_(struct npc_data *nd, bool first) { +int HP_status_calc_npc_(struct npc_data *nd, enum e_status_calc_opt opt) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_status_calc_npc__pre ) { - int (*preHookFunc) (struct npc_data *nd, bool *first); + int (*preHookFunc) (struct npc_data *nd, enum e_status_calc_opt *opt); for(hIndex = 0; hIndex < HPMHooks.count.HP_status_calc_npc__pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_status_calc_npc__pre[hIndex].func; - retVal___ = preHookFunc(nd, &first); + retVal___ = preHookFunc(nd, &opt); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -60140,13 +62285,13 @@ int HP_status_calc_npc_(struct npc_data *nd, bool first) { } } { - retVal___ = HPMHooks.source.status.calc_npc_(nd, first); + retVal___ = HPMHooks.source.status.calc_npc_(nd, opt); } if( HPMHooks.count.HP_status_calc_npc__post ) { - int (*postHookFunc) (int retVal___, struct npc_data *nd, bool *first); + int (*postHookFunc) (int retVal___, struct npc_data *nd, enum e_status_calc_opt *opt); for(hIndex = 0; hIndex < HPMHooks.count.HP_status_calc_npc__post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_status_calc_npc__post[hIndex].func; - retVal___ = postHookFunc(retVal___, nd, &first); + retVal___ = postHookFunc(retVal___, nd, &opt); } } return retVal___; @@ -60856,11 +63001,11 @@ int HP_status_natural_heal(struct block_list *bl, va_list args) { } return retVal___; } -int HP_status_natural_heal_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_status_natural_heal_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_status_natural_heal_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_status_natural_heal_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_status_natural_heal_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -60874,7 +63019,7 @@ int HP_status_natural_heal_timer(int tid, unsigned int tick, int id, intptr_t da retVal___ = HPMHooks.source.status.natural_heal_timer(tid, tick, id, data); } if( HPMHooks.count.HP_status_natural_heal_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_status_natural_heal_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_status_natural_heal_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -61582,14 +63727,14 @@ void HP_trade_commit(struct map_session_data *sd) { return; } /* unit */ -int HP_unit_init(void) { +int HP_unit_init(bool minimal) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_unit_init_pre ) { - int (*preHookFunc) (void); + int (*preHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_unit_init_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_unit_init_pre[hIndex].func; - retVal___ = preHookFunc(); + retVal___ = preHookFunc(&minimal); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -61597,13 +63742,13 @@ int HP_unit_init(void) { } } { - retVal___ = HPMHooks.source.unit.init(); + retVal___ = HPMHooks.source.unit.init(minimal); } if( HPMHooks.count.HP_unit_init_post ) { - int (*postHookFunc) (int retVal___); + int (*postHookFunc) (int retVal___, bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_unit_init_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_unit_init_post[hIndex].func; - retVal___ = postHookFunc(retVal___); + retVal___ = postHookFunc(retVal___, &minimal); } } return retVal___; @@ -61686,11 +63831,11 @@ struct unit_data* HP_unit_bl2ud2(struct block_list *bl) { } return retVal___; } -int HP_unit_attack_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_unit_attack_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_unit_attack_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_unit_attack_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_unit_attack_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -61704,7 +63849,7 @@ int HP_unit_attack_timer(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.unit.attack_timer(tid, tick, id, data); } if( HPMHooks.count.HP_unit_attack_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_unit_attack_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_unit_attack_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -61712,11 +63857,11 @@ int HP_unit_attack_timer(int tid, unsigned int tick, int id, intptr_t data) { } return retVal___; } -int HP_unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_unit_walktoxy_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_unit_walktoxy_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_unit_walktoxy_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_unit_walktoxy_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -61730,7 +63875,7 @@ int HP_unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.unit.walktoxy_timer(tid, tick, id, data); } if( HPMHooks.count.HP_unit_walktoxy_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_unit_walktoxy_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_unit_walktoxy_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -61764,11 +63909,11 @@ int HP_unit_walktoxy_sub(struct block_list *bl) { } return retVal___; } -int HP_unit_delay_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data) { +int HP_unit_delay_walktoxy_timer(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_unit_delay_walktoxy_timer_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_unit_delay_walktoxy_timer_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_unit_delay_walktoxy_timer_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -61782,7 +63927,7 @@ int HP_unit_delay_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t da retVal___ = HPMHooks.source.unit.delay_walktoxy_timer(tid, tick, id, data); } if( HPMHooks.count.HP_unit_delay_walktoxy_timer_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_unit_delay_walktoxy_timer_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_unit_delay_walktoxy_timer_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -61816,11 +63961,11 @@ int HP_unit_walktoxy(struct block_list *bl, short x, short y, int flag) { } return retVal___; } -int HP_unit_walktobl_sub(int tid, unsigned int tick, int id, intptr_t data) { +int HP_unit_walktobl_sub(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_unit_walktobl_sub_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_unit_walktobl_sub_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_unit_walktobl_sub_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -61834,7 +63979,7 @@ int HP_unit_walktobl_sub(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.unit.walktobl_sub(tid, tick, id, data); } if( HPMHooks.count.HP_unit_walktobl_sub_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_unit_walktobl_sub_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_unit_walktobl_sub_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -62180,11 +64325,11 @@ int HP_unit_can_move(struct block_list *bl) { } return retVal___; } -int HP_unit_resume_running(int tid, unsigned int tick, int id, intptr_t data) { +int HP_unit_resume_running(int tid, int64 tick, int id, intptr_t data) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_unit_resume_running_pre ) { - int (*preHookFunc) (int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_unit_resume_running_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_unit_resume_running_pre[hIndex].func; retVal___ = preHookFunc(&tid, &tick, &id, &data); @@ -62198,7 +64343,7 @@ int HP_unit_resume_running(int tid, unsigned int tick, int id, intptr_t data) { retVal___ = HPMHooks.source.unit.resume_running(tid, tick, id, data); } if( HPMHooks.count.HP_unit_resume_running_post ) { - int (*postHookFunc) (int retVal___, int *tid, unsigned int *tick, int *id, intptr_t *data); + int (*postHookFunc) (int retVal___, int *tid, int64 *tick, int *id, intptr_t *data); for(hIndex = 0; hIndex < HPMHooks.count.HP_unit_resume_running_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_unit_resume_running_post[hIndex].func; retVal___ = postHookFunc(retVal___, &tid, &tick, &id, &data); @@ -62206,11 +64351,11 @@ int HP_unit_resume_running(int tid, unsigned int tick, int id, intptr_t data) { } return retVal___; } -int HP_unit_set_walkdelay(struct block_list *bl, unsigned int tick, int delay, int type) { +int HP_unit_set_walkdelay(struct block_list *bl, int64 tick, int delay, int type) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_unit_set_walkdelay_pre ) { - int (*preHookFunc) (struct block_list *bl, unsigned int *tick, int *delay, int *type); + int (*preHookFunc) (struct block_list *bl, int64 *tick, int *delay, int *type); for(hIndex = 0; hIndex < HPMHooks.count.HP_unit_set_walkdelay_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_unit_set_walkdelay_pre[hIndex].func; retVal___ = preHookFunc(bl, &tick, &delay, &type); @@ -62224,7 +64369,7 @@ int HP_unit_set_walkdelay(struct block_list *bl, unsigned int tick, int delay, i retVal___ = HPMHooks.source.unit.set_walkdelay(bl, tick, delay, type); } if( HPMHooks.count.HP_unit_set_walkdelay_post ) { - int (*postHookFunc) (int retVal___, struct block_list *bl, unsigned int *tick, int *delay, int *type); + int (*postHookFunc) (int retVal___, struct block_list *bl, int64 *tick, int *delay, int *type); for(hIndex = 0; hIndex < HPMHooks.count.HP_unit_set_walkdelay_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_unit_set_walkdelay_post[hIndex].func; retVal___ = postHookFunc(retVal___, bl, &tick, &delay, &type); @@ -62518,11 +64663,11 @@ int HP_unit_calc_pos(struct block_list *bl, int tx, int ty, uint8 dir) { } return retVal___; } -int HP_unit_attack_timer_sub(struct block_list *src, int tid, unsigned int tick) { +int HP_unit_attack_timer_sub(struct block_list *src, int tid, int64 tick) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_unit_attack_timer_sub_pre ) { - int (*preHookFunc) (struct block_list *src, int *tid, unsigned int *tick); + int (*preHookFunc) (struct block_list *src, int *tid, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_unit_attack_timer_sub_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_unit_attack_timer_sub_pre[hIndex].func; retVal___ = preHookFunc(src, &tid, &tick); @@ -62536,7 +64681,7 @@ int HP_unit_attack_timer_sub(struct block_list *src, int tid, unsigned int tick) retVal___ = HPMHooks.source.unit.attack_timer_sub(src, tid, tick); } if( HPMHooks.count.HP_unit_attack_timer_sub_post ) { - int (*postHookFunc) (int retVal___, struct block_list *src, int *tid, unsigned int *tick); + int (*postHookFunc) (int retVal___, struct block_list *src, int *tid, int64 *tick); for(hIndex = 0; hIndex < HPMHooks.count.HP_unit_attack_timer_sub_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_unit_attack_timer_sub_post[hIndex].func; retVal___ = postHookFunc(retVal___, src, &tid, &tick); @@ -62621,14 +64766,14 @@ int HP_unit_counttargeted(struct block_list *bl) { } return retVal___; } -int HP_unit_fixdamage(struct block_list *src, struct block_list *target, unsigned int tick, int sdelay, int ddelay, int64 damage, int div, int type, int64 damage2) { +int HP_unit_fixdamage(struct block_list *src, struct block_list *target, int sdelay, int ddelay, int64 damage, short div, unsigned char type, int64 damage2) { int hIndex = 0; int retVal___ = 0; if( HPMHooks.count.HP_unit_fixdamage_pre ) { - int (*preHookFunc) (struct block_list *src, struct block_list *target, unsigned int *tick, int *sdelay, int *ddelay, int64 *damage, int *div, int *type, int64 *damage2); + int (*preHookFunc) (struct block_list *src, struct block_list *target, int *sdelay, int *ddelay, int64 *damage, short *div, unsigned char *type, int64 *damage2); for(hIndex = 0; hIndex < HPMHooks.count.HP_unit_fixdamage_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_unit_fixdamage_pre[hIndex].func; - retVal___ = preHookFunc(src, target, &tick, &sdelay, &ddelay, &damage, &div, &type, &damage2); + retVal___ = preHookFunc(src, target, &sdelay, &ddelay, &damage, &div, &type, &damage2); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -62636,13 +64781,13 @@ int HP_unit_fixdamage(struct block_list *src, struct block_list *target, unsigne } } { - retVal___ = HPMHooks.source.unit.fixdamage(src, target, tick, sdelay, ddelay, damage, div, type, damage2); + retVal___ = HPMHooks.source.unit.fixdamage(src, target, sdelay, ddelay, damage, div, type, damage2); } if( HPMHooks.count.HP_unit_fixdamage_post ) { - int (*postHookFunc) (int retVal___, struct block_list *src, struct block_list *target, unsigned int *tick, int *sdelay, int *ddelay, int64 *damage, int *div, int *type, int64 *damage2); + int (*postHookFunc) (int retVal___, struct block_list *src, struct block_list *target, int *sdelay, int *ddelay, int64 *damage, short *div, unsigned char *type, int64 *damage2); for(hIndex = 0; hIndex < HPMHooks.count.HP_unit_fixdamage_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_unit_fixdamage_post[hIndex].func; - retVal___ = postHookFunc(retVal___, src, target, &tick, &sdelay, &ddelay, &damage, &div, &type, &damage2); + retVal___ = postHookFunc(retVal___, src, target, &sdelay, &ddelay, &damage, &div, &type, &damage2); } } return retVal___; @@ -62776,13 +64921,13 @@ int HP_unit_free(struct block_list *bl, clr_type clrtype) { return retVal___; } /* vending */ -void HP_vending_init(void) { +void HP_vending_init(bool minimal) { int hIndex = 0; if( HPMHooks.count.HP_vending_init_pre ) { - void (*preHookFunc) (void); + void (*preHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_vending_init_pre; hIndex++ ) { preHookFunc = HPMHooks.list.HP_vending_init_pre[hIndex].func; - preHookFunc(); + preHookFunc(&minimal); } if( *HPMforce_return ) { *HPMforce_return = false; @@ -62790,13 +64935,13 @@ void HP_vending_init(void) { } } { - HPMHooks.source.vending.init(); + HPMHooks.source.vending.init(minimal); } if( HPMHooks.count.HP_vending_init_post ) { - void (*postHookFunc) (void); + void (*postHookFunc) (bool *minimal); for(hIndex = 0; hIndex < HPMHooks.count.HP_vending_init_post; hIndex++ ) { postHookFunc = HPMHooks.list.HP_vending_init_post[hIndex].func; - postHookFunc(); + postHookFunc(&minimal); } } return; diff --git a/src/plugins/HPMHooking/HPMHooking.sources.inc b/src/plugins/HPMHooking/HPMHooking.sources.inc index e6dd89814..53bb6bcad 100644 --- a/src/plugins/HPMHooking/HPMHooking.sources.inc +++ b/src/plugins/HPMHooking/HPMHooking.sources.inc @@ -30,6 +30,7 @@ memcpy(&HPMHooks.source.mob, mob, sizeof(struct mob_interface)); memcpy(&HPMHooks.source.npc, npc, sizeof(struct npc_interface)); memcpy(&HPMHooks.source.party, party, sizeof(struct party_interface)); memcpy(&HPMHooks.source.path, path, sizeof(struct path_interface)); +memcpy(&HPMHooks.source.pcg, pcg, sizeof(struct pc_groups_interface)); memcpy(&HPMHooks.source.pc, pc, sizeof(struct pc_interface)); memcpy(&HPMHooks.source.pet, pet, sizeof(struct pet_interface)); memcpy(&HPMHooks.source.quest, quest, sizeof(struct quest_interface)); diff --git a/src/plugins/Makefile.in b/src/plugins/Makefile.in index 53f44a0b4..0f1698d2a 100644 --- a/src/plugins/Makefile.in +++ b/src/plugins/Makefile.in @@ -6,6 +6,11 @@ # # # MYPLUGINS = my_cool_plugin my_second_plugin # # # +# This is only needed if you want to build your plugin through # +# 'make plugins' or 'make all'. If you don't add it to this list, # +# you will still be able to build your plugin through # +# 'make plugin.my_plugin' # +# # # Note: DO NOT include the .c extension!!! # MYPLUGINS = @@ -13,13 +18,21 @@ MYPLUGINS = # # ######### DO NOT EDIT ANYTHING BELOW THIS LINE!!! ################## +# All plugins in the src/plugins directory +ALLPLUGINS = $(basename $(wildcard *.c)) + +# Plugins that will be built through 'make plugins' or 'make all' PLUGINS = sample db2sql HPMHooking $(MYPLUGINS) -COMMON_H = $(shell ls ../common/*.h) -CONFIG_H = $(shell ls ../config/*.h ../config/*/*.h) -MAP_H = $(shell ls ../map/*.h) -CHAR_H = $(shell ls ../char/*.h) -LOGIN_H = $(shell ls ../login/*.h) +COMMON_D = ../common +COMMON_H = $(wildcard $(COMMON_D)/*.h) + +CONFIG_D = ../config +CONFIG_H = $(wildcard $(CONFIG_D)/*.h) $(wildcard $(CONFIG_D)/*/*.h) + +MAP_H = $(wildcard ../map/*.h) +CHAR_H = $(wildcard ../char/*.h) +LOGIN_H = $(wildcard ../login/*.h) ALL_H = $(COMMON_H) $(CONFIG_H) $(MAP_H) $(CHAR_H) $(LOGIN_H) @SET_MAKE@ @@ -28,11 +41,11 @@ CC = @CC@ export CC ##################################################################### -.PHONY: all $(PLUGINS) clean buildclean help +.PHONY: all $(ALLPLUGINS) clean buildclean help all: $(PLUGINS) Makefile -$(PLUGINS): %: ../../plugins/%@DLLEXT@ +$(ALLPLUGINS): %: ../../plugins/%@DLLEXT@ buildclean: @echo " CLEAN plugins (build temp files)" diff --git a/src/plugins/db2sql.c b/src/plugins/db2sql.c index d769a601e..46d654e0d 100644 --- a/src/plugins/db2sql.c +++ b/src/plugins/db2sql.c @@ -5,7 +5,9 @@ #include "../common/strlib.h" #include "../common/timer.h" #include "../common/HPMi.h" +#include "../common/malloc.h" #include "../common/mmo.h" +#include "../common/conf.h" #include "../config/core.h" #include "../map/clif.h" #include "../map/pc.h" @@ -14,125 +16,194 @@ #include <stdio.h> #include <stdlib.h> +#include "../common/HPMDataCheck.h" + HPExport struct hplugin_info pinfo = { - "DB2SQL", // Plugin name - SERVER_TYPE_MAP,// Which server types this plugin works with? - "0.4", // Plugin version - HPM_VERSION, // HPM Version (don't change, macro is automatically updated) + "DB2SQL", // Plugin name + SERVER_TYPE_MAP, // Which server types this plugin works with? + "0.5", // Plugin version + HPM_VERSION, // HPM Version (don't change, macro is automatically updated) }; -SqlStmt* stmt; +struct { + FILE *fp; + struct { + char *p; + size_t len; + } buf[4]; + char *db_name; +} tosql; +bool torun = false; -int (*parse_dbrow)(char** str, const char* source, int line, int scriptopt); +int (*itemdb_readdb_libconfig_sub) (config_setting_t *it, int n, const char *source); -char* trimbraces(char* str) { - size_t start; - size_t end; - - if( str == NULL ) - return str; - - for( start = 0; str[start] && str[start] == '{'; ++start ) - ; - for( end = strlen(str); start < end && str[end-1] && (str[end-1] == '}' || str[end-1] == '\n'); --end ) - ; - if( start == end ) - *str = '\0'; - else { - str[end] = '\0'; - memmove(str,str+start,end-start+1); - trim(str); +void hstr(const char *str) { + if( strlen(str) > tosql.buf[3].len ) { + tosql.buf[3].len = tosql.buf[3].len + strlen(str) + 1000; + RECREATE(tosql.buf[3].p,char,tosql.buf[3].len); } - return str; + safestrncpy(tosql.buf[3].p,str,strlen(str)); + normalize_name(tosql.buf[3].p,"\t\n "); } -int db2sql(char** str, const char* source, int line, int scriptopt) { +int db2sql(config_setting_t *entry, int n, const char *source) { struct item_data *it = NULL; - unsigned char offset = 0; -#ifdef RENEWAL - if( map->db_use_sql_item_db ) offset = 1; -#endif // RENEWAL - if( (it = itemdb->exists(parse_dbrow(str,source,line,scriptopt))) ) { - /* renewal has the 'matk' and 'equip_level' is now 'equip_level_min', and there is a new 'equip_level_max' field */ -#ifdef RENEWAL - if( SQL_SUCCESS != SQL->StmtPrepare(stmt, "REPLACE INTO `%s` (`id`,`name_english`,`name_japanese`,`type`,`price_buy`,`price_sell`,`weight`,`atk`,`matk`,`defence`,`range`,`slots`,`equip_jobs`,`equip_upper`,`equip_genders`,`equip_locations`,`weapon_level`,`equip_level_min`,`equip_level_max`,`refineable`,`view`,`script`,`equip_script`,`unequip_script`) VALUES ('%u',?,?,'%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u',?,?,?)",map->item_db_re_db, - it->nameid,it->flag.delay_consume?IT_DELAYCONSUME:it->type,it->value_buy,it->value_sell,it->weight,it->atk,it->matk,it->def,it->range,it->slot,(unsigned int)strtoul(str[11+offset],NULL,0),atoi(str[12+offset]),atoi(str[13+offset]),atoi(str[14+offset]),it->wlv,it->elv,it->elvmax,atoi(str[17+offset]),it->look) ) -#else // not RENEWAL - if( SQL_SUCCESS != SQL->StmtPrepare(stmt, "REPLACE INTO `%s` (`id`,`name_english`,`name_japanese`,`type`,`price_buy`,`price_sell`,`weight`,`atk`,`defence`,`range`,`slots`,`equip_jobs`,`equip_upper`,`equip_genders`,`equip_locations`,`weapon_level`,`equip_level`,`refineable`,`view`,`script`,`equip_script`,`unequip_script`) VALUES ('%u',?,?,'%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u',?,?,?)",map->item_db_db, - it->nameid,it->flag.delay_consume?IT_DELAYCONSUME:it->type,it->value_buy,it->value_sell,it->weight,it->atk,it->def,it->range,it->slot,(unsigned int)strtoul(str[11],NULL,0),atoi(str[12]),atoi(str[13]),atoi(str[14]),it->wlv,it->elv,atoi(str[17]),it->look) ) -#endif // RENEWAL - SqlStmt_ShowDebug(stmt); - else { - if ( SQL_SUCCESS != SQL->StmtBindParam(stmt, 0, SQLDT_STRING, it->name, strlen(it->name)) ) - SqlStmt_ShowDebug(stmt); - else { - if ( SQL_SUCCESS != SQL->StmtBindParam(stmt, 1, SQLDT_STRING, it->jname, strlen(it->jname)) ) - SqlStmt_ShowDebug(stmt); - else { -#ifdef RENEWAL - if( map->db_use_sql_item_db ) offset += 1; -#endif // RENEWAL - if( it->script ) trimbraces(str[19+offset]); - if ( SQL_SUCCESS != SQL->StmtBindParam(stmt, 2, SQLDT_STRING, it->script?str[19+offset]:"", it->script?strlen(str[19+offset]):0) ) - SqlStmt_ShowDebug(stmt); - else { - if( it->equip_script ) trimbraces(str[20+offset]); - if ( SQL_SUCCESS != SQL->StmtBindParam(stmt, 3, SQLDT_STRING, it->equip_script?str[20+offset]:"", it->equip_script?strlen(str[20+offset]):0) ) - SqlStmt_ShowDebug(stmt); - else { - if( it->unequip_script ) trimbraces(str[21+offset]); - if ( SQL_SUCCESS != SQL->StmtBindParam(stmt, 4, SQLDT_STRING, it->unequip_script?str[21+offset]:"", it->unequip_script?strlen(str[21+offset]):0) ) - SqlStmt_ShowDebug(stmt); - else { - if( SQL_SUCCESS != SQL->StmtExecute(stmt) ) - SqlStmt_ShowDebug(stmt); - } - } - } - } - } - } - return it->nameid; - } - return 0; -} + + if( (it = itemdb->exists(itemdb_readdb_libconfig_sub(entry,n,source))) ) { + char e_name[ITEM_NAME_LENGTH*2+1], e_jname[ITEM_NAME_LENGTH*2+1]; + const char *bonus = NULL; + char *str; + int i32; + unsigned int ui32, job = 0, upper = 0; + config_setting_t *t = NULL; -CPCMD(db2sql) { + SQL->EscapeString(NULL, e_name, it->name); + SQL->EscapeString(NULL, e_jname, it->jname); + if( it->script ) { libconfig->setting_lookup_string(entry, "Script", &bonus); hstr(bonus); str = tosql.buf[3].p; if ( strlen(str) > tosql.buf[0].len ) { tosql.buf[0].len = tosql.buf[0].len + strlen(str) + 1000; RECREATE(tosql.buf[0].p,char,tosql.buf[0].len); } SQL->EscapeString(NULL, tosql.buf[0].p, str); } + if( it->equip_script ) { libconfig->setting_lookup_string(entry, "OnEquipScript", &bonus); hstr(bonus); str = tosql.buf[3].p; if ( strlen(str) > tosql.buf[1].len ) { tosql.buf[1].len = tosql.buf[1].len + strlen(str) + 1000; RECREATE(tosql.buf[1].p,char,tosql.buf[1].len); } SQL->EscapeString(NULL, tosql.buf[1].p, str); } + if( it->unequip_script ) { libconfig->setting_lookup_string(entry, "OnUnequipScript", &bonus); hstr(bonus); str = tosql.buf[3].p; if ( strlen(str) > tosql.buf[2].len ) { tosql.buf[2].len = tosql.buf[2].len + strlen(str) + 1000; RECREATE(tosql.buf[2].p,char,tosql.buf[2].len); } SQL->EscapeString(NULL, tosql.buf[2].p, str); } + + if( libconfig->setting_lookup_int(entry, "Job", &i32) ) // This is an unsigned value, do not check for >= 0 + ui32 = (unsigned int)i32; + else + ui32 = UINT_MAX; + + job = ui32; + + if( libconfig->setting_lookup_int(entry, "Upper", &i32) && i32 >= 0 ) + ui32 = (unsigned int)i32; + else + ui32 = ITEMUPPER_ALL; + + upper = ui32; + + /* check if we have the equip_level_max, if so we send it -- otherwise we send NULL */ + if( (t = libconfig->setting_get_member(entry, "EquipLv")) && config_setting_is_aggregate(t) && libconfig->setting_length(t) >= 2 ) + fprintf(tosql.fp,"REPLACE INTO `%s` VALUES ('%u','%s','%s','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%s','%s','%s');\n", + tosql.db_name,it->nameid,e_name,e_jname,it->flag.delay_consume?IT_DELAYCONSUME:it->type,it->value_buy,it->value_sell,it->weight,it->atk,it->matk,it->def,it->range,it->slot,job,upper,it->sex,it->equip,it->wlv,it->elv,it->elvmax,it->flag.no_refine?0:1,it->look,it->flag.bindonequip?1:0,it->script?tosql.buf[0].p:"",it->equip_script?tosql.buf[1].p:"",it->unequip_script?tosql.buf[2].p:""); + else + fprintf(tosql.fp,"REPLACE INTO `%s` VALUES ('%u','%s','%s','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u','%u',NULL,'%u','%u','%u','%s','%s','%s');\n", + tosql.db_name,it->nameid,e_name,e_jname,it->flag.delay_consume?IT_DELAYCONSUME:it->type,it->value_buy,it->value_sell,it->weight,it->atk,it->matk,it->def,it->range,it->slot,job,upper,it->sex,it->equip,it->wlv,it->elv,it->flag.no_refine?0:1,it->look,it->flag.bindonequip?1:0,it->script?tosql.buf[0].p:"",it->equip_script?tosql.buf[1].p:"",it->unequip_script?tosql.buf[2].p:""); + } + return it?it->nameid:0; +} +void totable(void) { + fprintf(tosql.fp,"#\n" + "# Table structure for table `%s`\n" + "#\n" + "\n" + "DROP TABLE IF EXISTS `%s`;\n" + "CREATE TABLE `%s` (\n" + " `id` smallint(5) unsigned NOT NULL DEFAULT '0',\n" + " `name_english` varchar(50) NOT NULL DEFAULT '',\n" + " `name_japanese` varchar(50) NOT NULL DEFAULT '',\n" + " `type` tinyint(2) unsigned NOT NULL DEFAULT '0',\n" + " `price_buy` mediumint(10) DEFAULT NULL,\n" + " `price_sell` mediumint(10) DEFAULT NULL,\n" + " `weight` smallint(5) unsigned DEFAULT NULL,\n" + " `atk` smallint(5) unsigned DEFAULT NULL,\n" + " `matk` smallint(5) unsigned DEFAULT NULL,\n" + " `defence` smallint(5) unsigned DEFAULT NULL,\n" + " `range` tinyint(2) unsigned DEFAULT NULL,\n" + " `slots` tinyint(2) unsigned DEFAULT NULL,\n" + " `equip_jobs` int(12) unsigned DEFAULT NULL,\n" + " `equip_upper` tinyint(8) unsigned DEFAULT NULL,\n" + " `equip_genders` tinyint(2) unsigned DEFAULT NULL,\n" + " `equip_locations` smallint(4) unsigned DEFAULT NULL,\n" + " `weapon_level` tinyint(2) unsigned DEFAULT NULL,\n" + " `equip_level_min` smallint(5) unsigned DEFAULT NULL,\n" + " `equip_level_max` smallint(5) unsigned DEFAULT NULL,\n" + " `refineable` tinyint(1) unsigned DEFAULT NULL,\n" + " `view` smallint(3) unsigned DEFAULT NULL,\n" + " `bindonequip` tinyint(1) unsigned DEFAULT NULL,\n" + " `script` text,\n" + " `equip_script` text,\n" + " `unequip_script` text,\n" + " PRIMARY KEY (`id`)\n" + ") ENGINE=MyISAM;\n" + "\n",tosql.db_name,tosql.db_name,tosql.db_name); +} +void do_db2sql(void) { if( map->db_use_sql_item_db ) { ShowInfo("db2sql: this should not be used with 'db_use_sql_item_db' enabled, skipping...\n"); return; } - stmt = SQL->StmtMalloc(mysql_handle); - if( stmt == NULL ) { - SqlStmt_ShowDebug(stmt); - return; - } - /* link */ - parse_dbrow = itemdb->parse_dbrow; - itemdb->parse_dbrow = db2sql; - /* empty table */ -#ifdef RENEWAL - if ( SQL_ERROR == SQL->Query(mysql_handle, "DELETE FROM `%s`", map->item_db_re_db ) ) -#else // not RENEWAL - if ( SQL_ERROR == SQL->Query(mysql_handle, "DELETE FROM `%s`", map->item_db_db) ) -#endif // RENEWAL - Sql_ShowDebug(mysql_handle); - else { - itemdb->reload(); - } + itemdb_readdb_libconfig_sub = itemdb->readdb_libconfig_sub; + itemdb->readdb_libconfig_sub = db2sql; + /* */ + + if ((tosql.fp = fopen("sql-files/item_db_re.sql", "wt+")) == NULL) { + ShowError("itemdb_tosql: File not found \"%s\".\n", "sql-files/item_db_re.sql"); + return; + } + + tosql.db_name = map->item_db_re_db; + totable(); + + memset(&tosql.buf, 0, sizeof(tosql.buf) ); + + itemdb->clear(false); + itemdb->readdb_libconfig("re/item_db.conf"); + + fclose(tosql.fp); + + if ((tosql.fp = fopen("sql-files/item_db.sql", "wt+")) == NULL) { + ShowError("itemdb_tosql: File not found \"%s\".\n", "sql-files/item_db.sql"); + return; + } + + tosql.db_name = map->item_db_db; + totable(); + + itemdb->clear(false); + itemdb->readdb_libconfig("pre-re/item_db.conf"); + + fclose(tosql.fp); + + if ((tosql.fp = fopen("sql-files/item_db2.sql", "wt+")) == NULL) { + ShowError("itemdb_tosql: File not found \"%s\".\n", "sql-files/item_db2.sql"); + return; + } + + tosql.db_name = map->item_db2_db; + totable(); + + itemdb->clear(false); + itemdb->readdb_libconfig("item_db2.conf"); + + fclose(tosql.fp); + /* unlink */ - itemdb->parse_dbrow = parse_dbrow; + itemdb->readdb_libconfig_sub = itemdb_readdb_libconfig_sub; - SQL->StmtFree(stmt); + if( tosql.buf[0].p ) aFree(tosql.buf[0].p); + if( tosql.buf[1].p ) aFree(tosql.buf[1].p); + if( tosql.buf[2].p ) aFree(tosql.buf[2].p); + if( tosql.buf[3].p ) aFree(tosql.buf[3].p); } - -HPExport void plugin_init (void) { +CPCMD(db2sql) { + do_db2sql(); +} +void db2sql_arg(char *param) { + map->minimal = torun = true; +} +HPExport void server_preinit (void) { SQL = GET_SYMBOL("SQL"); itemdb = GET_SYMBOL("itemdb"); map = GET_SYMBOL("map"); strlib = GET_SYMBOL("strlib"); + iMalloc = GET_SYMBOL("iMalloc"); + libconfig = GET_SYMBOL("libconfig"); + - HPMi->addCPCommand("server:tools:db2sql",CPCMD_A(db2sql)); + addArg("--db2sql",false,db2sql_arg,NULL); +} +HPExport void plugin_init (void) { + addCPCommand("server:tools:db2sql",db2sql); +} +HPExport void server_online (void) { + if( torun ) + do_db2sql(); } diff --git a/src/plugins/sample.c b/src/plugins/sample.c index d1a95c71d..750ab31f9 100644 --- a/src/plugins/sample.c +++ b/src/plugins/sample.c @@ -14,6 +14,8 @@ #include "../map/pc.h" #include "../map/clif.h" +#include "../common/HPMDataCheck.h" /* should always be the last file included! (if you don't make it last, it'll intentionally break compile time) */ + HPExport struct hplugin_info pinfo = { "Sample", // Plugin name SERVER_TYPE_MAP,// Which server types this plugin works with? @@ -36,6 +38,7 @@ struct sample_data_struct { struct point lastMSGPosition; unsigned int someNumber; }; + /* sample packet implementation */ /* cmd 0xf3 - it is a client-server existent id, for clif_parse_GlobalMessage */ /* in this sample we do nothing and simply redirect */ @@ -48,7 +51,7 @@ void sample_packet0f3(int fd) { ShowInfo("sample_packet0f3: Hello World! received 0xf3 for '%s', redirecting!\n",sd->status.name); /* sample usage of appending data to a socket_data (session[]) entry */ - if( !(data = HPMi->getFromSession(session[fd],HPMi->pid,0)) ) { + if( !(data = getFromSession(session[fd],0)) ) { CREATE(data,struct sample_data_struct,1); data->lastMSGPosition.map = sd->status.last_point.map; @@ -57,17 +60,17 @@ void sample_packet0f3(int fd) { data->someNumber = rand()%777; ShowInfo("Created Appended session[] data, %d %d %d %d\n",data->lastMSGPosition.map,data->lastMSGPosition.x,data->lastMSGPosition.y,data->someNumber); - HPMi->addToSession(session[fd],data,HPMi->pid,0,true); + addToSession(session[fd],data,0,true); } else { ShowInfo("Existent Appended session[] data, %d %d %d %d\n",data->lastMSGPosition.map,data->lastMSGPosition.x,data->lastMSGPosition.y,data->someNumber); if( rand()%4 == 2 ) { ShowInfo("Removing Appended session[] data\n"); - HPMi->removeFromSession(session[fd],HPMi->pid,0); + removeFromSession(session[fd],0); } } /* sample usage of appending data to a map_session_data (sd) entry */ - if( !(data = HPMi->getFromMSD(sd,HPMi->pid,0)) ) { + if( !(data = getFromMSD(sd,0)) ) { CREATE(data,struct sample_data_struct,1); data->lastMSGPosition.map = sd->status.last_point.map; @@ -76,12 +79,12 @@ void sample_packet0f3(int fd) { data->someNumber = rand()%777; ShowInfo("Created Appended map_session_data data, %d %d %d %d\n",data->lastMSGPosition.map,data->lastMSGPosition.x,data->lastMSGPosition.y,data->someNumber); - HPMi->addToMSD(sd,data,HPMi->pid,0,true); + addToMSD(sd,data,0,true); } else { ShowInfo("Existent Appended map_session_data data, %d %d %d %d\n",data->lastMSGPosition.map,data->lastMSGPosition.x,data->lastMSGPosition.y,data->someNumber); if( rand()%4 == 2 ) { ShowInfo("Removing Appended map_session_data data\n"); - HPMi->removeFromMSD(sd,HPMi->pid,0); + removeFromMSD(sd,0); } } @@ -108,6 +111,10 @@ int my_pc_dropitem_post(int retVal, struct map_session_data *sd,int *n,int *amou } return 1; } +void parse_my_setting(const char *val) { + ShowDebug("Received 'my_setting:%s'\n",val); + /* do anything with the var e.g. config_switch(val) */ +} /* run when server starts */ HPExport void plugin_init (void) { char *server_type; @@ -124,7 +131,7 @@ HPExport void plugin_init (void) { script = GET_SYMBOL("script"); clif = GET_SYMBOL("clif"); pc = GET_SYMBOL("pc"); - + /* session[] */ session = GET_SYMBOL("session"); @@ -138,31 +145,43 @@ HPExport void plugin_init (void) { ShowInfo ("I'm being run from the '%s' filename\n", server_name); - if( HPMi->addCommand != NULL ) {//link our '@sample' command - HPMi->addCommand("sample",ACMD_A(sample)); - } + /* addAtcommand("command-key",command-function) tells map server to call ACMD(sample) when "sample" command is used */ + /* - it will print a warning when used on a non-map-server plugin */ + addAtcommand("sample",sample);//link our '@sample' command - if( HPMi->addScript != NULL ) {//link our 'sample' script command - HPMi->addScript("sample","i",BUILDIN_A(sample)); - } + /* addScriptCommand("script-command-name","script-command-params-info",script-function) tells map server to call BUILDIN(sample) for the "sample(i)" command */ + /* - it will print a warning when used on a non-map-server plugin */ + addScriptCommand("sample","i",sample); - if( HPMi->addCPCommand != NULL ) {//link our 'sample' console command - HPMi->addCPCommand("this:is:a:sample",CPCMD_A(sample)); - } - - if( HPMi->addPacket != NULL ) {//link our 'sample' packet to map-server - HPMi->addPacket(0xf3,-1,sample_packet0f3,hpClif_Parse,HPMi->pid); - } + /* addCPCommand("console-command-name",command-function) tells server to call CPCMD(sample) for the 'this is a sample <optional-args>' console call */ + /* in "console-command-name" usage of ':' indicates a category, for example 'this:is:a:sample' translates to 'this is a sample', + * therefore 'this -> is -> a -> sample', it can be used to aggregate multiple commands under the same category or to append commands to existing categories + * categories inherit the special keyword 'help' which prints the subsequent commands, e.g. 'server help' prints all categories and commands under 'server' + * therefore 'this help' would inform about 'is (category) -> a (category) -> sample (command)'*/ + addCPCommand("this:is:a:sample",sample); + /* addPacket(packetID,packetLength,packetFunction,packetIncomingPoint) */ + /* adds packetID of packetLength (-1 for dynamic length where length is defined in the packet { packetID (2 Byte) , packetLength (2 Byte) , ... }) + * to trigger packetFunction in the packetIncomingPoint section ( available points listed in enum HPluginPacketHookingPoints within src/common/HPMi.h ) */ + addPacket(0xf3,-1,sample_packet0f3,hpClif_Parse); + /* in this sample we add a PreHook to pc->dropitem */ /* to identify whether the item being dropped is on amount higher than 1 */ /* if so, it stores the amount on a variable (my_pc_dropitem_storage) and changes the amount to 1 */ addHookPre("pc->dropitem",my_pc_dropitem_pre); + /* in this sample we add a PostHook to pc->dropitem */ /* if the original pc->dropitem was successful and the amount stored on my_pc_dropitem_storage is higher than 1, */ /* our posthook will display a message to the user about the cap */ /* - by checking whether it was successful (retVal value) it allows for the originals conditions to take place */ - addHookPost("pc->dropitem",my_pc_dropitem_post); + addHookPost("pc->dropitem",my_pc_dropitem_post); +} +/* triggered when server starts loading, before any server-specific data is set */ +HPExport void server_preinit (void) { + /* makes map server listen to mysetting:value in any "battleconf" file (including imported or custom ones) */ + /* value is not limited to numbers, its passed to our plugins handler (parse_my_setting) as const char *, + * and thus can be manipulated at will */ + addBattleConf("my_setting",parse_my_setting); } /* run when server is ready (online) */ HPExport void server_online (void) { diff --git a/src/test/Makefile.in b/src/test/Makefile.in index 0c6d15c6b..c70997c63 100644 --- a/src/test/Makefile.in +++ b/src/test/Makefile.in @@ -1,23 +1,26 @@ -COMMON_H = $(shell ls ../common/*.h) -CONFIG_H = $(shell ls ../config/*.h ../config/*/*.h) +CONFIG_D = ../config +CONFIG_H = $(wildcard $(CONFIG_D)/*.h) $(wildcard $(CONFIG_D)/*/*.h) -MT19937AR_D = ../../3rdparty/mt19937ar -MT19937AR_OBJ = $(MT19937AR_D)/mt19937ar.o -MT19937AR_H = $(MT19937AR_D)/mt19937ar.h -MT19937AR_INCLUDE = -I$(MT19937AR_D) +COMMON_D = ../common +COMMON_H = $(wildcard $(COMMON_D)/*.h) LIBCONFIG_D = ../../3rdparty/libconfig LIBCONFIG_OBJ = $(addprefix $(LIBCONFIG_D)/, libconfig.o grammar.o scanctx.o \ - scanner.o strbuf.o) + scanner.o strbuf.o) LIBCONFIG_H = $(addprefix $(LIBCONFIG_D)/, libconfig.h grammar.h parsectx.h \ - scanctx.h scanner.h strbuf.h wincompat.h) + scanctx.h scanner.h strbuf.h wincompat.h) LIBCONFIG_INCLUDE = -I$(LIBCONFIG_D) +MT19937AR_D = ../../3rdparty/mt19937ar +MT19937AR_OBJ = $(MT19937AR_D)/mt19937ar.o +MT19937AR_H = $(MT19937AR_D)/mt19937ar.h +MT19937AR_INCLUDE = -I$(MT19937AR_D) + TEST_SPINLOCK_OBJ=obj/test_spinlock.o TEST_SPINLOCK_H= -TEST_SPINLOCK_DEPENDS=$(TEST_SPINLOCK_OBJ) ../common/obj_sql/common_sql.a ../common/obj_all/common.a $(MT19937AR_OBJ) - +TEST_SPINLOCK_DEPENDS=$(TEST_SPINLOCK_OBJ) $(COMMON_D)/obj_sql/common_sql.a $(COMMON_D)/obj_all/common.a $(MT19937AR_OBJ) + @SET_MAKE@ CC = @CC@ @@ -51,7 +54,8 @@ obj: test_spinlock: $(TEST_SPINLOCK_DEPENDS) Makefile @echo " LD $@" - @$(CC) @LDFLAGS@ -o ../../test_spinlock@EXEEXT@ $(TEST_SPINLOCK_OBJ) ../common/obj_sql/common_sql.a ../common/obj_all/common.a $(MT19937AR_OBJ) $(LIBCONFIG_OBJ) @LIBS@ @MYSQL_LIBS@ + @$(CC) @LDFLAGS@ -o ../../test_spinlock@EXEEXT@ $(TEST_SPINLOCK_OBJ) $(COMMON_D)/obj_sql/common_sql.a \ + $(COMMON_D)/obj_all/common.a $(MT19937AR_OBJ) $(LIBCONFIG_OBJ) @LIBS@ @MYSQL_LIBS@ # login object files @@ -60,13 +64,13 @@ obj/%.o: %.c $(COMMON_H) $(CONFIG_H) $(MT19937AR_H) $(LIBCONFIG_H) | obj @$(CC) @CFLAGS@ $(MT19937AR_INCLUDE) $(LIBCONFIG_INCLUDE) -DWITH_SQL @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $< # missing object files -../common/obj_all/common.a: +$(COMMON_D)/obj_all/common.a: @echo " MAKE $@" - @$(MAKE) -C ../common sql + @$(MAKE) -C $(COMMON_D) sql -../common/obj_sql/common_sql.a: +$(COMMON_D)/obj_sql/common_sql.a: @echo " MAKE $@" - @$(MAKE) -C ../common sql + @$(MAKE) -C $(COMMON_D) sql $(MT19937AR_OBJ): @echo " MAKE $@" diff --git a/src/tool/Makefile.in b/src/tool/Makefile.in index ee448a16a..3d0de1122 100644 --- a/src/tool/Makefile.in +++ b/src/tool/Makefile.in @@ -1,19 +1,20 @@ +CONFIG_D = ../config +CONFIG_H = $(wildcard $(CONFIG_D)/*.h) $(wildcard $(CONFIG_D)/*/*.h) + COMMON_D = ../common COMMON_OBJ = $(addprefix $(COMMON_D)/obj_all/, des.o grfio.o malloc.o \ - miniconsole.o minicore.o showmsg.o strlib.o utils.o) + nullpo.o miniconsole.o minicore.o showmsg.o strlib.o utils.o) COMMON_H = $(addprefix $(COMMON_D)/, cbasetypes.h console.h core.h des.h \ - grfio.h malloc.h mmo.h showmsg.h strlib.h utils.h) + grfio.h malloc.h mmo.h nullpo.h showmsg.h strlib.h utils.h) LIBCONFIG_D = ../../3rdparty/libconfig LIBCONFIG_OBJ = $(addprefix $(LIBCONFIG_D)/, libconfig.o grammar.o scanctx.o \ - scanner.o strbuf.o) + scanner.o strbuf.o) LIBCONFIG_H = $(addprefix $(LIBCONFIG_D)/, libconfig.h grammar.h parsectx.h \ - scanctx.h scanner.h strbuf.h wincompat.h) + scanctx.h scanner.h strbuf.h wincompat.h) LIBCONFIG_INCLUDE = -I$(LIBCONFIG_D) -CONFIG_H = $(shell ls ../config/*.h ../config/*/*.h) - MAPCACHE_OBJ = obj_all/mapcache.o @SET_MAKE@ @@ -63,13 +64,13 @@ obj_all/%.o: %.c $(COMMON_H) $(CONFIG_H) $(LIBCONFIG_H) | obj_all @$(CC) @CFLAGS@ $(LIBCONFIG_INCLUDE) @CPPFLAGS@ -c $(OUTPUT_OPTION) $< # missing common object files -../common/obj_all/%.o: +$(COMMON_D)/obj_all/%.o: @echo " MAKE $@" - @$(MAKE) -C ../common sql + @$(MAKE) -C $(COMMON_D) sql -../common/obj_all/mini%.o: +$(COMMON_D)/obj_all/mini%.o: @echo " MAKE $@" - @$(MAKE) -C ../common sql + @$(MAKE) -C $(COMMON_D) sql $(LIBCONFIG_OBJ): @echo " MAKE $@" diff --git a/src/tool/mapcache.c b/src/tool/mapcache.c index 49f948709..caa55c87a 100644 --- a/src/tool/mapcache.c +++ b/src/tool/mapcache.c @@ -181,7 +181,7 @@ void cache_map(char *name, struct map_data *m) strncpy(info.name, name, MAP_NAME_LENGTH); info.xs = MakeShortLE(m->xs); info.ys = MakeShortLE(m->ys); - info.len = MakeLongLE(len); + info.len = MakeLongLE((uint32)len); // Append map header then compressed cells at the end of the file fseek(map_cache_fp, header.file_size, SEEK_SET); |