summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/config/classes/general.h5
-rw-r--r--src/map/battle.c75
-rw-r--r--src/map/clif.c33
-rw-r--r--src/map/clif.h2
-rw-r--r--src/map/map.h9
-rw-r--r--src/map/pc.c64
-rw-r--r--src/map/pc.h13
-rw-r--r--src/map/skill.c26
-rw-r--r--src/map/status.c5
-rw-r--r--src/map/unit.c4
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc2
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.Hooks.inc2
12 files changed, 135 insertions, 105 deletions
diff --git a/src/config/classes/general.h b/src/config/classes/general.h
index b3da4a475..b75c907e3 100644
--- a/src/config/classes/general.h
+++ b/src/config/classes/general.h
@@ -22,6 +22,11 @@
#define MAX_SPIRITBALL 15
/**
+* Spirit Charm Limitation
+**/
+#define MAX_SPIRITCHARM 10
+
+/**
* when enabled, reflect damage doesn't bypass devotion (and thus damage is passed to crusader)
* uncomment to enable
**/
diff --git a/src/map/battle.c b/src/map/battle.c
index 459af3a81..f740d6518 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -401,24 +401,7 @@ int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 d
break;
}
} //end tsc check
- if( src && src->type == BL_PC ){
- struct map_session_data *sd = BL_CAST(BL_PC, src);
- int s;
- ARR_FIND(1, 6, s, sd->charm[s] > 0);
-
- if( s < 5 && atk_elem == s )
- ratio += sd->charm[s] * 2; // +2% custom value
- }
- if( target && target->type == BL_PC ) {
- struct map_session_data *tsd = BL_CAST(BL_PC, target);
- int t;
-
- ARR_FIND(1, 6, t, tsd->charm[t] > 0);
-
- if( t < 5 && atk_elem == t )
- damage -= damage * ( tsd->charm[t] * 3 ) / 100;// -3% custom value
- }
if( ratio < 100 )
return damage - (damage * (100 - ratio) / 100);
else
@@ -1251,14 +1234,16 @@ int64 battle_calc_defense(int attack_type, struct block_list *src, struct block_
def2 = status->calc_def2(target, tsc, def2, false); // status def(RE)
#endif
- if( sd ){
- i = sd->ignore_def[is_boss(target)?RC_BOSS:RC_NONBOSS];
+ if ( sd ) {
+ i = sd->ignore_def[is_boss(target) ? RC_BOSS : RC_NONBOSS];
i += sd->ignore_def[tstatus->race];
- if( i ){
- if( i > 100 ) i = 100;
+ if ( i ) {
+ if ( i > 100 ) i = 100;
def1 -= def1 * i / 100;
def2 -= def2 * i / 100;
}
+ if ( sd->spiritcharm[SPIRITS_TYPE_CHARM_LAND] > 0 ) // hidden from status window
+ def1 += 10 * def1 * sd->spiritcharm[SPIRITS_TYPE_CHARM_LAND] / 100;
}
if( sc && sc->data[SC_EXPIATIO] ){
@@ -1497,20 +1482,38 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
break;
case NJ_KOUENKA:
skillratio -= 10;
+ if ( sd && sd->spiritcharm[SPIRITS_TYPE_CHARM_FIRE] > 0 )
+ skillratio += 20 * sd->spiritcharm[SPIRITS_TYPE_CHARM_FIRE];
break;
case NJ_KAENSIN:
skillratio -= 50;
+ if ( sd && sd->spiritcharm[SPIRITS_TYPE_CHARM_FIRE] > 0 )
+ skillratio += 10 * sd->spiritcharm[SPIRITS_TYPE_CHARM_FIRE];
break;
case NJ_BAKUENRYU:
- skillratio += 50 * (skill_lv-1);
+ skillratio += 50 * (skill_lv - 1);
+ if ( sd && sd->spiritcharm[SPIRITS_TYPE_CHARM_FIRE] > 0 )
+ skillratio += 15 * sd->spiritcharm[SPIRITS_TYPE_CHARM_FIRE];
break;
+#ifdef RENEWAL
+ case NJ_HYOUSENSOU:
+ skillratio -= 30;
+ if ( sd && sd->spiritcharm[SPIRITS_TYPE_CHARM_WATER] > 0 )
+ skillratio += 5 * sd->spiritcharm[SPIRITS_TYPE_CHARM_WATER];
+#endif
case NJ_HYOUSYOURAKU:
skillratio += 50 * skill_lv;
+ if ( sd && sd->spiritcharm[SPIRITS_TYPE_CHARM_WATER] > 0 )
+ skillratio += 25 * sd->spiritcharm[SPIRITS_TYPE_CHARM_WATER];
break;
case NJ_RAIGEKISAI:
skillratio += 60 + 40 * skill_lv;
+ if ( sd && sd->spiritcharm[SPIRITS_TYPE_CHARM_WIND] > 0 )
+ skillratio += 15 * sd->spiritcharm[SPIRITS_TYPE_CHARM_WIND];
break;
case NJ_KAMAITACHI:
+ if ( sd && sd->spiritcharm[SPIRITS_TYPE_CHARM_WIND] > 0 )
+ skillratio += 10 * sd->spiritcharm[SPIRITS_TYPE_CHARM_WIND];
case NPC_ENERGYDRAIN:
skillratio += 100 * skill_lv;
break;
@@ -1536,6 +1539,8 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
break;
case NJ_HUUJIN:
skillratio += 50;
+ if ( sd && sd->spiritcharm[SPIRITS_TYPE_CHARM_WIND] > 0 )
+ skillratio += 20 * sd->spiritcharm[SPIRITS_TYPE_CHARM_WIND];
break;
#else
case WZ_VERMILION:
@@ -1757,12 +1762,12 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
skillratio += 100 * skill_lv;
break;
case KO_KAIHOU:
- if( sd ){
- ARR_FIND(1, 6, i, sd->charm[i] > 0);
- if( i < 5 ){
- skillratio += -100 + 200 * sd->charm[i];
+ if ( sd ) {
+ ARR_FIND(SPIRITS_TYPE_CHARM_WATER, SPIRITS_TYPE_SPHERE, i, sd->spiritcharm[i] > 0);
+ if ( i < SPIRITS_TYPE_SPHERE ) {
+ skillratio += -100 + 200 * sd->spiritcharm[i];
RE_LVL_DMOD(100);
- pc->del_charm(sd, sd->charm[i], i);
+ pc->del_charm(sd, sd->spiritcharm[i], i);
}
}
break;
@@ -3366,9 +3371,9 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
if (s_ele == -1){ // pl=-1 : the skill takes the weapon's element
s_ele = sstatus->rhw.ele;
- if( sd ){ //Summoning 10 charm will endow your weapon
- ARR_FIND(1, 6, i, sd->charm[i] >= 10);
- if( i < 5 ) s_ele = i;
+ if( sd ){ //Summoning 10 spiritcharm will endow your weapon
+ ARR_FIND(SPIRITS_TYPE_CHARM_WATER, SPIRITS_TYPE_SPHERE, i, sd->spiritcharm[i] >= MAX_SPIRITCHARM);
+ if( i < SPIRITS_TYPE_SPHERE ) s_ele = i;
}
}else if (s_ele == -2) //Use status element
s_ele = status_get_attack_sc_element(src,status->get_sc(src));
@@ -3411,8 +3416,8 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
break;
case KO_KAIHOU:
if( sd ){
- ARR_FIND(1, 6, i, sd->charm[i] > 0);
- if( i < 5 )
+ ARR_FIND(SPIRITS_TYPE_CHARM_WATER, SPIRITS_TYPE_SPHERE, i, sd->spiritcharm[i] > 0);
+ if( i < SPIRITS_TYPE_SPHERE )
s_ele = i;
}
break;
@@ -4257,9 +4262,9 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
{ //Take weapon's element
s_ele = sstatus->rhw.ele;
s_ele_ = sstatus->lhw.ele;
- if( sd ){ //Summoning 10 charm will endow your weapon.
- ARR_FIND(1, 6, i, sd->charm[i] >= 10);
- if( i < 5 ) s_ele = s_ele_ = i;
+ if( sd ){ //Summoning 10 spiritcharm will endow your weapon.
+ ARR_FIND(SPIRITS_TYPE_CHARM_WATER, SPIRITS_TYPE_SPHERE, i, sd->spiritcharm[i] >= MAX_SPIRITCHARM);
+ if( i < SPIRITS_TYPE_SPHERE ) s_ele = s_ele_ = i;
}
if( flag.arrow && sd && sd->bonus.arrow_ele )
s_ele = sd->bonus.arrow_ele;
diff --git a/src/map/clif.c b/src/map/clif.c
index eff41422c..d7b10f2f4 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -1277,11 +1277,15 @@ void clif_spiritball_single(int fd, struct map_session_data *sd) {
* Kagerou/Oboro amulet spirit
*------------------------------------------*/
void clif_charm_single(int fd, struct map_session_data *sd, short type) {
+
+ if ( type <= SPIRITS_TYPE_NONE || type >= SPIRITS_TYPE_SPHERE )
+ return;
+
WFIFOHEAD(fd, packet_len(0x08cf));
WFIFOW(fd,0)=0x08cf;
WFIFOL(fd,2)=sd->bl.id;
WFIFOW(fd,6)=type;
- WFIFOW(fd,8)=sd->charm[type];
+ WFIFOW(fd,8)=sd->spiritcharm[type];
WFIFOSET(fd, packet_len(0x08cf));
}
@@ -1367,10 +1371,8 @@ bool clif_spawn(struct block_list *bl)
for( i = 0; i < sd->sc_display_count; i++ ) {
clif->sc_load(&sd->bl, sd->bl.id,AREA,status->IconChangeTable[sd->sc_display[i]->type],sd->sc_display[i]->val1,sd->sc_display[i]->val2,sd->sc_display[i]->val3);
}
- for(i = 1; i < 5; i++){
- if( sd->charm[i] > 0 )
- clif->charm(sd, i);
- }
+ ARR_FIND(SPIRITS_TYPE_CHARM_WATER, SPIRITS_TYPE_SPHERE, i, sd->spiritcharm[i] > 0);
+ clif->spiritcharm(sd, i);
if (sd->status.robe)
clif->refreshlook(bl,bl->id,LOOK_ROBE,sd->status.robe,AREA);
}
@@ -4269,10 +4271,9 @@ void clif_getareachar_pc(struct map_session_data* sd,struct map_session_data* ds
if(dstsd->spiritball > 0)
clif->spiritball_single(sd->fd, dstsd);
- for(i = 1; i < 5; i++){
- if( dstsd->charm[i] > 0 )
- clif->charm_single(sd->fd, dstsd, i);
- }
+ ARR_FIND(SPIRITS_TYPE_CHARM_WATER, SPIRITS_TYPE_SPHERE, i, sd->spiritcharm[i] > 0);
+ clif->charm_single(sd->fd, dstsd, i);
+
for( i = 0; i < dstsd->sc_display_count; i++ ) {
clif->sc_load(&sd->bl,dstsd->bl.id,SELF,status->IconChangeTable[dstsd->sc_display[i]->type],dstsd->sc_display[i]->val1,dstsd->sc_display[i]->val2,dstsd->sc_display[i]->val3);
}
@@ -8489,10 +8490,9 @@ void clif_refresh(struct map_session_data *sd)
clif->updatestatus(sd,SP_LUK);
if (sd->spiritball)
clif->spiritball_single(sd->fd, sd);
- for(i = 1; i < 5; i++){
- if( sd->charm[i] > 0 )
- clif->charm_single(sd->fd, sd, i);
- }
+ ARR_FIND(SPIRITS_TYPE_CHARM_WATER, SPIRITS_TYPE_SPHERE, i, sd->spiritcharm[i] > 0);
+ clif->charm_single(sd->fd, sd, i);
+
if (sd->vd.cloth_color)
clif->refreshlook(&sd->bl,sd->bl.id,LOOK_CLOTHES_COLOR,sd->vd.cloth_color,SELF);
if(homun_alive(sd->hd))
@@ -17458,10 +17458,13 @@ void clif_charm(struct map_session_data *sd,short type)
nullpo_retv(sd);
+ if ( type <= SPIRITS_TYPE_NONE || type >= SPIRITS_TYPE_SPHERE )
+ return;
+
WBUFW(buf,0)=0x08cf;
WBUFL(buf,2)=sd->bl.id;
WBUFW(buf,6)=type;
- WBUFW(buf,8)=sd->charm[type];
+ WBUFW(buf,8)=sd->spiritcharm[type];
clif->send(buf,packet_len(0x08cf),&sd->bl,AREA);
}
/// Move Item from or to Personal Tab (CZ_WHATSOEVER) [FE]
@@ -19155,7 +19158,7 @@ void clif_defaults(void) {
clif->specialeffect_single = clif_specialeffect_single;
clif->specialeffect_value = clif_specialeffect_value;
clif->millenniumshield = clif_millenniumshield;
- clif->charm = clif_charm;
+ clif->spiritcharm = clif_charm;
clif->charm_single = clif_charm_single;
clif->snap = clif_snap;
clif->weather_check = clif_weather_check;
diff --git a/src/map/clif.h b/src/map/clif.h
index 4d11fc281..4c90a3a28 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -820,7 +820,7 @@ struct clif_interface {
void (*specialeffect_single) (struct block_list* bl, int type, int fd);
void (*specialeffect_value) (struct block_list* bl, int effect_id, int num, send_target target);
void (*millenniumshield) (struct block_list *bl, short shields );
- void (*charm) (struct map_session_data *sd, short type);
+ void (*spiritcharm) (struct map_session_data *sd, short type);
void (*charm_single) (int fd, struct map_session_data *sd, short type);
void (*snap) ( struct block_list *bl, short x, short y );
void (*weather_check) (struct map_session_data *sd);
diff --git a/src/map/map.h b/src/map/map.h
index bb6e43ac3..1374c61fe 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -295,6 +295,15 @@ enum {
ELE_MAX
};
+enum {
+ SPIRITS_TYPE_NONE = 0,
+ SPIRITS_TYPE_CHARM_WATER,
+ SPIRITS_TYPE_CHARM_LAND,
+ SPIRITS_TYPE_CHARM_FIRE,
+ SPIRITS_TYPE_CHARM_WIND,
+ SPIRITS_TYPE_SPHERE
+};
+
enum auto_trigger_flag {
ATF_SELF=0x01,
ATF_TARGET=0x02,
diff --git a/src/map/pc.c b/src/map/pc.c
index 6c3a32152..1aef4e1c2 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -7004,11 +7004,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) {
//Reset ticks.
sd->hp_loss.tick = sd->sp_loss.tick = sd->hp_regen.tick = sd->sp_regen.tick = 0;
- if ( sd && sd->spiritball )
- pc->delspiritball(sd,sd->spiritball,0);
-
- for(i = 1; i < 5; i++)
- pc->del_charm(sd, sd->charm[i], i);
+ RESET_SPIRITS(sd);
if (src) {
switch (src->type) {
@@ -9797,28 +9793,28 @@ int pc_charm_timer(int tid, int64 tick, int id, intptr_t data) {
if( (sd=(struct map_session_data *)map->id2sd(id)) == NULL || sd->bl.type!=BL_PC )
return 1;
- ARR_FIND(1, 5, type, sd->charm[type] > 0);
+ ARR_FIND(SPIRITS_TYPE_CHARM_WATER, SPIRITS_TYPE_SPHERE, type, sd->spiritcharm[type] > 0);
- if( sd->charm[type] <= 0 )
+ if( sd->spiritcharm[type] <= 0 )
{
- ShowError("pc_charm_timer: %d charm's available. (aid=%d cid=%d tid=%d)\n", sd->charm[type], sd->status.account_id, sd->status.char_id, tid);
- sd->charm[type] = 0;
+ ShowError("pc_charm_timer: %d spiritcharm's available. (aid=%d cid=%d tid=%d)\n", sd->spiritcharm[type], sd->status.account_id, sd->status.char_id, tid);
+ sd->spiritcharm[type] = 0;
return 0;
}
- ARR_FIND(0, sd->charm[type], i, sd->charm_timer[type][i] == tid);
- if( i == sd->charm[type] )
+ ARR_FIND(0, sd->spiritcharm[type], i, sd->charm_timer[type][i] == tid);
+ if( i == sd->spiritcharm[type] )
{
ShowError("pc_charm_timer: timer not found (aid=%d cid=%d tid=%d)\n", sd->status.account_id, sd->status.char_id, tid);
return 0;
}
- sd->charm[type]--;
- if( i != sd->charm[type] )
- memmove(sd->charm_timer[type]+i, sd->charm_timer[type]+i+1, (sd->charm[type]-i)*sizeof(int));
- sd->charm_timer[type][sd->charm[type]] = INVALID_TIMER;
+ sd->spiritcharm[type]--;
+ if( i != sd->spiritcharm[type] )
+ memmove(sd->charm_timer[type]+i, sd->charm_timer[type]+i+1, (sd->spiritcharm[type]-i)*sizeof(int));
+ sd->charm_timer[type][sd->spiritcharm[type]] = INVALID_TIMER;
- clif->charm(sd, type);
+ clif->spiritcharm(sd, type);
return 0;
}
@@ -9831,27 +9827,27 @@ int pc_add_charm(struct map_session_data *sd,int interval,int max,int type)
if(max > 10)
max = 10;
- if(sd->charm[type] < 0)
- sd->charm[type] = 0;
+ if(sd->spiritcharm[type] < 0)
+ sd->spiritcharm[type] = 0;
- if( sd->charm[type] && sd->charm[type] >= max )
+ if( sd->spiritcharm[type] && sd->spiritcharm[type] >= max )
{
if(sd->charm_timer[type][0] != INVALID_TIMER)
timer->delete(sd->charm_timer[type][0],pc->charm_timer);
- sd->charm[type]--;
- if( sd->charm[type] != 0 )
- memmove(sd->charm_timer[type]+0, sd->charm_timer[type]+1, (sd->charm[type])*sizeof(int));
- sd->charm_timer[type][sd->charm[type]] = INVALID_TIMER;
+ sd->spiritcharm[type]--;
+ if( sd->spiritcharm[type] != 0 )
+ memmove(sd->charm_timer[type]+0, sd->charm_timer[type]+1, (sd->spiritcharm[type])*sizeof(int));
+ sd->charm_timer[type][sd->spiritcharm[type]] = INVALID_TIMER;
}
tid = timer->add(timer->gettick()+interval, pc->charm_timer, sd->bl.id, 0);
- ARR_FIND(0, sd->charm[type], i, sd->charm_timer[type][i] == INVALID_TIMER || DIFF_TICK(timer->get(tid)->tick, timer->get(sd->charm_timer[type][i])->tick) < 0);
- if( i != sd->charm[type] )
- memmove(sd->charm_timer[type]+i+1, sd->charm_timer[type]+i, (sd->charm[type]-i)*sizeof(int));
+ ARR_FIND(0, sd->spiritcharm[type], i, sd->charm_timer[type][i] == INVALID_TIMER || DIFF_TICK(timer->get(tid)->tick, timer->get(sd->charm_timer[type][i])->tick) < 0);
+ if( i != sd->spiritcharm[type] )
+ memmove(sd->charm_timer[type]+i+1, sd->charm_timer[type]+i, (sd->spiritcharm[type]-i)*sizeof(int));
sd->charm_timer[type][i] = tid;
- sd->charm[type]++;
+ sd->spiritcharm[type]++;
- clif->charm(sd, type);
+ clif->spiritcharm(sd, type);
return 0;
}
@@ -9861,16 +9857,16 @@ int pc_del_charm(struct map_session_data *sd,int count,int type)
nullpo_ret(sd);
- if( sd->charm[type] <= 0 ) {
- sd->charm[type] = 0;
+ if( sd->spiritcharm[type] <= 0 ) {
+ sd->spiritcharm[type] = 0;
return 0;
}
if( count <= 0 )
return 0;
- if( count > sd->charm[type] )
- count = sd->charm[type];
- sd->charm[type] -= count;
+ if( count > sd->spiritcharm[type] )
+ count = sd->spiritcharm[type];
+ sd->spiritcharm[type] -= count;
if( count > 10 )
count = 10;
@@ -9885,7 +9881,7 @@ int pc_del_charm(struct map_session_data *sd,int count,int type)
sd->charm_timer[type][i] = INVALID_TIMER;
}
- clif->charm(sd, type);
+ clif->spiritcharm(sd, type);
return 0;
}
/*==========================================
diff --git a/src/map/pc.h b/src/map/pc.h
index 0adb25a7b..28e6e4007 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -31,6 +31,15 @@
#define MAX_PC_FEELHATE 3
#define PVP_CALCRANK_INTERVAL 1000 // PVP calculation interval
+#define RESET_SPIRITS(target) do { \
+ if ( target ) { \
+ if ( target->spiritball ) \
+ pc->delspiritball(target, target->spiritball, 0); \
+ for ( int c = SPIRITS_TYPE_CHARM_WATER; c < SPIRITS_TYPE_SPHERE; c++ ) \
+ pc->del_charm(target, target->spiritcharm[c], c); \
+ } \
+}while ( 0 )
+
//Equip indexes constants. (eg: sd->equip_index[EQI_AMMO] returns the index
//where the arrows are equipped)
enum equip_index {
@@ -366,8 +375,8 @@ struct map_session_data {
short catch_target_class; // pet catching, stores a pet class to catch (short now) [zzo]
short spiritball, spiritball_old;
int spirit_timer[MAX_SPIRITBALL];
- short charm[ELE_POISON+1]; // There are actually 5 charm Fire, Ice, Wind, Earth & Poison maybe because its color violet.
- int charm_timer[ELE_POISON+1][10];
+ short spiritcharm[SPIRITS_TYPE_SPHERE];
+ int charm_timer[SPIRITS_TYPE_SPHERE][MAX_SPIRITCHARM];
unsigned char potion_success_counter; //Potion successes in row counter
unsigned char mission_count; //Stores the bounty kill count for TK_MISSION
short mission_mobid; //Stores the target mob_id for TK_MISSION
diff --git a/src/map/skill.c b/src/map/skill.c
index c8737517d..098dc5d69 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -6047,7 +6047,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
) {
// split the if for readability, and included gunslingers in the check so that their coins cannot be removed [Reddozen]
sp = dstsd->spiritball * 7;
- pc->delspiritball(dstsd,dstsd->spiritball,0);
+ RESET_SPIRITS(dstsd);
} else if (dstmd && !(tstatus->mode&MD_BOSS) && rnd() % 100 < 20) {
// check if target is a monster and not a Boss, for the 20% chance to absorb 2 SP per monster's level [Reddozen]
sp = 2 * dstmd->level;
@@ -8914,7 +8914,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
if( dstsd && dstsd->spiritball && (sd == dstsd || map_flag_vs(src->m)) && (dstsd->class_&MAPID_BASEMASK)!=MAPID_GUNSLINGER )
{
sp = dstsd->spiritball; //1%sp per spiritball.
- pc->delspiritball(dstsd, dstsd->spiritball, 0);
+ RESET_SPIRITS(dstsd);
status_percent_heal(src, 0, sp);
}
clif->skill_nodamage(src, bl, skill_id, skill_lv, sp ? 1:0);
@@ -9455,10 +9455,10 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
int i;
int ttype = skill->get_ele(skill_id, skill_lv);
clif->skill_nodamage(src, bl, skill_id, skill_lv, 1);
- ARR_FIND(1, 6, i, sd->charm[i] > 0 && ttype != i);
- if( i < 6 )
- pc->del_charm(sd, sd->charm[i], i); // replace with a new one.
- pc->add_charm(sd, skill->get_time(skill_id, skill_lv), 10, ttype);
+ ARR_FIND(SPIRITS_TYPE_CHARM_WATER, SPIRITS_TYPE_SPHERE, i, sd->spiritcharm[i] > 0 && ttype != i);
+ if( i < SPIRITS_TYPE_SPHERE )
+ pc->del_charm(sd, sd->spiritcharm[i], i); // replace with a new one.
+ pc->add_charm(sd, skill->get_time(skill_id, skill_lv), MAX_SPIRITCHARM, ttype);
}
break;
@@ -11192,13 +11192,13 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_
break;
case KO_ZENKAI:
if( sd ){
- ARR_FIND(1, 6, i, sd->charm[i] > 0);
- if( i < 5 ){
- val1 = sd->charm[i]; // no. of aura
+ ARR_FIND(SPIRITS_TYPE_CHARM_WATER, SPIRITS_TYPE_SPHERE, i, sd->spiritcharm[i] > 0);
+ if( i < SPIRITS_TYPE_SPHERE ){
+ val1 = sd->spiritcharm[i]; // no. of aura
val2 = i; // aura type
limit += val1 * 1000;
subunt = i - 1;
- pc->del_charm(sd, sd->charm[i], i);
+ pc->del_charm(sd, sd->spiritcharm[i], i);
}
}
break;
@@ -13476,7 +13476,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
case KO_DOHU_KOUKAI:
{
int ttype = skill->get_ele(skill_id, skill_lv);
- if( sd->charm[ttype] >= 10 ){
+ if( sd->spiritcharm[ttype] >= MAX_SPIRITCHARM ){
clif->skill_fail(sd, skill_id, USESKILL_FAIL_SUMMON, 0);
return 0;
}
@@ -13486,8 +13486,8 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
case KO_ZENKAI:
{
int i;
- ARR_FIND(1, 6, i, sd->charm[i] > 0); // FIXME: 4 or 6?
- if( i > 4 ) {
+ ARR_FIND(SPIRITS_TYPE_CHARM_WATER, SPIRITS_TYPE_SPHERE, i, sd->spiritcharm[i] > 0);
+ if( i >= SPIRITS_TYPE_SPHERE ) {
clif->skill_fail(sd,skill_id,USESKILL_FAIL_SUMMON,0);
return 0;
}
diff --git a/src/map/status.c b/src/map/status.c
index 2a09b47d9..d761e9202 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -8635,7 +8635,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
break;
case SC__ENERVATION:
val2 = 20 + 10 * val1; // ATK Reduction
- if( sd ) pc->delspiritball(sd,sd->spiritball,0);
+ if ( sd ) RESET_SPIRITS(sd);
break;
case SC__GROOMY:
val2 = 20 + 10 * val1; //ASPD. Need to confirm if Movement Speed reduction is the same. [Jobbie]
@@ -11477,6 +11477,9 @@ int status_get_weapon_atk(struct block_list *bl, struct weapon_atk *watk, int fl
if ( r )
max += (rnd() % 100) % r + 1;
}
+
+ if ( sd->spiritcharm[SPIRITS_TYPE_CHARM_LAND] > 0 )
+ max += 10 * max * sd->spiritcharm[SPIRITS_TYPE_CHARM_LAND] / 100;
}
max = status->calc_watk(bl, sc, max, false);
diff --git a/src/map/unit.c b/src/map/unit.c
index 86e5a56d7..a5bd282a9 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -2619,8 +2619,8 @@ int unit_free(struct block_list *bl, clr_type clrtype) {
pc->cleareventtimer(sd);
pc->inventory_rental_clear(sd);
pc->delspiritball(sd,sd->spiritball,1);
- for(i = 1; i < 5; i++)
- pc->del_charm(sd, sd->charm[i], i);
+ for(i = SPIRITS_TYPE_CHARM_WATER; i < SPIRITS_TYPE_SPHERE; i++)
+ pc->del_charm(sd, sd->spiritcharm[i], i);
if( sd->st && sd->st->state != RUN ) {// free attached scripts that are waiting
script->free_state(sd->st);
diff --git a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
index 57f2f37a2..aca88dbaf 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
@@ -424,7 +424,7 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(clif->specialeffect_single, HP_clif_specialeffect_single) },
{ HP_POP(clif->specialeffect_value, HP_clif_specialeffect_value) },
{ HP_POP(clif->millenniumshield, HP_clif_millenniumshield) },
- { HP_POP(clif->charm, HP_clif_charm) },
+ { HP_POP(clif->spiritcharm, HP_clif_charm) },
{ HP_POP(clif->charm_single, HP_clif_charm_single) },
{ HP_POP(clif->snap, HP_clif_snap) },
{ HP_POP(clif->weather_check, HP_clif_weather_check) },
diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
index 3f466a165..c2e0f4a2f 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
@@ -11027,7 +11027,7 @@ void HP_clif_charm(struct map_session_data *sd, short type) {
}
}
{
- HPMHooks.source.clif.charm(sd, type);
+ HPMHooks.source.clif.spiritcharm(sd, type);
}
if( HPMHooks.count.HP_clif_charm_post ) {
void (*postHookFunc) (struct map_session_data *sd, short *type);