diff options
author | dastgirpojee <dastgirpojee@rocketmail.com> | 2013-10-11 10:46:32 -0700 |
---|---|---|
committer | dastgirpojee <dastgirpojee@rocketmail.com> | 2013-10-11 10:46:32 -0700 |
commit | d3d3fcdb60a03749aa927c4d9b8bf1e710e3d3b6 (patch) | |
tree | 7a50cf8fcc99e189c856dbf4c2ef1403e93f0711 /src/map | |
parent | e105044ee8c1c625b886e2306c22a3f8a68f5bf5 (diff) | |
parent | 231f7a4f31b27611af7006e3adc2d3c046356fd3 (diff) | |
download | hercules-d3d3fcdb60a03749aa927c4d9b8bf1e710e3d3b6.tar.gz hercules-d3d3fcdb60a03749aa927c4d9b8bf1e710e3d3b6.tar.bz2 hercules-d3d3fcdb60a03749aa927c4d9b8bf1e710e3d3b6.tar.xz hercules-d3d3fcdb60a03749aa927c4d9b8bf1e710e3d3b6.zip |
Merge pull request #3 from HerculesWS/master
Herc Merge
Diffstat (limited to 'src/map')
-rw-r--r-- | src/map/atcommand.c | 10 | ||||
-rw-r--r-- | src/map/battle.c | 20 | ||||
-rw-r--r-- | src/map/battle.h | 2 | ||||
-rw-r--r-- | src/map/clif.c | 116 | ||||
-rw-r--r-- | src/map/clif.h | 22 | ||||
-rw-r--r-- | src/map/homunculus.c | 22 | ||||
-rw-r--r-- | src/map/homunculus.h | 10 | ||||
-rw-r--r-- | src/map/itemdb.c | 19 | ||||
-rw-r--r-- | src/map/itemdb.h | 1 | ||||
-rw-r--r-- | src/map/log.c | 1 | ||||
-rw-r--r-- | src/map/log.h | 1 | ||||
-rw-r--r-- | src/map/packets.h | 15 | ||||
-rw-r--r-- | src/map/packets_struct.h | 35 | ||||
-rw-r--r-- | src/map/pc.c | 54 | ||||
-rw-r--r-- | src/map/pc.h | 3 | ||||
-rw-r--r-- | src/map/script.c | 124 | ||||
-rw-r--r-- | src/map/skill.c | 24 | ||||
-rw-r--r-- | src/map/status.c | 2 |
18 files changed, 393 insertions, 88 deletions
diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 3d04a6bff..10c96e317 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -6869,7 +6869,7 @@ ACMD(makehomun) { homunid = atoi(message); if( homunid == -1 && sd->status.hom_id && !homun_alive(sd->hd) ) { - if( !sd->hd->homunculus.vaporize ) + if( sd->hd->homunculus.vaporize ) homun->ressurect(sd, 100, sd->bl.x, sd->bl.y); else homun->call(sd); @@ -7956,10 +7956,14 @@ ACMD(feelreset) /*========================================== * AUCTION SYSTEM *------------------------------------------*/ -ACMD(auction) -{ +ACMD(auction) { nullpo_ret(sd); + if( !battle_config.feature_auction ) { + clif->colormes(sd->fd,COLOR_RED,msg_txt(1484)); + return false; + } + clif->auction_openwindow(sd); return true; diff --git a/src/map/battle.c b/src/map/battle.c index 928d14c22..ef62eb1d2 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -6474,6 +6474,10 @@ static const struct _battle_data { { "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, }, + + }; #ifndef STATS_OPT_OUT /** @@ -6695,6 +6699,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) diff --git a/src/map/battle.h b/src/map/battle.h index 6d5d5f186..533fa40b0 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -461,6 +461,8 @@ struct Battle_Config { int snovice_call_type; int guild_notice_changemap; + int feature_banking; + int feature_auction; } battle_config; // Dammage delayed info diff --git a/src/map/clif.c b/src/map/clif.c index 357c4dc6a..823a44956 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -61,10 +61,11 @@ struct clif_interface clif_s; //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; @@ -1378,7 +1379,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) ; @@ -14987,6 +14988,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 +15080,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; @@ -15151,6 +15158,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); @@ -15282,6 +15292,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 +15310,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); @@ -17725,6 +17742,79 @@ void clif_cart_additem_ack(struct map_session_data *sd, int 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); +} + /* */ unsigned short clif_decrypt_cmd( int cmd, struct map_session_data *sd ) { if( sd ) { @@ -17735,10 +17825,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 +17832,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 ) { @@ -17824,7 +17906,10 @@ int clif_parse(int fd) { 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)); @@ -18523,6 +18608,9 @@ 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; /*------------------------ *- Parse Incoming Packet *------------------------*/ @@ -18745,4 +18833,10 @@ 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; } diff --git a/src/map/clif.h b/src/map/clif.h index 1a2748353..2baca2aaf 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -414,6 +414,19 @@ 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, +}; + + /** * Structures **/ @@ -964,6 +977,9 @@ 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); /*------------------------ *- Parse Incoming Packet *------------------------*/ @@ -1184,6 +1200,12 @@ 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); }; struct clif_interface *clif; diff --git a/src/map/homunculus.c b/src/map/homunculus.c index 45e9af2b0..1e47053fe 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; @@ -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 ) { @@ -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; @@ -781,11 +781,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 +833,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 +908,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)) diff --git a/src/map/homunculus.h b/src/map/homunculus.h index 9562ed5c3..2cb558930 100644 --- a/src/map/homunculus.h +++ b/src/map/homunculus.h @@ -11,7 +11,7 @@ #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 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; @@ -94,7 +100,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); diff --git a/src/map/itemdb.c b/src/map/itemdb.c index fe2c43fcc..09eec557d 100644 --- a/src/map/itemdb.c +++ b/src/map/itemdb.c @@ -1704,12 +1704,11 @@ int itemdb_parse_dbrow(char** str, const char* source, int line, int scriptopt) * Reading item from item db * item_db2 overwriting item_db *------------------------------------------*/ -int itemdb_readdb(void) -{ +int itemdb_readdb(void) { const char* filename[] = { DBPATH"item_db.txt", "item_db2.txt" }; - + bool duplicate[MAX_ITEMDB]; int fi; for( fi = 0; fi < ARRAYLENGTH(filename); ++fi ) { @@ -1726,11 +1725,13 @@ int itemdb_readdb(void) continue; } + memset(&duplicate,0,sizeof(duplicate)); + // process rows one by one while(fgets(line, sizeof(line), fp)) { char *str[32], *p; - int i; + int i, id = 0; lines++; if(line[0] == '/' && line[1] == '/') continue; @@ -1807,9 +1808,14 @@ int itemdb_readdb(void) } } - if (!itemdb->parse_dbrow(str, filepath, lines, 0)) + if (!(id = itemdb->parse_dbrow(str, filepath, lines, 0))) continue; + if( duplicate[id] ) { + ShowWarning("itemdb_readdb:%s: duplicate entry of ID #%d (%s/%s)\n",filename[fi],id,itemdb_name(id),itemdb_jname(id)); + } else + duplicate[id] = true; + count++; } @@ -1836,7 +1842,7 @@ int itemdb_read_sqldb(void) { for( fi = 0; fi < ARRAYLENGTH(item_db_name); ++fi ) { uint32 count = 0; - + // 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); @@ -1856,6 +1862,7 @@ int itemdb_read_sqldb(void) { if (!itemdb->parse_dbrow(str, item_db_name[fi], -(atoi(str[0])), SCRIPT_IGNORE_EXTERNAL_BRACKETS)) continue; + ++count; } diff --git a/src/map/itemdb.h b/src/map/itemdb.h index fe67ebbef..0f46c1c01 100644 --- a/src/map/itemdb.h +++ b/src/map/itemdb.h @@ -40,6 +40,7 @@ enum item_itemid { ITEMID_RED_GEMSTONE = 716, ITEMID_BLUE_GEMSTONE = 717, ITEMID_TRAP = 1065, + ITEMID_STRANGE_EMBRYO = 6415, ITEMID_FACE_PAINT = 6120, ITEMID_STONE = 7049, ITEMID_SKULL_ = 7420, 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..9864a54d7 100644 --- a/src/map/log.h +++ b/src/map/log.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 diff --git a/src/map/packets.h b/src/map/packets.h index c91b5d50c..918f0a10f 100644 --- a/src/map/packets.h +++ b/src/map/packets.h @@ -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); diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h index f39b4a55b..9d7282c92 100644 --- a/src/map/packets_struct.h +++ b/src/map/packets_struct.h @@ -18,6 +18,9 @@ struct EQUIPSLOTINFO { * **/ enum packet_headers { + banking_withdraw_ackType = 0x9aa, + banking_deposit_ackType = 0x9a8, + banking_checkType = 0x9a6, cart_additem_ackType = 0x12c, sc_notickType = 0x196, #if PACKETVER < 20061218 @@ -543,6 +546,38 @@ struct packet_cart_additem_ack { 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)); + #pragma pack(pop) #endif /* _PACKETS_STRUCT_H_ */ diff --git a/src/map/pc.c b/src/map/pc.c index 6b7d6c735..157d9e28a 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -6438,7 +6438,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_ACTIVE); } for( i = 1; i < MAX_SKILL; i++ ) { @@ -6663,7 +6663,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_ACTIVE); } if( sd->md ) @@ -7588,7 +7588,7 @@ 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_ACTIVE); if(sd->status.manner < 0) clif->changestatus(sd,SP_MANNER,sd->status.manner); @@ -10079,6 +10079,51 @@ void pc_itemcd_do(struct map_session_data *sd, bool load) { return; } +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; + } + + 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); + } +} + /*========================================== * pc Init/Terminate *------------------------------------------*/ @@ -10402,4 +10447,7 @@ 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; } diff --git a/src/map/pc.h b/src/map/pc.h index fadb922b5..f770818c2 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -961,6 +961,9 @@ struct pc_interface { 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); }; struct pc_interface *pc; diff --git a/src/map/script.c b/src/map/script.c index 8460b23b0..1bedb78b6 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -6780,7 +6780,7 @@ BUILDIN(strnpcinfo) { } /*========================================== - * GetEquipID(Pos); Pos: 1-10 + * GetEquipID(Pos); Pos: 1-SCRIPT_EQUIP_TABLE_SIZE *------------------------------------------*/ BUILDIN(getequipid) { @@ -9564,44 +9564,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; + bool success = false; - sd=script->rid2sd(st); - if( sd == NULL ) + 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,21 +9650,29 @@ 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; } @@ -12166,12 +12212,9 @@ BUILDIN(getpetinfo) BUILDIN(gethominfo) { TBL_PC *sd=script->rid2sd(st); - TBL_HOM *hd; - int type=script_getnum(st,2); + int type = script_getnum(st,2); - hd = sd?sd->hd:NULL; - if(!homun_alive(hd)) - { + if(!sd || !sd->hd) { if (type == 2) script_pushconststr(st,"null"); else @@ -12180,13 +12223,13 @@ BUILDIN(gethominfo) } 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; + 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; @@ -17655,8 +17698,9 @@ void script_parse_builtin(void) { BUILDIN_DEF(warpportal,"iisii"), BUILDIN_DEF2(homunculus_evolution,"homevolution",""), //[orn] BUILDIN_DEF2(homunculus_mutate,"hommutate","?"), + BUILDIN_DEF2(homunculus_morphembryo,"morphembryo",""), + BUILDIN_DEF2(homunculus_checkcall,"checkhomcall",""), BUILDIN_DEF2(homunculus_shuffle,"homshuffle",""), //[Zephyrus] - BUILDIN_DEF(checkhomcall,""), BUILDIN_DEF(eaclass,"?"), //[Skotlex] BUILDIN_DEF(roclass,"i?"), //[Skotlex] BUILDIN_DEF(checkvending,"?"), diff --git a/src/map/skill.c b/src/map/skill.c index 248e19e77..70e946119 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -6971,21 +6971,23 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui if(sd) { struct map_session_data *f_sd = pc->get_father(sd); struct map_session_data *m_sd = pc->get_mother(sd); - // if neither was found - if(!f_sd && !m_sd) { - clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); - map->freeblock_unlock(); - return 0; + 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)); + clif->specialeffect(&m_sd->bl,408,AREA); + we_baby_parents = true; } - status->change_start(bl,SC_STUN,10000,skill_lv,0,0,0,skill->get_time2(skill_id,skill_lv),8); - if (f_sd) { + 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)); clif->specialeffect(&f_sd->bl,408,AREA); + we_baby_parents = true; } - if (m_sd) { - sc_start(&m_sd->bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)); - clif->specialeffect(&m_sd->bl,408,AREA); + if (!we_baby_parents) { + clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); + 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); } break; @@ -7516,7 +7518,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui 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); diff --git a/src/map/status.c b/src/map/status.c index 497d02bbf..ae900e04d 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -8230,7 +8230,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val 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( homun_alive(sd->hd) ) homun->vaporize(sd,HOM_ST_REST); if( sd->md ) mercenary->delete(sd->md,3); } break; |