diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index 8ee47f81ea..39755fcd40 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -4,6 +4,23 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. 2006/03/30 + * the auth function in login.c won't jstrescapecpy passwords that were + encrypted. Thanks to foobar. (but are still more cases to check for? Dunno, + the code is kinda long...) [Skotlex] + * Endure level 11 and above are now considered infinite-endure, and invoked + when Berserk is active. [Skotlex] + * Set the minimum pet hungry delay to 10 [Skotlex] + * modified functions skill_delayfix and skill_castfix to reduce number of + arguments. Added function skill_castfix_sc for mobs (who only get status + change cast reductions, not dex based ones). Also, skill_delayfix will + never return a value below min_skill_delay_limit. [Skotlex] + * Modified brandish spear so you won't see the skill-animation for every + targetted mob. [Skotlex] + * Added the Steel Body icon to auto-berserk. [Skotlex] + * Now you can't cast auto-counter while the previous one is active. + [Skotlex] + * Added Veider's suggestion to do a hack-report when players request the + name of an invisible/cloaked character. [Skotlex] * Added execution of OnInterIfInit, OnCharIfInit and OnInterIfInitOnce on script reload. [Lance] * Cleaned up mistakes in irc.c [Lance] diff --git a/src/login_sql/login.c b/src/login_sql/login.c index edc78d48fe..1fad6f4dc1 100644 --- a/src/login_sql/login.c +++ b/src/login_sql/login.c @@ -598,7 +598,12 @@ int mmo_auth( struct mmo_account* account , int fd){ strftime(tmpstr, 24, "%Y-%m-%d %H:%M:%S",localtime(&raw_time)); jstrescapecpy(t_uid,account->userid); - jstrescapecpy(t_pass, account->passwd); + + if (account.passwdenc==PASSWORDENC) { + memset(t_pass, 0, sizeof(t_pass)); + memcpy(t_pass, account->passwd, strlen(account->passwd)); + } else + jstrescapecpy(t_pass, account->passwd); // make query diff --git a/src/map/battle.c b/src/map/battle.c index dbd706e07a..479a2c0e11 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -160,12 +160,12 @@ int battle_delay_damage (unsigned int tick, struct block_list *src, struct block } // Žΐ?Ϋ‚ΙHP‚π‘€?μ -int battle_damage(struct block_list *bl,struct block_list *target,int damage, int flag) +int battle_damage(struct block_list *src,struct block_list *target,int damage, int flag) { struct map_session_data *sd = NULL; struct status_change *sc; - nullpo_retr(0, target); //bl‚ΝNULL‚ΕŒΔ‚Ξ‚κ‚ι‚±‚Ζ‚ͺ‚ ‚ι‚Μ‚Ε‘Ό‚Εƒ`ƒFƒbƒN + nullpo_retr(0, target); //stc‚ΝNULL‚ΕŒΔ‚Ξ‚κ‚ι‚±‚Ζ‚ͺ‚ ‚ι‚Μ‚Ε‘Ό‚Εƒ`ƒFƒbƒN sc = status_get_sc(target); @@ -174,16 +174,14 @@ int battle_damage(struct block_list *bl,struct block_list *target,int damage, in target->type == BL_PET) return 0; - if (bl) { - if (bl->prev == NULL) + if (src) { + if (src->prev == NULL) return 0; - if (bl->type == BL_PC) { - nullpo_retr(0, sd = (struct map_session_data *)bl); - } + BL_CAST(BL_PC, src, sd); } if (damage < 0) - return battle_heal(bl,target,-damage,0,flag); + return battle_heal(src,target,-damage,0,flag); if (!flag && sc && sc->count) { // “€Œ‹?A?Ξ‰»?A?‡–°‚π?Α‹Ž @@ -205,14 +203,30 @@ int battle_damage(struct block_list *bl,struct block_list *target,int damage, in status_change_end(target, SC_CLOAKING, -1); if (sc->data[SC_CHASEWALK].timer != -1) status_change_end(target, SC_CHASEWALK, -1); + if (sc->data[SC_ENDURE].timer != -1 && sc->data[SC_ENDURE].val1 <= 10) { + //Endure count is only reduced by non-players on non-gvg maps. + //if val1 is greater than 10, this is infinite endure. [Skotlex] + if (src && src->type != BL_PC && !map_flag_gvg(target->m) + && --(sc->data[SC_ENDURE].val2) < 0) + status_change_end(target, SC_ENDURE, -1); + } + if (sc->data[SC_GRAVITATION].timer != -1 && + sc->data[SC_GRAVITATION].val3 == BCT_SELF) { + struct skill_unit_group *sg = (struct skill_unit_group *)sc->data[SC_GRAVITATION].val4; + if (sg) { + skill_delunitgroup(sg); + sc->data[SC_GRAVITATION].val4 = 0; + status_change_end(target, SC_GRAVITATION, -1); + } + } } - - if (sc && sc->count && sc->data[SC_DEVOTION].val1 && bl && battle_getcurrentskill(bl) != PA_PRESSURE) + + if (sc && sc->count && sc->data[SC_DEVOTION].val1 && src && battle_getcurrentskill(src) != PA_PRESSURE) { //Devotion only works on attacks from a source (to prevent it from absorbing coma) [Skotlex] struct map_session_data *sd2 = map_id2sd(sc->data[SC_DEVOTION].val1); if (sd2 && sd2->devotion[sc->data[SC_DEVOTION].val2] == target->id) { - clif_damage(bl, &sd2->bl, gettick(), 0, 0, damage, 0, 0, 0); + clif_damage(src, &sd2->bl, gettick(), 0, 0, damage, 0, 0, 0); pc_damage(&sd2->bl, sd2, damage); return 0; } else @@ -220,11 +234,11 @@ int battle_damage(struct block_list *bl,struct block_list *target,int damage, in } unit_skillcastcancel(target, 2); if (target->type == BL_MOB) { - return mob_damage(bl,(TBL_MOB*)target, damage,0); + return mob_damage(src,(TBL_MOB*)target, damage,0); } else if (target->type == BL_PC) { - return pc_damage(bl,(TBL_PC*)target,damage); + return pc_damage(src,(TBL_PC*)target,damage); } else if (target->type == BL_SKILL) - return skill_unit_ondamaged((struct skill_unit *)target, bl, damage, gettick()); + return skill_unit_ondamaged((struct skill_unit *)target, src, damage, gettick()); return 0; } @@ -4305,6 +4319,9 @@ void battle_validate_conf() { if(battle_config.pet_support_min_friendly > 950) //Capped to 950/1000 [Skotlex] battle_config.pet_support_min_friendly = 950; + if(battle_config.pet_hungry_delay_rate < 10) + battle_config.pet_hungry_delay_rate=10; + if(battle_config.pet_max_atk1 > battle_config.pet_max_atk2) //Skotlex battle_config.pet_max_atk1 = battle_config.pet_max_atk2; diff --git a/src/map/clif.c b/src/map/clif.c index 7722c70ca1..38a4ec5308 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -9109,6 +9109,7 @@ void check_fake_id(int fd, struct map_session_data *sd, int target_id) { void clif_parse_GetCharNameRequest(int fd, struct map_session_data *sd) { int account_id; struct block_list* bl; + struct status_change *sc; RFIFOHEAD(fd); account_id = RFIFOL(fd,packet_db[sd->packet_ver][RFIFOW(fd,0)].pos[0]); @@ -9116,8 +9117,23 @@ void clif_parse_GetCharNameRequest(int fd, struct map_session_data *sd) { account_id-=account_id*2; //Is this possible? Lagged clients could request names of already gone mobs/players. [Skotlex] - if ((bl = map_id2bl(account_id)) != NULL) + if ((bl = map_id2bl(account_id)) != NULL) { + sc = status_get_sc(bl); + if (sc && ( + (sc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) && !sd->special_state.intravision) || + sc->option&OPTION_INVISIBLE) + ) { + //Asked name of invisible player, this shouldn't be possible! + //Possible bot? Thanks to veider and qspirit + unsigned char gm_msg[256]; + sprintf(gm_msg, "Hack on NameRequest: character '%s' (account: %d) requests name of invisible chars.", sd->status.name, sd->status.account_id); + ShowWarning(gm_msg); + // information is sended to all online GM + intif_wis_message_to_gm(wisp_server_name, battle_config.hack_info_GM_level, gm_msg); + return; + } clif_charnameack(fd, bl); + } } /*========================================== diff --git a/src/map/mob.c b/src/map/mob.c index ffbbfbd43e..30021c345a 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -2836,7 +2836,7 @@ int mobskill_use(struct mob_data *md, unsigned int tick, int event) } md->skillidx = i; flag = unit_skilluse_pos2(&md->bl, x, y, ms[i].skill_id, ms[i].skill_lv, - skill_castfix(&md->bl,ms[i].skill_id, ms[i].skill_lv, ms[i].casttime), ms[i].cancel); + skill_castfix_sc(&md->bl, ms[i].casttime), ms[i].cancel); if (!flag) md->skillidx = -1; //Skill failed. return flag; } else { @@ -2867,7 +2867,7 @@ int mobskill_use(struct mob_data *md, unsigned int tick, int event) } md->skillidx = i; flag = (bl && unit_skilluse_id2(&md->bl, bl->id, ms[i].skill_id, ms[i].skill_lv, - skill_castfix(&md->bl,ms[i].skill_id, ms[i].skill_lv, ms[i].casttime), ms[i].cancel)); + skill_castfix_sc(&md->bl,ms[i].casttime), ms[i].cancel)); if (!flag) md->skillidx = -1; return flag; } else { @@ -3016,8 +3016,8 @@ int mob_clone_spawn(struct map_session_data *sd, char *map, int x, int y, const ms[i].permillage = 500; //Default chance for moving/idle skills. ms[i].emotion = -1; ms[i].cancel = 0; - ms[i].delay = 5000+skill_delayfix(&sd->bl,skill_id, ms[i].skill_lv, 0); - ms[i].casttime = skill_castfix(&sd->bl,skill_id, ms[i].skill_lv, 0); + ms[i].delay = 5000+skill_delayfix(&sd->bl,skill_id, ms[i].skill_lv); + ms[i].casttime = skill_castfix(&sd->bl,skill_id, ms[i].skill_lv); inf = skill_get_inf(skill_id); if (inf&INF_ATTACK_SKILL) { diff --git a/src/map/pc.c b/src/map/pc.c index 57f4b8d501..815a033912 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -1475,7 +1475,7 @@ int pc_bonus(struct map_session_data *sd,int type,int val) if(sd->state.lr_flag != 2) { sd->special_state.infinite_endure = 1; if (sd->sc.data[SC_ENDURE].timer == -1) - sc_start(&sd->bl, SC_ENDURE,100,1,0); + sc_start(&sd->bl,SC_ENDURE,100,11,600000); } break; case SP_INTRAVISION: // Maya Purple Card effect allowing to see Hiding/Cloaking people [DracoRPG] @@ -4608,22 +4608,6 @@ int pc_damage(struct block_list *src,struct map_session_data *sd,int damage) skill_rest(sd,0); } - // ? ‚’‚Δ‚’‚½‚η‘«‚πŽ~‚ί‚ι - if (sd->sc.count) { - if (sd->sc.data[SC_ENDURE].timer != -1 && (src != NULL && src->type == BL_MOB) && !map_flag_gvg(sd->bl.m)) { - if (!sd->special_state.infinite_endure && (--sd->sc.data[SC_ENDURE].val2) < 0) - status_change_end(&sd->bl, SC_ENDURE, -1); - } - if (sd->sc.data[SC_GRAVITATION].timer != -1 && - sd->sc.data[SC_GRAVITATION].val3 == BCT_SELF) { - struct skill_unit_group *sg = (struct skill_unit_group *)sd->sc.data[SC_GRAVITATION].val4; - if (sg) { - skill_delunitgroup(sg); - status_change_end(&sd->bl, SC_GRAVITATION, -1); - } - } - } - // ‰‰‘t/ƒ_ƒ“ƒX‚Μ’†? if(damage > sd->status.max_hp>>2) skill_stop_dancing(&sd->bl); diff --git a/src/map/skill.c b/src/map/skill.c index dbeee7879a..6ccb90b2ef 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -1779,7 +1779,7 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds else //‰ρ•œSP+Œ»έ‚ΜSP‚ͺMSP‚ζ‚菬‚³‚’κ‡‚Ν‰ρ•œSP‚π‰ΑŽZ tsd->status.sp += sp; clif_heal(tsd->fd,SP_SP,sp); //SP‰ρ•œƒGƒtƒFƒNƒg‚Μ•\ަ - tsd->ud.canact_tick = tick + skill_delayfix(bl, SA_MAGICROD, sc->data[SC_MAGICROD].val1, skill_get_delay(SA_MAGICROD, sc->data[SC_MAGICROD].val1)); + tsd->ud.canact_tick = tick + skill_delayfix(bl, SA_MAGICROD, sc->data[SC_MAGICROD].val1); } clif_skill_nodamage(bl,bl,SA_MAGICROD,sc->data[SC_MAGICROD].val1,1); //ƒ}ƒWƒbƒNƒƒbƒhƒGƒtƒFƒNƒg‚π•\ަ } @@ -1911,6 +1911,7 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds switch(skillid){ //Skills who's damage should't show any skill-animation. case SM_MAGNUM: + case KN_BRANDISHSPEAR: case AS_SPLASHER: case ASC_METEORASSAULT: case SG_SUN_WARM: @@ -3978,11 +3979,12 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in ar=skilllv/3; skill_brandishspear_first(&tc,dir,x,y); skill_brandishspear_dir(&tc,dir,4); + clif_skill_nodamage(src,bl,skillid,skilllv,1); /* ”Ν?‡C */ if(skilllv == 10){ for(c=1;c<4;c++){ - map_foreachinarea(skill_area_sub, - bl->m,tc.val1[c],tc.val2[c],tc.val1[c],tc.val2[c],BL_CHAR, + map_foreachincell(skill_area_sub, + bl->m,tc.val1[c],tc.val2[c],BL_CHAR, src,skillid,skilllv,tick, flag|BCT_ENEMY|n, skill_castend_damage_id); } @@ -3998,8 +4000,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in if(skilllv > 3){ for(c=0;c<5;c++){ - map_foreachinarea(skill_area_sub, - bl->m,tc.val1[c],tc.val2[c],tc.val1[c],tc.val2[c],BL_CHAR, + map_foreachincell(skill_area_sub, + bl->m,tc.val1[c],tc.val2[c],BL_CHAR, src,skillid,skilllv,tick, flag|BCT_ENEMY|n, skill_castend_damage_id); if(skilllv > 6 && n==3 && c==4){ @@ -4011,8 +4013,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in /* ”Ν?‡@ */ for(c=0;c<10;c++){ if(c==0||c==5) skill_brandishspear_dir(&tc,dir,-1); - map_foreachinarea(skill_area_sub, - bl->m,tc.val1[c%5],tc.val2[c%5],tc.val1[c%5],tc.val2[c%5],BL_CHAR, + map_foreachincell(skill_area_sub, + bl->m,tc.val1[c%5],tc.val2[c%5],BL_CHAR, src,skillid,skilllv,tick, flag|BCT_ENEMY|1, skill_castend_damage_id); } @@ -5723,7 +5725,7 @@ int skill_castend_id( int tid, unsigned int tick, int id,int data ) if (ud->skillid == SA_MAGICROD) ud->canact_tick = tick; else - ud->canact_tick = tick + skill_delayfix(src, ud->skillid, ud->skilllv, skill_get_delay(ud->skillid, ud->skilllv)); + ud->canact_tick = tick + skill_delayfix(src, ud->skillid, ud->skilllv); unit_set_walkdelay(src, tick, skill_get_walkdelay(ud->skillid, ud->skilllv), 1); if(battle_config.skill_log && battle_config.skill_log&src->type) @@ -5831,7 +5833,7 @@ int skill_castend_pos( int tid, unsigned int tick, int id,int data ) ShowInfo("Type %d, ID %d skill castend pos [id =%d, lv=%d, (%d,%d)]\n", src->type, src->id, ud->skillid, ud->skilllv, ud->skillx, ud->skilly); unit_stop_walking(src,0); - ud->canact_tick = tick + skill_delayfix(src, ud->skillid, ud->skilllv, skill_get_delay(ud->skillid, ud->skilllv)); + ud->canact_tick = tick + skill_delayfix(src, ud->skillid, ud->skilllv); unit_set_walkdelay(src, tick, skill_get_walkdelay(ud->skillid, ud->skilllv), 1); skill_castend_pos2(src,ud->skillx,ud->skilly,ud->skillid,ud->skilllv,tick,0); @@ -8264,105 +8266,97 @@ int skill_check_condition(struct map_session_data *sd,int skill, int lv, int typ * ‰r?₯ŽžŠΤŒvŽZ *------------------------------------------ */ -int skill_castfix( struct block_list *bl, int skill_id, int skill_lv, int time) +int skill_castfix( struct block_list *bl, int skill_id, int skill_lv) { struct status_change *sc; int castnodex = skill_get_castnodex(skill_id, skill_lv); - + int time = skill_get_cast(skill_id, skill_lv); + struct map_session_data *sd; + nullpo_retr(0, bl); - - if (bl->type == BL_PC){ - struct map_session_data *sd = (struct map_session_data*)bl; - nullpo_retr(0, sd); - - // calculate base cast time (reduced by dex) - if (!(castnodex&1)) { // castnodex&~1? wtf. [blackhole89] - int scale = battle_config.castrate_dex_scale - status_get_dex(bl); - if (scale > 0) // not instant cast - time = time * scale / battle_config.castrate_dex_scale; - else return 0; // instant cast - } - - // config cast time multiplier - if (battle_config.cast_rate != 100) - time = time * battle_config.cast_rate / 100; - - // calculate cast time reduced by card bonuses - if (sd->castrate != 100) - time -= time * (100 - sd->castrate) / 100; - } else if (bl->type == BL_PET) { //Skotlex: Simple scaling - if (!(castnodex&1)) { - int scale = battle_config.castrate_dex_scale - status_get_dex(bl); - if (scale > 0) // not instant cast - time = time * scale / battle_config.castrate_dex_scale; - else return 0; // instant cast - } - if (battle_config.cast_rate != 100) - time = time * battle_config.cast_rate / 100; + BL_CAST(BL_PC, bl, sd); + + // calculate base cast time (reduced by dex) + if (!(castnodex&1)) { // castnodex&~1? wtf. [blackhole89] + int scale = battle_config.castrate_dex_scale - status_get_dex(bl); + if (scale > 0) // not instant cast + time = time * scale / battle_config.castrate_dex_scale; + else return 0; // instant cast } + // calculate cast time reduced by card bonuses + if (sd && sd->castrate != 100) + time = time * sd->castrate / 100; + + // config cast time multiplier + if (battle_config.cast_rate != 100) + time = time * battle_config.cast_rate / 100; + + // calculate cast time reduced by skill bonuses if (!(castnodex&2)) - { // calculate cast time reduced by skill bonuses - sc = status_get_sc(bl); - /* ƒTƒtƒ‰ƒMƒEƒ€ */ - if (sc && sc->count) { - if (sc->data[SC_SUFFRAGIUM].timer != -1) { - time -= time * (sc->data[SC_SUFFRAGIUM].val1 * 15) / 100; - status_change_end(bl, SC_SUFFRAGIUM, -1); - } - /* ƒuƒ‰ƒM‚ΜŽ? */ - if (sc->data[SC_POEMBRAGI].timer != -1) - time -= time * sc->data[SC_POEMBRAGI].val2 / 100; - } - } + time = skill_castfix_sc(bl, time); + // return final cast time return (time > 0) ? time : 0; } + +/*========================================== + * Does cast-time reductions based on sc data. + *------------------------------------------ + */ +int skill_castfix_sc(struct block_list *bl, int time) +{ + struct status_change *sc = status_get_sc(bl); + + if (time <= 0) return 0; + + if (sc && sc->count) { + if (sc->data[SC_SUFFRAGIUM].timer != -1) { + time -= time * (sc->data[SC_SUFFRAGIUM].val1 * 15) / 100; + status_change_end(bl, SC_SUFFRAGIUM, -1); + } + if (sc->data[SC_POEMBRAGI].timer != -1) + time -= time * sc->data[SC_POEMBRAGI].val2 / 100; + } + return (time > 0) ? time : 0; +} + /*========================================== * ƒfƒBƒŒƒCŒvŽZ *------------------------------------------ */ -int skill_delayfix( struct block_list *bl, int skill_id, int skill_lv, int time ) +int skill_delayfix(struct block_list *bl, int skill_id, int skill_lv) { - struct status_change *sc; int delaynodex = skill_get_delaynodex(skill_id, skill_lv); - + int time = skill_get_delay(skill_id, skill_lv); + nullpo_retr(0, bl); - if (bl->type == BL_PC){ - struct map_session_data *sd = (struct map_session_data*)bl; - nullpo_retr(0, sd); + // instant cast attack skills depend on aspd as delay [celest] + if (time == 0) { + if (skill_get_type(skill_id) == BF_WEAPON && !(skill_get_nk(skill_id)&NK_NO_DAMAGE)) + time = status_get_amotion(bl); //Use attack animation as default delay. + else + time = 300; // default delay, according to official servers + } else if (time < 0) + time = -time + status_get_amotion(bl); // if set to <0, the attack motion is added. - // instant cast attack skills depend on aspd as delay [celest] - if (time == 0) { - if (skill_get_type(skill_id) == BF_WEAPON && !(skill_get_nk(skill_id)&NK_NO_DAMAGE)) - time = status_get_amotion(bl); //Use attack animation as default delay. - else - time = 300; // default delay, according to official servers - } else if (time < 0) - time = -time + status_get_amotion(bl); // if set to <0, the attack motion is added. - - if (battle_config.delay_dependon_dex && !(delaynodex&1)) - { // if skill casttime is allowed to be reduced by dex - int scale = battle_config.castrate_dex_scale - status_get_dex(bl); - if (scale > 0) - time = time * scale / battle_config.castrate_dex_scale; - else - time = battle_config.min_skill_delay_limit; - } - - if (battle_config.delay_rate != 100) - time = time * battle_config.delay_rate / 100; - - if (sd->delayrate != 100) - time = time * sd->delayrate / 100; - - if (time < battle_config.min_skill_delay_limit) // check minimum skill delay - time = battle_config.min_skill_delay_limit; + if (battle_config.delay_dependon_dex && !(delaynodex&1)) + { // if skill casttime is allowed to be reduced by dex + int scale = battle_config.castrate_dex_scale - status_get_dex(bl); + if (scale > 0) + time = time * scale / battle_config.castrate_dex_scale; } + if (bl->type == BL_PC && ((TBL_PC*)bl)->delayrate != 100) + time = time * ((TBL_PC*)bl)->delayrate / 100; + + if (battle_config.delay_rate != 100) + time = time * battle_config.delay_rate / 100; + if (!(delaynodex&2)) { /* ƒuƒ‰ƒM‚ΜŽ? */ + struct status_change *sc; sc= status_get_sc(bl); if (sc && sc->count) { if (sc->data[SC_POEMBRAGI].timer != -1) @@ -8381,7 +8375,8 @@ int skill_delayfix( struct block_list *bl, int skill_id, int skill_lv, int time } } - return (time > 0) ? time : 0; + return (time < battle_config.min_skill_delay_limit)? + battle_config.min_skill_delay_limit:time; } /*========================================= diff --git a/src/map/skill.h b/src/map/skill.h index 4624e66b98..174a224b4e 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -188,8 +188,9 @@ int skill_clear_element_field(struct block_list *bl); int skill_unit_ondamaged(struct skill_unit *src,struct block_list *bl, int damage,unsigned int tick); -int skill_castfix( struct block_list *bl, int skill_id, int skill_lv, int time); -int skill_delayfix( struct block_list *bl, int skill_id, int skill_lv, int time); +int skill_castfix( struct block_list *bl, int skill_id, int skill_lv); +int skill_castfix_sc( struct block_list *bl, int time); +int skill_delayfix( struct block_list *bl, int skill_id, int skill_lv); int skill_check_condition( struct map_session_data *sd,int skill, int lv, int type); int skill_check_pc_partner(struct map_session_data *sd, int skill_id, int* skill_lv, int range, int cast_flag); int skill_check_unit_range(int m,int x,int y,int skillid, int skilllv); diff --git a/src/map/status.c b/src/map/status.c index 72934420cf..9c7cfdaa0d 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -128,7 +128,7 @@ void initChangeTables(void) { set_sc(AS_VENOMDUST, SC_POISON, SI_BLANK); set_sc(AS_SPLASHER, SC_SPLASHER, SI_BLANK); set_sc(NV_TRICKDEAD, SC_TRICKDEAD, SI_TRICKDEAD); - set_sc(SM_AUTOBERSERK, SC_AUTOBERSERK, SI_BLANK); + set_sc(SM_AUTOBERSERK, SC_AUTOBERSERK, SI_STEELBODY); set_sc(TF_SPRINKLESAND, SC_BLIND, SI_BLANK); set_sc(TF_THROWSTONE, SC_STUN, SI_BLANK); set_sc(MC_LOUD, SC_LOUD, SI_LOUD); @@ -404,7 +404,7 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, int { if ( (sc->data[SC_TRICKDEAD].timer != -1 && skill_num != NV_TRICKDEAD) - || (sc->data[SC_AUTOCOUNTER].timer != -1 && skill_num != KN_AUTOCOUNTER) + || sc->data[SC_AUTOCOUNTER].timer != -1 || (sc->data[SC_GOSPEL].timer != -1 && sc->data[SC_GOSPEL].val4 == BCT_SELF && skill_num != PA_GOSPEL) || (sc->data[SC_GRAVITATION].timer != -1 && sc->data[SC_GRAVITATION].val3 == BCT_SELF && skill_num != HW_GRAVITATION) ) @@ -3081,9 +3081,11 @@ int status_get_dmotion(struct block_list *bl) else return 2000; - if(sc && sc->count && (sc->data[SC_ENDURE].timer!=-1 || sc->data[SC_CONCENTRATION].timer!=-1 || sc->data[SC_BERSERK].timer!=-1)) - if (!map_flag_gvg(bl->m)) //Only works on non-gvg grounds. [Skotlex] - return 0; + if(sc && sc->count + && (sc->data[SC_ENDURE].timer!=-1 || sc->data[SC_CONCENTRATION].timer!=-1) + && !map_flag_gvg(bl->m) //Only works on non-gvg grounds. [Skotlex] + ) + return 0; return ret; } @@ -4176,6 +4178,8 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val } if (!(flag&4)) tick = 10000; + if (sc->data[SC_ENDURE].timer == -1 || sc->data[SC_ENDURE].val1 <= 10) + sc_start(bl, SC_ENDURE, 100, 11, tick); calc_flag = 1; break; @@ -5014,9 +5018,10 @@ int status_change_end( struct block_list* bl , int type,int tid ) sd->status.hp = 100; clif_updatestatus(sd,SP_HP); } + if(sc->data[SC_ENDURE].timer != -1) + status_change_end(bl, SC_ENDURE, -1); calc_flag = 1; break; - case SC_GRAVITATION: if (sc->data[type].val3 == BCT_SELF) { struct unit_data *ud = unit_bl2ud(bl); @@ -5310,8 +5315,9 @@ int status_change_timer(int tid, unsigned int tick, int id, int data) break; case SC_ENDURE: /* ƒCƒ“ƒfƒ…ƒA */ - if(sd && sd->special_state.infinite_endure) { - sc->data[type].timer=add_timer( 1000*60+tick,status_change_timer, bl->id, data ); + if(sc->data[type].val1 > 10 || (sd && sd->special_state.infinite_endure)) + { + sc->data[type].timer=add_timer(1000*60+tick,status_change_timer, bl->id, data); return 0; } break; diff --git a/src/map/unit.c b/src/map/unit.c index fee09279c1..e441bc6937 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -524,7 +524,7 @@ int unit_skilluse_id(struct block_list *src, int target_id, int skill_num, int s return unit_skilluse_id2( src, target_id, skill_num, skill_lv, - skill_castfix(src, skill_num, skill_lv, skill_get_cast(skill_num, skill_lv)), + skill_castfix(src, skill_num, skill_lv), skill_get_castcancel(skill_num) ); } @@ -803,7 +803,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, int skill_num, int case ALL_RESURRECTION: /* ƒŠƒUƒŒƒNƒVƒ‡ƒ“ */ if(battle_check_undead(status_get_race(target),status_get_elem_type(target))){ /* “G‚ͺƒAƒ“ƒfƒbƒh‚Θ‚η */ temp=1; /* ƒ^[ƒ“ƒAƒ“ƒfƒbƒg‚Ζ“―‚Ά‰r₯ŽžŠΤ */ - casttime = skill_castfix(src, PR_TURNUNDEAD, skill_lv, skill_get_cast(PR_TURNUNDEAD, skill_lv)); + casttime = skill_castfix(src, PR_TURNUNDEAD, skill_lv); } break; case MO_FINGEROFFENSIVE: /* Žw’e */ @@ -906,7 +906,7 @@ int unit_skilluse_pos(struct block_list *src, int skill_x, int skill_y, int skil return 0; return unit_skilluse_pos2( src, skill_x, skill_y, skill_num, skill_lv, - skill_castfix(src, skill_num, skill_lv, skill_get_cast(skill_num, skill_lv)), + skill_castfix(src, skill_num, skill_lv), skill_get_castcancel(skill_num) ); }