From 9c438ce762c392bf0731d34b85d3c9de93341f8e Mon Sep 17 00:00:00 2001 From: Akinari1087 Date: Wed, 6 Nov 2013 05:14:19 -0700 Subject: [PATCH] Merged Monster Transformation update from Hercules (9692bc0) - Merge credits to Aleos & Cydh -> Applied follow-up for using monster IDs with the commands (ead2a83) Merged revert of r15787 where character must face north (5188b69) Merged bug fix for visual effects on relog (f304c36) -> This fixes the Warlock Sphere issue on relog as well as many other visual effects Applied a possible map crash fix - Credits ivanyan http://rathena.org/board/tracker/issue-8212-server-crash-guild-retrieveitembound/ Started working on some source code documentation Renamed bank update SQL file to upgrade_20131105.sql --- conf/battle/misc.conf | 4 + conf/msg_conf/map_msg.conf | 6 + db/const.txt | 7 +- db/re/item_db.txt | 14 +- db/re/item_delay.txt | 8 + sql-files/item_db_re.sql | 14 +- ...rade_svn17600.sql => upgrade_20131105.sql} | 0 src/common/mmo.h | 3 +- src/map/atcommand.c | 5 + src/map/battle.c | 13 +- src/map/battle.h | 1 + src/map/clif.c | 30 +- src/map/guild.c | 2 +- src/map/script.c | 78 +++++ src/map/skill.c | 4 + src/map/status.c | 267 ++++++++++++------ src/map/status.h | 6 + 17 files changed, 351 insertions(+), 111 deletions(-) rename sql-files/upgrades/{upgrade_svn17600.sql => upgrade_20131105.sql} (100%) diff --git a/conf/battle/misc.conf b/conf/battle/misc.conf index 64690381a3..6e6507b93b 100644 --- a/conf/battle/misc.conf +++ b/conf/battle/misc.conf @@ -124,3 +124,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 enterting castles during WoE times +mon_trans_disable_in_gvg: no diff --git a/conf/msg_conf/map_msg.conf b/conf/msg_conf/map_msg.conf index b0650273fc..d152071f88 100644 --- a/conf/msg_conf/map_msg.conf +++ b/conf/msg_conf/map_msg.conf @@ -1506,5 +1506,11 @@ 1495: You can't withdraw that much money 1496: Banking is disabled +// Monster Transformation +1497: Traaaansformation-!! %s form!! +1498: Cannot transform into monster while in disguise. +1499: Character cannot be disguised while in monster form. +1500: Transforming into monster is not allowed in Guild Wars. + //Custom translations //import: conf/msg_conf/import/map_msg_eng_conf.txt diff --git a/db/const.txt b/db/const.txt index c1cbbd9992..d805aba916 100644 --- a/db/const.txt +++ b/db/const.txt @@ -1340,7 +1340,12 @@ SC_ANTI_M_BLAST 577 SC_B_TRAP 578 SC_H_MINE 579 SC_QD_SHOT_READY 580 -SC_EXTREMITYFIST2 581 +SC_MTF_ASPD 581 +SC_MTF_RANGEATK 582 +SC_MTF_MATK 583 +SC_MTF_MLEATKED 584 +SC_MTF_CRIDAMAGE 585 +SC_EXTREMITYFIST2 586 e_gasp 0 e_what 1 diff --git a/db/re/item_db.txt b/db/re/item_db.txt index 3ad1b1b933..398e491b02 100644 --- a/db/re/item_db.txt +++ b/db/re/item_db.txt @@ -5983,13 +5983,13 @@ 12655,Brain_Powder,Brain Powder,2,2000,,100,,,,,0xFFFFFFFF,63,2,,,,,,{},{},{} 12656,Magical_Powder,Magical Powder,2,3000,,200,,,,,0xFFFFFFFF,63,2,,,,,,{},{},{} 12657,Madness_Powder,Madness Powder,2,4000,,300,,,,,0xFFFFFFFF,63,2,,,,,,{},{},{} -12658,Trans_Scroll_Devi,Transformation Scroll(Deviruchi),2,20,,10,,,,,0xFFFFFFFF,63,2,,,,,,{},{},{} -12659,Trans_Scroll_Ray_Arch,Transformation Scroll(Raydric),2,20,,10,,,,,0xFFFFFFFF,63,2,,,,,,{},{},{} -12660,Trans_Scroll_Mavka,Transformation Scroll(Mavka),2,20,,10,,,,,0xFFFFFFFF,63,2,,,,,,{},{},{} -12661,Trans_Scroll_Marduk,Transformation Scroll(Marduk),2,20,,10,,,,,0xFFFFFFFF,63,2,,,,,,{},{},{} -12662,Trans_Scroll_Banshee,Transformation Scroll(Banshee),2,20,,10,,,,,0xFFFFFFFF,63,2,,,,,,{},{},{} -12663,Trans_Scroll_Poring,Transformation Scroll(Poring),2,20,,10,,,,,0xFFFFFFFF,63,2,,,,,,{},{},{} -12664,Trans_Scroll_Golem,Transformation Scroll(Golem),2,20,,10,,,,,0xFFFFFFFF,63,2,,,,,,{},{},{} +12658,Trans_Scroll_Devi,Transformation Scroll(Deviruchi),2,20,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ transform "Deviruchi",1200000,SC_MTF_ASPD; },{},{} +12659,Trans_Scroll_Ray_Arch,Transformation Scroll(Raydric),2,20,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ transform "Raydric Archer",1200000,SC_MTF_RANGEATK; },{},{} +12660,Trans_Scroll_Mavka,Transformation Scroll(Mavka),2,20,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ transform "Mavka",1200000,SC_MTF_RANGEATK; },{},{} +12661,Trans_Scroll_Marduk,Transformation Scroll(Marduk),2,20,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ transform "Marduk",1200000,SC_MTF_MATK; },{},{} +12662,Trans_Scroll_Banshee,Transformation Scroll(Banshee),2,20,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ transform "Banshee",1200000,SC_MTF_MATK; },{},{} +12663,Trans_Scroll_Poring,Transformation Scroll(Poring),2,20,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ transform "Poring",1200000,SC_MTF_CRIDAMAGE; },{},{} +12664,Trans_Scroll_Golem,Transformation Scroll(Golem),2,20,,10,,,,,0xFFFFFFFF,63,2,,,,,,{ transform "Golem",1200000,SC_MTF_MLEATKED; },{},{} 12665,Grovel_Buff,Grovel Buff,2,0,,0,,,,,0xFFFFFFFF,63,2,,,,,,{},{},{} 12666,Thai_Perfume_MATK,Thai Perfume MATK,2,20,,10,,,,,0xFFFFFFFF,63,2,,,,,,{},{},{} 12667,Thai_Perfume_ATK,Thai Perfume ATK,2,20,,10,,,,,0xFFFFFFFF,63,2,,,,,,{},{},{} diff --git a/db/re/item_delay.txt b/db/re/item_delay.txt index 47a5337564..86a84e3256 100644 --- a/db/re/item_delay.txt +++ b/db/re/item_delay.txt @@ -23,6 +23,14 @@ 11524,3000 // White_Raffle_Sap 11525,5000 // Mora_Hip_Tea +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) + // FIX ME! Delays need confirmation. 12968,300000 // Emergency_Scroll1 12969,300000 // Emergency_Scroll2 diff --git a/sql-files/item_db_re.sql b/sql-files/item_db_re.sql index 60a95dc8cb..9a6f3cf69b 100644 --- a/sql-files/item_db_re.sql +++ b/sql-files/item_db_re.sql @@ -6014,13 +6014,13 @@ REPLACE INTO `item_db_re` VALUES (12654,'Lucky_Egg_C9','Lucky Egg C9',2,20,NULL, REPLACE INTO `item_db_re` VALUES (12655,'Brain_Powder','Brain Powder',2,2000,NULL,100,NULL,NULL,NULL,NULL,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); REPLACE INTO `item_db_re` VALUES (12656,'Magical_Powder','Magical Powder',2,3000,NULL,200,NULL,NULL,NULL,NULL,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); REPLACE INTO `item_db_re` VALUES (12657,'Madness_Powder','Madness Powder',2,4000,NULL,300,NULL,NULL,NULL,NULL,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -REPLACE INTO `item_db_re` VALUES (12658,'Trans_Scroll_Devi','Transformation Scroll(Deviruchi)',2,20,NULL,10,NULL,NULL,NULL,NULL,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -REPLACE INTO `item_db_re` VALUES (12659,'Trans_Scroll_Ray_Arch','Transformation Scroll(Raydric)',2,20,NULL,10,NULL,NULL,NULL,NULL,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -REPLACE INTO `item_db_re` VALUES (12660,'Trans_Scroll_Mavka','Transformation Scroll(Mavka)',2,20,NULL,10,NULL,NULL,NULL,NULL,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -REPLACE INTO `item_db_re` VALUES (12661,'Trans_Scroll_Marduk','Transformation Scroll(Marduk)',2,20,NULL,10,NULL,NULL,NULL,NULL,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -REPLACE INTO `item_db_re` VALUES (12662,'Trans_Scroll_Banshee','Transformation Scroll(Banshee)',2,20,NULL,10,NULL,NULL,NULL,NULL,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -REPLACE INTO `item_db_re` VALUES (12663,'Trans_Scroll_Poring','Transformation Scroll(Poring)',2,20,NULL,10,NULL,NULL,NULL,NULL,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); -REPLACE INTO `item_db_re` VALUES (12664,'Trans_Scroll_Golem','Transformation Scroll(Golem)',2,20,NULL,10,NULL,NULL,NULL,NULL,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); +REPLACE INTO `item_db_re` VALUES (12658,'Trans_Scroll_Devi','Transformation Scroll(Deviruchi)',2,20,NULL,10,NULL,NULL,NULL,NULL,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,'transform "Deviruchi",1200000,SC_MTF_ASPD;',NULL,NULL); +REPLACE INTO `item_db_re` VALUES (12659,'Trans_Scroll_Ray_Arch','Transformation Scroll(Raydric)',2,20,NULL,10,NULL,NULL,NULL,NULL,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,'transform "Raydric Archer",1200000,SC_MTF_RANGEATK;',NULL,NULL); +REPLACE INTO `item_db_re` VALUES (12660,'Trans_Scroll_Mavka','Transformation Scroll(Mavka)',2,20,NULL,10,NULL,NULL,NULL,NULL,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,'transform "Mavka",1200000,SC_MTF_RANGEATK;',NULL,NULL); +REPLACE INTO `item_db_re` VALUES (12661,'Trans_Scroll_Marduk','Transformation Scroll(Marduk)',2,20,NULL,10,NULL,NULL,NULL,NULL,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,'transform "Marduk",1200000,SC_MTF_MATK;',NULL,NULL); +REPLACE INTO `item_db_re` VALUES (12662,'Trans_Scroll_Banshee','Transformation Scroll(Banshee)',2,20,NULL,10,NULL,NULL,NULL,NULL,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,'transform "Banshee",1200000,SC_MTF_MATK;',NULL,NULL); +REPLACE INTO `item_db_re` VALUES (12663,'Trans_Scroll_Poring','Transformation Scroll(Poring)',2,20,NULL,10,NULL,NULL,NULL,NULL,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,'transform "Poring",1200000,SC_MTF_CRIDAMAGE;',NULL,NULL); +REPLACE INTO `item_db_re` VALUES (12664,'Trans_Scroll_Golem','Transformation Scroll(Golem)',2,20,NULL,10,NULL,NULL,NULL,NULL,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,'transform "Golem",1200000,SC_MTF_MLEATKED;',NULL,NULL); REPLACE INTO `item_db_re` VALUES (12665,'Grovel_Buff','Grovel Buff',2,0,NULL,0,NULL,NULL,NULL,NULL,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); REPLACE INTO `item_db_re` VALUES (12666,'Thai_Perfume_MATK','Thai Perfume MATK',2,20,NULL,10,NULL,NULL,NULL,NULL,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); REPLACE INTO `item_db_re` VALUES (12667,'Thai_Perfume_ATK','Thai Perfume ATK',2,20,NULL,10,NULL,NULL,NULL,NULL,0xFFFFFFFF,63,2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql-files/upgrades/upgrade_svn17600.sql b/sql-files/upgrades/upgrade_20131105.sql similarity index 100% rename from sql-files/upgrades/upgrade_svn17600.sql rename to sql-files/upgrades/upgrade_20131105.sql diff --git a/src/common/mmo.h b/src/common/mmo.h index ec68cd4810..50e8049a6a 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -47,8 +47,7 @@ // 20120307 - 2012-03-07aRagexeRE+ - 0x970 #ifndef PACKETVER - #define PACKETVER 20130724 - //#define PACKETVER 20130320 + #define PACKETVER 20130807 //#define PACKETVER 20120410 #endif diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 7a10623b2c..f4240f360e 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -4828,6 +4828,11 @@ ACMD_FUNC(disguise) return -1; } + if (sd->sc.data[SC_MONSTER_TRANSFORM]) { + clif_displaymessage(fd, msg_txt(sd,1499)); // Character cannot be disguised while in monster transform. + return -1; + } + pc_disguise(sd, id); clif_displaymessage(fd, msg_txt(sd,122)); // Disguise applied. diff --git a/src/map/battle.c b/src/map/battle.c index 6f303782a1..8408a5f9c9 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -3896,6 +3896,11 @@ struct Damage battle_attack_sc_bonus(struct Damage wd, struct block_list *src, u ATK_ADD(wd.damage, wd.damage2, sc->data[SC_P_ALTER]->val2); RE_ALLATK_ADD(wd, sc->data[SC_P_ALTER]->val2); } + // Monster Transformation bonus + if(wd.flag&BF_LONG && sc->data[SC_MTF_RANGEATK]) { + ATK_ADD(wd.damage, wd.damage2, 25); + RE_ALLATK_ADD(wd, 25); + } } return wd; } @@ -4646,8 +4651,11 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl #ifdef RENEWAL if(is_attack_critical(wd, src, target, skill_id, skill_lv, false)) { - if(sd) // check for player so we don't crash out, monsters don't have bonus crit rates [helvetica] + if(sd) { // check for player so we don't crash out, monsters don't have bonus crit rates [helvetica] wd.damage = (int)floor((double)(wd.damage * 1.4 * (100 + sd->bonus.crit_atk_rate)) / 100); + if (sc && sc->data[SC_MTF_CRIDAMAGE]) // Monster Transformation Bonus + wd.damage *= (int)1.25; + } else wd.damage = (int)floor((double)wd.damage * 1.4); } @@ -6180,6 +6188,8 @@ 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(src, 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) @@ -7224,6 +7234,7 @@ static const struct _battle_data { { "bowling_bash_area", &battle_config.bowling_bash_area, 0, 0, 20, }, { "drop_rateincrease", &battle_config.drop_rateincrease, 0, 0, 1, }, { "feature.banking", &battle_config.feature_banking, 1, 0, 1, }, + { "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 6ffa6e1e50..30cd474438 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -495,6 +495,7 @@ extern struct Battle_Config int bowling_bash_area; int drop_rateincrease; int feature_banking; + int mon_trans_disable_in_gvg; } battle_config; diff --git a/src/map/clif.c b/src/map/clif.c index 6738a730f4..e9a96ecaa5 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -1345,6 +1345,15 @@ int clif_spawn(struct block_list *bl) #endif if (sd->status.robe) clif_refreshlook(bl,bl->id,LOOK_ROBE,sd->status.robe,AREA); + + if( sd->sc.data[SC_CAMOUFLAGE] ) + clif_status_load(bl,SI_CAMOUFLAGE,1); + if( sd->sc.data[SC_MONSTER_TRANSFORM] ) + clif_status_change(bl,SI_MONSTER_TRANSFORM,1,0,sd->sc.data[SC_MONSTER_TRANSFORM]->val1,0,0); + if( sd->sc.data[SC_MOONSTAR] ) + clif_status_load(bl,SI_MOONSTAR,1); + if( sd->sc.data[SC_SUPER_STAR] ) + clif_status_load(bl,SI_SUPER_STAR,1); } break; case BL_MOB: @@ -4156,10 +4165,17 @@ void clif_getareachar_unit(struct map_session_data* sd,struct block_list *bl) clif_specialeffect_single(bl,421,sd->fd); if( tsd->bg_id && map[tsd->bl.m].flag.battleground ) clif_sendbgemblem_single(sd->fd,tsd); - if( tsd->sc.data[SC_CAMOUFLAGE] ) - clif_status_load(bl,SI_CAMOUFLAGE,1); if ( tsd->status.robe ) clif_refreshlook(&sd->bl,bl->id,LOOK_ROBE,tsd->status.robe,SELF); + + if( tsd->sc.data[SC_CAMOUFLAGE] ) + clif_status_load(bl,SI_CAMOUFLAGE,1); + if( tsd->sc.data[SC_MONSTER_TRANSFORM] ) + clif_status_change(bl,SI_MONSTER_TRANSFORM,1,0,tsd->sc.data[SC_MONSTER_TRANSFORM]->val1,0,0); + if( tsd->sc.data[SC_MOONSTAR] ) + clif_status_load(bl,SI_MOONSTAR,1); + if( tsd->sc.data[SC_SUPER_STAR] ) + clif_status_load(bl,SI_SUPER_STAR,1); } break; case BL_MER: // Devotion Effects @@ -9655,6 +9671,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_displaymessage(sd->fd, msg_txt(sd,1500)); // 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) @@ -9670,10 +9691,8 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) // If player is dead, and is spawned (such as @refresh) send death packet. [Valaris] if(pc_isdead(sd)) clif_clearunit_area(&sd->bl, CLR_DEAD); - else { + else skill_usave_trigger(sd); - clif_changed_dir(&sd->bl, SELF); - } // Trigger skill effects if you appear standing on them if(!battle_config.pc_invincible_time) @@ -16564,6 +16583,7 @@ int clif_autoshadowspell_list(struct map_session_data *sd) { return 1; } + /*=========================================== * Skill list for Four Elemental Analysis * and Change Material skills. diff --git a/src/map/guild.c b/src/map/guild.c index abd2aa0268..5a945ad5cd 100644 --- a/src/map/guild.c +++ b/src/map/guild.c @@ -920,7 +920,7 @@ void guild_retrieveitembound(int char_id,int aid,int guild_id) for(i=0; imax_member; i++){ TBL_PC *pl_sd = g->member[i].sd; if(pl_sd && pl_sd->state.storage_flag == 2) - storage_guild_storageclose(sd); + storage_guild_storageclose(pl_sd); } } intif_itembound_req(char_id,aid,guild_id); diff --git a/src/map/script.c b/src/map/script.c index f2a72cc080..9bc4115bbe 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -18015,6 +18015,82 @@ BUILDIN_FUNC(getserverdef){ return 0; } +/*========================================== + * Turns a player into a monster and grants SC attribute effect. [malufett/Hercules] + * montransform , , , , , , ; + *------------------------------------------*/ +BUILDIN_FUNC(montransform) { + + TBL_PC *sd; + enum sc_type type; + char msg[CHAT_SIZE_MAX]; + int tick, mob_id, val1, val2, val3, val4; + + if( (sd = script_rid2sd(st)) == NULL ) + return 1; + + if( script_isstring(st, 2) ) + mob_id = mobdb_searchname(script_getstr(st, 2)); + else + mob_id = mobdb_checkid(script_getnum(st, 2)); + + tick = script_getnum(st, 3); + type = (sc_type)script_getnum(st, 4); + val1 = val2 = val3 = val4 = 0; + + if (mob_id == 0) { + if( script_isstring(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 0; + } + + if (mob_id == MOBID_EMPERIUM) { + ShowWarning("buildin_montransform: Monster 'Emperium' cannot be used.\n"); + return 0; + } + + if (!(type > SC_NONE && type < SC_MAX)) { + ShowWarning("buildin_montransform: Unsupported status change id %d\n", type); + return 0; + } + + 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 mob_db *monster = mob_db(mob_id); + + if (battle_config.mon_trans_disable_in_gvg && map_flag_gvg2(sd->bl.m)) { + clif_displaymessage(sd->fd, msg_txt(sd,1500)); // Transforming into monster is not allowed in Guild Wars. + return 0; + } + + if (sd->disguise){ + clif_displaymessage(sd->fd, msg_txt(sd,1498)); // Cannot transform into monster while in disguise. + return 0; + } + + sprintf(msg, msg_txt(sd,1497), monster->name); // Traaaansformation-!! %s form!! + clif_disp_overhead(&sd->bl, msg); + status_change_end(&sd->bl, SC_MONSTER_TRANSFORM, INVALID_TIMER); // Clear previous + sc_start2(NULL, &sd->bl, SC_MONSTER_TRANSFORM, 100, mob_id, type, tick); + sc_start4(NULL, &sd->bl, type, 100, val1, val2, val3, val4, tick); + } + + return 0; +} + #include "../custom/script.inc" // declarations that were supposed to be exported from npc_chat.c @@ -18495,6 +18571,8 @@ struct script_function buildin_func[] = { BUILDIN_DEF(is_clientver,"ii?"), BUILDIN_DEF(getserverdef,"i"), + BUILDIN_DEF2(montransform, "transform", "vii????"), // Monster Transform [malufett/Hercules] + #include "../custom/script_def.inc" {NULL,NULL,NULL}, diff --git a/src/map/skill.c b/src/map/skill.c index 2186cb6576..2992cebba1 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -6882,6 +6882,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case SC_HEAT_BARREL: case SC_HEAT_BARREL_AFTER: case SC_P_ALTER: case SC_E_CHAIN: case SC_C_MARKER: case SC_B_TRAP: case SC_H_MINE: + case SC_MTF_ASPD: case SC_MTF_RANGEATK: case SC_MTF_MATK: + case SC_MTF_MLEATKED: case SC_MTF_CRIDAMAGE: #ifdef RENEWAL case SC_EXTREMITYFIST2: #endif @@ -8365,6 +8367,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case SC_HEAT_BARREL: case SC_HEAT_BARREL_AFTER: case SC_P_ALTER: case SC_E_CHAIN: case SC_C_MARKER: case SC_B_TRAP: case SC_H_MINE: + case SC_MTF_ASPD: case SC_MTF_RANGEATK: case SC_MTF_MATK: + case SC_MTF_MLEATKED: case SC_MTF_CRIDAMAGE: #ifdef RENEWAL case SC_EXTREMITYFIST2: #endif diff --git a/src/map/status.c b/src/map/status.c index f8b3c7c362..15e55e7eb6 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -1019,6 +1019,10 @@ void initChangeTables(void) { StatusChangeFlagTable[SC_MOONSTAR] |= SCB_NONE; StatusChangeFlagTable[SC_SUPER_STAR] |= SCB_NONE; + StatusChangeFlagTable[SC_MTF_ASPD] = SCB_ASPD|SCB_HIT; + StatusChangeFlagTable[SC_MTF_MATK] = SCB_MATK; + StatusChangeFlagTable[SC_MTF_MLEATKED] |= SCB_ALL; + #ifdef RENEWAL // renewal EDP increases your weapon atk StatusChangeFlagTable[SC_EDP] |= SCB_WATK; @@ -3150,6 +3154,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 ) @@ -4842,8 +4848,10 @@ static unsigned short status_calc_matk(struct block_list *bl, struct status_chan matk += matk * sc->data[SC_MELODYOFSINK]->val3/100; if (sc->data[SC_BEYONDOFWARCRY]) matk -= matk * sc->data[SC_BEYONDOFWARCRY]->val3/100; - if( sc->data[SC_ZANGETSU] ) + if (sc->data[SC_ZANGETSU]) matk += matk * sc->data[SC_ZANGETSU]->val2 / 100; + if (sc->data[SC_MTF_MATK]) + matk += matk * 25 / 100; return (unsigned short)cap_value(matk,0,USHRT_MAX); } @@ -4861,18 +4869,18 @@ static signed short status_calc_critical(struct block_list *bl, struct status_ch critical += sc->data[SC_FORTUNE]->val2; if (sc->data[SC_TRUESIGHT]) critical += sc->data[SC_TRUESIGHT]->val2; - if(sc->data[SC_CLOAKING]) + if (sc->data[SC_CLOAKING]) critical += critical; - if(sc->data[SC_STRIKING]) + if (sc->data[SC_STRIKING]) critical += sc->data[SC_STRIKING]->val1*10; #ifdef RENEWAL if (sc->data[SC_SPEARQUICKEN]) critical += 3*sc->data[SC_SPEARQUICKEN]->val1*10; #endif - if(sc->data[SC__INVISIBILITY]) + if (sc->data[SC__INVISIBILITY]) critical += critical * sc->data[SC__INVISIBILITY]->val3 / 100; - if(sc->data[SC__UNLUCKY]) + if (sc->data[SC__UNLUCKY]) critical -= critical * sc->data[SC__UNLUCKY]->val2 / 100; return (short)cap_value(critical,10,SHRT_MAX); @@ -4917,6 +4925,8 @@ static signed short status_calc_hit(struct block_list *bl, struct status_change hit -= hit * (5 + sc->data[SC_ILLUSIONDOPING]->val1) / 100; //Custom if(sc->data[SC_HEAT_BARREL]) hit -= sc->data[SC_HEAT_BARREL]->val4; + if (sc->data[SC_MTF_ASPD]) + hit += 5; return (short)cap_value(hit,1,SHRT_MAX); } @@ -5427,8 +5437,15 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha } #ifdef RENEWAL_ASPD -// flag&1 - fixed value [malufett] -// flag&2 - percentage value +/*========================================== +* Renewal attack speed modifiers after base calculation +* Note: This function only affects RENEWAL players +* @param bl: Object to change aspd (PC) +* @param sc: Object's status change information +* @param flag: flag&1 - fixed value [malufett] +* flag&2 - percentage value +* @return modified aspd +*------------------------------------------*/ static short status_calc_aspd(struct block_list *bl, struct status_change *sc, short flag) { int i, pots = 0, skills1 = 0, skills2 = 0; @@ -5552,26 +5569,44 @@ static short status_calc_aspd(struct block_list *bl, struct status_change *sc, s } #endif +/*========================================== +* Modifies ASPD by a number, rather than a percentage (10 = 1 ASPD) +* A subtraction reduces the delay, meaning an increase in ASPD +* Note: This comes after the percentage changes +* @param bl: Object to change aspd (PC|HOM|MERC|MOB|ELEM) +* @param sc: Object's status change information +* @param aspd: Object's current ASPD +* @return modified aspd +*------------------------------------------*/ static short status_calc_fix_aspd(struct block_list *bl, struct status_change *sc, int aspd) { - if (!sc || !sc->count) - return cap_value(aspd, 0, 2000); + if (!sc || !sc->count) + return cap_value(aspd, 0, 2000); - if (!sc->data[SC_QUAGMIRE]) { - if (sc->data[SC_OVERED_BOOST]) + if (!sc->data[SC_QUAGMIRE]) { + if (sc->data[SC_OVERED_BOOST]) aspd = 2000 - sc->data[SC_OVERED_BOOST]->val3*10; - } + } if ((sc->data[SC_GUST_OPTION] || sc->data[SC_BLAST_OPTION] || sc->data[SC_WILD_STORM_OPTION])) aspd -= 50; // +5 ASPD - if( sc && sc->data[SC_FIGHTINGSPIRIT] && sc->data[SC_FIGHTINGSPIRIT]->val2 ) + if (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->data[SC_MTF_ASPD]) + aspd -= 10; - return cap_value(aspd, 0, 2000); // will be recap for proper bl anyway + return cap_value(aspd, 0, 2000); // will be recap for proper bl anyway } -/// Calculates an object's ASPD modifier (alters the base amotion value). -/// Note that the scale of aspd_rate is 1000 = 100%. +/*========================================== +* Calculates an object's ASPD modifier (alters the base amotion value). +* Note: The scale of aspd_rate is 1000 = 100%. +* Note2: This only affects Homunculus, Mercenaries, and Pre-renewal Players +* @param bl: Object to change aspd (PC|HOM|MERC|MOB|ELEM) +* @param sc: Object's status change information +* @param aspd_rate: Object's current ASPD +* @return modified aspd_rate +*------------------------------------------*/ static short status_calc_aspd_rate(struct block_list *bl, struct status_change *sc, int aspd_rate) { int i; @@ -5709,6 +5744,14 @@ static short status_calc_aspd_rate(struct block_list *bl, struct status_change * return (short)cap_value(aspd_rate,0,SHRT_MAX); } +/*========================================== +* Modifies the damage delay time +* The lower your delay, the quicker you can act after taking damage +* @param bl: Object to change aspd (PC|HOM|MERC|MOB|ELEM) +* @param sc: Object's status change information +* @param dmotion: Object's current damage delay +* @return modified delay rate +*------------------------------------------*/ static unsigned short status_calc_dmotion(struct block_list *bl, struct status_change *sc, int dmotion) { if( !sc || !sc->count || map_flag_gvg(bl->m) || map[bl->m].flag.battleground ) @@ -5726,6 +5769,16 @@ static unsigned short status_calc_dmotion(struct block_list *bl, struct status_c return (unsigned short)cap_value(dmotion,0,USHRT_MAX); } +/*========================================== +* Calculates a player's max HP +* Values can either be percentages or fixed, based on how equations are formulated +* Examples: maxhp += maxhp * value; (percentage increase) +* maxhp -= value (fixed decrease) +* @param bl: Object to change aspd (PC|HOM|MERC|MOB|ELEM) +* @param sc: Object's status change information +* @param maxhp: Object's current max HP +* @return modified maxhp +*------------------------------------------*/ static unsigned int status_calc_maxhp(struct block_list *bl, struct status_change *sc, uint64 maxhp) { if(!sc || !sc->count) @@ -5744,7 +5797,7 @@ static unsigned int status_calc_maxhp(struct block_list *bl, struct status_chang if(sc->data[SC_MARIONETTE]) maxhp -= 1000; if(sc->data[SC_SOLID_SKIN_OPTION]) - maxhp += 2000;// Fix amount. + maxhp += 2000; if(sc->data[SC_POWER_OF_GAIA]) maxhp += 3000; if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 2) @@ -5790,6 +5843,16 @@ static unsigned int status_calc_maxhp(struct block_list *bl, struct status_chang return (unsigned int)cap_value(maxhp,1,UINT_MAX); } +/*========================================== +* Calculates a player's max SP +* Values can either be percentages or fixed, bas ed on how equations are formulated +* Examples: maxsp += maxhp * value; (percentage increase) +* maxsp -= value (fixed decrease) +* @param bl: Object to change aspd (PC|HOM|MERC|MOB|ELEM) +* @param sc: Object's status change information +* @param maxsp: Object's current max SP +* @return modified maxsp +*------------------------------------------*/ static unsigned int status_calc_maxsp(struct block_list *bl, struct status_change *sc, unsigned int maxsp) { if(!sc || !sc->count) @@ -5813,6 +5876,13 @@ static unsigned int status_calc_maxsp(struct block_list *bl, struct status_chang return cap_value(maxsp,1,UINT_MAX); } +/*========================================== +* Changes a player's element based on status changes +* @param bl: Object to change aspd (PC|HOM|MERC|MOB|ELEM) +* @param sc: Object's status change information +* @param element: Object's current element +* @return new element +*------------------------------------------*/ static unsigned char status_calc_element(struct block_list *bl, struct status_change *sc, int element) { if(!sc || !sc->count) @@ -5834,6 +5904,13 @@ static unsigned char status_calc_element(struct block_list *bl, struct status_ch return (unsigned char)cap_value(element,0,UCHAR_MAX); } +/*========================================== +* Changes a player's element level based on status changes +* @param bl: Object to change aspd (PC|HOM|MERC|MOB|ELEM) +* @param sc: Object's status change information +* @param lv: Object's current element level +* @return new element level +*------------------------------------------*/ static unsigned char status_calc_element_lv(struct block_list *bl, struct status_change *sc, int lv) { if(!sc || !sc->count) @@ -5857,7 +5934,13 @@ static unsigned char status_calc_element_lv(struct block_list *bl, struct status return (unsigned char)cap_value(lv,1,4); } - +/*========================================== +* Changes a player's attack element based on status changes +* @param bl: Object to change aspd (PC|HOM|MERC|MOB|ELEM) +* @param sc: Object's status change information +* @param element: Object's current attack element +* @return new attack element +*------------------------------------------*/ unsigned char status_calc_attack_element(struct block_list *bl, struct status_change *sc, int element) { if(!sc || !sc->count) @@ -8351,9 +8434,6 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty if( sd ) val1 = sd->status.job_level * pc_checkskill(sd, RK_RUNEMASTERY) / 4; //DEF/MDEF Increase break; - case SC_FIGHTINGSPIRIT: - val_flag |= 1|2; - break; case SC_ABUNDANCE: val4 = tick / 10000; tick_time = 10000; // [GodLesZ] tick time @@ -8373,16 +8453,11 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty 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; @@ -8405,13 +8480,9 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty 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 @@ -8421,7 +8492,6 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty 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_READING_SB: // val2 = sp reduction per second @@ -8438,7 +8508,6 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty if( val4 < 1 ) val4 = 1; tick_time = 1000; // [GodLesZ] tick time - val_flag |= 1; break; case SC_SHAPESHIFT: switch( val1 ) @@ -8470,7 +8539,6 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty if( s_sd ) s_sd->shadowform_id = bl->id; val4 = tick / 1000; - val_flag |= 1|2|4; tick_time = 1000; // [GodLesZ] tick time } break; @@ -8483,17 +8551,14 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty 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); @@ -8509,7 +8574,6 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty case SC__LAZINESS: val2 = 10 + 10 * val1; // Cast Increase val3 = 10 * val1; // Flee Reduction - val_flag |= 1|2|4; break; case SC__UNLUCKY: { @@ -8520,13 +8584,11 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty default: rand_eff = SC_POISON; break; } val2 = 10 * val1; // Crit and Flee2 Reduction - val_flag |= 1|2|4; status_change_start(src,bl,rand_eff,10000,val1,0,0,0,tick,10); break; } case SC__WEAKNESS: val2 = 10 * val1; - val_flag |= 1|2; // bypasses coating protection and MADO sc_start(src,bl,SC_STRIPWEAPON,100,val1,tick); sc_start(src,bl,SC_STRIPSHIELD,100,val1,tick); @@ -8540,7 +8602,6 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty val2 = 100; break; case SC_PROPERTYWALK: - val_flag |= 1|2; val3 = 0; break; case SC_STRIKING: @@ -8652,7 +8713,6 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty val3 = 5 + (2 * val1); // Max rage counters tick = -1; //endless duration in the client tick_time = 6000; // [GodLesZ] tick time - val_flag |= 1|2|4; break; case SC_EXEEDBREAK: val1 *= 150; // 150 * skill_lv @@ -8668,16 +8728,9 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty val1 *= 15; // Defence added if( sd ) val1 += 10 * pc_checkskill(sd,CR_DEFENDER); - val_flag |= 1|2; break; case SC_BANDING: tick_time = 5000; // [GodLesZ] tick time - val_flag |= 1; - break; - case SC_SHIELDSPELL_DEF: - case SC_SHIELDSPELL_MDEF: - case SC_SHIELDSPELL_REF: - val_flag |= 1|2; break; case SC_MAGNETICFIELD: val3 = tick / 1000; @@ -8693,18 +8746,12 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty 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: if( sd ) val2 = (sd->status.job_level / 2) + (50 + 5 * 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; - val_flag |= 1; break; case SC_RAISINGDRAGON: val3 = tick / 5000; @@ -8726,14 +8773,10 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty 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) @@ -8741,21 +8784,15 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty 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. @@ -8763,30 +8800,24 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty 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: @@ -8808,7 +8839,6 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty 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. @@ -8957,8 +8987,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty break; case SC_MONSTER_TRANSFORM: if( !mobdb_checkid(val1) ) - val1 = 1002; //Default poring - val_flag |= 1; + val1 = 1002; //Default poring break; /** @@ -9022,6 +9051,66 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty break; } + /* values that must be set regardless of flag&4 e.g. val_flag [Ind]*/ + switch(type) { +// Start |1 val_flag setting + case SC_ROLLINGCUTTER: + case SC_BANDING: + case SC_SPHERE_1: + case SC_SPHERE_2: + case SC_SPHERE_3: + case SC_SPHERE_4: + case SC_SPHERE_5: + case SC_LIGHTNINGWALK: + case SC_MONSTER_TRANSFORM: + case SC_EXPBOOST: + case SC_JEXPBOOST: + case SC_ITEMBOOST: + val_flag |= 1; + break; +// Start |1|2 val_flag setting + case SC_FIGHTINGSPIRIT: + case SC_VENOMIMPRESS: + case SC_WEAPONBLOCKING: + case SC__INVISIBILITY: + case SC__ENERVATION: + case SC__WEAKNESS: + case SC_PROPERTYWALK: + case SC_PRESTIGE: + case SC_SHIELDSPELL_DEF: + case SC_SHIELDSPELL_MDEF: + case SC_SHIELDSPELL_REF: + case SC_CRESCENTELBOW: + case SC_CHILLY_AIR_OPTION: + case SC_GUST_OPTION: + case SC_WILD_STORM_OPTION: + case SC_UPHEAVAL_OPTION: + case SC_CIRCLE_OF_FIRE_OPTION: + val_flag |= 1|2; + break; +// Start |1|2|4 val_flag setting + case SC_POISONINGWEAPON: + case SC_CLOAKINGEXCEED: + case SC_HALLUCINATIONWALK: + case SC__SHADOWFORM: + case SC__GROOMY: + case SC__LAZINESS: + case SC__UNLUCKY: + case SC_FORCEOFVANGUARD: + case SC_SPELLFIST: + case SC_CURSEDCIRCLE_ATKER: + case SC_PYROTECHNIC_OPTION: + case SC_HEATER_OPTION: + case SC_AQUAPLAY_OPTION: + case SC_COOLER_OPTION: + case SC_BLAST_OPTION: + case SC_PETROLOGY_OPTION: + case SC_CURSED_SOIL_OPTION: + case SC_WATER_BARRIER: + val_flag |= 1|2|4; + break; + } + //Those that make you stop attacking/walking.... switch (type) { case SC_FREEZE: @@ -9084,27 +9173,27 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty 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_DEEPSLEEP: 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_STONE: sc->opt1 = OPT1_STONEWAIT; break; + case SC_FREEZE: sc->opt1 = OPT1_FREEZE; break; + case SC_STUN: sc->opt1 = OPT1_STUN; break; + case SC_DEEPSLEEP: 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_CRYSTALIZE: sc->opt1 = OPT1_CRYSTALIZE; break; + case SC_CRYSTALIZE: 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_POISON: sc->opt2 |= OPT2_POISON; break; + case SC_CURSE: sc->opt2 |= OPT2_CURSE; break; + case SC_SILENCE: sc->opt2 |= OPT2_SILENCE; break; case SC_SIGNUMCRUCIS: sc->opt2 |= OPT2_SIGNUMCRUCIS; break; - case SC_BLIND: sc->opt2 |= OPT2_BLIND; break; - case SC_ANGELUS: sc->opt2 |= OPT2_ANGELUS; break; - case SC_BLEEDING: sc->opt2 |= OPT2_BLEEDING; break; - case SC_DPOISON: sc->opt2 |= OPT2_DPOISON; break; + case SC_BLIND: sc->opt2 |= OPT2_BLIND; break; + case SC_ANGELUS: sc->opt2 |= OPT2_ANGELUS; break; + case SC_BLEEDING: sc->opt2 |= OPT2_BLEEDING; break; + case SC_DPOISON: sc->opt2 |= OPT2_DPOISON; break; //OPT3 case SC_TWOHANDQUICKEN: case SC_ONEHAND: @@ -9855,6 +9944,10 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const status_change_end(tbl, SC_STOP, INVALID_TIMER); } break; + case SC_MONSTER_TRANSFORM: + if (sce->val2) + status_change_end(bl, (sc_type)sce->val2, INVALID_TIMER); + break; /** * 3rd Stuff **/ diff --git a/src/map/status.h b/src/map/status.h index 30056a980e..2de17be010 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -679,6 +679,12 @@ typedef enum sc_type { SC_H_MINE, SC_QD_SHOT_READY, + SC_MTF_ASPD, + SC_MTF_RANGEATK, + SC_MTF_MATK, + SC_MTF_MLEATKED, + SC_MTF_CRIDAMAGE, + #ifdef RENEWAL SC_EXTREMITYFIST2, #endif