|
@@ -130,6 +130,7 @@ int overbrand_brandish_nounit_pos;
|
|
static char dir_ka = -1; // Holds temporary direction to the target for SR_KNUCKLEARROW
|
|
static char dir_ka = -1; // Holds temporary direction to the target for SR_KNUCKLEARROW
|
|
|
|
|
|
//Early declaration
|
|
//Early declaration
|
|
|
|
+bool skill_strip_equip(struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv);
|
|
int skill_block_check(struct block_list *bl, enum sc_type type, uint16 skill_id);
|
|
int skill_block_check(struct block_list *bl, enum sc_type type, uint16 skill_id);
|
|
static int skill_check_unit_range (struct block_list *bl, int x, int y, uint16 skill_id, uint16 skill_lv);
|
|
static int skill_check_unit_range (struct block_list *bl, int x, int y, uint16 skill_id, uint16 skill_lv);
|
|
static int skill_check_unit_range2 (struct block_list *bl, int x, int y, uint16 skill_id, uint16 skill_lv, bool isNearNPC);
|
|
static int skill_check_unit_range2 (struct block_list *bl, int x, int y, uint16 skill_id, uint16 skill_lv, bool isNearNPC);
|
|
@@ -1529,9 +1530,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
|
|
sc_start(src,bl,SC_FLING,100, sd?sd->spiritball_old:5,skill_get_time(skill_id,skill_lv));
|
|
sc_start(src,bl,SC_FLING,100, sd?sd->spiritball_old:5,skill_get_time(skill_id,skill_lv));
|
|
break;
|
|
break;
|
|
case GS_DISARM:
|
|
case GS_DISARM:
|
|
- rate = sstatus->dex / (4 * (7 - skill_lv)) + sstatus->luk / (4 * (6 - skill_lv));
|
|
|
|
- rate = rate + status_get_lv(src) - (tstatus->agi * rate / 100) - tstatus->luk - status_get_lv(bl);
|
|
|
|
- skill_strip_equip(src,bl, EQP_WEAPON, rate, skill_lv, skill_get_time(skill_id,skill_lv));
|
|
|
|
|
|
+ skill_strip_equip(src, bl, skill_id, skill_lv);
|
|
clif_skill_nodamage(src,bl,skill_id,skill_lv,1);
|
|
clif_skill_nodamage(src,bl,skill_id,skill_lv,1);
|
|
break;
|
|
break;
|
|
case NPC_EVILLAND:
|
|
case NPC_EVILLAND:
|
|
@@ -1563,15 +1562,10 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
|
|
sc_start4(src,bl,SC_BURNING,100,skill_lv,1000,src->id,0,skill_get_time(skill_id,skill_lv));
|
|
sc_start4(src,bl,SC_BURNING,100,skill_lv,1000,src->id,0,skill_get_time(skill_id,skill_lv));
|
|
break;
|
|
break;
|
|
case WL_EARTHSTRAIN:
|
|
case WL_EARTHSTRAIN:
|
|
- {
|
|
|
|
- uint16 i;
|
|
|
|
- const int pos[5] = { EQP_WEAPON, EQP_HELM, EQP_SHIELD, EQP_ARMOR, EQP_ACC };
|
|
|
|
|
|
+ if (dmg_lv != ATK_DEF) // Only strip if we make a successful hit.
|
|
|
|
+ break;
|
|
|
|
|
|
- if (dmg_lv != ATK_DEF) // Only strip if we make a successful hit.
|
|
|
|
- break;
|
|
|
|
- for (i = 0; i < skill_lv; i++)
|
|
|
|
- skill_strip_equip(src, bl, pos[i], 5 * skill_lv, skill_lv, skill_get_time2(skill_id, skill_lv));
|
|
|
|
- }
|
|
|
|
|
|
+ skill_strip_equip(src, bl, skill_id, skill_lv);
|
|
break;
|
|
break;
|
|
case WL_JACKFROST:
|
|
case WL_JACKFROST:
|
|
case NPC_JACKFROST:
|
|
case NPC_JACKFROST:
|
|
@@ -2623,32 +2617,135 @@ int skill_break_equip(struct block_list *src, struct block_list *bl, unsigned sh
|
|
return where; //Return list of pieces broken.
|
|
return where; //Return list of pieces broken.
|
|
}
|
|
}
|
|
|
|
|
|
-int skill_strip_equip(struct block_list *src,struct block_list *bl, unsigned short where, int rate, int lv, int time)
|
|
|
|
|
|
+/**
|
|
|
|
+ * Strip equipment from a target
|
|
|
|
+ * @param src: Source of call
|
|
|
|
+ * @param target: Target to strip
|
|
|
|
+ * @param skill_id: Skill used
|
|
|
|
+ * @param skill_lv: Skill level used
|
|
|
|
+ * @return True on successful strip or false otherwise
|
|
|
|
+ */
|
|
|
|
+bool skill_strip_equip(struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv)
|
|
{
|
|
{
|
|
- struct status_change *sc;
|
|
|
|
|
|
+ nullpo_retr(false, src);
|
|
|
|
+ nullpo_retr(false, target);
|
|
|
|
+
|
|
|
|
+ struct status_change *tsc = status_get_sc(target);
|
|
|
|
+
|
|
|
|
+ if (!tsc || tsc->option&OPTION_MADOGEAR) // Mado Gear cannot be divested [Ind]
|
|
|
|
+ return false;
|
|
|
|
+
|
|
const int pos[5] = {EQP_WEAPON, EQP_SHIELD, EQP_ARMOR, EQP_HELM, EQP_ACC};
|
|
const int pos[5] = {EQP_WEAPON, EQP_SHIELD, EQP_ARMOR, EQP_HELM, EQP_ACC};
|
|
const enum sc_type sc_atk[5] = {SC_STRIPWEAPON, SC_STRIPSHIELD, SC_STRIPARMOR, SC_STRIPHELM, SC__STRIPACCESSORY};
|
|
const enum sc_type sc_atk[5] = {SC_STRIPWEAPON, SC_STRIPSHIELD, SC_STRIPARMOR, SC_STRIPHELM, SC__STRIPACCESSORY};
|
|
const enum sc_type sc_def[5] = {SC_CP_WEAPON, SC_CP_SHIELD, SC_CP_ARMOR, SC_CP_HELM, SC_NONE};
|
|
const enum sc_type sc_def[5] = {SC_CP_WEAPON, SC_CP_SHIELD, SC_CP_ARMOR, SC_CP_HELM, SC_NONE};
|
|
- int i;
|
|
|
|
|
|
+ struct status_data *sstatus = status_get_status_data(src), *tstatus = status_get_status_data(target);
|
|
|
|
+ int rate, time, location;
|
|
|
|
+
|
|
|
|
+ switch (skill_id) { // Rate
|
|
|
|
+ case RG_STRIPWEAPON:
|
|
|
|
+ case RG_STRIPARMOR:
|
|
|
|
+ case RG_STRIPSHIELD:
|
|
|
|
+ case RG_STRIPHELM:
|
|
|
|
+ case GC_WEAPONCRUSH:
|
|
|
|
+ rate = 50 * (skill_lv + 1) + 2 * (sstatus->dex - tstatus->dex);
|
|
|
|
+ break;
|
|
|
|
+ case ST_FULLSTRIP: {
|
|
|
|
+ int min_rate = 50 + 20 * skill_lv;
|
|
|
|
+
|
|
|
|
+ rate = min_rate + 2 * (sstatus->dex - tstatus->dex);
|
|
|
|
+ rate = max(min_rate, rate);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ case GS_DISARM:
|
|
|
|
+ rate = sstatus->dex / (4 * (7 - skill_lv)) + sstatus->luk / (4 * (6 - skill_lv));
|
|
|
|
+ rate = rate + status_get_lv(src) - (tstatus->agi * rate / 100) - tstatus->luk - status_get_lv(target);
|
|
|
|
+ break;
|
|
|
|
+ case WL_EARTHSTRAIN: {
|
|
|
|
+ int job_lv = 0;
|
|
|
|
+
|
|
|
|
+ if (src->type == BL_PC)
|
|
|
|
+ job_lv = ((TBL_PC*)src)->status.job_level;
|
|
|
|
+ rate = 6 * skill_lv + job_lv / 4 + sstatus->dex / 10;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ case SC_STRIPACCESSARY:
|
|
|
|
+ rate = 12 + 2 * skill_lv;
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
|
|
if (rnd()%100 >= rate)
|
|
if (rnd()%100 >= rate)
|
|
- return 0;
|
|
|
|
|
|
+ return false;
|
|
|
|
|
|
- sc = status_get_sc(bl);
|
|
|
|
- if (!sc || sc->option&OPTION_MADOGEAR ) //Mado Gear cannot be divested [Ind]
|
|
|
|
- return 0;
|
|
|
|
|
|
+ switch (skill_id) { // Duration
|
|
|
|
+ case SC_STRIPACCESSARY:
|
|
|
|
+ case GS_DISARM:
|
|
|
|
+ time = skill_get_time(skill_id, skill_lv);
|
|
|
|
+ break;
|
|
|
|
+ case WL_EARTHSTRAIN:
|
|
|
|
+ case RG_STRIPWEAPON:
|
|
|
|
+ case RG_STRIPARMOR:
|
|
|
|
+ case RG_STRIPSHIELD:
|
|
|
|
+ case RG_STRIPHELM:
|
|
|
|
+ case GC_WEAPONCRUSH:
|
|
|
|
+ case ST_FULLSTRIP:
|
|
|
|
+ if (skill_id == WL_EARTHSTRAIN)
|
|
|
|
+ time = skill_get_time2(skill_id, skill_lv);
|
|
|
|
+ else
|
|
|
|
+ time = skill_get_time(skill_id, skill_lv);
|
|
|
|
+
|
|
|
|
+ if (target->type == BL_PC)
|
|
|
|
+ time += skill_lv + 500 * (sstatus->dex - tstatus->dex);
|
|
|
|
+ else {
|
|
|
|
+ time += 15000;
|
|
|
|
+ time += skill_lv + 500 * (sstatus->dex - tstatus->dex);
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ switch (skill_id) { // Location
|
|
|
|
+ case GC_WEAPONCRUSH:
|
|
|
|
+ case RG_STRIPWEAPON:
|
|
|
|
+ case GS_DISARM:
|
|
|
|
+ location = EQP_WEAPON;
|
|
|
|
+ break;
|
|
|
|
+ case RG_STRIPARMOR:
|
|
|
|
+ location = EQP_ARMOR;
|
|
|
|
+ break;
|
|
|
|
+ case RG_STRIPSHIELD:
|
|
|
|
+ location = EQP_SHIELD;
|
|
|
|
+ break;
|
|
|
|
+ case RG_STRIPHELM:
|
|
|
|
+ location = EQP_HELM;
|
|
|
|
+ break;
|
|
|
|
+ case ST_FULLSTRIP:
|
|
|
|
+ location = EQP_WEAPON|EQP_SHIELD|EQP_ARMOR|EQP_HELM;
|
|
|
|
+ break;
|
|
|
|
+ case SC_STRIPACCESSARY:
|
|
|
|
+ location = EQP_ACC;
|
|
|
|
+ break;
|
|
|
|
+ case WL_EARTHSTRAIN:
|
|
|
|
+ location = EQP_SHIELD|EQP_ARMOR|EQP_HELM;
|
|
|
|
+ if (skill_lv >= 4)
|
|
|
|
+ location |= EQP_WEAPON;
|
|
|
|
+ if (skill_lv >= 5)
|
|
|
|
+ location |= EQP_ACC;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
|
|
- for (i = 0; i < ARRAYLENGTH(pos); i++) {
|
|
|
|
- if (where&pos[i] && sc_def[i] > SC_NONE && sc->data[sc_def[i]])
|
|
|
|
- where&=~pos[i];
|
|
|
|
|
|
+ for (uint8 i = 0; i < ARRAYLENGTH(pos); i++) {
|
|
|
|
+ if (location&pos[i] && sc_def[i] > SC_NONE && tsc->data[sc_def[i]])
|
|
|
|
+ location &=~ pos[i];
|
|
}
|
|
}
|
|
- if (!where) return 0;
|
|
|
|
|
|
+ if (!location)
|
|
|
|
+ return false;
|
|
|
|
|
|
- for (i = 0; i < ARRAYLENGTH(pos); i++) {
|
|
|
|
- if (where&pos[i] && !sc_start(src,bl, sc_atk[i], 100, lv, time))
|
|
|
|
- where&=~pos[i];
|
|
|
|
|
|
+ for (uint8 i = 0; i < ARRAYLENGTH(pos); i++) {
|
|
|
|
+ if (location&pos[i] && !sc_start(src, target, sc_atk[i], 100, skill_lv, time))
|
|
|
|
+ location &=~ pos[i];
|
|
}
|
|
}
|
|
- return where?1:0;
|
|
|
|
|
|
+ return location ? true : false;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -7594,53 +7691,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
|
case ST_FULLSTRIP:
|
|
case ST_FULLSTRIP:
|
|
case GC_WEAPONCRUSH:
|
|
case GC_WEAPONCRUSH:
|
|
case SC_STRIPACCESSARY: {
|
|
case SC_STRIPACCESSARY: {
|
|
- unsigned short location = 0;
|
|
|
|
- int d = 0;
|
|
|
|
-
|
|
|
|
- //Rate in percent
|
|
|
|
- if ( skill_id == ST_FULLSTRIP ) {
|
|
|
|
- i = 5 + 2*skill_lv + (sstatus->dex - tstatus->dex)/5;
|
|
|
|
- } else if( skill_id == SC_STRIPACCESSARY ) {
|
|
|
|
- i = 12 + 2 * skill_lv + (sstatus->dex - tstatus->dex)/5;
|
|
|
|
- } else {
|
|
|
|
- i = 5 + 5*skill_lv + (sstatus->dex - tstatus->dex)/5;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (i < 5) i = 5; //Minimum rate 5%
|
|
|
|
-
|
|
|
|
- //Duration in ms
|
|
|
|
- if( skill_id == GC_WEAPONCRUSH){
|
|
|
|
- d = skill_get_time(skill_id,skill_lv);
|
|
|
|
- if(bl->type == BL_PC)
|
|
|
|
- d += skill_lv * 15 + (sstatus->dex - tstatus->dex);
|
|
|
|
- else
|
|
|
|
- d += skill_lv * 30 + (sstatus->dex - tstatus->dex) / 2;
|
|
|
|
- }else
|
|
|
|
- d = skill_get_time(skill_id,skill_lv) + (sstatus->dex - tstatus->dex)*500;
|
|
|
|
-
|
|
|
|
- if (d < 0) d = 0; //Minimum duration 0ms
|
|
|
|
-
|
|
|
|
- switch (skill_id) {
|
|
|
|
- case RG_STRIPWEAPON:
|
|
|
|
- case GC_WEAPONCRUSH:
|
|
|
|
- location = EQP_WEAPON;
|
|
|
|
- break;
|
|
|
|
- case RG_STRIPSHIELD:
|
|
|
|
- location = EQP_SHIELD;
|
|
|
|
- break;
|
|
|
|
- case RG_STRIPARMOR:
|
|
|
|
- location = EQP_ARMOR;
|
|
|
|
- break;
|
|
|
|
- case RG_STRIPHELM:
|
|
|
|
- location = EQP_HELM;
|
|
|
|
- break;
|
|
|
|
- case ST_FULLSTRIP:
|
|
|
|
- location = EQP_WEAPON|EQP_SHIELD|EQP_ARMOR|EQP_HELM;
|
|
|
|
- break;
|
|
|
|
- case SC_STRIPACCESSARY:
|
|
|
|
- location = EQP_ACC;
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
|
|
+ bool i;
|
|
|
|
|
|
//Special message when trying to use strip on FCP [Jobbie]
|
|
//Special message when trying to use strip on FCP [Jobbie]
|
|
if( sd && skill_id == ST_FULLSTRIP && tsc && tsc->data[SC_CP_WEAPON] && tsc->data[SC_CP_HELM] && tsc->data[SC_CP_ARMOR] && tsc->data[SC_CP_SHIELD])
|
|
if( sd && skill_id == ST_FULLSTRIP && tsc && tsc->data[SC_CP_WEAPON] && tsc->data[SC_CP_HELM] && tsc->data[SC_CP_ARMOR] && tsc->data[SC_CP_SHIELD])
|
|
@@ -7649,8 +7700,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
- //Attempts to strip at rate i and duration d
|
|
|
|
- if( (i = skill_strip_equip(src,bl, location, i, skill_lv, d)) || (skill_id != ST_FULLSTRIP && skill_id != GC_WEAPONCRUSH ) )
|
|
|
|
|
|
+ if( (i = skill_strip_equip(src, bl, skill_id, skill_lv)) || (skill_id != ST_FULLSTRIP && skill_id != GC_WEAPONCRUSH ) )
|
|
clif_skill_nodamage(src,bl,skill_id,skill_lv,i);
|
|
clif_skill_nodamage(src,bl,skill_id,skill_lv,i);
|
|
|
|
|
|
//Nothing stripped.
|
|
//Nothing stripped.
|