summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2006-08-08 15:07:29 +0000
committerskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2006-08-08 15:07:29 +0000
commitbc5f5bce06657ed1899f9635d7d4b353a033569e (patch)
treed02e5d2e1476a542b9f6e35aaa2c06157ed59a95 /src
parent98112951df16e14ac20a683d3b207dec002e9097 (diff)
downloadhercules-bc5f5bce06657ed1899f9635d7d4b353a033569e.tar.gz
hercules-bc5f5bce06657ed1899f9635d7d4b353a033569e.tar.bz2
hercules-bc5f5bce06657ed1899f9635d7d4b353a033569e.tar.xz
hercules-bc5f5bce06657ed1899f9635d7d4b353a033569e.zip
- Fixed yet again AS_SPLASHER doing full damage on all characters. Now you can use the NK split damage value in the skill_db if you want damage divided by the amount of targets rather than by 2.
- Fixed crash on the battle_drain functions. - Cleaned up HAMI_CASTLE, HLIF_AVOID, HAMI_DEFENCE so that it's usable by other types of objects other than Homunculus. - Cleaned up the Asura Strike code so that the SP/Spheres/States is not consumed when the skill fails due to Fog of Wall. - When a negative delay for a skill is specified, this delay is now added on top of the character's amotion rather than adelay - Modified main.sql to make the guild table allow NULL on the emblem data. - Added file conf-tmpl/Changelog.txt git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@8185 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src')
-rw-r--r--src/map/battle.c7
-rw-r--r--src/map/battle.h1
-rw-r--r--src/map/clif.c1
-rw-r--r--src/map/skill.c84
-rw-r--r--src/map/unit.c10
5 files changed, 52 insertions, 51 deletions
diff --git a/src/map/battle.c b/src/map/battle.c
index 14bbd7197..0fed7c26f 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -1451,7 +1451,7 @@ static struct Damage battle_calc_weapon_attack(
case AS_SPLASHER:
i = 400+50*skill_lv;
if (sd) i += 20*pc_checkskill(sd,AS_POISONREACT);
- if (wflag) i/=2; //Splash damage is half.
+ if (wflag>1) i/=wflag; //Splash damage is half.
skillratio += i;
flag.cardfix = 0;
break;
@@ -3044,7 +3044,8 @@ int battle_weapon_attack( struct block_list *src,struct block_list *target,
}
if (rdamage > 0) { //By sending attack type "none" skill_additional_effect won't be invoked. [Skotlex]
- battle_drain(tsd, src, rdamage, rdamage, sstatus->race, is_boss(src));
+ if(tsd && src != target)
+ battle_drain(tsd, src, rdamage, rdamage, sstatus->race, is_boss(src));
battle_delay_damage(tick+wd.amotion, target, src, 0, 0, 0, rdamage, ATK_DEF, rdelay);
}
@@ -3088,7 +3089,7 @@ int battle_check_undead(int race,int element)
}
//Returns the upmost level master starting with the given object
-static struct block_list* battle_get_master(struct block_list *src)
+struct block_list* battle_get_master(struct block_list *src)
{
struct block_list *prev; //Used for infinite loop check (master of yourself?)
do {
diff --git a/src/map/battle.h b/src/map/battle.h
index d410e7a12..91ca7962f 100644
--- a/src/map/battle.h
+++ b/src/map/battle.h
@@ -55,6 +55,7 @@ int battle_weapon_attack( struct block_list *bl,struct block_list *target,
unsigned int tick,int flag);
// 各種パラメータを得る
+struct block_list* battle_get_master(struct block_list *src);
struct block_list* battle_gettargeted(struct block_list *target);
int battle_gettarget(struct block_list *bl);
int battle_getcurrentskill(struct block_list *bl);
diff --git a/src/map/clif.c b/src/map/clif.c
index 31be94733..9bf290300 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -9730,7 +9730,6 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd) {
//Whether skill fails or not is irrelevant, the char ain't idle. [Skotlex]
sd->idletime = last_tick;
-
if (skillnum >= HM_SKILLBASE && skillnum < HM_SKILLBASE+MAX_HOMUNSKILL) {
clif_parse_UseSkillToId_homun(sd->hd, sd, tick, skillnum, skilllv, target_id);
return;
diff --git a/src/map/skill.c b/src/map/skill.c
index 5eaadd6bd..929d4eb90 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -1775,7 +1775,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
struct Damage dmg;
struct status_data *sstatus, *tstatus;
struct status_change *sc;
- struct map_session_data *sd=NULL, *tsd=NULL;
+ struct map_session_data *sd, *tsd;
int type,lv,damage,rdamage=0;
if(skillid > 0 && skilllv <= 0) return 0;
@@ -1793,11 +1793,9 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
if (!status_check_skilluse(dsrc, bl, skillid, 2))
return 0;
}
-
- if (dsrc->type == BL_PC)
- sd = (struct map_session_data *)dsrc;
- if (bl->type == BL_PC)
- tsd = (struct map_session_data *)bl;
+
+ BL_CAST(BL_PC, dsrc, sd);
+ BL_CAST(BL_PC, bl, tsd);
sstatus = status_get_status_data(dsrc);
tstatus = status_get_status_data(bl);
@@ -2111,7 +2109,8 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
status_fix_damage(bl,src,rdamage,0);
clif_damage(src,src,tick, dmg.amotion,0,rdamage,1,4,0);
//Use Reflect Shield to signal this kind of skill trigger. [Skotlex]
- battle_drain(tsd, src, rdamage, rdamage, sstatus->race, is_boss(src));
+ if (tsd && src != bl)
+ battle_drain(tsd, src, rdamage, rdamage, sstatus->race, is_boss(src));
skill_additional_effect(bl,src,CR_REFLECTSHIELD, 1,BF_WEAPON,tick);
}
@@ -2849,8 +2848,8 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
map_foreachinrange(skill_area_sub, bl,
skill_get_splash(skillid, skilllv), BL_CHAR,
src, skillid, skilllv, tick, BCT_ENEMY, skill_area_sub_count);
- else
- skill_area_temp[0] = 1;
+ else if (skillid==AS_SPLASHER) //Need split damage anyway.
+ skill_area_temp[0] = 2;
map_foreachinrange(skill_area_sub, bl,
skill_get_splash(skillid, skilllv), BL_CHAR,
@@ -3697,6 +3696,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
case NJ_KASUMIKIRI:
case NJ_UTSUSEMI:
case NJ_NEN:
+ case HLIF_AVOID: //[orn]
+ case HAMI_DEFENCE: //[orn]
clif_skill_nodamage(src,bl,skillid,skilllv,
sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
break;
@@ -5447,8 +5448,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
break;
case AM_CALLHOMUN: //[orn]
- {
- int i = 0;
if (sd)
{
if ((sd->status.hom_id == 0 || sd->homunculus.vaporize == 1)) {
@@ -5466,7 +5465,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
clif_skill_fail(sd,skillid,0,0);
}
break;
- }
+
case AM_REST: //[orn]
{
if (sd)
@@ -5502,31 +5501,22 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
}
case HAMI_CASTLE: //[orn]
+ if(rand()%100 > 20*skilllv || src == bl)
+ break; //Failed.
{
- if(hd && rand()%100 < 20*skilllv)
- {
- int x,y;
- struct walkpath_data wpd;
- struct map_session_data *sd = hd->master;
- if( path_search(&wpd,hd->bl.m,hd->bl.x,hd->bl.y,sd->bl.x,sd->bl.y,0) != 0 ) {
- clif_skill_fail(sd,skillid,0,0);
- break;
- }
-
- clif_skill_nodamage(&hd->bl,&sd->bl,skillid,skilllv,1);
-
- x = hd->bl.x;
- y = hd->bl.y;
+ int x,y;
+ x = src->x;
+ y = src->y;
- unit_movepos(&hd->bl,sd->bl.x,sd->bl.y,0,0);
- unit_movepos(&sd->bl,x,y,0,0);
- clif_fixpos(&hd->bl) ;
- clif_fixpos(&sd->bl) ;
+ if (unit_movepos(src,bl->x,bl->y,0,0)) {
+ clif_skill_nodamage(src,bl,skillid,skilllv,1);
+ clif_fixpos(src) ;
+ if (unit_movepos(bl,x,y,0,0))
+ clif_fixpos(bl) ;
- map_foreachinarea(skill_chastle_mob_changetarget,hd->bl.m,
- hd->bl.x-AREA_SIZE,hd->bl.y-AREA_SIZE,
- hd->bl.x+AREA_SIZE,hd->bl.y+AREA_SIZE,
- BL_MOB,&hd->master->bl,&hd->bl);
+ //TODO: Shouldn't also players and the like switch targets?
+ map_foreachinrange(skill_chastle_mob_changetarget,src,
+ AREA_SIZE, BL_MOB, bl, src);
}
}
break;
@@ -5560,12 +5550,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
}
}
break;
- case HLIF_AVOID: //[orn]
- case HAMI_DEFENCE: //[orn]
- if ( hd ) {
- clif_skill_nodamage(src,&hd->master->bl,skillid,skilllv,
- sc_start(&hd->master->bl,type,100,skilllv,skill_get_time(skillid,skilllv))) ;
- }
case HAMI_BLOODLUST: //[orn]
case HFLI_FLEET: //[orn]
case HFLI_SPEED: //[orn]
@@ -5772,8 +5756,9 @@ int skill_castend_id (int tid, unsigned int tick, int id, int data)
return 1;
} while(0);
//Skill failed.
- if (ud->skillid == MO_EXTREMITYFIST && sd)
- { //When Asura fails...
+ if (ud->skillid == MO_EXTREMITYFIST && sd &&
+ !(sc && sc->count && sc->data[SC_FOGWALL].timer != -1))
+ { //When Asura fails... (except when it fails from Fog of Wall)
//Consume SP/spheres
skill_check_condition(sd,ud->skillid, ud->skilllv,1);
sc = &sd->sc;
@@ -8574,7 +8559,7 @@ int skill_delayfix (struct block_list *bl, int skill_id, int skill_lv)
else
time = battle_config.default_skill_delay;
} else if (time < 0)
- time = -time + status_get_adelay(bl); // if set to <0, the attack delay is added.
+ 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
@@ -9354,12 +9339,17 @@ int skill_ganbatein (struct block_list *bl, va_list ap)
int skill_chastle_mob_changetarget(struct block_list *bl,va_list ap)
{
struct mob_data* md;
+ struct unit_data*ud = unit_bl2ud(bl);
struct block_list *from_bl;
struct block_list *to_bl;
- nullpo_retr(0, md = (struct mob_data*)bl);
- nullpo_retr(0, from_bl = va_arg(ap,struct block_list *));
- nullpo_retr(0, to_bl = va_arg(ap,struct block_list *));
- if(md->target_id == from_bl->id)
+ md = (struct mob_data*)bl;
+ from_bl = va_arg(ap,struct block_list *);
+ to_bl = va_arg(ap,struct block_list *);
+
+ if(ud && ud->target == from_bl->id)
+ ud->target = to_bl->id;
+
+ if(md->bl.type == BL_MOB && md->target_id == from_bl->id)
md->target_id = to_bl->id;
return 0;
}
diff --git a/src/map/unit.c b/src/map/unit.c
index 7eace7b06..c9a7c5176 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -786,6 +786,16 @@ int unit_skilluse_id2(struct block_list *src, int target_id, int skill_num, int
if (target)
target_id = target->id;
}
+ if (src->type==BL_HOM)
+ switch(skill_num)
+ { //Homun-auto-target skills.
+ case HLIF_AVOID:
+ case HAMI_DEFENCE:
+ case HAMI_CASTLE:
+ target = battle_get_master(src);
+ if (!target) return 0;
+ }
+
if(!target && (target=map_id2bl(target_id)) == NULL )
return 0;
if(src->m != target->m)