summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2006-08-18 16:43:20 +0000
committerskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2006-08-18 16:43:20 +0000
commitaff8dade6593463301abee054981a4ea21fff273 (patch)
treecaacd036116e75a315e95302871e2f23718e5c03 /src
parent39292f6f6a30287d2a4ffdd035f80616a8e6e8a4 (diff)
downloadhercules-aff8dade6593463301abee054981a4ea21fff273.tar.gz
hercules-aff8dade6593463301abee054981a4ea21fff273.tar.bz2
hercules-aff8dade6593463301abee054981a4ea21fff273.tar.xz
hercules-aff8dade6593463301abee054981a4ea21fff273.zip
- Made HLIF_HEAL a self skill that auto-selects target to caster's master.
- Implemented SC_BLOODLUST and SC_CHANGE, cleaned up HLIF_CHANGE - Applied a correction to HVAN_EXPLOSION - Fixed Homun ASPD calculation being able to underflow and give you min speed. - Added monster_ai&128 to make aggressive mobs ignore that behaviour of always picking Homun targets above player targets regardless of who is closer. - Fixed homun info packet being unable to display HP/SP correctly once the values are above 32k. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@8349 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src')
-rw-r--r--src/map/battle.c15
-rw-r--r--src/map/clif.c22
-rw-r--r--src/map/mob.c2
-rw-r--r--src/map/skill.c18
-rw-r--r--src/map/status.c39
-rw-r--r--src/map/unit.c1
6 files changed, 68 insertions, 29 deletions
diff --git a/src/map/battle.c b/src/map/battle.c
index f16a58314..fbe9fcfba 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -404,6 +404,13 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i
}
if (!damage) return 0;
+
+ //Probably not the most correct place, but it'll do here
+ //(since battle_drain is strictly for players currently)
+ if (sc->data[SC_BLOODLUST].timer != -1 && flag&BF_WEAPON && damage > 0 &&
+ rand()%100 < sc->data[SC_BLOODLUST].val3)
+ status_heal(src, damage*sc->data[SC_BLOODLUST].val4/100, 0, 3);
+
}
//SC effects from caster side. Currently none.
/*
@@ -1030,7 +1037,6 @@ static struct Damage battle_calc_weapon_attack(
case GS_GROUNDDRIFT:
case NJ_TATAMIGAESHI:
case NJ_ISSEN:
- case HVAN_EXPLOSION: //[orn]
flag.hit = 1;
break;
case CR_SHIELDBOOMERANG:
@@ -1195,6 +1201,7 @@ static struct Damage battle_calc_weapon_attack(
i = (flag.cri?1:0)|
(flag.arrow?2:0)|
(skill_num == HW_MAGICCRASHER?4:0)|
+ (!skill_num && sc && sc->data[SC_CHANGE].timer!=-1?4:0)|
(skill_num == MO_EXTREMITYFIST?8:0)|
(sc && sc->data[SC_WEAPONPERFECTION].timer!=-1?8:0);
if (flag.arrow && sd)
@@ -2504,7 +2511,7 @@ struct Damage battle_calc_misc_attack(
case CR_ACIDDEMONSTRATION:
md.flag = (md.flag&~BF_RANGEMASK)|BF_LONG;
break;
- case HVAN_EXPLOSION: //[orn]
+ case HVAN_EXPLOSION:
case NPC_SELFDESTRUCTION:
case NPC_SMOKING:
flag.elefix = flag.cardfix = 0;
@@ -2726,8 +2733,8 @@ int battle_calc_return_damage(struct block_list *bl, int *damage, int flag) {
struct map_session_data *sd=NULL;
struct status_change *sc;
int rdamage = 0;
-
- if (bl->type == BL_PC) sd = (struct map_session_data*)bl;
+
+ BL_CAST(BL_PC, bl, sd);
sc = status_get_sc(bl);
if(flag&BF_WEAPON) {
diff --git a/src/map/clif.c b/src/map/clif.c
index 0a2b995b9..4537deb26 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -1466,14 +1466,14 @@ int clif_hominfo(struct map_session_data *sd, struct homun_data *hd, int flag)
memset(buf,0,packet_len_table[0x22e]);
WBUFW(buf,0)=0x22e;
memcpy(WBUFP(buf,2),sd->homunculus.name,NAME_LENGTH);
- WBUFB(buf,26)=sd->homunculus.rename_flag * 2;
+// WBUFB(buf,26)=sd->homunculus.rename_flag * 2;
// Bit field, bit 0 : rename_flag (1 = already renamed), bit 1 : homunc vaporized (1 = true), bit 2 : homunc dead (1 = true)
WBUFB(buf,26)=sd->homunculus.rename_flag | (sd->homunculus.vaporize << 1) | (sd->homunculus.hp?0:4);
WBUFW(buf,27)=sd->homunculus.level;
WBUFW(buf,29)=sd->homunculus.hunger;
WBUFW(buf,31)=(unsigned short) (sd->homunculus.intimacy / 100) ;
WBUFW(buf,33)=0; // equip id
- WBUFW(buf,35)=status->rhw.atk2;
+ WBUFW(buf,35)=status->rhw.atk2+status->batk;
WBUFW(buf,37)=status->matk_max;
WBUFW(buf,39)=status->hit;
WBUFW(buf,41)=status->cri/10; //crit is a +1 decimal value!
@@ -1481,10 +1481,20 @@ int clif_hominfo(struct map_session_data *sd, struct homun_data *hd, int flag)
WBUFW(buf,45)=status->mdef;
WBUFW(buf,47)=status->flee;
WBUFW(buf,49)=(flag)?0:status->amotion;
- WBUFW(buf,51)=status->hp;
- WBUFW(buf,53)=status->max_hp;
- WBUFW(buf,55)=status->sp;
- WBUFW(buf,57)=status->max_sp;
+ if (status->max_hp > SHRT_MAX) {
+ WBUFW(buf,51) = status->hp/(status->max_hp/100);
+ WBUFW(buf,53) = 100;
+ } else {
+ WBUFW(buf,51)=status->hp;
+ WBUFW(buf,53)=status->max_hp;
+ }
+ if (status->max_sp > SHRT_MAX) {
+ WBUFW(buf,55) = status->sp/(status->max_sp/100);
+ WBUFW(buf,57) = 100;
+ } else {
+ WBUFW(buf,55)=status->sp;
+ WBUFW(buf,57)=status->max_sp;
+ }
WBUFL(buf,59)=sd->homunculus.exp;
WBUFL(buf,63)=hd->exp_next;
WBUFW(buf,67)=sd->homunculus.skillpts;
diff --git a/src/map/mob.c b/src/map/mob.c
index 84671a70d..e3bce2257 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -774,7 +774,7 @@ static int mob_ai_sub_hard_activesearch(struct block_list *bl,va_list ap)
!(status_get_mode(&md->bl)&MD_BOSS))
return 0; //Gangster paradise protection.
default:
- if ((*target) && (*target)->type == BL_HOM && bl->type != BL_HOM)
+ if (!(battle_config.mob_ai&128) && (*target) && (*target)->type == BL_HOM && bl->type != BL_HOM)
return 0; //For some reason Homun targets are never overriden.
if((dist=distance_bl(&md->bl, bl)) < md->db->range2 &&
diff --git a/src/map/skill.c b/src/map/skill.c
index b8fd82f3b..f8b946eb0 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -3091,12 +3091,12 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
case CR_ACIDDEMONSTRATION:
case TF_THROWSTONE:
case NPC_SMOKING:
- case HVAN_EXPLOSION: //[orn]
case GS_FLING:
case NJ_ZENYNAGE:
skill_attack(BF_MISC,src,src,bl,skillid,skilllv,tick,flag);
break;
+ case HVAN_EXPLOSION:
case NPC_SELFDESTRUCTION:
if (src != bl)
skill_attack(BF_MISC,src,src,bl,skillid,skilllv,tick,flag);
@@ -4063,7 +4063,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
case NPC_SELFDESTRUCTION:
//Self Destruction hits everyone in range (allies+enemies)
//Except for Summoned Marine spheres on non-versus maps, where it's just enemy.
- i = (md && md->special_state.ai == 2 && !map_flag_vs(src->m))?
+ i = ((hd || (md && md->special_state.ai == 2)) && !map_flag_vs(src->m))?
BCT_ENEMY:BCT_ALL;
clif_skill_nodamage(src, src, skillid, -1, 1);
map_foreachinrange(skill_area_sub, bl,
@@ -5554,14 +5554,12 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
clif_skill_fail(hd->master,skillid,0,0);
break;
case HLIF_CHANGE: //[orn]
- if ( hd ) {
- clif_skill_nodamage(src,bl,skillid,skilllv,
- sc_start(&hd->bl,type,100,skilllv,skill_get_time(skillid,skilllv))) ;
- status_heal(&hd->bl, hd->master->homunculus.max_hp, 0, 0);
- skill_blockmerc_start(hd, skillid, skill_get_time2(skillid,skilllv)) ;
- }
- else
- clif_skill_fail(hd->master,skillid,0,0);
+ clif_skill_nodamage(src,bl,skillid,skilllv,
+ sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
+ if (sd)
+ skill_blockpc_start(sd, skillid, skill_get_time2(skillid,skilllv));
+ if (hd)
+ skill_blockmerc_start(hd, skillid, skill_get_time2(skillid,skilllv));
break;
default:
diff --git a/src/map/status.c b/src/map/status.c
index 99449554b..f40e39c9b 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -376,7 +376,7 @@ void initChangeTables(void) {
add_sc(SA_ELEMENTWIND, SC_ELEMENTALCHANGE);
set_sc(HLIF_AVOID, SC_AVOID, SI_BLANK, SCB_SPEED);
- set_sc(HLIF_CHANGE, SC_CHANGE, SI_BLANK, SCB_INT);
+ set_sc(HLIF_CHANGE, SC_CHANGE, SI_BLANK, SCB_MAXHP|SCB_MAXSP);
set_sc(HFLI_FLEET, SC_FLEET, SI_BLANK, SCB_ASPD|SCB_BATK|SCB_WATK);
set_sc(HFLI_SPEED, SC_SPEED, SI_BLANK, SCB_FLEE); //[orn]
set_sc(HAMI_DEFENCE, SC_DEFENCE, SI_BLANK, SCB_DEF); //[orn]
@@ -2255,6 +2255,14 @@ int status_calc_homunculus(struct homun_data *hd, int first)
status->rhw.atk = status->dex;
status->rhw.atk2 = status->str + hom->level;
+ status->aspd_rate = 1000;
+
+ skill = (1000 -4*status->agi -status->dex)
+ *hd->homunculusDB->baseASPD/1000;
+
+ status->amotion = cap_value(skill,battle_config.max_aspd,2000);
+ status->adelay = 2*status->amotion;
+
status_calc_misc(status, BL_HOM, hom->level);
status_calc_bl(&hd->bl, SCB_ALL); //Status related changes.
@@ -2725,14 +2733,15 @@ void status_calc_bl_sub_hom(struct homun_data *hd, unsigned long flag) //[orn]
if(flag&(SCB_ASPD|SCB_AGI|SCB_DEX)) {
flag|=SCB_ASPD;
- status->amotion = hd->homunculusDB->baseASPD - ((status->agi*4+status->dex)* hd->homunculusDB->baseASPD / 1000);
+ skill = (1000 -4*status->agi -status->dex)
+ *hd->homunculusDB->baseASPD/1000;
+
status->aspd_rate = status_calc_aspd_rate(&hd->bl, &hd->sc , b_status->aspd_rate);
if(status->aspd_rate != 1000)
- status->amotion = status->amotion *status->aspd_rate/1000;
-
- status->amotion = cap_value(status->amotion,battle_config.max_aspd,2000);
+ skill = skill*status->aspd_rate/1000;
+ status->amotion = cap_value(skill,battle_config.max_aspd,2000);
status->adelay = 2*status->amotion;
}
@@ -3109,8 +3118,6 @@ static unsigned short status_calc_int(struct block_list *bl, struct status_chang
int_ -= int_ * sc->data[SC_STRIPHELM].val2/100;
if(sc->data[SC_NEN].timer!=-1)
int_ += sc->data[SC_NEN].val1;
- if(sc->data[SC_CHANGE].timer!=-1)
- int_ += 60;
if(sc->data[SC_MARIONETTE].timer!=-1)
int_ -= (sc->data[SC_MARIONETTE].val4>>16)&0xFF;
if(sc->data[SC_MARIONETTE2].timer!=-1)
@@ -3686,6 +3693,8 @@ static unsigned int status_calc_maxhp(struct block_list *bl, struct status_chang
if(!sc || !sc->count)
return cap_value(maxhp,1,UINT_MAX);
+ if(sc->data[SC_CHANGE].timer!=-1)
+ maxhp = sc->data[SC_CHANGE].val3;
if(sc->data[SC_INCMHPRATE].timer!=-1)
maxhp += maxhp * sc->data[SC_INCMHPRATE].val1/100;
if(sc->data[SC_APPLEIDUN].timer!=-1)
@@ -3703,6 +3712,8 @@ static unsigned int status_calc_maxsp(struct block_list *bl, struct status_chang
if(!sc || !sc->count)
return cap_value(maxsp,1,UINT_MAX);
+ if(sc->data[SC_CHANGE].timer!=-1)
+ maxsp = sc->data[SC_CHANGE].val2;
if(sc->data[SC_INCMSPRATE].timer!=-1)
maxsp += maxsp * sc->data[SC_INCMSPRATE].val1/100;
if(sc->data[SC_SERVICE4U].timer!=-1)
@@ -5459,6 +5470,8 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val
break;
case SC_BLOODLUST:
val2 = 20+10*val1; //Atk rate change.
+ val3 = 3*val1; //Leech chance
+ val4 = 20; //Leech percent
break;
case SC_FLEET:
val2 = 30*val1; //Aspd change
@@ -5494,6 +5507,14 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val
case SC_BUNSINJYUTSU:
val2=(val1+1)/2; // number of hits blocked
break;
+ case SC_CHANGE:
+ {
+ struct status_data *status = status_get_base_status(bl);
+ if (!status) return 0;
+ val2= status->max_hp; //Base Max HP
+ val3= status->max_sp; //Base Max SP
+ }
+ break;
default:
if (calc_flag == SCB_NONE && StatusSkillChangeTable[type]==0)
{ //Status change with no calc, and no skill associated...? unknown?
@@ -5717,7 +5738,9 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val
sc->data[type].val2 = 5*status->max_hp/100;
status_heal(bl, status->max_hp, 0, 1); //Do not use percent_heal as this healing must override BERSERK's block.
status_set_sp(bl, 0, 0); //Damage all SP
- }
+ } else if (type==SC_CHANGE) //Heal all HP
+ status_percent_heal(bl, 100, 0);
+
if (type==SC_RUN) {
struct unit_data *ud = unit_bl2ud(bl);
diff --git a/src/map/unit.c b/src/map/unit.c
index 52284d83d..bed5a93d2 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -784,6 +784,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, int skill_num, int
if (src->type==BL_HOM)
switch(skill_num)
{ //Homun-auto-target skills.
+ case HLIF_HEAL:
case HLIF_AVOID:
case HAMI_DEFENCE:
case HAMI_CASTLE: