- the auth function in login.c won't jstrescapecpy passwords that were encrypted.

- Moved the Endure and Gravitation sc ends to battle_damage from pc_damage.
- Endure level 11 and above are now considered infinite-endure.
- Set the minimum pet hungry delay to 10
- modified function skill_delayfix to only receive skill/lv, actual time is now always acquired from skill_get_delay. It also now will never return a value below min_skill_delay_limit.
- Modified brandish spear so you won't see the skill-animation for every targetted mob. Also cleaned it up to use map_foreachincell calls.
- splitted skill_cast_fix into skill_cast_fix and skill_cast_fix_sc, the first does cast adjustments based on dex and server settings, the later only based on sc changes. Mobs use the later while everyone else use the former (which invokes the later when appropiate)
- Added the Steel Body icon to auto-berserk.
- Now you can't cast auto-counter while the previous one is active.
- For the duration of Berserk, infinite-endure is activated.
- Added Veider's suggestion to do a hack-report when players request the name of an invisible/cloaked character.


git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@5813 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
skotlex 2006-03-30 15:50:54 +00:00
parent 2c0794767e
commit 39d33a2f80
10 changed files with 177 additions and 136 deletions

View File

@ -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]

View File

@ -598,6 +598,11 @@ 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);
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);

View File

@ -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で呼ばれることがあるので他でチェック
nullpo_retr(0, target); //stcはNULLで呼ばれることがあるので他でチェック
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;

View File

@ -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);
}
}
/*==========================================

View File

@ -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) {

View File

@ -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);
}
}
}
// 演奏/ダンスの中?
if(damage > sd->status.max_hp>>2)
skill_stop_dancing(&sd->bl);

View File

@ -1779,7 +1779,7 @@ int skill_attack( int attack_type, struct block_list* src, struct block_list *ds
else //回復SP+現在のSPがMSPより小さい場合は回復SPを加算
tsd->status.sp += sp;
clif_heal(tsd->fd,SP_SP,sp); //SP回復エフェクトの表示
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); //マジックロッドエフェクトを表示
}
@ -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);
/* 範?④ */
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,16 +8266,15 @@ int skill_check_condition(struct map_session_data *sd,int skill, int lv, int typ
* ?
*------------------------------------------
*/
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);
BL_CAST(BL_PC, bl, sd);
// calculate base cast time (reduced by dex)
if (!(castnodex&1)) { // castnodex&~1? wtf. [blackhole89]
@ -8283,56 +8284,54 @@ int skill_castfix( struct block_list *bl, int skill_id, int skill_lv, int time)
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 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;
}
// 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ƒ€ */
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);
}
/* ƒuƒ‰ƒMÌŽ? */
if (sc->data[SC_POEMBRAGI].timer != -1)
time -= time * sc->data[SC_POEMBRAGI].val2 / 100;
}
}
// return final cast time
return (time > 0) ? time : 0;
}
/*==========================================
*
*------------------------------------------
*/
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))
@ -8347,22 +8346,17 @@ int skill_delayfix( struct block_list *bl, int skill_id, int skill_lv, int time
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 (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 (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 (!(delaynodex&2))
{ /* ブラギの<E382AE>? */
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;
}
/*=========================================

View File

@ -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);

View File

@ -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,8 +3081,10 @@ 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]
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;

View File

@ -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: /* リザレクション */
if(battle_check_undead(status_get_race(target),status_get_elem_type(target))){ /* 敵がアンデッドなら */
temp=1; /* ターンアンデットと同じ詠唱時間 */
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: /* 指弾 */
@ -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)
);
}