summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
authormalufett <malufett.eat.my.binaries@gmail.com>2013-10-16 03:11:25 +0800
committermalufett <malufett.eat.my.binaries@gmail.com>2013-10-16 03:11:25 +0800
commit9692bc034537693d331148ae8bd15153265c6cf0 (patch)
tree274e4f14e69802e5bfd59976f3a7bf7649f98ab8 /src/map
parent3e58e470d0bfc5e615246ef6a7ffff6a1190e0c9 (diff)
downloadhercules-9692bc034537693d331148ae8bd15153265c6cf0.tar.gz
hercules-9692bc034537693d331148ae8bd15153265c6cf0.tar.bz2
hercules-9692bc034537693d331148ae8bd15153265c6cf0.tar.xz
hercules-9692bc034537693d331148ae8bd15153265c6cf0.zip
Fixed Bug#7374
-Hercules now fully support Monster Transformation. Signed-off-by: malufett <malufett.eat.my.binaries@gmail.com>
Diffstat (limited to 'src/map')
-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
7 files changed, 145 insertions, 2 deletions
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