summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--conf/battle/misc.conf4
-rw-r--r--conf/messages.conf6
-rw-r--r--db/const.txt6
-rw-r--r--db/item_delay.txt7
-rw-r--r--db/re/item_db.txt14
-rw-r--r--db/sc_config.txt5
-rw-r--r--src/map/atcommand.c8
-rw-r--r--src/map/battle.c9
-rw-r--r--src/map/battle.h2
-rw-r--r--src/map/clif.c5
-rw-r--r--src/map/script.c75
-rw-r--r--src/map/status.c16
-rw-r--r--src/map/status.h32
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 <monster name>, <duration>, <sc type>, <val1>, <val2>, <val3>, <val4>; */
+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