Ver código fonte

* 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

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@13736 54d463be-8e91-2dee-dedb-b68131a5f0ec

Inkfish 16 anos atrás
pai
commit
0595535167
6 arquivos alterados com 110 adições e 66 exclusões
  1. 10 3
      Changelog-Trunk.txt
  2. 2 2
      db/skill_unit_db.txt
  3. 28 30
      src/map/battle.c
  4. 38 21
      src/map/skill.c
  5. 2 0
      src/map/status.c
  6. 30 10
      src/map/unit.c

+ 10 - 3
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

+ 2 - 2
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

+ 28 - 30
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)
 {

+ 38 - 21
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;
 }
 /*==========================================

+ 2 - 0
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)

+ 30 - 10
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);