summaryrefslogtreecommitdiff
path: root/src/map/skill.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/skill.c')
-rw-r--r--src/map/skill.c212
1 files changed, 135 insertions, 77 deletions
diff --git a/src/map/skill.c b/src/map/skill.c
index b3c264e43..13418fece 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -2089,7 +2089,7 @@ int skill_blown(struct block_list* src, struct block_list* target, int count, in
case BL_MOB:
{
const struct mob_data *md = BL_UCCAST(BL_MOB, target);
- if (md->class_ == MOBID_EMPELIUM)
+ if (md->status.mode&MD_NOKNOCKBACK)
return 0;
if (src != target && is_boss(target)) // Bosses can't be knocked-back
return 0;
@@ -2833,7 +2833,7 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr
if ( ssc->data[SC_POISONINGWEAPON]->val1 == 9 )// Oblivion Curse gives a 2nd success chance after the 1st one passes which is reducible. [Rytech]
rate = 100 - tstatus->int_ * 4 / 5;
sc_start(src, bl,ssc->data[SC_POISONINGWEAPON]->val2,rate,ssc->data[SC_POISONINGWEAPON]->val1,skill->get_time2(GC_POISONINGWEAPON,1) - (tstatus->vit + tstatus->luk) / 2 * 1000);
- status_change_end(src,SC_POISONINGWEAPON,-1);
+ status_change_end(src, SC_POISONINGWEAPON, INVALID_TIMER);
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
}
}
@@ -4374,7 +4374,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
clif->slide(src, x, y);
clif->fixpos(src); // the official server send these two packets.
skill->attack(BF_WEAPON, src, src, bl, skill_id, skill_lv, tick, flag);
- if ( rnd() % 100 < 4 * skill_lv && skill_id == GC_DARKILLUSION )
+ if (rnd() % 100 < 4 * skill_lv && skill_id == GC_DARKILLUSION)
skill->castend_damage_id(src, bl, GC_CROSSIMPACT, skill_lv, tick, flag);
}
}
@@ -5123,7 +5123,7 @@ int skill_castend_id(int tid, int64 tick, int id, intptr_t data) {
unit->set_walkdelay(src, tick, battle_config.default_walk_delay+skill->get_walkdelay(ud->skill_id, ud->skill_lv), 1);
if(battle_config.skill_log && battle_config.skill_log&src->type)
- ShowInfo("Type %d, ID %d skill castend id [id =%d, lv=%d, target ID %d]\n",
+ ShowInfo("Type %u, ID %d skill castend id [id =%d, lv=%d, target ID %d]\n",
src->type, src->id, ud->skill_id, ud->skill_lv, target->id);
map->freeblock_lock();
@@ -5401,12 +5401,12 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
type = status->skill2sc(skill_id);
tsc = status->get_sc(bl);
- tsce = (tsc && type != -1)?tsc->data[type]:NULL;
+ tsce = (tsc != NULL && type != SC_NONE) ? tsc->data[type] : NULL;
- if (src!=bl && type > -1 &&
- (element = skill->get_ele(skill_id, skill_lv)) > ELE_NEUTRAL &&
- skill->get_inf(skill_id) != INF_SUPPORT_SKILL &&
- battle->attr_fix(NULL, NULL, 100, element, tstatus->def_ele, tstatus->ele_lv) <= 0)
+ if (src != bl && type > SC_NONE
+ && (element = skill->get_ele(skill_id, skill_lv)) > ELE_NEUTRAL
+ && skill->get_inf(skill_id) != INF_SUPPORT_SKILL
+ && battle->attr_fix(NULL, NULL, 100, element, tstatus->def_ele, tstatus->ele_lv) <= 0)
return 1; //Skills that cause an status should be blocked if the target element blocks its element.
map->freeblock_lock();
@@ -6047,7 +6047,14 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
break;
case MC_CHANGECART:
- clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
+ clif->skill_nodamage(src, bl, skill_id, skill_lv, 1);
+ break;
+
+ case MC_CARTDECORATE:
+ if (sd) {
+ clif->skill_nodamage(src, bl, skill_id, skill_lv, 1);
+ clif->selectcart(sd);
+ }
break;
case TK_MISSION:
@@ -7290,7 +7297,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
case NPC_REBIRTH:
if( md && md->state.rebirth )
break; // only works once
- sc_start(src,bl,type,100,skill_lv,-1);
+ sc_start(src, bl, type, 100, skill_lv, INFINITE_DURATION);
break;
case NPC_DARKBLESSING:
@@ -7498,7 +7505,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
memset(&item_tmp,0,sizeof(item_tmp));
item_tmp.nameid = skill->dbs->db[su->group->skill_id].itemid[i];
item_tmp.identify = 1;
- if (item_tmp.nameid && (success=pc->additem(sd,&item_tmp,skill->dbs->db[su->group->skill_id].amount[i],LOG_TYPE_OTHER)) != 0) {
+ if (item_tmp.nameid && (success=pc->additem(sd,&item_tmp,skill->dbs->db[su->group->skill_id].amount[i],LOG_TYPE_SKILL)) != 0) {
clif->additem(sd,0,0,success);
map->addflooritem(&sd->bl, &item_tmp, skill->dbs->db[su->group->skill_id].amount[i], sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 0);
}
@@ -7510,7 +7517,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
memset(&item_tmp,0,sizeof(item_tmp));
item_tmp.nameid = su->group->item_id?su->group->item_id:ITEMID_TRAP;
item_tmp.identify = 1;
- if (item_tmp.nameid && (flag=pc->additem(sd,&item_tmp,1,LOG_TYPE_OTHER)) != 0) {
+ if (item_tmp.nameid && (flag=pc->additem(sd,&item_tmp,1,LOG_TYPE_SKILL)) != 0) {
clif->additem(sd,0,0,flag);
map->addflooritem(&sd->bl, &item_tmp, 1, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 0);
}
@@ -8511,9 +8518,8 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
for(i = 0; i < SC_MAX; i++) {
if ( !tsc->data[i] )
continue;
- if( SC_COMMON_MAX > i )
- if ( status->get_sc_type(i)&SC_NO_CLEARANCE )
- continue;
+ if (status->get_sc_type(i)&SC_NO_CLEARANCE)
+ continue;
switch (i) {
case SC_ASSUMPTIO:
if( bl->type == BL_MOB )
@@ -8641,7 +8647,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
break;
}
- sc_start(src, bl, SC_STOP, 100, skill_lv, INVALID_TIMER); //Can't move while selecting a spellbook.
+ sc_start(src, bl, SC_STOP, 100, skill_lv, INFINITE_DURATION); //Can't move while selecting a spellbook.
clif->spellbook_list(sd);
clif->skill_nodamage(src, bl, skill_id, skill_lv, 1);
}
@@ -8770,7 +8776,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
if( sd ) {
int idx1 = skill->get_index(sd->reproduceskill_id), idx2 = skill->get_index(sd->cloneskill_id);
if( sd->status.skill[idx1].id || sd->status.skill[idx2].id ) {
- sc_start(src,src,SC_STOP,100,skill_lv,-1);// The skill_lv is stored in val1 used in skill_select_menu to determine the used skill lvl [Xazax]
+ sc_start(src, src, SC_STOP, 100, skill_lv, INFINITE_DURATION); // The skill_lv is stored in val1 used in skill_select_menu to determine the used skill lvl [Xazax]
clif->autoshadowspell_list(sd);
clif->skill_nodamage(src,bl,skill_id,1,1);
}
@@ -8887,7 +8893,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
splashrange = 3;
switch( opt ) {
case 1:
- sc_start(src,bl,SC_SHIELDSPELL_DEF,100,opt,INVALID_TIMER); //Splash AoE ATK
+ sc_start(src, bl, SC_SHIELDSPELL_DEF, 100, opt, INFINITE_DURATION); // Splash AoE ATK
clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL);
map->foreachinrange(skill->area_sub,src,splashrange,BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id);
status_change_end(bl,SC_SHIELDSPELL_DEF,INVALID_TIMER);
@@ -8914,7 +8920,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
splashrange = 3;
switch( opt ) {
case 1:
- sc_start(src,bl,SC_SHIELDSPELL_MDEF,100,opt,INVALID_TIMER); //Splash AoE MATK
+ sc_start(src, bl, SC_SHIELDSPELL_MDEF, 100, opt, INFINITE_DURATION); // Splash AoE MATK
clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, BDT_SKILL);
map->foreachinrange(skill->area_sub,src,splashrange,BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id);
status_change_end(bl,SC_SHIELDSPELL_MDEF,INVALID_TIMER);
@@ -8951,7 +8957,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
sc_start(src,bl,SC_SCRESIST,100,rate,shield->refine * 30000));
break;
case 3:
- sc_start(src,bl,SC_SHIELDSPELL_REF,100,opt,INVALID_TIMER); //HP Recovery
+ sc_start(src, bl, SC_SHIELDSPELL_REF, 100, opt, INFINITE_DURATION); // HP Recovery
val = sstatus->max_hp * ((status->get_lv(src) / 10) + (shield->refine + 1)) / 100;
status->heal(bl, val, 0, 2);
status_change_end(bl,SC_SHIELDSPELL_REF,INVALID_TIMER);
@@ -9424,7 +9430,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
case SO_EL_CONTROL:
if( sd ) {
- int mode = EL_MODE_PASSIVE; // Standard mode.
+ uint32 mode = EL_MODE_PASSIVE; // Standard mode.
if( !sd->ed ) break;
@@ -9436,7 +9442,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
case 2: mode = EL_MODE_ASSIST; break;
case 3: mode = EL_MODE_AGGRESSIVE; break;
}
- if( !elemental->change_mode(sd->ed,mode) ) {
+ if (!elemental->change_mode(sd->ed, mode)) {
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
break;
}
@@ -9661,7 +9667,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
if(sd) {
struct mob_data *summon_md;
- summon_md = mob->once_spawn_sub(src, src->m, src->x, src->y, status->get_name(src), MOBID_KO_KAGE, "", SZ_SMALL, AI_NONE);
+ summon_md = mob->once_spawn_sub(src, src->m, src->x, src->y, clif->get_bl_name(src), MOBID_KO_KAGE, "", SZ_SMALL, AI_NONE);
if( summon_md ) {
summon_md->master_id = src->id;
summon_md->special_state.ai = AI_ZANZOU;
@@ -9841,7 +9847,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
break;
for (i = 0; i < summons[skill_lv-1].quantity; i++) {
- struct mob_data *summon_md = mob->once_spawn_sub(src, src->m, src->x, src->y, status->get_name(src),
+ struct mob_data *summon_md = mob->once_spawn_sub(src, src->m, src->x, src->y, clif->get_bl_name(src),
summons[skill_lv-1].mob_id, "", SZ_SMALL, AI_ATTACK);
if (summon_md != NULL) {
summon_md->master_id = src->id;
@@ -10016,7 +10022,7 @@ int skill_castend_pos(int tid, int64 tick, int id, intptr_t data)
}
if(battle_config.skill_log && battle_config.skill_log&src->type)
- ShowInfo("Type %d, ID %d skill castend pos [id =%d, lv=%d, (%d,%d)]\n",
+ ShowInfo("Type %u, ID %d skill castend pos [id =%d, lv=%d, (%d,%d)]\n",
src->type, src->id, ud->skill_id, ud->skill_lv, ud->skillx, ud->skilly);
if (ud->walktimer != INVALID_TIMER)
@@ -10260,7 +10266,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
sc = status->get_sc(src);
type = status->skill2sc(skill_id);
- sce = (sc && type != -1)?sc->data[type]:NULL;
+ sce = (sc != NULL && type != SC_NONE) ? sc->data[type] : NULL;
switch (skill_id) { //Skill effect.
case WZ_METEOR:
@@ -10582,7 +10588,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
}
// Correct info, don't change any of this! [Celest]
- md = mob->once_spawn_sub(src, src->m, x, y, status->get_name(src), class_, "", SZ_SMALL, AI_NONE);
+ md = mob->once_spawn_sub(src, src->m, x, y, clif->get_bl_name(src), class_, "", SZ_SMALL, AI_NONE);
if (md) {
md->master_id = src->id;
md->special_state.ai = (skill_id == AM_SPHEREMINE) ? AI_SPHERE : AI_FLORA;
@@ -10827,7 +10833,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
case NC_SILVERSNIPER:
{
- struct mob_data *md = mob->once_spawn_sub(src, src->m, x, y, status->get_name(src), MOBID_SILVERSNIPER, "", SZ_SMALL, AI_NONE);
+ struct mob_data *md = mob->once_spawn_sub(src, src->m, x, y, clif->get_bl_name(src), MOBID_SILVERSNIPER, "", SZ_SMALL, AI_NONE);
if (md) {
md->master_id = src->id;
md->special_state.ai = AI_FLORA;
@@ -11663,7 +11669,7 @@ int skill_unit_onplace(struct skill_unit *src, struct block_list *bl, int64 tick
return 0;
type = status->skill2sc(sg->skill_id);
- sce = (sc && type != -1)?sc->data[type]:NULL;
+ sce = (sc != NULL && type != SC_NONE) ? sc->data[type] : NULL;
skill_id = sg->skill_id; //In case the group is deleted, we need to return the correct skill id, still.
switch (sg->unit_id) {
case UNT_SPIDERWEB:
@@ -11770,6 +11776,10 @@ int skill_unit_onplace(struct skill_unit *src, struct block_list *bl, int64 tick
sc_start4(ss,bl,type,100,sg->skill_lv,sg->val1,sg->val2,0,sg->limit);
break;
case UNT_APPLEIDUN:
+ // If Aegis, apple of idun doesn't update its effect
+ if (!battle_config.song_timer_reset && sc && sce)
+ return 0;
+ // Let it fall through
case UNT_WHISTLE:
case UNT_ASSASSINCROSS:
case UNT_POEMBRAGI:
@@ -11777,19 +11787,34 @@ int skill_unit_onplace(struct skill_unit *src, struct block_list *bl, int64 tick
case UNT_DONTFORGETME:
case UNT_FORTUNEKISS:
case UNT_SERVICEFORYOU:
+ // Don't buff themselves without link!
if (sg->src_id==bl->id && !(sc && sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_BARDDANCER))
return 0;
if (!sc) return 0;
if (!sce)
sc_start4(ss,bl,type,100,sg->skill_lv,sg->val1,sg->val2,0,sg->limit);
+ // From here songs are already active
else if (battle_config.song_timer_reset && sce->val4 == 1) {
- //Readjust timers since the effect will not last long.
+ // eA style:
+ // Readjust timers since the effect will not last long.
sce->val4 = 0;
timer->delete(sce->timer, status->change_timer);
sce->timer = timer->add(tick+sg->limit, status->change_timer, bl->id, type);
+ } else if (!battle_config.song_timer_reset) {
+ // Aegis style:
+ // Songs won't renew unless finished
+ const struct TimerData *td = timer->get(sce->timer);
+ if (DIFF_TICK32(td->tick, timer->gettick()) < sg->interval) {
+ // Update with new values as the current one will vanish soon
+ timer->delete(sce->timer, status->change_timer);
+ sce->timer = timer->add(tick+sg->limit, status->change_timer, bl->id, type);
+ sce->val1 = sg->skill_lv; // Why are we storing skill_lv as val1?
+ sce->val2 = sg->val1;
+ sce->val3 = sg->val2;
+ sce->val4 = 0;
+ }
}
-
break;
case UNT_FOGWALL:
@@ -11924,7 +11949,7 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
case UNT_MANHOLE:
return 0;
default:
- ShowError("skill_unit_onplace_timer: interval error (unit id %x)\n", sg->unit_id);
+ ShowError("skill_unit_onplace_timer: interval error (unit id %x)\n", (unsigned int)sg->unit_id);
return 0;
}
}
@@ -12194,18 +12219,25 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
if (md && md->class_ == MOBID_EMPELIUM)
break;
#endif
- if ((sg->src_id == bl->id && !(tsc && tsc->data[SC_SOULLINK] && tsc->data[SC_SOULLINK]->val2 == SL_BARDDANCER))
- || (!(battle_config.song_timer_reset) && tsc && tsc->data[type] && tsc->data[type]->val4 == 1))
+ // Don't buff themselves!
+ if ((sg->src_id == bl->id && !(tsc && tsc->data[SC_SOULLINK] && tsc->data[SC_SOULLINK]->val2 == SL_BARDDANCER)))
break;
- heal = skill->calc_heal(ss,bl,sg->skill_id, sg->skill_lv, true);
- if( tsc && tsc->data[SC_AKAITSUKI] && heal )
- heal = ~heal + 1;
- clif->skill_nodamage(&src->bl, bl, AL_HEAL, heal, 1);
- status->heal(bl, heal, 0, 0);
-
- if (!battle_config.song_timer_reset)
+ // Aegis style
+ // Check if the remaining time is enough to survive the next update
+ if (!battle_config.song_timer_reset
+ && !(tsc && tsc->data[type] && tsc->data[type]->val4 == 1)) {
+ // Apple of Idun is not active. Start it now
sc_start4(ss, bl, type, 100, sg->skill_lv, sg->val1, sg->val2, 0, sg->limit);
+ }
+
+ if (tstatus->hp < tstatus->max_hp) {
+ heal = skill->calc_heal(ss,bl,sg->skill_id, sg->skill_lv, true);
+ if( tsc && tsc->data[SC_AKAITSUKI] && heal )
+ heal = ~heal + 1;
+ clif->skill_nodamage(&src->bl, bl, AL_HEAL, heal, 1);
+ status->heal(bl, heal, 0, 0);
+ }
}
break;
case UNT_POEMBRAGI:
@@ -12215,12 +12247,30 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
case UNT_DONTFORGETME:
case UNT_FORTUNEKISS:
case UNT_SERVICEFORYOU:
- if (battle_config.song_timer_reset
- || (!(battle_config.song_timer_reset) && tsc && tsc->data[type] && tsc->data[type]->val4 == 1)
- || (sg->src_id == bl->id && !(tsc && tsc->data[SC_SOULLINK] && tsc->data[SC_SOULLINK]->val2 == SL_BARDDANCER))
- )
+ // eA style: doesn't need this
+ if (battle_config.song_timer_reset)
+ break;
+ // Don't let buff themselves!
+ if (sg->src_id == bl->id && !(tsc && tsc->data[SC_SOULLINK] && tsc->data[SC_SOULLINK]->val2 == SL_BARDDANCER))
break;
+ // Aegis style
+ // Check if song has enough time to survive the next check
+ if (!(battle_config.song_timer_reset) && tsc && tsc->data[type] && tsc->data[type]->val4 == 1) {
+ const struct TimerData *td = timer->get(tsc->data[type]->timer);
+ if (DIFF_TICK32(td->tick, timer->gettick()) < sg->interval) {
+ // Update with new values as the current one will vanish
+ timer->delete(tsc->data[type]->timer, status->change_timer);
+ tsc->data[type]->timer = timer->add(tick+sg->limit, status->change_timer, bl->id, type);
+ tsc->data[type]->val1 = sg->skill_lv;
+ tsc->data[type]->val2 = sg->val1;
+ tsc->data[type]->val3 = sg->val2;
+ tsc->data[type]->val4 = 0;
+ }
+ break; // Had enough time or not, it now has. Exit
+ }
+
+ // Song was not active. Start it now
sc_start4(ss, bl, type, 100, sg->skill_lv, sg->val1, sg->val2, 0, sg->limit);
break;
case UNT_TATAMIGAESHI:
@@ -12617,7 +12667,7 @@ int skill_unit_onout(struct skill_unit *src, struct block_list *bl, int64 tick)
nullpo_ret(sg=src->group);
sc = status->get_sc(bl);
type = status->skill2sc(sg->skill_id);
- sce = (sc && type != -1)?sc->data[type]:NULL;
+ sce = (sc != NULL && type != SC_NONE) ? sc->data[type] : NULL;
if( bl->prev == NULL
|| (status->isdead(bl) && sg->unit_id != UNT_ANKLESNARE && sg->unit_id != UNT_SPIDERWEB && sg->unit_id != UNT_THORNS_TRAP)
@@ -12681,7 +12731,7 @@ int skill_unit_onleft(uint16 skill_id, struct block_list *bl, int64 tick) {
sc = NULL;
type = status->skill2sc(skill_id);
- sce = (sc && type != -1)?sc->data[type]:NULL;
+ sce = (sc != NULL && type != SC_NONE) ? sc->data[type] : NULL;
switch (skill_id) {
case WZ_QUAGMIRE:
@@ -12742,8 +12792,9 @@ int skill_unit_onleft(uint16 skill_id, struct block_list *bl, int64 tick) {
case DC_DONTFORGETME:
case DC_FORTUNEKISS:
case DC_SERVICEFORYOU:
- if ((battle_config.song_timer_reset && sce) // athena style
- || (!battle_config.song_timer_reset && sce && sce->val4 != 1)
+
+ if ((battle_config.song_timer_reset && sce) // eAthena style: update everytime
+ || (!battle_config.song_timer_reset && sce && sce->val4 != 1) // Aegis style: update only when it was not a reduced effect
) {
timer->delete(sce->timer, status->change_timer);
//NOTE: It'd be nice if we could get the skill_lv for a more accurate extra time, but alas...
@@ -14836,7 +14887,7 @@ int skill_vfcastfix(struct block_list *bl, double time, uint16 skill_id, uint16
}
if (sc->data[SC_MYSTICSCROLL])
VARCAST_REDUCTION(sc->data[SC_MYSTICSCROLL]->val1);
-
+
// Fixed cast reduction bonuses
if( sc->data[SC__LAZINESS] )
fixcast_r = max(fixcast_r, sc->data[SC__LAZINESS]->val2);
@@ -15262,12 +15313,12 @@ void skill_weaponrefine (struct map_session_data *sd, int idx)
else
per += 5 * ((signed int)sd->status.job_level - 50);
- pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_OTHER); // FIXME: is this the correct reason flag?
+ pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_REFINE); // FIXME: is this the correct reason flag?
if (per > rnd() % 1000) {
int ep = 0;
- logs->pick_pc(sd, LOG_TYPE_OTHER, -1, item, ditem);
+ logs->pick_pc(sd, LOG_TYPE_REFINE, -1, item, ditem);
item->refine++;
- logs->pick_pc(sd, LOG_TYPE_OTHER, 1, item, ditem);
+ logs->pick_pc(sd, LOG_TYPE_REFINE, 1, item, ditem);
if(item->equip) {
ep = item->equip;
pc->unequipitem(sd, idx, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE);
@@ -15300,7 +15351,7 @@ void skill_weaponrefine (struct map_session_data *sd, int idx)
if(item->equip)
pc->unequipitem(sd, idx, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE);
clif->refine(sd->fd,1,idx,item->refine);
- pc->delitem(sd, idx, 1, 0, DELITEM_NORMAL, LOG_TYPE_OTHER);
+ pc->delitem(sd, idx, 1, 0, DELITEM_NORMAL, LOG_TYPE_REFINE);
clif->misceffect(&sd->bl,2);
clif->emotion(&sd->bl, E_OMG);
}
@@ -16467,7 +16518,7 @@ struct skill_unit_group_tickset *skill_unitgrouptickset_search(struct block_list
}
if (j == -1) {
- ShowWarning ("skill_unitgrouptickset_search: tickset is full. ( failed for skill '%s' on unit %d )\n",skill->get_name(group->skill_id),bl->type);
+ ShowWarning ("skill_unitgrouptickset_search: tickset is full. ( failed for skill '%s' on unit %u )\n", skill->get_name(group->skill_id), bl->type);
j = id % MAX_SKILLUNITGROUPTICKSET;
}
@@ -17673,7 +17724,7 @@ int skill_poisoningweapon( struct map_session_data *sd, int nameid) {
return 0;
}
- status_change_end(&sd->bl, SC_POISONINGWEAPON, -1);//Status must be forced to end so that a new poison will be applied if a player decides to change poisons. [Rytech]
+ status_change_end(&sd->bl, SC_POISONINGWEAPON, INVALID_TIMER); // Status must be forced to end so that a new poison will be applied if a player decides to change poisons. [Rytech]
chance = 2 + 2 * sd->menuskill_val; // 2 + 2 * skill_lv
sc_start4(&sd->bl, &sd->bl, SC_POISONINGWEAPON, 100, pc->checkskill(sd, GC_RESEARCHNEWPOISON), //in Aegis it store the level of GC_RESEARCHNEWPOISON in val1
type, chance, 0, skill->get_time(GC_POISONINGWEAPON, sd->menuskill_val));
@@ -17793,13 +17844,13 @@ int skill_spellbook (struct map_session_data *sd, int nameid) {
for(i = SC_SPELLBOOK7; i >= SC_SPELLBOOK1; i--){ // This is how official saves spellbook. [malufett]
if( !sc->data[i] ){
sc->data[SC_READING_SB]->val2 += point; // increase points
- sc_start4(&sd->bl,&sd->bl, (sc_type)i, 100, skill_id, pc->checkskill(sd,skill_id), point, 0, INVALID_TIMER);
+ sc_start4(&sd->bl, &sd->bl, (sc_type)i, 100, skill_id, pc->checkskill(sd, skill_id), point, 0, INFINITE_DURATION);
break;
}
}
- }else{
- sc_start2(&sd->bl,&sd->bl, SC_READING_SB, 100, 0, point, INVALID_TIMER);
- sc_start4(&sd->bl,&sd->bl, SC_SPELLBOOK7, 100, skill_id, pc->checkskill(sd,skill_id), point, 0, INVALID_TIMER);
+ } else {
+ sc_start2(&sd->bl, &sd->bl, SC_READING_SB, 100, 0, point, INFINITE_DURATION);
+ sc_start4(&sd->bl, &sd->bl, SC_SPELLBOOK7, 100, skill_id, pc->checkskill(sd, skill_id), point, 0, INFINITE_DURATION);
}
return 1;
@@ -17827,27 +17878,31 @@ int skill_select_menu(struct map_session_data *sd,uint16 skill_id) {
sc_start4(&sd->bl,&sd->bl,SC__AUTOSHADOWSPELL,100,id,lv,prob,0,skill->get_time(SC_AUTOSHADOWSPELL,aslvl));
return 0;
}
-int skill_elementalanalysis(struct map_session_data* sd, int n, uint16 skill_lv, unsigned short* item_list) {
+
+int skill_elementalanalysis(struct map_session_data *sd, uint16 skill_lv, const struct itemlist *item_list)
+{
int i;
nullpo_ret(sd);
nullpo_ret(item_list);
- if( n <= 0 )
+ if (VECTOR_LENGTH(*item_list) <= 0)
return 1;
- for (i = 0; i < n; i++) {
- int nameid, add_amount, del_amount, idx, product;
+ for (i = 0; i < VECTOR_LENGTH(*item_list); i++) {
struct item tmp_item;
-
- idx = item_list[i*2+0]-2;
- del_amount = item_list[i*2+1];
+ const struct itemlist_entry *entry = &VECTOR_INDEX(*item_list, i);
+ int nameid, add_amount, product;
+ int del_amount = entry->amount;
+ int idx = entry->id;
if( skill_lv == 2 )
del_amount -= (del_amount % 10);
add_amount = (skill_lv == 1) ? del_amount * (5 + rnd()%5) : del_amount / 10 ;
- if( (nameid = sd->status.inventory[idx].nameid) <= 0 || del_amount > sd->status.inventory[idx].amount ) {
+ if (idx < 0 || idx >= MAX_INVENTORY
+ || (nameid = sd->status.inventory[idx].nameid) <= 0
+ || del_amount < 0 || del_amount > sd->status.inventory[idx].amount) {
clif->skill_fail(sd,SO_EL_ANALYSIS,USESKILL_FAIL_LEVEL,0);
return 1;
}
@@ -17897,7 +17952,8 @@ int skill_elementalanalysis(struct map_session_data* sd, int n, uint16 skill_lv,
return 0;
}
-int skill_changematerial(struct map_session_data *sd, int n, unsigned short *item_list) {
+int skill_changematerial(struct map_session_data *sd, const struct itemlist *item_list)
+{
int i, j, k, c, p = 0, nameid, amount;
nullpo_ret(sd);
@@ -17912,11 +17968,13 @@ int skill_changematerial(struct map_session_data *sd, int n, unsigned short *ite
// Verification of overlap between the objects required and the list submitted.
for( j = 0; j < MAX_PRODUCE_RESOURCE; j++ ) {
if( skill->dbs->produce_db[i].mat_id[j] > 0 ) {
- for( k = 0; k < n; k++ ) {
- int idx = item_list[k*2+0]-2;
+ for (k = 0; k < VECTOR_LENGTH(*item_list); k++) {
+ const struct itemlist_entry *entry = &VECTOR_INDEX(*item_list, k);
+ int idx = entry->id;
+ Assert_ret(idx >= 0 && idx < MAX_INVENTORY);
+ amount = entry->amount;
nameid = sd->status.inventory[idx].nameid;
- amount = item_list[k*2+1];
- if( nameid > 0 && sd->status.inventory[idx].identify == 0 ){
+ if (nameid > 0 && sd->status.inventory[idx].identify == 0) {
clif->msgtable_skill(sd, GN_CHANGEMATERIAL, MSG_SKILL_ITEM_NEED_IDENTIFY);
return 0;
}
@@ -17929,7 +17987,7 @@ int skill_changematerial(struct map_session_data *sd, int n, unsigned short *ite
break; // No more items required
}
p++;
- } while(n == j && c == n);
+ } while (c == j && VECTOR_LENGTH(*item_list) == c);
p--;
if ( p > 0 ) {
skill->produce_mix(sd,GN_CHANGEMATERIAL,skill->dbs->produce_db[i].nameid,0,0,0,p);
@@ -18076,7 +18134,7 @@ int skill_blockpc_start_(struct map_session_data *sd, uint16 skill_id, int tick)
return 0;
else {
int cursor;
- /** somehow, the timer vanished. (bugreport:8367) **/
+ /* somehow, the timer vanished. (bugreport:8367) */
ers_free(skill->cd_entry_ers, cd->entry[i]);
cd->entry[i] = NULL;
@@ -18788,7 +18846,7 @@ bool skill_parse_row_skilldb(char* split[], int columns, int current) {
safestrncpy(skill->dbs->db[idx].name, trim(split[15]), sizeof(skill->dbs->db[idx].name));
safestrncpy(skill->dbs->db[idx].desc, trim(split[16]), sizeof(skill->dbs->db[idx].desc));
strdb_iput(skill->name2id_db, skill->dbs->db[idx].name, skill_id);
- script->set_constant2(skill->dbs->db[idx].name,(int)skill_id,0);
+ script->set_constant2(skill->dbs->db[idx].name, (int)skill_id, false, false);
return true;
}