From 9692bc034537693d331148ae8bd15153265c6cf0 Mon Sep 17 00:00:00 2001 From: malufett Date: Wed, 16 Oct 2013 03:11:25 +0800 Subject: Fixed Bug#7374 -Hercules now fully support Monster Transformation. Signed-off-by: malufett --- conf/battle/misc.conf | 4 +++ conf/messages.conf | 6 +++++ db/const.txt | 6 +++++ db/item_delay.txt | 7 +++++ db/re/item_db.txt | 14 +++++----- db/sc_config.txt | 5 ++++ src/map/atcommand.c | 8 +++++- src/map/battle.c | 9 ++++++- src/map/battle.h | 2 ++ src/map/clif.c | 5 ++++ src/map/script.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/map/status.c | 16 +++++++++++ src/map/status.h | 32 ++++++++++++++++++++++ 13 files changed, 180 insertions(+), 9 deletions(-) diff --git a/conf/battle/misc.conf b/conf/battle/misc.conf index 9814a2140..d2fc61430 100644 --- a/conf/battle/misc.conf +++ b/conf/battle/misc.conf @@ -116,3 +116,7 @@ cashshop_show_points: no // 1 = Yes // 2 = Yes, when there are unread mails mail_show_status: 0 + +// Is monster transformation disabled during Guild Wars? +// If set to yes, monster transforming is automatically removed/disabled when entering castles during WoE times +mon_trans_disable_in_gvg: no diff --git a/conf/messages.conf b/conf/messages.conf index 4a08c0893..3a16d8054 100644 --- a/conf/messages.conf +++ b/conf/messages.conf @@ -1526,5 +1526,11 @@ //src/map/atcommand.c::ACMD(auction) 1484: Auction is disabled +//Monster Transformation +1485: Traaaansformation-!! %s form!! +1486: Cannot transform into monster while in disguise. +1487: Character cannot be disguised while in monster form. +1488: Transforming into monster is not allowed in Guild Wars. + //Custom translations import: conf/import/msg_conf.txt diff --git a/db/const.txt b/db/const.txt index 23a28c088..af3dedbc5 100644 --- a/db/const.txt +++ b/db/const.txt @@ -1236,6 +1236,12 @@ SC_OFFERTORIUM 559 SC_FRIGG_SONG 560 SC_MONSTER_TRANSFORM 563 SC_ANGEL_PROTECT 564 +SC_ILLUSIONDOPING 565 +SC_MTF_ASPD 566 +SC_MTF_RANGEATK 567 +SC_MTF_MATK 568 +SC_MTF_MLEATKED 569 +SC_MTF_CRIDAMAGE 570 e_gasp 0 e_what 1 diff --git a/db/item_delay.txt b/db/item_delay.txt index c5bf0da7d..8905edb11 100644 --- a/db/item_delay.txt +++ b/db/item_delay.txt @@ -35,3 +35,10 @@ 12732,1000 // Runstone_Pertz,Wyrd Rune 22540,60000 // Runstone_Luxanima,Lux Anima Rune +12658, 10000 // Transformation Scroll(Deviruchi) +12659, 10000 // Transformation Scroll(Raydric) +12660, 10000 // Transformation Scroll(Mavka) +12661, 10000 // Transformation Scroll(Marduk) +12662, 10000 // Transformation Scroll(Banshee) +12663, 10000 // Transformation Scroll(Poring) +12664, 10000 // Transformation Scroll(Golem) \ No newline at end of file diff --git a/db/re/item_db.txt b/db/re/item_db.txt index 7385672d9..d686f8677 100644 --- a/db/re/item_db.txt +++ b/db/re/item_db.txt @@ -5975,13 +5975,13 @@ 12655,Brain_Powder,Brain Powder,11,2000,,100,,,,,0xFFFFFFFF,63,2,,,,,,{},{},{} 12656,Magical_Powder,Magical Powder,11,3000,,200,,,,,0xFFFFFFFF,63,2,,,,,,{},{},{} 12657,Madness_Powder,Madness Powder,11,4000,,300,,,,,0xFFFFFFFF,63,2,,,,,,{},{},{} -12658,Trans_Scroll_Devi,Transformation Scroll(Deviruchi),2,20,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ sc_start4 SC_MONSTER_TRANSFORM,1200000,1109,0,0,0; },{},{} -12659,Trans_Scroll_Ray_Arch,Transformation Scroll(Raydric),2,20,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ sc_start4 SC_MONSTER_TRANSFORM,1200000,1276,0,0,0; },{},{} -12660,Trans_Scroll_Mavka,Transformation Scroll(Mavka),2,20,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ sc_start4 SC_MONSTER_TRANSFORM,1200000,1884,0,0,0; },{},{} -12661,Trans_Scroll_Marduk,Transformation Scroll(Marduk),2,20,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ sc_start4 SC_MONSTER_TRANSFORM,1200000,1140,0,0,0; },{},{} -12662,Trans_Scroll_Banshee,Transformation Scroll(Banshee),2,20,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ sc_start4 SC_MONSTER_TRANSFORM,1200000,1867,0,0,0; },{},{} -12663,Trans_Scroll_Poring,Transformation Scroll(Poring),2,20,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ sc_start4 SC_MONSTER_TRANSFORM,1200000,1002,0,0,0; },{},{} -12664,Trans_Scroll_Golem,Transformation Scroll(Golem),2,20,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ sc_start4 SC_MONSTER_TRANSFORM,1200000,1040,0,0,0; },{},{} +12658,Trans_Scroll_Devi,Transformation Scroll(Deviruchi),2,20,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ montransform "Deviruchi",1200000,SC_MTF_ASPD; },{},{} +12659,Trans_Scroll_Ray_Arch,Transformation Scroll(Raydric),2,20,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ montransform "Raydric Archer",1200000,SC_MTF_RANGEATK; },{},{} +12660,Trans_Scroll_Mavka,Transformation Scroll(Mavka),2,20,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ montransform "Mavka",1200000,SC_MTF_RANGEATK; },{},{} +12661,Trans_Scroll_Marduk,Transformation Scroll(Marduk),2,20,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ montransform "Marduk",1200000,SC_MTF_MATK; },{},{} +12662,Trans_Scroll_Banshee,Transformation Scroll(Banshee),2,20,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ montransform "Banshee",1200000,SC_MTF_MATK; },{},{} +12663,Trans_Scroll_Poring,Transformation Scroll(Poring),2,20,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ montransform "Poring",1200000,SC_MTF_CRIDAMAGE; },{},{} +12664,Trans_Scroll_Golem,Transformation Scroll(Golem),2,20,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ montransform "Golem",1200000,SC_MTF_MLEATKED; },{},{} // // ID,AegisName,Name,Type,Buy,Sell,Weight,ATK,DEF,Range,Slots,Job,Upper,Gender,Loc,wLV,eLV,Refineable,View,{ Script },{ OnEquip_Script },{ OnUnequip_Script } diff --git a/db/sc_config.txt b/db/sc_config.txt index a9715dfbf..1adfec6ca 100644 --- a/db/sc_config.txt +++ b/db/sc_config.txt @@ -378,6 +378,11 @@ SC_LIGHT_OF_REGENE, 1 //SC_ALL_RIDING_REUSE_LIMIT, 1 //SC_HANDICAPSTATE_DEEP_SLEEP, 80 SC_MONSTER_TRANSFORM, 12 +SC_MTF_ASPD, 12 +SC_MTF_RANGEATK, 12 +SC_MTF_MATK, 12 +SC_MTF_MLEATKED,12 +SC_MTF_CRIDAMAGE, 12 SC_FULL_THROTTLE, 18 SC_REBOUND, 18 diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 10c96e317..cc29fa1bb 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -4713,7 +4713,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(1488)); // Character cannot be disguised while in monster form. + return false; + } + pc->disguise(sd, id); clif->message(fd, msg_txt(122)); // Disguise applied. diff --git a/src/map/battle.c b/src/map/battle.c index ef62eb1d2..1c736d9b7 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -4534,6 +4534,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){ @@ -4721,6 +4723,8 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list #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) ) @@ -5472,6 +5476,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, 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) @@ -6477,7 +6484,7 @@ static const struct _battle_data { { "feature.banking", &battle_config.feature_banking, 1, 0, 1, }, { "feature.auction", &battle_config.feature_auction, 0, 0, 2, }, - + { "mon_trans_disable_in_gvg", &battle_config.mon_trans_disable_in_gvg, 0, 0, 1, }, }; #ifndef STATS_OPT_OUT /** diff --git a/src/map/battle.h b/src/map/battle.h index 533fa40b0..1aa07b2be 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -463,6 +463,8 @@ struct Battle_Config { int feature_banking; int feature_auction; + + int mon_trans_disable_in_gvg; } battle_config; // Dammage delayed info diff --git a/src/map/clif.c b/src/map/clif.c index f50082883..81dbc28ec 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -9600,6 +9600,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( 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) diff --git a/src/map/script.c b/src/map/script.c index 7d92f092a..dbd64536e 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -16938,6 +16938,79 @@ BUILDIN(npcskill) { return true; } + +/* Turns a player into a monster and grants SC attribute effect. [malufett/Hercules] + * montransform , , , , , , ; */ +BUILDIN(montransform) { + int tick; + enum sc_type type; + const char * monster; + struct block_list* bl; + int mob_id, val1, val2, val3, val4; + + monster = script_getstr(st, 2); + tick = script_getnum(st, 3); + type = (sc_type)script_getnum(st, 4); + val1 = val2 = val3 = val4 = 0; + + if( (bl = map->id2bl(st->rid)) == NULL ) + return true; + + if( (mob_id = mob->db_searchname(monster)) == 0 ) + mob_id = mob->db_checkid(atoi(monster)); + + if( mob_id == 0 ) { + ShowWarning("buildin_montransform: Attempted to use non-existing monster '%s'.\n", monster); + return false; + } + + if(mob_id == MOBID_EMPERIUM) { + ShowWarning("buildin_montransform: Monster 'Emperium' cannot be used.\n"); + return false; + } + + 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( type && tick != 0 ){ + struct map_session_data *sd = map->id2sd(bl->id); + char msg[CHAT_SIZE_MAX]; + + 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); // Traaaansformation-!! %s form!! + clif->message(sd->fd, msg); + status_change_end(bl, SC_MONSTER_TRANSFORM, INVALID_TIMER); // Clear previous + sc_start2(bl, SC_MONSTER_TRANSFORM, 100, mob_id, type, tick); + sc_start4(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; @@ -17900,6 +17973,8 @@ void script_parse_builtin(void) { BUILDIN_DEF(sit, "?"), BUILDIN_DEF(stand, "?"), BUILDIN_DEF(issit, "?"), + + BUILDIN_DEF(montransform, "sii????"), // Monster Transform [malufett/Hercules] /* New BG Commands [Hercules] */ BUILDIN_DEF(bg_create_team,"sii"), diff --git a/src/map/status.c b/src/map/status.c index ae900e04d..8a2ac7cd6 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -991,6 +991,9 @@ 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->DisplayType Table [Ind/Hercules] */ status->DisplayType[SC_ALL_RIDING] = true; @@ -3083,6 +3086,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 ) @@ -4590,6 +4595,9 @@ unsigned short status_calc_matk(struct block_list *bl, struct status_change *sc, 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_MTF_MATK]) + matk += matk * 25 / 100; + if (sc->data[SC_BEYOND_OF_WARCRY]) matk -= matk * sc->data[SC_BEYOND_OF_WARCRY]->val3/100; @@ -4639,6 +4647,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); } @@ -5342,6 +5352,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 } @@ -9631,6 +9643,10 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const case SC_FULL_THROTTLE: sc_start(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 ) { diff --git a/src/map/status.h b/src/map/status.h index c7518a213..9b1721d1a 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -671,6 +671,12 @@ typedef enum sc_type { SC_ANGEL_PROTECT, SC_ILLUSIONDOPING, + SC_MTF_ASPD, + SC_MTF_RANGEATK, + SC_MTF_MATK, + SC_MTF_MLEATKED, + SC_MTF_CRIDAMAGE, + 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 +1411,32 @@ enum si_type { //SI_ = 735, SI_CHILL = 736, SI_BURNT = 737, + 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_MAX, }; // JOINTBEAT stackable ailments -- cgit v1.2.3-60-g2f50