Implementation of Status Changes in YAML (#1685)
* Removes the initialization of Status Changes via hard-code and puts it into YAML form. * From this database it is much easier to delegate icons, calc flags, opt flags, miscellaneous flags, and several other things for all stats changes. * Statuses can quickly be reloaded via atcommand reloadstatus. Thanks to @cydh, @Atemo, @Lemongrass3110, and the others who helped! Signed-off-by: Cydh Ramdh <cydh@pservero.com> Co-authored-by: atemo <capucrath@gmail.com> Co-authored-by: Lemongrass3110 <lemongrass@kstp.at>
This commit is contained in:
@@ -218,6 +218,7 @@ int skill_get_ammo_qty( uint16 skill_id, uint16 skill_lv ) { skill_get_l
|
||||
int skill_get_state( uint16 skill_id ) { skill_get(skill_id, skill_db.find(skill_id)->require.state); }
|
||||
int skill_get_status_count( uint16 skill_id ) { skill_get(skill_id, skill_db.find(skill_id)->require.status.size()); }
|
||||
int skill_get_spiritball( uint16 skill_id, uint16 skill_lv ) { skill_get_lv(skill_id, skill_lv, skill_db.find(skill_id)->require.spiritball); }
|
||||
sc_type skill_get_sc(int16 skill_id) { if (!skill_check(skill_id)) return SC_NONE; return skill_db.find(skill_id)->sc; }
|
||||
|
||||
int skill_get_splash( uint16 skill_id , uint16 skill_lv ) {
|
||||
int splash = skill_get_splash_(skill_id, skill_lv);
|
||||
@@ -1601,22 +1602,34 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
|
||||
break;
|
||||
|
||||
case NPC_PETRIFYATTACK:
|
||||
sc_start4(src,bl,status_skill2sc(skill_id),(20*skill_lv),
|
||||
skill_lv,0,0,skill_get_time(skill_id,skill_lv),
|
||||
skill_get_time2(skill_id,skill_lv));
|
||||
sc_start4(src,bl,SC_STONE,50+10*skill_lv,skill_lv,0,0,skill_get_time(skill_id,skill_lv),skill_get_time2(skill_id,skill_lv));
|
||||
break;
|
||||
case NPC_CURSEATTACK:
|
||||
sc_start(src,bl,SC_CURSE,(20*skill_lv),skill_lv,skill_get_time2(skill_id,skill_lv));
|
||||
break;
|
||||
case NPC_SLEEPATTACK:
|
||||
sc_start(src,bl,SC_SLEEP,(20*skill_lv),skill_lv,skill_get_time2(skill_id,skill_lv));
|
||||
break;
|
||||
case NPC_BLINDATTACK:
|
||||
sc_start(src,bl,SC_BLIND,(20*skill_lv),skill_lv,skill_get_time2(skill_id,skill_lv));
|
||||
break;
|
||||
case NPC_POISON:
|
||||
sc_start(src,bl,SC_POISON,(20*skill_lv),skill_lv,skill_get_time2(skill_id,skill_lv));
|
||||
break;
|
||||
case NPC_SILENCEATTACK:
|
||||
sc_start(src,bl,SC_SILENCE,(20*skill_lv),skill_lv,skill_get_time2(skill_id,skill_lv));
|
||||
break;
|
||||
case NPC_STUNATTACK:
|
||||
sc_start(src,bl,SC_STUN,(20*skill_lv),skill_lv,skill_get_time2(skill_id,skill_lv));
|
||||
break;
|
||||
case NPC_BLEEDING:
|
||||
sc_start(src,bl,status_skill2sc(skill_id),(20*skill_lv),skill_lv,skill_get_time2(skill_id,skill_lv));
|
||||
sc_start(src,bl,SC_BLEEDING,(20*skill_lv),skill_lv,skill_get_time2(skill_id,skill_lv));
|
||||
break;
|
||||
case NPC_ACIDBREATH:
|
||||
sc_start(src,bl,SC_POISON,70,skill_lv,skill_get_time2(skill_id,skill_lv));
|
||||
break;
|
||||
case NPC_ICEBREATH:
|
||||
sc_start(src,bl,status_skill2sc(skill_id),70,skill_lv,skill_get_time2(skill_id,skill_lv));
|
||||
sc_start(src,bl,SC_FREEZE,70,skill_lv,skill_get_time2(skill_id,skill_lv));
|
||||
break;
|
||||
case NPC_MENTALBREAKER:
|
||||
{ //Based on observations by Tharis, Mental Breaker should do SP damage
|
||||
@@ -1772,7 +1785,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
|
||||
sc_start(src,bl, SC_ADORAMUS, skill_lv * 4 + (sd ? sd->status.job_level : 50) / 2, skill_lv, skill_get_time2(skill_id, skill_lv));
|
||||
break;
|
||||
case WL_COMET:
|
||||
sc_start(src, bl, status_skill2sc(skill_id), 100, skill_lv, 20000);
|
||||
sc_start(src, bl, SC_BURNING, 100, skill_lv, 20000);
|
||||
break;
|
||||
case NPC_COMET:
|
||||
sc_start4(src,bl,SC_BURNING,100,skill_lv,1000,src->id,0,skill_get_time(skill_id,skill_lv));
|
||||
@@ -1899,7 +1912,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
|
||||
sc_start(src,bl, SC_POISON, 5 * skill_lv, skill_lv, skill_get_time(skill_id, skill_lv));
|
||||
break;
|
||||
case GN_SPORE_EXPLOSION:
|
||||
sc_start(src, bl, status_skill2sc(skill_id), 100, skill_lv, skill_get_time(skill_id, skill_lv));
|
||||
sc_start(src, bl, SC_SPORE_EXPLOSION, 100, skill_lv, skill_get_time(skill_id, skill_lv));
|
||||
break;
|
||||
case GN_SLINGITEM_RANGEMELEEATK:
|
||||
if( sd ) {
|
||||
@@ -1935,8 +1948,10 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
|
||||
sc_start(src,bl, SC_STUN, rate, skill_lv, skill_get_time(skill_id,skill_lv));
|
||||
break;
|
||||
case EL_ROCK_CRUSHER:
|
||||
sc_start(src,bl, SC_ROCK_CRUSHER,50,skill_lv,skill_get_time(EL_ROCK_CRUSHER,skill_lv));
|
||||
break;
|
||||
case EL_ROCK_CRUSHER_ATK:
|
||||
sc_start(src,bl,status_skill2sc(skill_id),50,skill_lv,skill_get_time(EL_ROCK_CRUSHER,skill_lv));
|
||||
sc_start(src,bl,SC_ROCK_CRUSHER_ATK,50,skill_lv,skill_get_time(EL_ROCK_CRUSHER,skill_lv));
|
||||
break;
|
||||
case EL_TYPOON_MIS:
|
||||
sc_start(src,bl,SC_SILENCE,10*skill_lv,skill_lv,skill_get_time(skill_id,skill_lv));
|
||||
@@ -1993,8 +2008,6 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
|
||||
sc_start(src,bl,SC_STUN,100,skill_lv,skill_get_time2(skill_id,skill_lv));
|
||||
break;
|
||||
case RL_BANISHING_BUSTER: {
|
||||
uint16 i, n = skill_lv;
|
||||
|
||||
if (!tsc || !tsc->count)
|
||||
break;
|
||||
|
||||
@@ -2007,99 +2020,24 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; n > 0 && i < SC_MAX; i++) {
|
||||
if (!tsc->data[i])
|
||||
uint16 n = skill_lv;
|
||||
|
||||
for (const auto &it : status_db) {
|
||||
sc_type status = static_cast<sc_type>(it.first);
|
||||
|
||||
if (n <= 0)
|
||||
break;
|
||||
if (!tsc->data[status])
|
||||
continue;
|
||||
switch (i) {
|
||||
case SC_WEIGHT50: case SC_WEIGHT90: case SC_HALLUCINATION:
|
||||
case SC_STRIPWEAPON: case SC_STRIPSHIELD: case SC_STRIPARMOR:
|
||||
case SC_STRIPHELM: case SC_CP_WEAPON: case SC_CP_SHIELD:
|
||||
case SC_CP_ARMOR: case SC_CP_HELM: case SC_COMBO:
|
||||
case SC_STRFOOD: case SC_AGIFOOD: case SC_VITFOOD:
|
||||
case SC_INTFOOD: case SC_DEXFOOD: case SC_LUKFOOD:
|
||||
case SC_HITFOOD: case SC_FLEEFOOD: case SC_BATKFOOD:
|
||||
case SC_WATKFOOD: case SC_MATKFOOD: case SC_CRIFOOD:
|
||||
case SC_DANCING: case SC_SPIRIT: case SC_AUTOBERSERK:
|
||||
case SC_CARTBOOST: case SC_MELTDOWN: case SC_SAFETYWALL:
|
||||
case SC_SMA: case SC_SPEEDUP0: case SC_NOCHAT:
|
||||
case SC_ANKLE: case SC_SPIDERWEB: case SC_JAILED:
|
||||
case SC_ITEMBOOST: case SC_EXPBOOST: case SC_LIFEINSURANCE:
|
||||
case SC_BOSSMAPINFO: case SC_PNEUMA: case SC_AUTOSPELL:
|
||||
case SC_INCHITRATE: case SC_INCATKRATE: case SC_NEN:
|
||||
case SC_READYSTORM: case SC_READYDOWN: case SC_READYTURN:
|
||||
case SC_READYCOUNTER: case SC_DODGE: case SC_WARM:
|
||||
/*case SC_SPEEDUP1:*/ case SC_AUTOTRADE: case SC_CRITICALWOUND:
|
||||
case SC_JEXPBOOST: case SC_INVINCIBLE: case SC_INVINCIBLEOFF:
|
||||
case SC_HELLPOWER: case SC_MANU_ATK: case SC_MANU_DEF:
|
||||
case SC_SPL_ATK: case SC_SPL_DEF: case SC_MANU_MATK:
|
||||
case SC_SPL_MATK: case SC_RICHMANKIM: case SC_ETERNALCHAOS:
|
||||
case SC_DRUMBATTLE: case SC_NIBELUNGEN: case SC_ROKISWEIL:
|
||||
case SC_INTOABYSS: case SC_SIEGFRIED: case SC_FOOD_STR_CASH:
|
||||
case SC_FOOD_AGI_CASH: case SC_FOOD_VIT_CASH: case SC_FOOD_DEX_CASH:
|
||||
case SC_FOOD_INT_CASH: case SC_FOOD_LUK_CASH: case SC_ELECTRICSHOCKER:
|
||||
case SC__STRIPACCESSORY: case SC__ENERVATION: case SC__GROOMY:
|
||||
case SC__IGNORANCE: case SC__LAZINESS: case SC__UNLUCKY:
|
||||
case SC__WEAKNESS: case SC_SAVAGE_STEAK: case SC_COCKTAIL_WARG_BLOOD:
|
||||
case SC_MAGNETICFIELD: case SC_MINOR_BBQ: case SC_SIROMA_ICE_TEA:
|
||||
case SC_DROCERA_HERB_STEAMED: case SC_PUTTI_TAILS_NOODLES: case SC_NEUTRALBARRIER_MASTER:
|
||||
case SC_NEUTRALBARRIER: case SC_STEALTHFIELD_MASTER: case SC_STEALTHFIELD:
|
||||
case SC_LEADERSHIP: case SC_GLORYWOUNDS: case SC_SOULCOLD:
|
||||
case SC_HAWKEYES: case SC_REGENERATION: case SC_SEVENWIND:
|
||||
case SC_MIRACLE: case SC_S_LIFEPOTION: case SC_L_LIFEPOTION:
|
||||
case SC_INCHEALRATE: case SC_PUSH_CART: case SC_PARTYFLEE:
|
||||
case SC_RAISINGDRAGON: case SC_GT_REVITALIZE: case SC_GT_ENERGYGAIN:
|
||||
case SC_GT_CHANGE: case SC_ANGEL_PROTECT: case SC_MONSTER_TRANSFORM:
|
||||
case SC_FULL_THROTTLE: case SC_REBOUND: case SC_TELEKINESIS_INTENSE:
|
||||
case SC_MOONSTAR: case SC_SUPER_STAR: case SC_ALL_RIDING:
|
||||
case SC_MTF_ASPD: case SC_MTF_RANGEATK: case SC_MTF_MATK:
|
||||
case SC_MTF_MLEATKED: case SC_MTF_CRIDAMAGE: case SC_HEAT_BARREL:
|
||||
case SC_P_ALTER: case SC_E_CHAIN:
|
||||
case SC_C_MARKER: case SC_B_TRAP: case SC_H_MINE:
|
||||
case SC_STRANGELIGHTS: case SC_DECORATION_OF_MUSIC: case SC_GN_CARTBOOST:
|
||||
case SC_RECOGNIZEDSPELL: case SC_CHASEWALK2: case SC_BITE:
|
||||
case SC_ACTIVE_MONSTER_TRANSFORM: case SC_DORAM_BUF_01: case SC_DORAM_BUF_02:
|
||||
case SC_SPORE_EXPLOSION:
|
||||
case SC_NEWMOON: case SC_FLASHKICK: case SC_NOVAEXPLOSING:
|
||||
case SC_SOULUNITY: case SC_SOULSHADOW: case SC_SOULFAIRY:
|
||||
case SC_SOULFALCON: case SC_SOULGOLEM: case SC_USE_SKILL_SP_SPA:
|
||||
case SC_USE_SKILL_SP_SHA: case SC_SP_SHA:
|
||||
// 4th Jobs
|
||||
case SC_SERVANTWEAPON: case SC_SERVANT_SIGN: case SC_GUARD_STANCE:
|
||||
case SC_ATTACK_STANCE: case SC_PROTECTSHADOWEQUIP: case SC_SHADOW_STRIP:
|
||||
case SC_ABYSSFORCEWEAPON:
|
||||
#ifdef RENEWAL
|
||||
case SC_EXTREMITYFIST2:
|
||||
#endif
|
||||
case SC_HIDING: case SC_CLOAKING: case SC_CHASEWALK:
|
||||
case SC_CLOAKINGEXCEED: case SC__INVISIBILITY: case SC_UTSUSEMI:
|
||||
case SC_MTF_ASPD2: case SC_MTF_RANGEATK2: case SC_MTF_MATK2:
|
||||
case SC_2011RWC_SCROLL: case SC_JP_EVENT04: case SC_MTF_MHP:
|
||||
case SC_MTF_MSP: case SC_MTF_PUMPKIN: case SC_MTF_HITFLEE:
|
||||
case SC_ATTHASTE_CASH: case SC_REUSE_REFRESH:
|
||||
case SC_REUSE_LIMIT_A: case SC_REUSE_LIMIT_B: case SC_REUSE_LIMIT_C:
|
||||
case SC_REUSE_LIMIT_D: case SC_REUSE_LIMIT_E: case SC_REUSE_LIMIT_F:
|
||||
case SC_REUSE_LIMIT_G: case SC_REUSE_LIMIT_H: case SC_REUSE_LIMIT_MTF:
|
||||
case SC_REUSE_LIMIT_ASPD_POTION: case SC_REUSE_MILLENNIUMSHIELD: case SC_REUSE_CRUSHSTRIKE:
|
||||
case SC_REUSE_STORMBLAST: case SC_ALL_RIDING_REUSE_LIMIT:
|
||||
case SC_SPRITEMABLE: case SC_BITESCAR:
|
||||
case SC_CLAN_INFO: case SC_SWORDCLAN: case SC_ARCWANDCLAN:
|
||||
case SC_GOLDENMACECLAN: case SC_CROSSBOWCLAN:
|
||||
case SC_DAILYSENDMAILCNT:
|
||||
case SC_WEDDING: case SC_XMAS: case SC_SUMMER:
|
||||
case SC_DRESSUP: case SC_HANBOK: case SC_OKTOBERFEST:
|
||||
case SC_LHZ_DUN_N1: case SC_LHZ_DUN_N2: case SC_LHZ_DUN_N3: case SC_LHZ_DUN_N4:
|
||||
case SC_ENTRY_QUEUE_APPLY_DELAY: case SC_ENTRY_QUEUE_NOTIFY_ADMISSION_TIME_OUT:
|
||||
case SC_REUSE_LIMIT_LUXANIMA: case SC_LUXANIMA: case SC_SOULENERGY:
|
||||
case SC_EP16_2_BUFF_SS: case SC_EP16_2_BUFF_SC: case SC_EP16_2_BUFF_AC:
|
||||
case SC_EMERGENCY_MOVE: case SC_MADOGEAR: case SC_HOMUN_TIME:
|
||||
case SC_PACKING_ENVELOPE1: case SC_PACKING_ENVELOPE2: case SC_PACKING_ENVELOPE3:
|
||||
case SC_PACKING_ENVELOPE4: case SC_PACKING_ENVELOPE5: case SC_PACKING_ENVELOPE6:
|
||||
case SC_PACKING_ENVELOPE7: case SC_PACKING_ENVELOPE8: case SC_PACKING_ENVELOPE9: case SC_PACKING_ENVELOPE10:
|
||||
continue;
|
||||
|
||||
if (it.second->flag[SCF_NOBANISHINGBUSTER])
|
||||
continue;
|
||||
|
||||
switch (status) {
|
||||
case SC_WHISTLE: case SC_ASSNCROS: case SC_POEMBRAGI:
|
||||
case SC_APPLEIDUN: case SC_HUMMING: case SC_DONTFORGETME:
|
||||
case SC_FORTUNE: case SC_SERVICE4U:
|
||||
if (!battle_config.dispel_song || tsc->data[i]->val4 == 0)
|
||||
if (!battle_config.dispel_song || tsc->data[status]->val4 == 0)
|
||||
continue; //If in song area don't end it, even if config enabled
|
||||
break;
|
||||
case SC_ASSUMPTIO:
|
||||
@@ -2107,9 +2045,9 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if( i == SC_BERSERK || i == SC_SATURDAYNIGHTFEVER )
|
||||
tsc->data[i]->val2 = 0;
|
||||
status_change_end(bl,(sc_type)i,INVALID_TIMER);
|
||||
if( status == SC_BERSERK || status == SC_SATURDAYNIGHTFEVER )
|
||||
tsc->data[status]->val2 = 0;
|
||||
status_change_end(bl,status,INVALID_TIMER);
|
||||
n--;
|
||||
}
|
||||
//Remove bonus_script by Banishing Buster
|
||||
@@ -2802,7 +2740,7 @@ int skill_break_equip(struct block_list *src, struct block_list *bl, unsigned sh
|
||||
else if (rnd()%10000 >= rate)
|
||||
where&=~where_list[i];
|
||||
else if (!sd) //Cause Strip effect.
|
||||
sc_start(src,bl,scatk[i],100,0,skill_get_time(status_sc2skill(scatk[i]),1));
|
||||
sc_start(src,bl,scatk[i],100,0,skill_get_time(status_db.getSkill(scatk[i]),1));
|
||||
}
|
||||
}
|
||||
if (!where) //Nothing to break.
|
||||
@@ -4490,14 +4428,19 @@ static TIMER_FUNC(skill_timerskill){
|
||||
case PR_LEXDIVINA:
|
||||
if (src->type == BL_MOB) {
|
||||
// Monsters use the default duration when casting Lex Divina
|
||||
sc_start(src, target, status_skill2sc(skl->skill_id), skl->type, skl->skill_lv, skill_get_time2(status_sc2skill(status_skill2sc(skl->skill_id)), 1));
|
||||
sc_start(src, target, SC_SILENCE, skl->type, skl->skill_lv, skill_get_time2(status_db.getSkill(SC_SILENCE), 1));
|
||||
break;
|
||||
}
|
||||
// Fall through
|
||||
sc_start(src, target, SC_SILENCE, skl->type, skl->skill_lv, skill_get_time2(skl->skill_id, skl->skill_lv));
|
||||
break;
|
||||
case PR_STRECOVERY:
|
||||
sc_start(src, target, SC_BLIND, skl->type, skl->skill_lv, skill_get_time2(skl->skill_id, skl->skill_lv));
|
||||
break;
|
||||
case BS_HAMMERFALL:
|
||||
sc_start(src, target, SC_STUN, skl->type, skl->skill_lv, skill_get_time2(skl->skill_id, skl->skill_lv));
|
||||
break;
|
||||
case MER_LEXDIVINA:
|
||||
sc_start(src, target, status_skill2sc(skl->skill_id), skl->type, skl->skill_lv, skill_get_time2(skl->skill_id, skl->skill_lv));
|
||||
sc_start(src, target, SC_SILENCE, skl->type, skl->skill_lv, skill_get_time2(skl->skill_id, skl->skill_lv));
|
||||
break;
|
||||
case WZ_WATERBALL:
|
||||
{
|
||||
@@ -4884,15 +4827,15 @@ static int skill_tarotcard(struct block_list* src, struct block_list *target, ui
|
||||
{
|
||||
enum sc_type sc[] = { SC_STOP, SC_FREEZE, SC_STONE };
|
||||
uint8 rand_eff = rnd() % 3;
|
||||
int time = ((rand_eff == 0) ? skill_get_time2(skill_id, skill_lv) : skill_get_time2(status_sc2skill(sc[rand_eff]), 1));
|
||||
int time = ((rand_eff == 0) ? skill_get_time2(skill_id, skill_lv) : skill_get_time2(status_db.getSkill(sc[rand_eff]), 1));
|
||||
sc_start(src, target, sc[rand_eff], 100, skill_lv, time);
|
||||
break;
|
||||
}
|
||||
case 9: // DEATH - curse, coma and poison
|
||||
{
|
||||
status_change_start(src, target, SC_COMA, 10000, skill_lv, 0, src->id, 0, 0, SCSTART_NONE);
|
||||
sc_start(src, target, SC_CURSE, 100, skill_lv, skill_get_time2(status_sc2skill(SC_CURSE), 1));
|
||||
sc_start2(src, target, SC_POISON, 100, skill_lv, src->id, skill_get_time2(status_sc2skill(SC_POISON), 1));
|
||||
sc_start(src, target, SC_CURSE, 100, skill_lv, skill_get_time2(status_db.getSkill(SC_CURSE), 1));
|
||||
sc_start2(src, target, SC_POISON, 100, skill_lv, src->id, skill_get_time2(status_db.getSkill(SC_POISON), 1));
|
||||
break;
|
||||
}
|
||||
case 10: // TEMPERANCE - confusion
|
||||
@@ -4906,7 +4849,7 @@ static int skill_tarotcard(struct block_list* src, struct block_list *target, ui
|
||||
clif_damage(src, target, tick, 0, 0, 6666, 0, DMG_NORMAL, 0, false);
|
||||
sc_start(src, target, SC_INCATKRATE, 100, -50, skill_get_time2(skill_id, skill_lv));
|
||||
sc_start(src, target, SC_INCMATKRATE, 100, -50, skill_get_time2(skill_id, skill_lv));
|
||||
sc_start(src, target, SC_CURSE, skill_lv, 100, skill_get_time2(status_sc2skill(SC_CURSE), 1));
|
||||
sc_start(src, target, SC_CURSE, skill_lv, 100, skill_get_time2(status_db.getSkill(SC_CURSE), 1));
|
||||
break;
|
||||
}
|
||||
case 12: // THE TOWER - 4444 damage
|
||||
@@ -4917,7 +4860,7 @@ static int skill_tarotcard(struct block_list* src, struct block_list *target, ui
|
||||
}
|
||||
case 13: // THE STAR - stun
|
||||
{
|
||||
sc_start(src, target, SC_STUN, 100, skill_lv, skill_get_time2(status_sc2skill(SC_STUN), 1));
|
||||
sc_start(src, target, SC_STUN, 100, skill_lv, skill_get_time2(status_db.getSkill(SC_STUN), 1));
|
||||
break;
|
||||
}
|
||||
default: // THE SUN - atk, matk, hit, flee and def reduced, immune to more tarot card effects
|
||||
@@ -4966,7 +4909,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
|
||||
|
||||
if (skill_id && skill_id != AG_DEADLY_PROJECTION && skill_get_type(skill_id) == BF_MAGIC && status_isimmune(bl) == 100)
|
||||
{ //GTB makes all targetted magic display miss with a single bolt.
|
||||
sc_type sct = status_skill2sc(skill_id);
|
||||
sc_type sct = skill_get_sc(skill_id);
|
||||
if(sct != SC_NONE)
|
||||
status_change_end(bl, sct, INVALID_TIMER);
|
||||
clif_skill_damage(src, bl, tick, status_get_amotion(src), status_get_dmotion(bl), 0, 1, skill_id, skill_lv, skill_get_hit(skill_id));
|
||||
@@ -5957,7 +5900,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
|
||||
|
||||
case NPC_MAGICALATTACK:
|
||||
skill_attack(BF_MAGIC,src,src,bl,skill_id,skill_lv,tick,flag);
|
||||
sc_start(src,src,status_skill2sc(skill_id),100,skill_lv,skill_get_time(skill_id,skill_lv));
|
||||
sc_start(src,src,SC_MAGICALATTACK,100,skill_lv,skill_get_time(skill_id,skill_lv));
|
||||
break;
|
||||
|
||||
case HVAN_CAPRICE: //[blackhole89]
|
||||
@@ -6209,7 +6152,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
|
||||
|
||||
case GC_DARKCROW:
|
||||
skill_attack(BF_WEAPON, src, src, bl, skill_id, skill_lv, tick, flag);
|
||||
sc_start(src, bl, status_skill2sc(skill_id), 100, skill_lv, skill_get_time(skill_id, skill_lv)); // Should be applied even on miss
|
||||
sc_start(src, bl, SC_DARKCROW, 100, skill_lv, skill_get_time(skill_id, skill_lv)); // Should be applied even on miss
|
||||
break;
|
||||
|
||||
case WL_DRAINLIFE:
|
||||
@@ -6376,7 +6319,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
|
||||
break;
|
||||
case WL_FROSTMISTY:
|
||||
// Causes Freezing status through walls.
|
||||
sc_start(src, bl, status_skill2sc(skill_id), 25 + 5 * skill_lv, skill_lv, skill_get_time(skill_id, skill_lv));
|
||||
sc_start(src, bl, SC_FREEZING, 25 + 5 * skill_lv, skill_lv, skill_get_time(skill_id, skill_lv));
|
||||
sc_start(src, bl, SC_MISTY_FROST, 100, skill_lv, skill_get_time2(skill_id, skill_lv));
|
||||
// Doesn't deal damage through non-shootable walls.
|
||||
if( !battle_config.skill_wall_check || (battle_config.skill_wall_check && path_search(NULL,src->m,src->x,src->y,bl->x,bl->y,1,CELL_CHKWALL)) )
|
||||
@@ -6632,14 +6575,13 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
|
||||
if( src->type == BL_ELEM ) {
|
||||
s_elemental_data *ele = BL_CAST(BL_ELEM,src);
|
||||
struct status_change *tsc_ele = status_get_sc(&ele->bl);
|
||||
sc_type type = status_skill2sc(skill_id), type2;
|
||||
|
||||
type2 = static_cast<sc_type>(type - 1);
|
||||
sc_type type = SC_TIDAL_WEAPON_OPTION, type2 = SC_TIDAL_WEAPON;
|
||||
|
||||
clif_skill_nodamage(src,battle_get_master(src),skill_id,skill_lv,1);
|
||||
clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, DMG_SINGLE);
|
||||
if( (tsc_ele && tsc_ele->data[type2]) || (tsc && tsc->data[type]) ) {
|
||||
elemental_clean_single_effect(ele, skill_id);
|
||||
status_change_end(battle_get_master(src),type,INVALID_TIMER);
|
||||
status_change_end(src,type2,INVALID_TIMER);
|
||||
}
|
||||
if( rnd()%100 < 50 )
|
||||
skill_attack(skill_get_type(skill_id),src,src,bl,skill_id,skill_lv,tick,flag);
|
||||
@@ -6676,13 +6618,21 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
|
||||
{
|
||||
TBL_HOM *hd = BL_CAST(BL_HOM,src);
|
||||
int duration = max(skill_lv, (status_get_str(src) / 7 - status_get_str(bl) / 10)) * 1000; //Yommy formula
|
||||
sc_type type;
|
||||
|
||||
if (skill_id == MH_TINDER_BREAKER && unit_movepos(src, bl->x, bl->y, 1, 1)) {
|
||||
clif_blown(src);
|
||||
clif_skill_poseffect(src,skill_id,skill_lv,bl->x,bl->y,tick);
|
||||
if( skill_id == MH_TINDER_BREAKER ){
|
||||
type = SC_TINDER_BREAKER2;
|
||||
if( unit_movepos(src, bl->x, bl->y, 1, 1) ){
|
||||
clif_blown(src);
|
||||
clif_skill_poseffect(src,skill_id,skill_lv,bl->x,bl->y,tick);
|
||||
}
|
||||
}else if( skill_id == MH_CBC ){
|
||||
type = SC_CBC;
|
||||
}else if( skill_id == MH_EQC ){
|
||||
type = SC_EQC;
|
||||
}
|
||||
clif_skill_nodamage(src,bl,skill_id,skill_lv,
|
||||
sc_start4(src,bl,status_skill2sc(skill_id),100,skill_lv,src->id,0,0,duration));
|
||||
|
||||
clif_skill_nodamage(src,bl,skill_id,skill_lv,sc_start4(src,bl,type,100,skill_lv,src->id,0,0,duration));
|
||||
skill_attack(skill_get_type(skill_id),src,src,bl,skill_id,skill_lv,tick,flag);
|
||||
}
|
||||
break;
|
||||
@@ -6742,13 +6692,12 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
|
||||
break;
|
||||
|
||||
case SU_SCAROFTAROU:
|
||||
sc_start(src, bl, SC_BITESCAR, 10, skill_lv, skill_get_time(skill_id, skill_lv)); //! TODO: What's the activation chance for the Bite effect?
|
||||
skill_attack(skill_get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, flag);
|
||||
break;
|
||||
case SU_SV_STEMSPEAR:
|
||||
if (skill_id == SU_SCAROFTAROU)
|
||||
sc_start(src, bl, status_skill2sc(skill_id), 10, skill_lv, skill_get_time(skill_id, skill_lv)); //! TODO: What's the activation chance for the Bite effect?
|
||||
else {
|
||||
if (sd && pc_checkskill(sd, SU_SPIRITOFLAND))
|
||||
sc_start(src, src, SC_DORAM_WALKSPEED, 100, 50, skill_get_time(SU_SPIRITOFLAND, 1));
|
||||
}
|
||||
if (sd && pc_checkskill(sd, SU_SPIRITOFLAND))
|
||||
sc_start(src, src, SC_DORAM_WALKSPEED, 100, 50, skill_get_time(SU_SPIRITOFLAND, 1));
|
||||
skill_attack(skill_get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, flag);
|
||||
break;
|
||||
|
||||
@@ -6903,7 +6852,7 @@ static int skill_apply_songs(struct block_list* target, va_list ap)
|
||||
default: // Buff/Debuff type songs
|
||||
if (skill_id == CG_HERMODE && src->id != target->id)
|
||||
status_change_clear_buffs(target, SCCB_BUFFS); // Should dispell only allies.
|
||||
return sc_start(src, target, status_skill2sc(skill_id), 100, skill_lv, skill_get_time(skill_id, skill_lv));
|
||||
return sc_start(src, target, skill_get_sc(skill_id), 100, skill_lv, skill_get_time(skill_id, skill_lv));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7061,12 +7010,11 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
||||
return skill_castend_pos2(src,bl->x,bl->y,skill_id,skill_lv,tick,0);
|
||||
}
|
||||
|
||||
type = status_skill2sc(skill_id);
|
||||
status_change *sc = status_get_sc(src);
|
||||
type = skill_get_sc(skill_id);
|
||||
tsc = status_get_sc(bl);
|
||||
tsce = (tsc && type != -1)?tsc->data[type]:NULL;
|
||||
tsce = (tsc && type != SC_NONE)?tsc->data[type]:NULL;
|
||||
|
||||
if (src!=bl && type > -1 &&
|
||||
if (src!=bl && type > SC_NONE &&
|
||||
CHK_ELEMENT((i = skill_get_ele(skill_id, skill_lv))) && i > ELE_NEUTRAL &&
|
||||
skill_get_inf(skill_id) != INF_SUPPORT_SKILL &&
|
||||
battle_attr_fix(NULL, NULL, 100, i, tstatus->def_ele, tstatus->ele_lv) <= 0)
|
||||
@@ -7703,6 +7651,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
||||
sc_start(src, bl, type, 100, skill_lv, skill_get_time2(skill_id, skill_lv));
|
||||
} else {
|
||||
uint16 climax_lv = 0, splash_size = skill_get_splash(skill_id, skill_lv);
|
||||
status_change *sc = status_get_sc(src);
|
||||
|
||||
if (sc && sc->data[SC_CLIMAX])
|
||||
climax_lv = sc->data[SC_CLIMAX]->val1;
|
||||
@@ -7885,23 +7834,16 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
||||
sc_start(src,bl,type,100,skill_lv,skill_get_time(skill_id,skill_lv)));
|
||||
break;
|
||||
|
||||
case AS_ENCHANTPOISON: // Prevent spamming [Valaris]
|
||||
if (sd && dstsd && dstsd->sc.count) {
|
||||
if (dstsd->sc.data[SC_FIREWEAPON] ||
|
||||
dstsd->sc.data[SC_WATERWEAPON] ||
|
||||
dstsd->sc.data[SC_WINDWEAPON] ||
|
||||
dstsd->sc.data[SC_EARTHWEAPON] ||
|
||||
dstsd->sc.data[SC_SHADOWWEAPON] ||
|
||||
dstsd->sc.data[SC_GHOSTWEAPON]
|
||||
// dstsd->sc.data[SC_ENCPOISON] //People say you should be able to recast to lengthen the timer. [Skotlex]
|
||||
) {
|
||||
clif_skill_nodamage(src,bl,skill_id,skill_lv,0);
|
||||
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
|
||||
break;
|
||||
case AS_ENCHANTPOISON:
|
||||
if( sc_start( src, bl, type, 100, skill_lv, skill_get_time( skill_id, skill_lv ) ) ){
|
||||
clif_skill_nodamage( src, bl, skill_id, skill_lv, 1 );
|
||||
}else{
|
||||
clif_skill_nodamage( src, bl, skill_id, skill_lv, 0 );
|
||||
|
||||
if( sd != nullptr ){
|
||||
clif_skill_fail( sd, skill_id, USESKILL_FAIL_LEVEL, 0 );
|
||||
}
|
||||
}
|
||||
clif_skill_nodamage(src,bl,skill_id,skill_lv,
|
||||
sc_start(src,bl,type,100,skill_lv,skill_get_time(skill_id,skill_lv)));
|
||||
break;
|
||||
|
||||
case LK_TENSIONRELAX:
|
||||
@@ -8544,7 +8486,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
||||
}
|
||||
|
||||
if( skill_id == SP_SOULCOLLECT ){
|
||||
clif_skill_nodamage(src, bl, skill_id, skill_lv, sc_start2(src, bl, type, 100, skill_lv, pc_checkskill(sd, SP_SOULENERGY), max(1000, skill_get_time(skill_id, skill_lv))));
|
||||
clif_skill_nodamage(src, bl, skill_id, skill_lv, sc_start2(src, bl, type, 100, skill_lv, pc_checkskill(sd, SP_SOULENERGY), skill_get_time(skill_id, skill_lv)));
|
||||
}else{
|
||||
clif_skill_nodamage(src, bl, skill_id, skill_lv, sc_start(src, bl, type, 100, skill_lv, skill_get_time(skill_id, skill_lv)));
|
||||
}
|
||||
@@ -9237,116 +9179,21 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
||||
if(!tsc || !tsc->count)
|
||||
break;
|
||||
|
||||
for(i=0;i<SC_MAX;i++) {
|
||||
if (!tsc->data[i])
|
||||
//Statuses that can't be Dispelled
|
||||
for (const auto &it : status_db) {
|
||||
sc_type status = static_cast<sc_type>(it.first);
|
||||
|
||||
if (!tsc->data[status])
|
||||
continue;
|
||||
switch (i) {
|
||||
case SC_WEIGHT50: case SC_WEIGHT90: case SC_HALLUCINATION:
|
||||
case SC_STRIPWEAPON: case SC_STRIPSHIELD: case SC_STRIPARMOR:
|
||||
case SC_STRIPHELM: case SC_CP_WEAPON: case SC_CP_SHIELD:
|
||||
case SC_CP_ARMOR: case SC_CP_HELM: case SC_COMBO:
|
||||
case SC_STRFOOD: case SC_AGIFOOD: case SC_VITFOOD:
|
||||
case SC_INTFOOD: case SC_DEXFOOD: case SC_LUKFOOD:
|
||||
case SC_HITFOOD: case SC_FLEEFOOD: case SC_BATKFOOD:
|
||||
case SC_WATKFOOD: case SC_MATKFOOD: case SC_CRIFOOD:
|
||||
case SC_DANCING: case SC_EDP: case SC_AUTOBERSERK:
|
||||
case SC_CARTBOOST: case SC_MELTDOWN: case SC_SAFETYWALL:
|
||||
case SC_SMA: case SC_SPEEDUP0: case SC_NOCHAT:
|
||||
case SC_ANKLE: case SC_SPIDERWEB: case SC_JAILED:
|
||||
case SC_ITEMBOOST: case SC_EXPBOOST: case SC_LIFEINSURANCE:
|
||||
case SC_BOSSMAPINFO: case SC_PNEUMA: case SC_AUTOSPELL:
|
||||
case SC_INCHITRATE: case SC_INCATKRATE: case SC_NEN:
|
||||
case SC_READYSTORM: case SC_READYDOWN: case SC_READYTURN:
|
||||
case SC_READYCOUNTER: case SC_DODGE: case SC_WARM:
|
||||
/*case SC_SPEEDUP1:*/ case SC_AUTOTRADE: case SC_CRITICALWOUND:
|
||||
case SC_JEXPBOOST: case SC_INVINCIBLE: case SC_INVINCIBLEOFF:
|
||||
case SC_HELLPOWER: case SC_MANU_ATK: case SC_MANU_DEF:
|
||||
case SC_SPL_ATK: case SC_SPL_DEF: case SC_MANU_MATK:
|
||||
case SC_SPL_MATK: case SC_RICHMANKIM: case SC_ETERNALCHAOS:
|
||||
case SC_DRUMBATTLE: case SC_NIBELUNGEN: case SC_ROKISWEIL:
|
||||
case SC_INTOABYSS: case SC_SIEGFRIED: case SC_FOOD_STR_CASH:
|
||||
case SC_FOOD_AGI_CASH: case SC_FOOD_VIT_CASH: case SC_FOOD_DEX_CASH:
|
||||
case SC_FOOD_INT_CASH: case SC_FOOD_LUK_CASH: case SC_SEVENWIND:
|
||||
case SC_MIRACLE: case SC_S_LIFEPOTION: case SC_L_LIFEPOTION:
|
||||
case SC_INCHEALRATE: case SC_ELECTRICSHOCKER: case SC__STRIPACCESSORY:
|
||||
case SC_SAVAGE_STEAK: case SC_COCKTAIL_WARG_BLOOD: case SC_MINOR_BBQ:
|
||||
case SC_SIROMA_ICE_TEA: case SC_DROCERA_HERB_STEAMED: case SC_PUTTI_TAILS_NOODLES:
|
||||
case SC_NEUTRALBARRIER_MASTER: case SC_NEUTRALBARRIER: case SC_STEALTHFIELD_MASTER:
|
||||
case SC_STEALTHFIELD: case SC_GIANTGROWTH: case SC_MILLENNIUMSHIELD:
|
||||
case SC_REFRESH: case SC_STONEHARDSKIN: case SC_VITALITYACTIVATION:
|
||||
case SC_FIGHTINGSPIRIT: case SC_ABUNDANCE: case SC__SHADOWFORM:
|
||||
case SC_RECOGNIZEDSPELL:case SC_LEADERSHIP: case SC_GLORYWOUNDS:
|
||||
case SC_SOULCOLD: case SC_HAWKEYES: case SC_REGENERATION:
|
||||
case SC_PUSH_CART: case SC_RAISINGDRAGON: case SC_GT_ENERGYGAIN:
|
||||
case SC_GT_CHANGE: case SC_GT_REVITALIZE: case SC_REFLECTDAMAGE:
|
||||
case SC_INSPIRATION: case SC_EXEEDBREAK: case SC_FORCEOFVANGUARD:
|
||||
case SC_BANDING: case SC_DUPLELIGHT: case SC_EXPIATIO:
|
||||
case SC_LAUDAAGNUS: case SC_LAUDARAMUS: case SC_GATLINGFEVER:
|
||||
case SC_INCREASING: case SC_ADJUSTMENT: case SC_MADNESSCANCEL:
|
||||
case SC_ANGEL_PROTECT: case SC_MONSTER_TRANSFORM: case SC_FULL_THROTTLE:
|
||||
case SC_REBOUND: case SC_TELEKINESIS_INTENSE: case SC_MOONSTAR:
|
||||
case SC_SUPER_STAR: case SC_ALL_RIDING: case SC_MTF_ASPD:
|
||||
case SC_MTF_RANGEATK: case SC_MTF_MATK: case SC_MTF_MLEATKED:
|
||||
case SC_MTF_CRIDAMAGE: case SC_HEAT_BARREL:
|
||||
case SC_P_ALTER: case SC_E_CHAIN: case SC_C_MARKER:
|
||||
case SC_B_TRAP: case SC_H_MINE: case SC_STRANGELIGHTS:
|
||||
case SC_DECORATION_OF_MUSIC: case SC_GN_CARTBOOST: case SC_CHASEWALK2:
|
||||
case SC_ACTIVE_MONSTER_TRANSFORM: case SC_DORAM_BUF_01: case SC_DORAM_BUF_02:
|
||||
case SC_SPORE_EXPLOSION:
|
||||
case SC_NEWMOON: case SC_FLASHKICK: case SC_NOVAEXPLOSING:
|
||||
case SC_SOULUNITY: case SC_SOULSHADOW: case SC_SOULFAIRY:
|
||||
case SC_SOULFALCON: case SC_SOULGOLEM: case SC_USE_SKILL_SP_SPA:
|
||||
case SC_USE_SKILL_SP_SHA: case SC_SP_SHA:
|
||||
// 4th Jobs
|
||||
case SC_SERVANTWEAPON: case SC_SERVANT_SIGN: case SC_GUARD_STANCE:
|
||||
case SC_ATTACK_STANCE: case SC_PROTECTSHADOWEQUIP: case SC_SHADOW_STRIP:
|
||||
case SC_ABYSSFORCEWEAPON:
|
||||
#ifdef RENEWAL
|
||||
case SC_EXTREMITYFIST2:
|
||||
#endif
|
||||
case SC_HIDING: case SC_CLOAKING: case SC_CHASEWALK:
|
||||
case SC_CLOAKINGEXCEED: case SC__INVISIBILITY: case SC_UTSUSEMI:
|
||||
case SC_MTF_ASPD2: case SC_MTF_RANGEATK2: case SC_MTF_MATK2:
|
||||
case SC_2011RWC_SCROLL: case SC_JP_EVENT04: case SC_MTF_MHP:
|
||||
case SC_MTF_MSP: case SC_MTF_PUMPKIN: case SC_MTF_HITFLEE:
|
||||
case SC_ATTHASTE_CASH: case SC_ARMOR_ELEMENT_WATER: case SC_REUSE_REFRESH:
|
||||
case SC_REUSE_LIMIT_A: case SC_REUSE_LIMIT_B: case SC_REUSE_LIMIT_C:
|
||||
case SC_REUSE_LIMIT_D: case SC_REUSE_LIMIT_E: case SC_REUSE_LIMIT_F:
|
||||
case SC_REUSE_LIMIT_G: case SC_REUSE_LIMIT_H: case SC_REUSE_LIMIT_MTF:
|
||||
case SC_REUSE_LIMIT_ASPD_POTION: case SC_REUSE_MILLENNIUMSHIELD: case SC_REUSE_CRUSHSTRIKE:
|
||||
case SC_REUSE_STORMBLAST: case SC_ALL_RIDING_REUSE_LIMIT:
|
||||
case SC_SPRITEMABLE: case SC_BITESCAR: case SC_CRUSHSTRIKE:
|
||||
case SC_QUEST_BUFF1: case SC_QUEST_BUFF2: case SC_QUEST_BUFF3:
|
||||
case SC_ARMOR_ELEMENT_EARTH: case SC_ARMOR_ELEMENT_FIRE: case SC_ARMOR_ELEMENT_WIND:
|
||||
case SC_ENTRY_QUEUE_APPLY_DELAY: case SC_ENTRY_QUEUE_NOTIFY_ADMISSION_TIME_OUT:
|
||||
case SC_MADOGEAR:
|
||||
// Clans
|
||||
case SC_CLAN_INFO:
|
||||
case SC_SWORDCLAN:
|
||||
case SC_ARCWANDCLAN:
|
||||
case SC_GOLDENMACECLAN:
|
||||
case SC_CROSSBOWCLAN:
|
||||
case SC_JUMPINGCLAN:
|
||||
case SC_DAILYSENDMAILCNT:
|
||||
case SC_WEDDING: case SC_XMAS: case SC_SUMMER:
|
||||
case SC_DRESSUP: case SC_HANBOK: case SC_OKTOBERFEST:
|
||||
case SC_LHZ_DUN_N1: case SC_LHZ_DUN_N2: case SC_LHZ_DUN_N3: case SC_LHZ_DUN_N4:
|
||||
case SC_REUSE_LIMIT_LUXANIMA: case SC_LUXANIMA: case SC_SOULENERGY:
|
||||
case SC_EP16_2_BUFF_SS: case SC_EP16_2_BUFF_SC: case SC_EP16_2_BUFF_AC:
|
||||
case SC_EMERGENCY_MOVE: case SC_HOMUN_TIME:
|
||||
case SC_PACKING_ENVELOPE1: case SC_PACKING_ENVELOPE2: case SC_PACKING_ENVELOPE3:
|
||||
case SC_PACKING_ENVELOPE4: case SC_PACKING_ENVELOPE5: case SC_PACKING_ENVELOPE6:
|
||||
case SC_PACKING_ENVELOPE7: case SC_PACKING_ENVELOPE8: case SC_PACKING_ENVELOPE9: case SC_PACKING_ENVELOPE10:
|
||||
continue;
|
||||
case SC_WHISTLE:
|
||||
case SC_ASSNCROS:
|
||||
case SC_POEMBRAGI:
|
||||
case SC_APPLEIDUN:
|
||||
case SC_HUMMING:
|
||||
case SC_DONTFORGETME:
|
||||
case SC_FORTUNE:
|
||||
case SC_SERVICE4U:
|
||||
if (!battle_config.dispel_song || tsc->data[i]->val4 == 0)
|
||||
|
||||
if (it.second->flag[SCF_NODISPELL])
|
||||
continue;
|
||||
switch (status) {
|
||||
// bugreport:4888 these songs may only be dispelled if you're not in their song area anymore
|
||||
case SC_WHISTLE: case SC_ASSNCROS: case SC_POEMBRAGI:
|
||||
case SC_APPLEIDUN: case SC_HUMMING: case SC_DONTFORGETME:
|
||||
case SC_FORTUNE: case SC_SERVICE4U:
|
||||
if (!battle_config.dispel_song || tsc->data[status]->val4 == 0)
|
||||
continue; //If in song area don't end it, even if config enabled
|
||||
break;
|
||||
case SC_ASSUMPTIO:
|
||||
@@ -9354,8 +9201,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if(i == SC_BERSERK) tsc->data[i]->val2=0; //Mark a dispelled berserk to avoid setting hp to 100 by setting hp penalty to 0.
|
||||
status_change_end(bl, (sc_type)i, INVALID_TIMER);
|
||||
if (i == SC_BERSERK || i == SC_SATURDAYNIGHTFEVER)
|
||||
tsc->data[status]->val2 = 0; //Mark a dispelled berserk to avoid setting hp to 100 by setting hp penalty to 0.
|
||||
status_change_end(bl, status, INVALID_TIMER);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -10161,7 +10009,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
||||
break;
|
||||
}
|
||||
if (tsc) {
|
||||
if (tsc->data[status_skill2sc(skill_id)]) { // Allow refreshing an already active soul link.
|
||||
if (tsc->data[skill_get_sc(skill_id)]) { // Allow refreshing an already active soul link.
|
||||
clif_skill_nodamage(src, bl, skill_id, skill_lv, sc_start(src, bl, type, 100, skill_lv, skill_get_time(skill_id, skill_lv)));
|
||||
break;
|
||||
} else if (tsc->data[SC_SPIRIT] || tsc->data[SC_SOULGOLEM] || tsc->data[SC_SOULSHADOW] || tsc->data[SC_SOULFALCON] || tsc->data[SC_SOULFAIRY]) { // Soul links from Soul Linker and Soul Reaper skills don't stack.
|
||||
@@ -10190,7 +10038,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
||||
if (tsce) {
|
||||
if(sd)
|
||||
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
|
||||
status_change_start(src,src,SC_STUN,10000,skill_lv,0,0,0,10000,8);
|
||||
status_change_start(src,src,SC_STUN,10000,skill_lv,0,0,0,10000,SCSTART_NORATEDEF);
|
||||
status_change_end(bl, SC_SWOO, INVALID_TIMER);
|
||||
break;
|
||||
}
|
||||
@@ -10825,106 +10673,32 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
||||
|
||||
if(!tsc || !tsc->count)
|
||||
break;
|
||||
for( i = 0; i < SC_MAX; i++ ) {
|
||||
if (!tsc->data[i])
|
||||
|
||||
//Statuses change that can't be removed by Cleareance
|
||||
for (const auto &it : status_db) {
|
||||
sc_type status = static_cast<sc_type>(it.first);
|
||||
|
||||
if (!tsc->data[status])
|
||||
continue;
|
||||
switch (i) {
|
||||
case SC_WEIGHT50: case SC_WEIGHT90: case SC_HALLUCINATION:
|
||||
case SC_STRIPWEAPON: case SC_STRIPSHIELD: case SC_STRIPARMOR:
|
||||
case SC_STRIPHELM: case SC_CP_WEAPON: case SC_CP_SHIELD:
|
||||
case SC_CP_ARMOR: case SC_CP_HELM: case SC_COMBO:
|
||||
case SC_STRFOOD: case SC_AGIFOOD: case SC_VITFOOD:
|
||||
case SC_INTFOOD: case SC_DEXFOOD: case SC_LUKFOOD:
|
||||
case SC_HITFOOD: case SC_FLEEFOOD: case SC_BATKFOOD:
|
||||
case SC_WATKFOOD: case SC_MATKFOOD: case SC_CRIFOOD:
|
||||
case SC_DANCING: case SC_SPIRIT: case SC_AUTOBERSERK:
|
||||
case SC_CARTBOOST: case SC_MELTDOWN: case SC_SAFETYWALL:
|
||||
case SC_SMA: case SC_SPEEDUP0: case SC_NOCHAT:
|
||||
case SC_ANKLE: case SC_SPIDERWEB: case SC_JAILED:
|
||||
case SC_ITEMBOOST: case SC_EXPBOOST: case SC_LIFEINSURANCE:
|
||||
case SC_BOSSMAPINFO: case SC_PNEUMA: case SC_AUTOSPELL:
|
||||
case SC_INCHITRATE: case SC_INCATKRATE: case SC_NEN:
|
||||
case SC_READYSTORM: case SC_READYDOWN: case SC_READYTURN:
|
||||
case SC_READYCOUNTER: case SC_DODGE: case SC_WARM:
|
||||
/*case SC_SPEEDUP1:*/ case SC_AUTOTRADE: case SC_CRITICALWOUND:
|
||||
case SC_JEXPBOOST: case SC_INVINCIBLE: case SC_INVINCIBLEOFF:
|
||||
case SC_HELLPOWER: case SC_MANU_ATK: case SC_MANU_DEF:
|
||||
case SC_SPL_ATK: case SC_SPL_DEF: case SC_MANU_MATK:
|
||||
case SC_SPL_MATK: case SC_RICHMANKIM: case SC_ETERNALCHAOS:
|
||||
case SC_DRUMBATTLE: case SC_NIBELUNGEN: case SC_ROKISWEIL:
|
||||
case SC_INTOABYSS: case SC_SIEGFRIED: case SC_WHISTLE:
|
||||
case SC_ASSNCROS: case SC_POEMBRAGI: case SC_APPLEIDUN:
|
||||
case SC_HUMMING: case SC_DONTFORGETME: case SC_FORTUNE:
|
||||
case SC_SERVICE4U: case SC_FOOD_STR_CASH: case SC_FOOD_AGI_CASH:
|
||||
case SC_FOOD_VIT_CASH: case SC_FOOD_DEX_CASH: case SC_FOOD_INT_CASH:
|
||||
case SC_FOOD_LUK_CASH: case SC_ELECTRICSHOCKER: case SC_BITE:
|
||||
case SC__STRIPACCESSORY: case SC__ENERVATION: case SC__GROOMY:
|
||||
case SC__IGNORANCE: case SC__LAZINESS: case SC__UNLUCKY:
|
||||
case SC__WEAKNESS: case SC_SAVAGE_STEAK: case SC_COCKTAIL_WARG_BLOOD:
|
||||
case SC_MAGNETICFIELD: case SC_MINOR_BBQ: case SC_SIROMA_ICE_TEA:
|
||||
case SC_DROCERA_HERB_STEAMED: case SC_PUTTI_TAILS_NOODLES: case SC_NEUTRALBARRIER_MASTER:
|
||||
case SC_NEUTRALBARRIER: case SC_STEALTHFIELD_MASTER: case SC_STEALTHFIELD:
|
||||
case SC_LEADERSHIP: case SC_GLORYWOUNDS: case SC_SOULCOLD:
|
||||
case SC_HAWKEYES: case SC_REGENERATION: case SC_SEVENWIND:
|
||||
case SC_MIRACLE: case SC_S_LIFEPOTION: case SC_L_LIFEPOTION:
|
||||
case SC_INCHEALRATE: case SC_PUSH_CART: case SC_PARTYFLEE:
|
||||
case SC_RAISINGDRAGON: case SC_GT_REVITALIZE: case SC_GT_ENERGYGAIN:
|
||||
case SC_GT_CHANGE: case SC_ANGEL_PROTECT: case SC_MONSTER_TRANSFORM:
|
||||
case SC_FULL_THROTTLE: case SC_REBOUND: case SC_TELEKINESIS_INTENSE:
|
||||
case SC_MOONSTAR: case SC_SUPER_STAR: case SC_ALL_RIDING:
|
||||
case SC_MTF_ASPD: case SC_MTF_RANGEATK: case SC_MTF_MATK:
|
||||
case SC_MTF_MLEATKED: case SC_MTF_CRIDAMAGE: case SC_HEAT_BARREL:
|
||||
case SC_P_ALTER: case SC_E_CHAIN:
|
||||
case SC_C_MARKER: case SC_B_TRAP: case SC_H_MINE:
|
||||
case SC_NEWMOON: case SC_FLASHKICK: case SC_DIMENSION:
|
||||
case SC_NOVAEXPLOSING:
|
||||
case SC_SOULUNITY: case SC_SOULSHADOW: case SC_SOULFAIRY:
|
||||
case SC_SOULFALCON: case SC_SOULGOLEM: case SC_USE_SKILL_SP_SPA:
|
||||
case SC_USE_SKILL_SP_SHA: case SC_SP_SHA:
|
||||
case SC_STRANGELIGHTS: case SC_DECORATION_OF_MUSIC: case SC_GN_CARTBOOST:
|
||||
case SC_RECOGNIZEDSPELL: case SC_CHASEWALK2: case SC_ACTIVE_MONSTER_TRANSFORM:
|
||||
case SC_SPORE_EXPLOSION:
|
||||
// 4th Jobs
|
||||
case SC_SERVANTWEAPON: case SC_SERVANT_SIGN: case SC_GUARD_STANCE:
|
||||
case SC_ATTACK_STANCE: case SC_PROTECTSHADOWEQUIP: case SC_SHADOW_STRIP:
|
||||
case SC_ABYSSFORCEWEAPON:
|
||||
#ifdef RENEWAL
|
||||
case SC_EXTREMITYFIST2:
|
||||
#endif
|
||||
case SC_HIDING: case SC_CLOAKING: case SC_CHASEWALK:
|
||||
case SC_CLOAKINGEXCEED: case SC__INVISIBILITY: case SC_UTSUSEMI:
|
||||
case SC_MTF_ASPD2: case SC_MTF_RANGEATK2: case SC_MTF_MATK2:
|
||||
case SC_2011RWC_SCROLL: case SC_JP_EVENT04: case SC_MTF_MHP:
|
||||
case SC_MTF_MSP: case SC_MTF_PUMPKIN: case SC_MTF_HITFLEE:
|
||||
case SC_ATTHASTE_CASH: case SC_REUSE_REFRESH:
|
||||
case SC_REUSE_LIMIT_A: case SC_REUSE_LIMIT_B: case SC_REUSE_LIMIT_C:
|
||||
case SC_REUSE_LIMIT_D: case SC_REUSE_LIMIT_E: case SC_REUSE_LIMIT_F:
|
||||
case SC_REUSE_LIMIT_G: case SC_REUSE_LIMIT_H: case SC_REUSE_LIMIT_MTF:
|
||||
case SC_REUSE_LIMIT_ASPD_POTION: case SC_REUSE_MILLENNIUMSHIELD: case SC_REUSE_CRUSHSTRIKE:
|
||||
case SC_REUSE_STORMBLAST: case SC_ALL_RIDING_REUSE_LIMIT:
|
||||
case SC_SPRITEMABLE: case SC_DORAM_BUF_01: case SC_DORAM_BUF_02:
|
||||
case SC_QUEST_BUFF1: case SC_QUEST_BUFF2: case SC_QUEST_BUFF3:
|
||||
case SC_CLAN_INFO: case SC_SWORDCLAN: case SC_ARCWANDCLAN:
|
||||
case SC_GOLDENMACECLAN: case SC_CROSSBOWCLAN:
|
||||
case SC_DAILYSENDMAILCNT:
|
||||
case SC_WEDDING: case SC_XMAS: case SC_SUMMER:
|
||||
case SC_DRESSUP: case SC_HANBOK: case SC_OKTOBERFEST:
|
||||
case SC_LHZ_DUN_N1: case SC_LHZ_DUN_N2: case SC_LHZ_DUN_N3: case SC_LHZ_DUN_N4:
|
||||
case SC_ENTRY_QUEUE_APPLY_DELAY: case SC_ENTRY_QUEUE_NOTIFY_ADMISSION_TIME_OUT:
|
||||
case SC_REUSE_LIMIT_LUXANIMA: case SC_LUXANIMA: case SC_SOULENERGY:
|
||||
case SC_EP16_2_BUFF_SS: case SC_EP16_2_BUFF_SC: case SC_EP16_2_BUFF_AC:
|
||||
case SC_EMERGENCY_MOVE: case SC_MADOGEAR: case SC_HOMUN_TIME:
|
||||
case SC_PACKING_ENVELOPE1: case SC_PACKING_ENVELOPE2: case SC_PACKING_ENVELOPE3:
|
||||
case SC_PACKING_ENVELOPE4: case SC_PACKING_ENVELOPE5: case SC_PACKING_ENVELOPE6:
|
||||
case SC_PACKING_ENVELOPE7: case SC_PACKING_ENVELOPE8: case SC_PACKING_ENVELOPE9: case SC_PACKING_ENVELOPE10:
|
||||
|
||||
if (it.second->flag[SCF_NOCLEARANCE])
|
||||
continue;
|
||||
case SC_ASSUMPTIO:
|
||||
if( bl->type == BL_MOB )
|
||||
continue;
|
||||
break;
|
||||
|
||||
switch (status) {
|
||||
case SC_WHISTLE: case SC_ASSNCROS: case SC_POEMBRAGI:
|
||||
case SC_APPLEIDUN: case SC_HUMMING: case SC_DONTFORGETME:
|
||||
case SC_FORTUNE: case SC_SERVICE4U:
|
||||
if (!battle_config.dispel_song || tsc->data[status]->val4 == 0)
|
||||
continue; //If in song area don't end it, even if config enabled
|
||||
break;
|
||||
case SC_ASSUMPTIO:
|
||||
if (bl->type == BL_MOB)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if(i == SC_BERSERK) tsc->data[i]->val2=0; //Mark a dispelled berserk to avoid setting hp to 100 by setting hp penalty to 0.
|
||||
status_change_end(bl,(sc_type)i,INVALID_TIMER);
|
||||
if (i == SC_BERSERK || i == SC_SATURDAYNIGHTFEVER)
|
||||
tsc->data[status]->val2 = 0; //Mark a dispelled berserk to avoid setting hp to 100 by setting hp penalty to 0.
|
||||
status_change_end(bl,status,INVALID_TIMER);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -11929,7 +11703,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
||||
struct status_change *sc = status_get_sc(&ele->bl);
|
||||
|
||||
if( (sc && sc->data[type2]) || (tsc && tsc->data[type]) ) {
|
||||
elemental_clean_single_effect(ele, skill_id);
|
||||
status_change_end(src,type,INVALID_TIMER);
|
||||
status_change_end(bl,type2,INVALID_TIMER);
|
||||
} else {
|
||||
clif_skill_nodamage(src,src,skill_id,skill_lv,1);
|
||||
if (!(skill_id >= EM_EL_FLAMETECHNIC && skill_id <= EM_EL_DEADLY_POISON))
|
||||
@@ -11957,7 +11732,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
||||
|
||||
clif_skill_nodamage(src,src,skill_id,skill_lv,1);
|
||||
if( (sc && sc->data[type2]) || (tsc && tsc->data[type]) ) {
|
||||
elemental_clean_single_effect(ele, skill_id);
|
||||
status_change_end(bl,type,INVALID_TIMER);
|
||||
status_change_end(src,type2,INVALID_TIMER);
|
||||
} else {
|
||||
// This not heals at the end.
|
||||
clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, DMG_SINGLE);
|
||||
@@ -13354,9 +13130,8 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
|
||||
sd = BL_CAST(BL_PC, src);
|
||||
|
||||
sc = status_get_sc(src);
|
||||
status_data *sstatus = status_get_status_data(src);
|
||||
type = status_skill2sc(skill_id);
|
||||
sce = (sc && type != -1)?sc->data[type]:NULL;
|
||||
type = skill_get_sc(skill_id);
|
||||
sce = (sc && type != SC_NONE)?sc->data[type]:NULL;
|
||||
|
||||
switch (skill_id) { //Skill effect.
|
||||
case WZ_METEOR:
|
||||
@@ -13746,7 +13521,9 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
|
||||
// Final heal increased by HPlus.
|
||||
// Is this the right place for this??? [Rytech]
|
||||
// Can HPlus also affect SP recovery???
|
||||
if (sd && sstatus->hplus > 0) {
|
||||
status_data *sstatus = status_get_status_data(src);
|
||||
|
||||
if (sstatus && sstatus->hplus > 0) {
|
||||
potion_hp += potion_hp * sstatus->hplus / 100;
|
||||
potion_sp += potion_sp * sstatus->hplus / 100;
|
||||
}
|
||||
@@ -14283,7 +14060,7 @@ int skill_castend_map (struct map_session_data *sd, uint16 skill_id, const char
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( ( sd->sc.opt1 && sd->sc.opt1 != OPT1_BURNING ) || sd->sc.option&OPTION_HIDE ) {
|
||||
if( sd->sc.cant.cast ) {
|
||||
skill_failed(sd);
|
||||
return 0;
|
||||
}
|
||||
@@ -15134,7 +14911,7 @@ static int skill_unit_onplace(struct skill_unit *unit, struct block_list *bl, t_
|
||||
if (sc && sc->data[SC_HOVERING] && skill->inf2[INF2_IGNOREHOVERING])
|
||||
return 0; // Under Hovering characters are immune to select trap and ground target skills.
|
||||
|
||||
type = status_skill2sc(sg->skill_id);
|
||||
type = skill_get_sc(sg->skill_id);
|
||||
sce = (sc && 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) {
|
||||
@@ -15463,7 +15240,7 @@ int skill_unit_onplace_timer(struct skill_unit *unit, struct block_list *bl, t_t
|
||||
tsc = status_get_sc(bl);
|
||||
sc = status_get_sc(ss);
|
||||
tstatus = status_get_status_data(bl);
|
||||
type = status_skill2sc(sg->skill_id);
|
||||
type = skill_get_sc(sg->skill_id);
|
||||
skill_id = sg->skill_id;
|
||||
|
||||
std::bitset<INF2_MAX> inf2 = skill_db.find(skill_id)->inf2;
|
||||
@@ -16234,8 +16011,8 @@ int skill_unit_onout(struct skill_unit *src, struct block_list *bl, t_tick tick)
|
||||
return 0;
|
||||
|
||||
sc = status_get_sc(bl);
|
||||
type = status_skill2sc(sg->skill_id);
|
||||
sce = (sc && type != -1)?sc->data[type]:NULL;
|
||||
type = skill_get_sc(sg->skill_id);
|
||||
sce = (sc && type != SC_NONE)?sc->data[type]:NULL;
|
||||
|
||||
if (bl->prev == NULL || (status_isdead(bl) && sg->unit_id != UNT_ANKLESNARE)) //Need to delete the trap if the source died.
|
||||
return 0;
|
||||
@@ -16265,8 +16042,8 @@ int skill_unit_onout(struct skill_unit *src, struct block_list *bl, t_tick tick)
|
||||
{
|
||||
for(uint16 i = BA_WHISTLE; i <= DC_SERVICEFORYOU; i++) {
|
||||
if(skill_get_inf2(i, INF2_ISSONG)) {
|
||||
type = status_skill2sc(i);
|
||||
sce = (sc && type != -1)?sc->data[type]:NULL;
|
||||
type = skill_get_sc(i);
|
||||
sce = (sc && type != SC_NONE)?sc->data[type]:NULL;
|
||||
if(sce)
|
||||
return i;
|
||||
}
|
||||
@@ -16302,8 +16079,8 @@ int skill_unit_onleft(uint16 skill_id, struct block_list *bl, t_tick tick)
|
||||
if (sc && !sc->count)
|
||||
sc = NULL;
|
||||
|
||||
type = status_skill2sc(skill_id);
|
||||
sce = (sc && type != -1)?sc->data[type]:NULL;
|
||||
type = skill_get_sc(skill_id);
|
||||
sce = (sc && type != SC_NONE)?sc->data[type]:NULL;
|
||||
|
||||
switch (skill_id)
|
||||
{
|
||||
@@ -16368,8 +16145,8 @@ int skill_unit_onleft(uint16 skill_id, struct block_list *bl, t_tick tick)
|
||||
{
|
||||
for(uint16 i = BA_WHISTLE; i <= DC_SERVICEFORYOU; i++){
|
||||
if(skill_get_inf2(i, INF2_ISSONG)){
|
||||
type = status_skill2sc(i);
|
||||
sce = (sc && type != -1)?sc->data[type]:NULL;
|
||||
type = skill_get_sc(i);
|
||||
sce = (sc && type != SC_NONE)?sc->data[type]:NULL;
|
||||
if(sce && !sce->val4){ //We don't want dissonance updating this anymore
|
||||
delete_timer(sce->timer, status_change_timer);
|
||||
sce->val4 = 1; //Store the fact that this is a "reduced" duration effect.
|
||||
@@ -16560,7 +16337,7 @@ int skill_check_condition_char_sub (struct block_list *bl, va_list ap)
|
||||
if(pc_isdead(tsd))
|
||||
return 0;
|
||||
|
||||
if (tsd->sc.data[SC_SILENCE] || ( tsd->sc.opt1 && tsd->sc.opt1 != OPT1_BURNING ))
|
||||
if (tsd->sc.cant.cast)
|
||||
return 0;
|
||||
|
||||
if( is_chorus ) {
|
||||
@@ -20299,10 +20076,9 @@ int skill_delunit(struct skill_unit* unit)
|
||||
case SC_ESCAPE:
|
||||
{
|
||||
struct block_list* target = map_id2bl(group->val2);
|
||||
enum sc_type type = status_skill2sc(group->skill_id);
|
||||
|
||||
if( target )
|
||||
status_change_end(target, type, INVALID_TIMER);
|
||||
status_change_end(target, SC_ANKLE, INVALID_TIMER);
|
||||
}
|
||||
break;
|
||||
case WZ_ICEWALL:
|
||||
@@ -20529,15 +20305,21 @@ int skill_delunitgroup_(std::shared_ptr<s_skill_unit_group> group, const char* f
|
||||
break;
|
||||
case SG_SUN_WARM:
|
||||
case SG_MOON_WARM:
|
||||
case SG_STAR_WARM:
|
||||
case LG_BANDING:
|
||||
{
|
||||
case SG_STAR_WARM: {
|
||||
status_change *sc = status_get_sc(src);
|
||||
sc_type type = status_skill2sc(group->skill_id);
|
||||
|
||||
if (sc && sc->data[type]) {
|
||||
sc->data[type]->val4 = 0;
|
||||
status_change_end(src, type, INVALID_TIMER);
|
||||
if (sc && sc->data[SC_WARM]) {
|
||||
sc->data[SC_WARM]->val4 = 0;
|
||||
status_change_end(src, SC_WARM, INVALID_TIMER);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LG_BANDING: {
|
||||
status_change *sc = status_get_sc(src);
|
||||
|
||||
if (sc && sc->data[SC_BANDING]) {
|
||||
sc->data[SC_BANDING]->val4 = 0;
|
||||
status_change_end(src, SC_BANDING, INVALID_TIMER);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -22118,12 +21900,11 @@ void skill_toggle_magicpower(struct block_list *bl, uint16 skill_id)
|
||||
status_change_end(bl, SC_MAGICPOWER, INVALID_TIMER);
|
||||
} else {
|
||||
sc->data[SC_MAGICPOWER]->val4 = 1;
|
||||
status_calc_bl(bl, status_sc2scb_flag(SC_MAGICPOWER));
|
||||
status_calc_bl(bl, status_db.getCalcFlag(SC_MAGICPOWER));
|
||||
if(bl->type == BL_PC){// update current display.
|
||||
clif_updatestatus(((TBL_PC *)bl),SP_MATK1);
|
||||
clif_updatestatus(((TBL_PC *)bl),SP_MATK2);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23138,6 +22919,10 @@ int skill_block_check(struct block_list *bl, sc_type type , uint16 skill_id) {
|
||||
*/
|
||||
int skill_disable_check(struct status_change *sc, uint16 skill_id)
|
||||
{
|
||||
enum sc_type type = skill_get_sc(skill_id);
|
||||
|
||||
if (type <= SC_NONE || type >= SC_MAX)
|
||||
return 0;
|
||||
switch( skill_id ) { //HP & SP Consumption Check
|
||||
case BS_MAXIMIZE:
|
||||
case NV_TRICKDEAD:
|
||||
@@ -23168,11 +22953,11 @@ int skill_disable_check(struct status_change *sc, uint16 skill_id)
|
||||
case SP_SOULCOLLECT:
|
||||
case IG_GUARD_STANCE:
|
||||
case IG_ATTACK_STANCE:
|
||||
if( sc->data[status_skill2sc(skill_id)] )
|
||||
if( sc->data[type] )
|
||||
return 1;
|
||||
break;
|
||||
|
||||
// These 2 skills contain a master and are not correctly pulled using skill2sc
|
||||
// These 2 skills contain a master and are not correctly pulled using skill_get_sc
|
||||
case NC_NEUTRALBARRIER:
|
||||
if( sc->data[SC_NEUTRALBARRIER_MASTER] )
|
||||
return 1;
|
||||
@@ -24226,6 +24011,31 @@ uint64 SkillDatabase::parseBodyNode(const YAML::Node &node) {
|
||||
}
|
||||
}
|
||||
|
||||
if (this->nodeExists(node, "Status")) {
|
||||
std::string status;
|
||||
|
||||
if (!this->asString(node, "Status", status))
|
||||
return 0;
|
||||
|
||||
std::string status_constant = "SC_" + status;
|
||||
int64 constant;
|
||||
|
||||
if (!script_get_constant(status_constant.c_str(), &constant)) {
|
||||
this->invalidWarning(node["Status"], "Status %s is invalid.\n", status.c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (constant < SC_NONE || constant >= SC_MAX) {
|
||||
this->invalidWarning(node["Status"], "Status %s is unknown. Defaulting to SC_NONE.\n", status.c_str());
|
||||
constant = SC_NONE;
|
||||
}
|
||||
|
||||
skill->sc = static_cast<sc_type>(constant);
|
||||
} else {
|
||||
if (!exists)
|
||||
skill->sc = SC_NONE;
|
||||
}
|
||||
|
||||
if (!exists) {
|
||||
this->put(skill_id, skill);
|
||||
this->skilldb_id2idx[skill_id] = this->skill_num;
|
||||
@@ -24722,15 +24532,8 @@ static bool skill_parse_row_skilldamage(char* split[], int columns, int current)
|
||||
return true;
|
||||
}
|
||||
|
||||
/*===============================
|
||||
* DB reading.
|
||||
* skill_db.yml
|
||||
* skill_nocast_db.txt
|
||||
* produce_db.txt
|
||||
* create_arrow_db.txt
|
||||
*------------------------------*/
|
||||
static void skill_readdb(void)
|
||||
{
|
||||
/** Reads skill database files */
|
||||
static void skill_readdb(void) {
|
||||
int i;
|
||||
const char* dbsubpath[] = {
|
||||
"",
|
||||
@@ -24757,6 +24560,7 @@ static void skill_readdb(void)
|
||||
safesnprintf(dbsubpath1,n1,"%s%s",db_path,dbsubpath[i]);
|
||||
safesnprintf(dbsubpath2,n1,"%s%s",db_path,dbsubpath[i]);
|
||||
}
|
||||
|
||||
sv_readdb(dbsubpath2, "skill_nocast_db.txt" , ',', 2, 2, -1, skill_parse_row_nocastdb, i > 0);
|
||||
|
||||
sv_readdb(dbsubpath2, "produce_db.txt" , ',', 5, 5+2*MAX_PRODUCE_RESOURCE, MAX_SKILL_PRODUCE_DB, skill_parse_row_producedb, i > 0);
|
||||
@@ -24784,7 +24588,6 @@ void skill_reload (void) {
|
||||
skill_arrow_db.clear();
|
||||
|
||||
skill_readdb();
|
||||
initChangeTables(); // Re-init Status Change tables
|
||||
|
||||
/* lets update all players skill tree : so that if any skill modes were changed they're properly updated */
|
||||
s_mapiterator *iter = mapit_getallusers();
|
||||
|
||||
Reference in New Issue
Block a user