From 8ff9db48cd5f38b532232b30c5ead723d09259cd Mon Sep 17 00:00:00 2001 From: skotlex Date: Thu, 14 Dec 2006 18:15:24 +0000 Subject: - Added function skill_strip to handle stripping code. The RG strip skills and GS_DISARM use it now. - Modified the strip-related status changes so they handle removing the equipped item instead of leaving it up to the skill-code. They return 0 when nothing could be stripped. - Cleaned some the MD_DETECTOR code. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@9499 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/skill.c | 147 +++++++++++++++++--------------------------------------- 1 file changed, 44 insertions(+), 103 deletions(-) (limited to 'src/map/skill.c') diff --git a/src/map/skill.c b/src/map/skill.c index c7f135df1..0c2485307 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -1356,22 +1356,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int rate = 3*skilllv; if (sstatus->dex > tstatus->dex) rate += (sstatus->dex - tstatus->dex)/5; - - if (rand()%100 >= rate) - break; - - if (dstsd) { - if (dstsd->equip_index[EQI_HAND_R]<0 || - !dstsd->inventory_data[dstsd->equip_index[EQI_HAND_R]] || - !(dstsd->unstripable_equip&EQP_WEAPON) || - (tsc && tsc->data[SC_CP_WEAPON].timer != -1) - ) //Fail - break; - pc_unequipitem(dstsd,dstsd->equip_index[EQI_HAND_R],3); - } else if (tstatus->mode&MD_BOSS || - (tsc && tsc->data[SC_CP_WEAPON].timer != -1)) - break; - sc_start(bl,SC_STRIPWEAPON,100,skilllv,skill_get_time(skillid,skilllv)); + skill_strip_equip(bl, EQP_WEAPON, rate, skilllv, skill_get_time(skillid,skilllv)); break; } @@ -1721,6 +1706,36 @@ int skill_break_equip (struct block_list *bl, unsigned short where, int rate, in return where; //Return list of pieces broken. } + +int skill_strip_equip(struct block_list *bl, unsigned short where, int rate, int lv, int time) +{ + struct status_change *sc; + const int pos[4] = {EQP_WEAPON, EQP_SHIELD, EQP_ARMOR, EQP_HELM}; + const int sc_atk[4] = {SC_STRIPWEAPON, SC_STRIPSHIELD, SC_STRIPARMOR, SC_STRIPHELM}; + const int sc_def[4] = {SC_CP_WEAPON, SC_CP_SHIELD, SC_CP_ARMOR, SC_CP_HELM}; + int i; + + if (rand()%100 >= rate) + return 0; + + sc = status_get_sc(bl); + if (!sc) + return 0; + + for (i = 0; i < sizeof(pos)/sizeof(pos[0]); i++) { + if (where&pos[i] && sc->data[sc_def[i]].timer != -1) + where&=~pos[i]; + } + if (!where) return 0; + + for (i = 0; i < sizeof(pos)/sizeof(pos[0]); i++) { + if (where&pos[i] && !sc_start(bl, sc_atk[i], 100, lv, time)) + where&=~pos[i]; + } + return where?1:0; +} + + /*========================================================================= Used to knock back players, monsters, traps, etc If count&0xf00000, the direction is send in the 6th byte. @@ -4429,106 +4444,32 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in case RG_STRIPSHIELD: case RG_STRIPARMOR: case RG_STRIPHELM: - case ST_FULLSTRIP: // Rewritten most of the code [DracoRPG] - { - int strip_fix, equip = 0; - int sclist[4] = {0,0,0,0}; - + case ST_FULLSTRIP: + i = 5+2*skilllv; + if (sstatus->dex > tstatus->dex) + i += (sstatus->dex - tstatus->dex)/5; switch (skillid) { case RG_STRIPWEAPON: - equip = EQP_WEAPON; + type = EQP_WEAPON; break; case RG_STRIPSHIELD: - equip = EQP_SHIELD; + type = EQP_SHIELD; break; case RG_STRIPARMOR: - equip = EQP_ARMOR; + type = EQP_ARMOR; break; case RG_STRIPHELM: - equip = EQP_HELM; + type = EQP_HELM; break; case ST_FULLSTRIP: - equip = EQP_WEAPON|EQP_SHIELD|EQP_ARMOR|EQP_HELM; - break; - } - - strip_fix = sstatus->dex - tstatus->dex; - if(strip_fix < 0) - strip_fix=0; - if (rand()%100 >= 5+2*skilllv+strip_fix/5) - { - if (sd) - clif_skill_fail(sd,skillid,0,0); + type = EQP_WEAPON|EQP_SHIELD|EQP_ARMOR|EQP_HELM; break; } - if (dstsd) { - for (i=0;iequip_index[i]<0 || !dstsd->inventory_data[dstsd->equip_index[i]]) - continue; - switch (i) { - case EQI_HAND_L: //Shield / left-hand weapon - if(dstsd->inventory_data[dstsd->equip_index[i]]->type == IT_ARMOR) - { //Shield - if (equip&EQP_SHIELD && - !(dstsd->unstripable_equip&EQP_SHIELD) && - !(tsc && tsc->data[SC_CP_SHIELD].timer != -1) - ){ - sclist[1] = SC_STRIPSHIELD; // Okay, we found a shield to strip - It is really a shield, not a two-handed weapon or a left-hand weapon - pc_unequipitem(dstsd,dstsd->equip_index[i],3); - } - continue; - } - //Continue to weapon - case EQI_HAND_R: - if (equip&EQP_WEAPON && - !(dstsd->unstripable_equip&EQP_WEAPON) && - !(tsc && tsc->data[SC_CP_WEAPON].timer != -1) - ) { - sclist[0] = SC_STRIPWEAPON; // Okay, we found a weapon to strip - It can be a right-hand, left-hand or two-handed weapon - pc_unequipitem(dstsd,dstsd->equip_index[i],3); - } - break; - case EQI_ARMOR: //Armor - if (equip &EQP_ARMOR && - !(dstsd->unstripable_equip &EQP_ARMOR) && - !(tsc && tsc->data[SC_CP_ARMOR].timer != -1) - ) { - sclist[2] = SC_STRIPARMOR; // Okay, we found an armor to strip - pc_unequipitem(dstsd,dstsd->equip_index[i],3); - } - break; - case EQI_HEAD_TOP: //Helm - if (equip &EQP_HELM && - !(dstsd->unstripable_equip &EQP_HELM) && - !(tsc && tsc->data[SC_CP_HELM].timer != -1) - ) { - sclist[3] = SC_STRIPHELM; // Okay, we found a helm to strip - pc_unequipitem(dstsd,dstsd->equip_index[i],3); - } - break; - } - } - } else if (!(tstatus->mode&MD_BOSS)) { - if (equip&EQP_WEAPON && !(tsc && tsc->data[SC_CP_WEAPON].timer != -1)) - sclist[0] = SC_STRIPWEAPON; - if (equip&EQP_SHIELD && !(tsc && tsc->data[SC_CP_SHIELD].timer != -1)) - sclist[1] = SC_STRIPSHIELD; - if (equip&EQP_ARMOR && !(tsc && tsc->data[SC_CP_ARMOR].timer != -1)) - sclist[2] = SC_STRIPARMOR; - if (equip&EQP_HELM && !(tsc && tsc->data[SC_CP_HELM].timer != -1)) - sclist[3] = SC_STRIPHELM; - } - equip = 0; //Reuse equip to hold how many stats are invoked. - for (i=0;i<4;i++) { - if (sclist[i]) // Start the SC only if an equipment was stripped from this location - equip+=sc_start(bl,sclist[i],100,skilllv,skill_get_time(skillid,skilllv)+strip_fix/2); - } - if (equip) - clif_skill_nodamage(src,bl,skillid,skilllv,1); - else if (sd) //Nothing stripped. - clif_skill_fail(sd,skillid,0,0); + if (!clif_skill_nodamage(src,bl,skillid,skilllv, + skill_strip_equip(bl, type, i, skilllv, skill_get_time(skillid,skilllv))) + && sd) + clif_skill_fail(sd,skillid,0,0); //Nothing stripped. break; - } /* PotionPitcher */ case AM_BERSERKPITCHER: -- cgit v1.2.3-60-g2f50