summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changelog-Trunk.txt13
-rw-r--r--db/skill_unit_db.txt4
-rw-r--r--src/map/battle.c58
-rw-r--r--src/map/skill.c59
-rw-r--r--src/map/status.c2
-rw-r--r--src/map/unit.c40
6 files changed, 110 insertions, 66 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt
index dacb7f899..1ff24936c 100644
--- a/Changelog-Trunk.txt
+++ b/Changelog-Trunk.txt
@@ -2,9 +2,16 @@ Date Added
AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK.
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
-
-2009/05/07
- * Added check on stackable items to 'checkweight' (bugreport:1569, bugreport:2756, bugreport 2994) [Inkfish]
+09/05/07
+ * Fixed splash damage from Baphomet Card might miss. [Inkfish]
+ * Check if group unit is expired before processing it. (bugreport:3054) [Inkfish]
+ * Fixed Grand Corss outdated behavior (bugreport:1590) [Inkfish]
+ - use new damage formula
+ - DEF is reduced to 2/3 during cast time
+ - block shields switching within attack duration
+ - monsters don't damage themselves any more
+ - intervals between hits are 300ms
+ * Added check on stackable items to 'checkweight' (bugreport:1569, bugreport:2756, bugreport:2994) [Inkfish]
* Fixed flee penalty wasn't applied for battleground and wouldn't be restored on map change [Inkfish]
* Fixed players can pull water from ME cell (follow up to r13730) [Inkfish]
2009/05/04
diff --git a/db/skill_unit_db.txt b/db/skill_unit_db.txt
index aa7e60c7e..8cfab0c26 100644
--- a/db/skill_unit_db.txt
+++ b/db/skill_unit_db.txt
@@ -52,7 +52,7 @@
140,0x92, , -1, 0,1000,enemy, 0x000 //AS_VENOMDUST
220,0xb0, , 0, 0, -1,all, 0x002 //RG_GRAFFITI
229,0xb1, , 0, 1,1000,enemy, 0x006 //AM_DEMONSTRATION
-254,0x86, , -1, 0, 400,enemy, 0x010 //CR_GRANDCROSS
+254,0x86, , -1, 0, 300,enemy, 0x010 //CR_GRANDCROSS
285,0x9a, , 3, 0, -1,all, 0x010 //SA_VOLCANO
286,0x9b, , 3, 0, -1,all, 0x010 //SA_DELUGE
287,0x9c, , 3, 0, -1,all, 0x010 //SA_VIOLENTGALE
@@ -76,7 +76,7 @@
329,0xae, , 3, 0, -1,all, 0x140 //DC_FORTUNEKISS
330,0xaf, , 3, 0, -1,all, 0x140 //DC_SERVICEFORYOU
336,0xb2, , 0,-1, -1,noone, 0x000 //WE_CALLPARTNER
-339,0x86, , -1, 0, 400,enemy, 0x000 //NPC_DARKGRANDCROSS
+339,0x86, , -1, 0, 300,enemy, 0x000 //NPC_DARKGRANDCROSS
362,0xb4, , 0, 2, 300,all, 0x000 //HP_BASILICA
369,0xb3, , -1, 0,10000,all, 0x008 //PA_GOSPEL
395,0xb5, , 4, 0, -1,all, 0x200 //CG_MOONLIT
diff --git a/src/map/battle.c b/src/map/battle.c
index 9d6ead21e..2b9443e82 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -141,7 +141,7 @@ struct block_list* battle_getenemy(struct block_list *target, int type, int rang
return bl_list[rand()%c];
}
-// ƒ_ƒ??[ƒW‚Ì’x‰„
+// ƒ_??[ƒW‚Ì’x‰„
struct delay_damage {
struct block_list *src;
int target;
@@ -268,7 +268,7 @@ int battle_attr_fix(struct block_list *src, struct block_list *target, int damag
}
/*==========================================
- * ƒ_ƒ??[ƒW?Å?IŒvŽZ
+ * ƒ_??[ƒW??IŒvŽZ
*------------------------------------------*/
int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,int div_,int skill_num,int skill_lv,int flag)
{
@@ -645,7 +645,7 @@ static int battle_calc_drain(int damage, int rate, int per)
}
/*==========================================
- * ?C—ûƒ_ƒ??[ƒW
+ * ?C—ûƒ_??[ƒW
*------------------------------------------*/
int battle_addmastery(struct map_session_data *sd,struct block_list *target,int dmg,int type)
{
@@ -1116,21 +1116,19 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
flag.hit = 1; //SG_FUSION always hit [Komurka]
flag.idef = flag.idef2 = 1; //def ignore [Komurka]
}
- if (skill_num && !flag.hit)
+ if( !flag.hit )
switch(skill_num)
{
case AS_SPLASHER:
- if (wflag) // Always hits the one exploding.
- break;
- flag.hit = 1;
+ if( !wflag ) // Always hits the one exploding.
+ flag.hit = 1;
break;
case CR_SHIELDBOOMERANG:
- if (sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_CRUSADER)
+ if( sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_CRUSADER )
flag.hit = 1;
break;
- case 0:
- //If flag, this is splash damage from Baphomet Card and it always hits.
- if (wflag)
+ case 0:
+ if( wflag ) //If flag, this is splash damage from Baphomet Card and it always hits.
flag.hit = 1;
break;
}
@@ -1888,9 +1886,6 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
else if(wd.div_ < 0) //Since the attack missed...
wd.div_ *= -1;
- if(skill_num == CR_GRANDCROSS || skill_num == NPC_GRANDDARKNESS)
- return wd; //Enough, rest is not needed.
-
if(sd && (skill=pc_checkskill(sd,BS_WEAPONRESEARCH)) > 0)
ATK_ADD(skill*2);
@@ -1918,6 +1913,9 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
}
}
+ if(skill_num == CR_GRANDCROSS || skill_num == NPC_GRANDDARKNESS)
+ return wd; //Enough, rest is not needed.
+
if (sd)
{
if (skill_num != CR_SHIELDBOOMERANG) //Only Shield boomerang doesn't takes the Star Crumbs bonus.
@@ -2462,19 +2460,6 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
else
ad.damage = ad.damage * (100-mdef)/100 - mdef2;
}
-
- if(skill_num == CR_GRANDCROSS || skill_num == NPC_GRANDDARKNESS)
- { //Apply the physical part of the skill's damage. [Skotlex]
- struct Damage wd = battle_calc_weapon_attack(src,target,skill_num,skill_lv,mflag);
- ad.damage = (wd.damage + ad.damage) * (100 + 40*skill_lv)/100;
- if(src==target)
- {
- if (src->type == BL_PC)
- ad.damage = ad.damage/2;
- else
- ad.damage = 0;
- }
- }
if (skill_num == NPC_EARTHQUAKE)
{ //Adds atk2 to the damage, should be influenced by number of hits and skill-ratio, but not mdef reductions. [Skotlex]
@@ -2491,6 +2476,19 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
if (!(nk&NK_NO_ELEFIX))
ad.damage=battle_attr_fix(src, target, ad.damage, s_ele, tstatus->def_ele, tstatus->ele_lv);
+ if( skill_num == CR_GRANDCROSS || skill_num == NPC_GRANDDARKNESS )
+ { //Apply the physical part of the skill's damage. [Skotlex]
+ struct Damage wd = battle_calc_weapon_attack(src,target,skill_num,skill_lv,mflag);
+ ad.damage = battle_attr_fix(src, target, wd.damage + ad.damage, s_ele, tstatus->def_ele, tstatus->ele_lv);
+ if( src == target )
+ {
+ if( src->type == BL_PC )
+ ad.damage = ad.damage/2;
+ else
+ ad.damage = 0;
+ }
+ }
+
if (sd && !(nk&NK_NO_CARDFIX_ATK)) {
short t_class = status_get_class(target);
short cardfix=1000;
@@ -2561,7 +2559,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
}
/*==========================================
- * ‚»‚Ì‘¼ƒ_ƒ??[ƒWŒvŽZ
+ * ‚»‚Ì‘¼ƒ_??[ƒWŒvŽZ
*------------------------------------------*/
struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *target,int skill_num,int skill_lv,int mflag)
{
@@ -2797,7 +2795,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
return md;
}
/*==========================================
- * ƒ_ƒ??[ƒWŒvŽZˆêŠ‡?ˆ—?—p
+ * ƒ_??[ƒWŒvŽZˆêŠ‡?ˆ—?—p
*------------------------------------------*/
struct Damage battle_calc_attack(int attack_type,struct block_list *bl,struct block_list *target,int skill_num,int skill_lv,int count)
{
@@ -2899,7 +2897,7 @@ void battle_drain(TBL_PC *sd, struct block_list *tbl, int rdamage, int ldamage,
}
/*==========================================
- * ’Ê?í?UŒ‚?ˆ—?‚Ü‚Æ‚ß
+ * ’Ê??UŒ‚?ˆ—?‚Ü‚Æ‚ß
*------------------------------------------*/
enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* target, unsigned int tick, int flag)
{
diff --git a/src/map/skill.c b/src/map/skill.c
index a5600d74b..18c09f135 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -5567,6 +5567,9 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr data)
}
ud->skilltimer = INVALID_TIMER;
+
+ if( sd && (ud->skillid == CR_GRANDCROSS || ud->skillid == NPC_GRANDDARKNESS) )
+ status_calc_bl(&sd->bl, SCB_DEF); // restore original DEF
}
if (ud->skilltarget == id)
@@ -5691,6 +5694,16 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr data)
case GS_DESPERADO:
sd->canequip_tick = tick + skill_get_time(ud->skillid, ud->skilllv);
break;
+ case CR_GRANDCROSS:
+ case NPC_GRANDDARKNESS:
+ if( (sc = status_get_sc(src)) && sc->data[SC_STRIPSHIELD] )
+ {
+ const struct TimerData *timer = get_timer(sc->data[SC_STRIPSHIELD]->timer);
+ if( timer && timer->func == status_change_timer && DIFF_TICK(timer->tick,gettick()+skill_get_time(ud->skillid, ud->skilllv)) > 0 )
+ break;
+ }
+ sc_start2(src, SC_STRIPSHIELD, 100, 0, 1, skill_get_time(ud->skillid, ud->skilllv));
+ break;
}
}
if (skill_get_state(ud->skillid) != ST_MOVE_ENABLE)
@@ -10032,27 +10045,6 @@ static int skill_unit_timer_sub (DBKey key, void* data, va_list ap)
nullpo_retr(0, group);
- dissonance = skill_dance_switch(unit, 0);
-
- if( unit->range >= 0 && group->interval != -1 )
- {
- if( battle_config.skill_wall_check )
- map_foreachinshootrange(skill_unit_timer_sub_onplace, bl, unit->range, group->bl_flag, bl,tick);
- else
- map_foreachinrange(skill_unit_timer_sub_onplace, bl, unit->range, group->bl_flag, bl,tick);
-
- if(unit->range == -1) //Unit disabled, but it should not be deleted yet.
- group->unit_id = UNT_USED_TRAPS;
-
- if( !unit->alive )
- {
- if( dissonance ) skill_dance_switch(unit, 1);
- return 0;
- }
- }
-
- if( dissonance ) skill_dance_switch(unit, 1);
-
// check for expiration
if( (DIFF_TICK(tick,group->tick) >= group->limit || DIFF_TICK(tick,group->tick) >= unit->limit) )
{// skill unit expired (inlined from skill_unit_onlimit())
@@ -10173,6 +10165,31 @@ static int skill_unit_timer_sub (DBKey key, void* data, va_list ap)
}
}
+ //Don't continue if unit or even group is expired and has been deleted.
+ if( !group || !unit->alive )
+ return 0;
+
+ dissonance = skill_dance_switch(unit, 0);
+
+ if( unit->range >= 0 && group->interval != -1 )
+ {
+ if( battle_config.skill_wall_check )
+ map_foreachinshootrange(skill_unit_timer_sub_onplace, bl, unit->range, group->bl_flag, bl,tick);
+ else
+ map_foreachinrange(skill_unit_timer_sub_onplace, bl, unit->range, group->bl_flag, bl,tick);
+
+ if(unit->range == -1) //Unit disabled, but it should not be deleted yet.
+ group->unit_id = UNT_USED_TRAPS;
+
+ if( !unit->alive )
+ {
+ if( dissonance ) skill_dance_switch(unit, 1);
+ return 0;
+ }
+ }
+
+ if( dissonance ) skill_dance_switch(unit, 1);
+
return 0;
}
/*==========================================
diff --git a/src/map/status.c b/src/map/status.c
index 1fe6ec122..c7b7b1567 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -4930,6 +4930,8 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
break;
case SC_STRIPSHIELD:
+ if( val2 == 1 ) val2 = 0; //GX effect. Do not take shield off..
+ else
if (sd) {
int i;
if(sd->unstripable_equip&EQP_SHIELD)
diff --git a/src/map/unit.c b/src/map/unit.c
index bd2997723..b5a56fb4b 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -1072,14 +1072,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, short skill_num, sh
ud->canact_tick = tick + casttime + 100;
if ( battle_config.display_status_timers && sd )
clif_status_change(src, SI_ACTIONDELAY, 1, casttime);
- if( sd )
- {
- switch( skill_num )
- {
- case CG_ARROWVULCAN:
- sd->canequip_tick = tick + casttime;
- }
- }
+
ud->skilltarget = target_id;
ud->skillx = 0;
ud->skilly = 0;
@@ -1099,9 +1092,24 @@ int unit_skilluse_id2(struct block_list *src, int target_id, short skill_num, sh
status_calc_bl(&sd->bl, SCB_SPEED);
else
unit_stop_walking(src,1);
+
+ if( sd )
+ {
+ switch( skill_num )
+ {
+ case CG_ARROWVULCAN:
+ sd->canequip_tick = tick + casttime;
+ break;
+ case CR_GRANDCROSS:
+ case NPC_GRANDDARKNESS:
+ status_calc_bl(src, SCB_DEF);
+ break;
+ }
+ }
}
else
skill_castend_id(ud->skilltimer,tick,src->id,0);
+
return 1;
}
@@ -1613,8 +1621,6 @@ int unit_skillcastcancel(struct block_list *bl,int type)
ud->canact_tick = tick;
if ( battle_config.display_status_timers && sd )
clif_status_change(bl, SI_ACTIONDELAY, 0, 0);
- if( sd )
- sd->canequip_tick = tick;
if(type&1 && sd)
skill = sd->skillid_old;
@@ -1633,6 +1639,20 @@ int unit_skillcastcancel(struct block_list *bl,int type)
if( sd && pc_checkskill(sd,SA_FREECAST) > 0 )
status_calc_bl(&sd->bl, SCB_SPEED);
+ if( sd )
+ {
+ switch( skill )
+ {
+ case CG_ARROWVULCAN:
+ sd->canequip_tick = tick;
+ break;
+ case CR_GRANDCROSS:
+ case NPC_GRANDDARKNESS:
+ status_calc_bl(bl, SCB_DEF);
+ break;
+ }
+ }
+
if(bl->type==BL_MOB) ((TBL_MOB*)bl)->skillidx = -1;
clif_skillcastcancel(bl);